[dpdk-dev,v1,01/10] net/i40e: add API to convert VF Id to PF Id

Message ID 1503676941-80981-2-git-send-email-david.hunt@intel.com (mailing list archive)
State Superseded, archived
Headers

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel-compilation success Compilation OK

Commit Message

Hunt, David Aug. 25, 2017, 4:02 p.m. UTC
  Need a way to convert a vf id to a pf id on the host so as to query the pf
for relevant statistics which are used for the frequency changes in the
vm_power_manager app. Used when profiles are passed down from the guest
to the host, allowing the host to map the vfs to pfs.

Signed-off-by: Nemanja Marjanovic <nemanja.marjanovic@intel.com>
Signed-off-by: Rory Sexton <rory.sexton@intel.com>
Signed-off-by: David Hunt <david.hunt@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c |  1 +
 drivers/net/i40e/i40e_rxtx.c   | 27 +++++++++++++++++++++++++++
 drivers/net/i40e/i40e_rxtx.h   |  1 +
 lib/librte_ether/rte_ethdev.h  | 11 +++++++++++
 4 files changed, 40 insertions(+)
  

Comments

Thomas Monjalon Sept. 22, 2017, 9:56 a.m. UTC | #1
25/08/2017 18:02, David Hunt:
> 
> +static inline uint64_t
> +vfid_to_pfid_direct(uint8_t port_id, uint64_t vfid)
> +{
> +       struct rte_eth_dev *dev = &rte_eth_devices[port_id];
> +       uint64_t pfid  = (*dev->dev_ops->vfid_to_pfid)(dev, vfid);
> +       return pfid;
> +}

I would like to comment this API but there is no associated doxygen.

If the application is aware of the VFs, it probably already knows
how PF and VF are associated.

Until now, the functions to control VF from PF are driver-specifics.
  
Hunt, David Sept. 22, 2017, 12:39 p.m. UTC | #2
Hi Thomas,


On 22/9/2017 10:56 AM, Thomas Monjalon wrote:
> 25/08/2017 18:02, David Hunt:
>> +static inline uint64_t
>> +vfid_to_pfid_direct(uint8_t port_id, uint64_t vfid)
>> +{
>> +       struct rte_eth_dev *dev = &rte_eth_devices[port_id];
>> +       uint64_t pfid  = (*dev->dev_ops->vfid_to_pfid)(dev, vfid);
>> +       return pfid;
>> +}
> I would like to comment this API but there is no associated doxygen.

Sure, we'll add Doxygen comments.

>
> If the application is aware of the VFs, it probably already knows
> how PF and VF are associated.
>
> Until now, the functions to control VF from PF are driver-specifics.

Working out the relationship between the PF and the VF has turned out to 
be quite a challenge. :)

The application on the guest is aware of the VFs. The application on the 
host is aware of the PF and can access the VFs through the PF. However, 
the application on the host is not aware of how each VF on VM associates 
as which VF on the PF. I.E. the PF needs to know which index in its 
array of VFs the VF in use by the guest application is stored at. This 
is what this additional function is used for. It gives the PF the index 
of the VF in question in its array of VFs. We have researched 
alternative ways to determine this association but this is the only 
method that provides this functionality. Without this the PF does not 
know how each VF is associated with PF.

We also realize that the mac addresses need to be in sync between the 
host and the guest for correct operation of this scheme.

As mentioned in my previous mail, we are working on an updated patch 
set, targeting early next week.

Regards,
Dave.
  
Jingjing Wu Sept. 25, 2017, 2:43 a.m. UTC | #3
> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of David Hunt
> Sent: Saturday, August 26, 2017 12:02 AM
> To: dev@dpdk.org
> Cc: Hunt, David <david.hunt@intel.com>; Marjanovic, Nemanja
> <nemanja.marjanovic@intel.com>; Sexton, Rory <rory.sexton@intel.com>
> Subject: [dpdk-dev] [PATCH v1 01/10] net/i40e: add API to convert VF Id to PF Id
> 
> Need a way to convert a vf id to a pf id on the host so as to query the pf for
> relevant statistics which are used for the frequency changes in the
> vm_power_manager app. Used when profiles are passed down from the guest
> to the host, allowing the host to map the vfs to pfs.
> 
> Signed-off-by: Nemanja Marjanovic <nemanja.marjanovic@intel.com>
> Signed-off-by: Rory Sexton <rory.sexton@intel.com>
> Signed-off-by: David Hunt <david.hunt@intel.com>
> ---
>  drivers/net/i40e/i40e_ethdev.c |  1 +
>  drivers/net/i40e/i40e_rxtx.c   | 27 +++++++++++++++++++++++++++
>  drivers/net/i40e/i40e_rxtx.h   |  1 +
>  lib/librte_ether/rte_ethdev.h  | 11 +++++++++++
>  4 files changed, 40 insertions(+)
> 
> diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
> index 5f26e24..8fb67d8 100644
> --- a/drivers/net/i40e/i40e_ethdev.c
> +++ b/drivers/net/i40e/i40e_ethdev.c
> @@ -445,6 +445,7 @@ static const struct rte_pci_id pci_id_i40e_map[] = {  };
> 
>  static const struct eth_dev_ops i40e_eth_dev_ops = {
> +	.vfid_to_pfid                 = i40e_vf_mac_to_vsi,
>  	.dev_configure                = i40e_dev_configure,
>  	.dev_start                    = i40e_dev_start,
>  	.dev_stop                     = i40e_dev_stop,
> diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c index
> d42c23c..1379d5e 100644
> --- a/drivers/net/i40e/i40e_rxtx.c
> +++ b/drivers/net/i40e/i40e_rxtx.c
> @@ -806,6 +806,33 @@ i40e_recv_pkts(void *rx_queue, struct rte_mbuf
> **rx_pkts, uint16_t nb_pkts)
>  	return nb_rx;
>  }
> 
> +uint64_t
> +i40e_vf_mac_to_vsi(struct rte_eth_dev *dev, uint64_t vfid) {
> +	struct ether_addr *vf_mac_addr = (struct ether_addr *)&vfid;
> +	struct ether_addr *mac;
> +	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data-
> >dev_private);
> +	int vsi_id = 0, i, x;
> +	struct i40e_pf_vf *vf;
> +	uint16_t vf_num = pf->vf_num;
> +
> +	for (x = 0; x < vf_num; x++) {
> +		int mac_addr_matches = 1;
> +		vf = &pf->vfs[x];
> +		mac = &vf->mac_addr;
> +
> +		for (i = 0; i < ETHER_ADDR_LEN; i++) {
> +			if (mac->addr_bytes[i] != vf_mac_addr->addr_bytes[i])
> +				mac_addr_matches = 0;
> +		}
> +		if (mac_addr_matches) {
> +			vsi_id = vf->vsi->vsi_id;
> +			return vsi_id;
> +		}

vsi and vsi_id is not a common concept in API level.
How about just return vf_id and rename the function like i40e_query_vf_id_by_mac?
In i40e driver, we can get the vsi_id by vf_id.

> +	}
> +
> +	return -1;
It's an ops to API, you need to use error code but not -1.


Thanks
Jingjing
  
Hunt, David Sept. 25, 2017, 9:57 a.m. UTC | #4
On 25/9/2017 3:43 AM, Wu, Jingjing wrote:
>
>> -----Original Message-----
>> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of David Hunt
>> Sent: Saturday, August 26, 2017 12:02 AM
>> To: dev@dpdk.org
>> Cc: Hunt, David <david.hunt@intel.com>; Marjanovic, Nemanja
>> <nemanja.marjanovic@intel.com>; Sexton, Rory <rory.sexton@intel.com>
>> Subject: [dpdk-dev] [PATCH v1 01/10] net/i40e: add API to convert VF Id to PF Id
>>
>> Need a way to convert a vf id to a pf id on the host so as to query the pf for
>> relevant statistics which are used for the frequency changes in the
>> vm_power_manager app. Used when profiles are passed down from the guest
>> to the host, allowing the host to map the vfs to pfs.
>>
>> Signed-off-by: Nemanja Marjanovic <nemanja.marjanovic@intel.com>
>> Signed-off-by: Rory Sexton <rory.sexton@intel.com>
>> Signed-off-by: David Hunt <david.hunt@intel.com>
>> ---
>>   drivers/net/i40e/i40e_ethdev.c |  1 +
>>   drivers/net/i40e/i40e_rxtx.c   | 27 +++++++++++++++++++++++++++
>>   drivers/net/i40e/i40e_rxtx.h   |  1 +
>>   lib/librte_ether/rte_ethdev.h  | 11 +++++++++++
>>   4 files changed, 40 insertions(+)
>>
>> diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
>> index 5f26e24..8fb67d8 100644
>> --- a/drivers/net/i40e/i40e_ethdev.c
>> +++ b/drivers/net/i40e/i40e_ethdev.c
>> @@ -445,6 +445,7 @@ static const struct rte_pci_id pci_id_i40e_map[] = {  };
>>
>>   static const struct eth_dev_ops i40e_eth_dev_ops = {
>> +	.vfid_to_pfid                 = i40e_vf_mac_to_vsi,
>>   	.dev_configure                = i40e_dev_configure,
>>   	.dev_start                    = i40e_dev_start,
>>   	.dev_stop                     = i40e_dev_stop,
>> diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c index
>> d42c23c..1379d5e 100644
>> --- a/drivers/net/i40e/i40e_rxtx.c
>> +++ b/drivers/net/i40e/i40e_rxtx.c
>> @@ -806,6 +806,33 @@ i40e_recv_pkts(void *rx_queue, struct rte_mbuf
>> **rx_pkts, uint16_t nb_pkts)
>>   	return nb_rx;
>>   }
>>
>> +uint64_t
>> +i40e_vf_mac_to_vsi(struct rte_eth_dev *dev, uint64_t vfid) {
>> +	struct ether_addr *vf_mac_addr = (struct ether_addr *)&vfid;
>> +	struct ether_addr *mac;
>> +	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data-
>>> dev_private);
>> +	int vsi_id = 0, i, x;
>> +	struct i40e_pf_vf *vf;
>> +	uint16_t vf_num = pf->vf_num;
>> +
>> +	for (x = 0; x < vf_num; x++) {
>> +		int mac_addr_matches = 1;
>> +		vf = &pf->vfs[x];
>> +		mac = &vf->mac_addr;
>> +
>> +		for (i = 0; i < ETHER_ADDR_LEN; i++) {
>> +			if (mac->addr_bytes[i] != vf_mac_addr->addr_bytes[i])
>> +				mac_addr_matches = 0;
>> +		}
>> +		if (mac_addr_matches) {
>> +			vsi_id = vf->vsi->vsi_id;
>> +			return vsi_id;
>> +		}
> vsi and vsi_id is not a common concept in API level.

Agreed. We're removing from the API level in next patch set version.

> How about just return vf_id and rename the function like i40e_query_vf_id_by_mac?
> In i40e driver, we can get the vsi_id by vf_id.

The next revision will just return the vf_id, and we'll rename the 
function.

>> +	}
>> +
>> +	return -1;
> It's an ops to API, you need to use error code but not -1.

Will fix.

Thanks,
Dave,
  

Patch

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 5f26e24..8fb67d8 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -445,6 +445,7 @@  static const struct rte_pci_id pci_id_i40e_map[] = {
 };
 
 static const struct eth_dev_ops i40e_eth_dev_ops = {
+	.vfid_to_pfid                 = i40e_vf_mac_to_vsi,
 	.dev_configure                = i40e_dev_configure,
 	.dev_start                    = i40e_dev_start,
 	.dev_stop                     = i40e_dev_stop,
diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c
index d42c23c..1379d5e 100644
--- a/drivers/net/i40e/i40e_rxtx.c
+++ b/drivers/net/i40e/i40e_rxtx.c
@@ -806,6 +806,33 @@  i40e_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 	return nb_rx;
 }
 
+uint64_t
+i40e_vf_mac_to_vsi(struct rte_eth_dev *dev, uint64_t vfid) {
+	struct ether_addr *vf_mac_addr = (struct ether_addr *)&vfid;
+	struct ether_addr *mac;
+	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+	int vsi_id = 0, i, x;
+	struct i40e_pf_vf *vf;
+	uint16_t vf_num = pf->vf_num;
+
+	for (x = 0; x < vf_num; x++) {
+		int mac_addr_matches = 1;
+		vf = &pf->vfs[x];
+		mac = &vf->mac_addr;
+
+		for (i = 0; i < ETHER_ADDR_LEN; i++) {
+			if (mac->addr_bytes[i] != vf_mac_addr->addr_bytes[i])
+				mac_addr_matches = 0;
+		}
+		if (mac_addr_matches) {
+			vsi_id = vf->vsi->vsi_id;
+			return vsi_id;
+		}
+	}
+
+	return -1;
+}
+
 uint16_t
 i40e_recv_scattered_pkts(void *rx_queue,
 			 struct rte_mbuf **rx_pkts,
diff --git a/drivers/net/i40e/i40e_rxtx.h b/drivers/net/i40e/i40e_rxtx.h
index 20084d6..bc6d355 100644
--- a/drivers/net/i40e/i40e_rxtx.h
+++ b/drivers/net/i40e/i40e_rxtx.h
@@ -192,6 +192,7 @@  union i40e_tx_offload {
 	};
 };
 
+uint64_t i40e_vf_mac_to_vsi(struct rte_eth_dev *dev, uint64_t vfid);
 int i40e_dev_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id);
 int i40e_dev_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id);
 int i40e_dev_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id);
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 0adf327..fec7e92 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1411,6 +1411,8 @@  typedef int (*eth_l2_tunnel_offload_set_t)
 	 uint8_t en);
 /**< @internal enable/disable the l2 tunnel offload functions */
 
+typedef uint64_t  (*vfid_to_pfid)(struct rte_eth_dev *dev,
+				uint64_t vfid);
 
 typedef int (*eth_filter_ctrl_t)(struct rte_eth_dev *dev,
 				 enum rte_filter_type filter_type,
@@ -1429,6 +1431,7 @@  typedef int (*eth_get_dcb_info)(struct rte_eth_dev *dev,
  * @internal A structure containing the functions exported by an Ethernet driver.
  */
 struct eth_dev_ops {
+	vfid_to_pfid               vfid_to_pfid;  /**< Convert vfid to pfid */
 	eth_dev_configure_t        dev_configure; /**< Configure device. */
 	eth_dev_start_t            dev_start;     /**< Start device. */
 	eth_dev_stop_t             dev_stop;      /**< Stop device. */
@@ -2928,6 +2931,14 @@  static inline int rte_eth_tx_descriptor_status(uint8_t port_id,
 	return (*dev->dev_ops->tx_descriptor_status)(txq, offset);
 }
 
+static inline uint64_t
+vfid_to_pfid_direct(uint8_t port_id, uint64_t vfid)
+{
+	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+	uint64_t pfid  = (*dev->dev_ops->vfid_to_pfid)(dev, vfid);
+	return pfid;
+}
+
 /**
  * Send a burst of output packets on a transmit queue of an Ethernet device.
  *