Skip to contentSkip to conversation

switching device representation

PATCH New Declan Doherty 9 participants 73 messages Mar 28, 2018 – Apr 27, 2018

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

v6 cover switching device representation

This patchset follows on from the port rerpesentor patchsets and the community discussion that resulted. It outlines the model for representing and controlling switching capable devices in a new programmer's guide entry based upon the excellent summary by Adrien Mazarguil in
(http://dpdk.org/ml/archives/dev/2018-March/092513.html).

The next patches introduce changes to librte_ether to:
1, support the definition of a switch domain and make it public to application through the rte_eth_dev_info structure.
2, Add generic ethdev create/destroy APIs to facilitate and generalise the creation of ethdev's on different bus types.
3, Add ethdev attribute to dev_flags to specify that a port is a representor port and make public through the rte_eth_dev_info structure.
4, Add devargs parsing for generic eth_devargs to facilate parsing in NET PMDs. This will be refactored to take account of the changes in
(http://dpdk.org/ml/archives/dev/2018-March/092513.html)

This patchset also includes the enablement of port representor for ixgbe and i40e PF devices.

Adrien Mazarguil (1):
doc: add switch representation documentation

Declan Doherty (6):
ethdev: add switch identifier parameter to port
ethdev: add generic create/destroy ethdev APIs
ethdev: Add port representor device flag
app/testpmd: add port name to device info
net/i40e: add support for representor ports
net/ixgbe: add support for representor ports

Remy Horton (1):
ethdev: add common devargs parser

 app/test-pmd/config.c                           |   4 +
 doc/guides/prog_guide/index.rst                 |   1 +
 doc/guides/prog_guide/switch_representation.rst | 829 ++++++++++++++++++++++++
 drivers/net/i40e/Makefile                       |   3 +
 drivers/net/i40e/i40e_ethdev.c                  |  71 +-
 drivers/net/i40e/i40e_ethdev.h                  |  12 +
 drivers/net/i40e/i40e_vf_representor.c          | 392 +++++++++++
 drivers/net/i40e/meson.build                    |   4 +-
 drivers/net/i40e/rte_pmd_i40e.c                 |  43 ++
 drivers/net/i40e/rte_pmd_i40e.h                 |  18 +
 drivers/net/ixgbe/Makefile                      |   1 +
 drivers/net/ixgbe/ixgbe_ethdev.c                |  70 +-
 drivers/net/ixgbe/ixgbe_ethdev.h                |  12 +
 drivers/net/ixgbe/ixgbe_vf_representor.c        | 210 ++++++
 drivers/net/ixgbe/meson.build                   |   4 +-
 lib/Makefile                                    |   1 +
 lib/librte_ether/Makefile                       |   1 +
 lib/librte_ether/meson.build                    |   1 +
 lib/librte_ether/rte_ethdev.c                   | 291 ++++++++-
 lib/librte_ether/rte_ethdev.h                   |  10 +-
 lib/librte_ether/rte_ethdev_core.h              |   1 +
 lib/librte_ether/rte_ethdev_driver.h            |  87 +++
 lib/librte_ether/rte_ethdev_pci.h               |  12 +
 lib/librte_ether/rte_ethdev_representor.h       |  31 +
 lib/librte_ether/rte_ethdev_version.map         |   9 +
 25 files changed, 2097 insertions(+), 21 deletions(-)
 create mode 100644 doc/guides/prog_guide/switch_representation.rst
 create mode 100644 drivers/net/i40e/i40e_vf_representor.c
 create mode 100644 drivers/net/ixgbe/ixgbe_vf_representor.c
 create mode 100644 lib/librte_ether/rte_ethdev_representor.h
Signature · 1 line
2.14.3
#1 lore raw

PATCH v6 1/8 doc: add switch representation documentation

From: Adrien Mazarguil <[email protected]>

Add document to describe a model for representing switching capable devices in DPDK, using a general ethdev port model and through port representors.This document also details the port model and the rte_flow semantics required for flow programming, as well as listing some example use cases.

---
 doc/guides/prog_guide/index.rst                 |   1 +
 doc/guides/prog_guide/switch_representation.rst | 829 ++++++++++++++++++++++++
 2 files changed, 830 insertions(+)
 create mode 100644 doc/guides/prog_guide/switch_representation.rst
doc/guides/prog_guide/index.rst +1 -0
index bbbe7895d..09224af2e 100644
@@ -17,6 +17,7 @@ Programmer's Guide
     mbuf_lib
     poll_mode_drv
     rte_flow
+    switch_representation
     traffic_metering_and_policing
     traffic_management
     bbdev
doc/guides/prog_guide/switch_representation.rst new file +829 -0

829 lines not on this page · raw message

Signature · 1 line
2.14.3
#2 lore raw

Re: [PATCH v6 1/8] doc: add switch representation documentation

28/03/2018 15:54, Declan Doherty:

Quoted 9 lines

From: Adrien Mazarguil <[email protected]>

Add document to describe a model for representing switching capable devices in DPDK, using a general ethdev port model and through port representors.This document also details the port model and the rte_flow semantics required for flow programming, as well as listing some example use cases.

It is strange to have different From: and SoB:
If Adrien participated in this writing, he should have his SoB too I think.

#3 lore raw

Re: [PATCH v6 1/8] doc: add switch representation documentation

Quoted 9 lines · Thomas Monjalon

28/03/2018 15:54, Declan Doherty:

Quoted 8 lines

From: Adrien Mazarguil <[email protected]>

Add document to describe a model for representing switching capable devices in DPDK, using a general ethdev port model and through port representors.This document also details the port model and the rte_flow semantics required for flow programming, as well as listing some example use cases.

Quoted 7 lines
Quoted 1 line

It is strange to have different From: and SoB:
If Adrien participated in this writing, he should have his SoB too I think.

Yep, I just wanted to make sure that Adrien was credited with the generation of the content as he authored the vast majority of it in this mail (http://dpdk.org/ml/archives/dev/2018-March/092513.html) but I didn't want to assume his sign-off until he had a chance to comment. I'll address in next revision.

#4 lore raw

Re: [PATCH v6 1/8] doc: add switch representation documentation

In reply to Declan Doherty

Hi Declan,

Quoted 9 lines · Declan Doherty

From: Adrien Mazarguil <[email protected]>

Add document to describe a model for representing switching capable devices in DPDK, using a general ethdev port model and through port representors.This document also details the port model and the rte_flow semantics required for flow programming, as well as listing some example use cases.

OK for using the text of my original RFC, however since I'm not the *commit* author, I suggest to make it yours with:

git commit --amend --reset-author

You can then include my SoB line:

Thanks. More cosmetic comments below.

<snip>

Quoted 52 lines
doc/guides/prog_guide/switch_representation.rst new file +52 -0
+Port Representors
+-----------------
+
+In many cases, traffic steering rules cannot be determined in advance;
+applications usually have to process a bit of traffic in software before
+thinking about offloading specific flows to hardware.
+
+Applications therefore need the ability to receive and inject traffic to
+various device endpoints (other VFs, PFs or physical ports) before
+connecting them together. Device drivers must provide means to hook the
+"other end" of these endpoints and to refer them when configuring flow
+rules.
+
+This role is left to so-called "port representors" (also known as "VF
+representors" in the specific context of VFs), which are to DPDK what the
+Ethernet switch device driver model (**switchdev**) [1]_ is to Linux, and
+which can be thought as a software "patch panel" front-end for applications.
+
+- DPDK port representors are implemented as additional virtual Ethernet
+  device (**ethdev**) instances, spawned on an as needed basis through
+  configuration parameters passed to the driver of the underlying
+  device using devargs.
+
+::
+
+   -w pci:dbdf,representor=0
+   -w pci:dbdf,representor=[0-3]
+   -w pci:dbdf,representor=[0,5-11]
+
+- As virtual devices, they may be more limited than their physical
+  counterparts, for instance by exposing only a subset of device
+  configuration callbacks and/or by not necessarily having Rx/Tx capability.
+
+- Among other things, they can be used to assign MAC addresses to the
+  resource they represent.
+
+- Applications can tell port representors apart from other physcial of virtual
+  port by checking the dev_flags field within their device information
+  structure for the RTE_ETH_DEV_REPRESENTOR bit-field.
+
+.. code-block:: c
+
+  struct rte_eth_dev_info {
+	..
+	uint32_t dev_flags; /**< Device flags */
+	..
+  };
+
+- The device or group relationship of ports can be discovered using the
+  switch_id field within the device information structure. By default the
+  switch_id of a port will be it's port_id but ports within the same switch
+  domain will share the same *switch_id* which in the case of SR-IOV devices

doc/guides/prog_guide/switch_representation.rst line 98

Quoted 10 lines
doc/guides/prog_guide/switch_representation.rst new file +10 -0
+  would align to the port_id of the physical function port.
+
+.. code-block:: c
+
+  struct rte_eth_dev_info {
+	..
+	uint16_t switch_id; /**< Switch Domain Id */
+	..
+  };
+

OK for these additions, note this section may have to be updated later depending on how the API settles (especially on the devargs side) according to discussions which are still going on.

<snip>

Quoted 2 lines

+VF representors
+~~~~~~~~~~~~~~~

Looks like you capitalized all words in some section titles but missed others such as this one. I'm not a huge fan of capitalization in the middle of sentences and actually prefer the original form, but I know it's very common.

So I don't mind which you choose, however it should be consistent across all section titles.

<snip>

Quoted 28 lines
doc/guides/prog_guide/switch_representation.rst new file +28 -0
+Switching Examples
+------------------
+
+This section provides practical examples based on the established Testpmd
+flow command syntax [2]_, in the context described in `traffic steering`_
+
+::
+
+      .-------------.                 .-------------. .-------------.
+      | hypervisor  |                 |    VM 1     | |    VM 2     |
+      | application |                 | application | | application |
+      `--+---+---+--'                 `----------+--' `--+----------'
+         |   |   |                               |       |
+         |   |   `-------------------.           |       |
+         |   `---------.             |           |       |
+         |             |             |           |       |
+   .----(A)----. .----(B)----. .----(C)----.     |       |
+   | port_id 3 | | port_id 4 | | port_id 5 |     |       |
+   `-----+-----' `-----+-----' `-----+-----'     |       |
+        |             |             |           |       |
+      .-+--.    .-----+-----. .-----+-----. .---+--. .--+---.
+      | PF |    | VF 1 rep. | | VF 2 rep. | | VF 1 | | VF 2 |
+      `-+--'    `-----+-----' `-----+-----' `--(D)-' `-(E)--'
+        |             |             |           |       |
+        |             |   .---------'           |       |
+        `-----.       |   |   .-----------------'       |
+              |       |   |   |   .---------------------'
+              |       |   |   |   |

doc/guides/prog_guide/switch_representation.rst line 721

Quoted 10 lines
doc/guides/prog_guide/switch_representation.rst new file +10 -0
+           .--|-------|---|---|---|--.
+           |  |       |   `---|---'  |
+           |  |       `-------'      |
+           |  `---------.            |
+           `------------|------------'
+                        |
+                   .---(F)----.
+                   | physical |
+                   |  port 0  |
+                   `----------'

This diagram is a somewhat broken horizontally.

doc/guides/prog_guide/switch_representation.rst line 732

Quoted 11 lines
doc/guides/prog_guide/switch_representation.rst new file +11 -0
+
+By default, PF (**A**) can communicate with the physical port it is
+associated with (**F**), while VF 1 (**D**) and VF 2 (**E**) are isolated
+and restricted to communicate with the hypervisor application through their
+respective representors (**B** and **C**) if supported.
+
+Examples in subsequent sections apply to hypervisor applications only and
+are based on port representors **A**, **B** and **C**.
+
+.. [2] `Flow syntax
+    <http://dpdk.org/doc/guides/testpmd_app_ug/testpmd_funcs.html#flow-syntax>`

Internal documentation links should not go through HTTP where possible but use the ":ref:foo" syntax, see doc/guides/contributing/documentation.rst.

Signature · 2 lines
Adrien Mazarguil
6WIND
#5 lore raw

PATCH v6 2/8 ethdev: add switch identifier parameter to port

In reply to Declan Doherty

Introduces a new port attribute to ethdev port's which denotes the switch domain a port belongs to. By default all port's switch identifiers are the their port_id. Ports which share a common switch domain are configured with the same switch id.

---
 app/test-pmd/config.c              | 1 +
 lib/librte_ether/rte_ethdev.c      | 3 +++
 lib/librte_ether/rte_ethdev.h      | 1 +
 lib/librte_ether/rte_ethdev_core.h | 1 +
 4 files changed, 6 insertions(+)
app/test-pmd/config.c +1 -0
index 4bb255c62..e12f8c515 100644
@@ -517,6 +517,7 @@ port_infos_display(portid_t port_id)
 	printf("Min possible number of TXDs per queue: %hu\n",
 		dev_info.tx_desc_lim.nb_min);
 	printf("TXDs number alignment: %hu\n", dev_info.tx_desc_lim.nb_align);
+	printf("Switch Id: %u\n", dev_info.switch_id);
 }
 
 void
lib/librte_ether/rte_ethdev.c +3 -0
index 23857c91f..f32d18cad 100644
@@ -290,6 +290,8 @@ rte_eth_dev_allocate(const char *name)
 	eth_dev = eth_dev_get(port_id);
 	snprintf(eth_dev->data->name, sizeof(eth_dev->data->name), "%s", name);
 	eth_dev->data->port_id = port_id;
+	eth_dev->data->switch_id = port_id;
+	/**< Default switch_id is the port_id of the device */
 	eth_dev->data->mtu = ETHER_MTU;
 
 unlock:
@@ -2395,6 +2397,7 @@ rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info)
 	dev_info->driver_name = dev->device->driver->name;
 	dev_info->nb_rx_queues = dev->data->nb_rx_queues;
 	dev_info->nb_tx_queues = dev->data->nb_tx_queues;
+	dev_info->switch_id = dev->data->switch_id;
 }
 
 int
lib/librte_ether/rte_ethdev.h +1 -0
index 036153306..dced4fc41 100644
@@ -1029,6 +1029,7 @@ struct rte_eth_dev_info {
 	/** Configured number of rx/tx queues */
 	uint16_t nb_rx_queues; /**< Number of RX queues. */
 	uint16_t nb_tx_queues; /**< Number of TX queues. */
+	uint16_t switch_id; /**< Switch Domain Id */
 };
 
 /**
lib/librte_ether/rte_ethdev_core.h +1 -0
index e5681e466..caed7a4e6 100644
@@ -585,6 +585,7 @@ struct rte_eth_dev_data {
 	struct ether_addr* hash_mac_addrs;
 	/** Device Ethernet MAC addresses of hash filtering. */
 	uint16_t port_id;           /**< Device [external] port identifier. */
+	uint16_t switch_id;	    /**< Switch which port is associated with */
 	__extension__
 	uint8_t promiscuous   : 1, /**< RX promiscuous mode ON(1) / OFF(0). */
 		scattered_rx : 1,  /**< RX of scattered packets is ON(1) / OFF(0) */
Signature · 1 line
2.14.3
#6 lore raw

Re: [PATCH v6 2/8] ethdev: add switch identifier parameter to port

Hi Declan,

Thanks for the series! See some comments below

Wednesday, March 28, 2018 4:54 PM, Declan Doherty:

Quoted 34 lines

Subject: [dpdk-dev][PATCH v6 2/8] ethdev: add switch identifier parameter to port

Introduces a new port attribute to ethdev port's which denotes the switch domain a port belongs to. By default all port's switch identifiers are the their port_id. Ports which share a common switch domain are configured with the same switch id.

---
 app/test-pmd/config.c              | 1 +
 lib/librte_ether/rte_ethdev.c      | 3 +++
 lib/librte_ether/rte_ethdev.h      | 1 +
 lib/librte_ether/rte_ethdev_core.h | 1 +
 4 files changed, 6 insertions(+)
app/test-pmd/config.c index renamed from app/test-pmd/config.c +0 -0

4bb255c62..e12f8c515 100644

app/test-pmd/config.c +1 -0
@@ -517,6 +517,7 @@ port_infos_display(portid_t port_id)
 	printf("Min possible number of TXDs per queue: %hu\n",
 		dev_info.tx_desc_lim.nb_min);
 	printf("TXDs number alignment: %hu\n",
 dev_info.tx_desc_lim.nb_align);
+	printf("Switch Id: %u\n", dev_info.switch_id);
 }
 

void

lib/librte_ether/rte_ethdev.c +0 -0
index 23857c91f..f32d18cad 100644

lib/librte_ether/rte_ethdev.c rte_eth_dev_allocate(const char *name) · line 295

Quoted 6 lines
lib/librte_ether/rte_ethdev.c +2 -0
@@ -290,6 +290,8 @@ rte_eth_dev_allocate(const char *name)
 	eth_dev = eth_dev_get(port_id);
 	snprintf(eth_dev->data->name, sizeof(eth_dev->data->name),
 "%s", name);
 	eth_dev->data->port_id = port_id;
+	eth_dev->data->switch_id = port_id;
+	/**< Default switch_id is the port_id of the device */

Why such default is needed? Why not let the PMD to set it always?

lib/librte_ether/rte_ethdev.c rte_eth_dev_info_get(uint16_t port_id, struct · line 2401

Quoted 9 lines
lib/librte_ether/rte_ethdev.c +0 -0
 	eth_dev->data->mtu = ETHER_MTU;
 

unlock:

lib/librte_ether/rte_ethdev.c +1 -0
@@ -2395,6 +2397,7 @@ rte_eth_dev_info_get(uint16_t port_id, struct
 rte_eth_dev_info *dev_info)
 	dev_info->driver_name = dev->device->driver->name;
 	dev_info->nb_rx_queues = dev->data->nb_rx_queues;
 	dev_info->nb_tx_queues = dev->data->nb_tx_queues;
+	dev_info->switch_id = dev->data->switch_id;

Why there is a need to keep the switch_id on device data?
I think PMD to store it on its private structure and report it in dev_info is enough.

Quoted 33 lines
lib/librte_ether/rte_ethdev.c +0 -0
 }
 

int

lib/librte_ether/rte_ethdev.h +1 -0
index 036153306..dced4fc41 100644
@@ -1029,6 +1029,7 @@ struct rte_eth_dev_info {
 	/** Configured number of rx/tx queues */
 	uint16_t nb_rx_queues; /**< Number of RX queues. */
 	uint16_t nb_tx_queues; /**< Number of TX queues. */
+	uint16_t switch_id; /**< Switch Domain Id */
 };
 
 /**
lib/librte_ether/rte_ethdev_core.h +1 -0
index e5681e466..caed7a4e6 100644
@@ -585,6 +585,7 @@ struct rte_eth_dev_data {
 	struct ether_addr* hash_mac_addrs;
 	/** Device Ethernet MAC addresses of hash filtering. */
 	uint16_t port_id;           /**< Device [external] port identifier. */
+	uint16_t switch_id;	    /**< Switch which port is associated with
 */
 	__extension__
 	uint8_t promiscuous   : 1, /**< RX promiscuous mode ON(1) / OFF(0).

*/
scattered_rx : 1, /**< RX of scattered packets is ON(1) /
OFF(0) */
--
2.14.3

#7 lore raw

Re: [PATCH v6 2/8] ethdev: add switch identifier parameter to port

Quoted 33 lines · Shahaf Shuler

Hi Declan,

Thanks for the series! See some comments below

Wednesday, March 28, 2018 4:54 PM, Declan Doherty:

Quoted 28 lines

Subject: [dpdk-dev][PATCH v6 2/8] ethdev: add switch identifier parameter to port

Introduces a new port attribute to ethdev port's which denotes the switch domain a port belongs to. By default all port's switch identifiers are the their port_id. Ports which share a common switch domain are configured with the same switch id.

---
  app/test-pmd/config.c              | 1 +
  lib/librte_ether/rte_ethdev.c      | 3 +++
  lib/librte_ether/rte_ethdev.h      | 1 +
  lib/librte_ether/rte_ethdev_core.h | 1 +
  4 files changed, 6 insertions(+)
app/test-pmd/config.c index renamed from app/test-pmd/config.c +0 -0

4bb255c62..e12f8c515 100644

app/test-pmd/config.c +1 -0
@@ -517,6 +517,7 @@ port_infos_display(portid_t port_id)
  	printf("Min possible number of TXDs per queue: %hu\n",
  		dev_info.tx_desc_lim.nb_min);
  	printf("TXDs number alignment: %hu\n",
 dev_info.tx_desc_lim.nb_align);
+	printf("Switch Id: %u\n", dev_info.switch_id);
  }
 
Quoted 14 lines

lib/librte_ether/rte_ethdev.c rte_eth_dev_allocate(const char *name) · line 295

Quoted 12 lines

void

lib/librte_ether/rte_ethdev.c +2 -0
index 23857c91f..f32d18cad 100644
@@ -290,6 +290,8 @@ rte_eth_dev_allocate(const char *name)
  	eth_dev = eth_dev_get(port_id);
  	snprintf(eth_dev->data->name, sizeof(eth_dev->data->name),
 "%s", name);
  	eth_dev->data->port_id = port_id;
+	eth_dev->data->switch_id = port_id;
+	/**< Default switch_id is the port_id of the device */

Why such default is needed? Why not let the PMD to set it always?

I saw this a simple way to have a consistent default value (the port_id) for all PMDs, without the need to modify existing PMD which don't currently have any concept of a switch domain.

Also taking the approach of just leaving it up to the PMD to decide the value would mean that some form of synchronisation would be required so that two device don't select the switch domain identifier.

Quoted 14 lines

lib/librte_ether/rte_ethdev.c rte_eth_dev_info_get(uint16_t port_id, struct · line 2401

Quoted 10 lines
lib/librte_ether/rte_ethdev.c +0 -0
  	eth_dev->data->mtu = ETHER_MTU;
 

unlock:

lib/librte_ether/rte_ethdev.c +1 -0
@@ -2395,6 +2397,7 @@ rte_eth_dev_info_get(uint16_t port_id, struct
 rte_eth_dev_info *dev_info)
  	dev_info->driver_name = dev->device->driver->name;
  	dev_info->nb_rx_queues = dev->data->nb_rx_queues;
  	dev_info->nb_tx_queues = dev->data->nb_tx_queues;
+	dev_info->switch_id = dev->data->switch_id;

Why there is a need to keep the switch_id on device data?
I think PMD to store it on its private structure and report it in dev_info is enough.

That way would require every PMD to be modified to maintain a switch_id structure, which I know isn't a big deal, as only the device which need to support it would need it, but we would need to change the dev_info->switch_id from being a uint16_t to being a signed value so we could have a default of -1 for device which don't support switch domain. I thought the former approach was cleaner.

Quoted 34 lines
Quoted 33 lines
lib/librte_ether/rte_ethdev.c +0 -0
  }
 

int

lib/librte_ether/rte_ethdev.h +1 -0
index 036153306..dced4fc41 100644
@@ -1029,6 +1029,7 @@ struct rte_eth_dev_info {
  	/** Configured number of rx/tx queues */
  	uint16_t nb_rx_queues; /**< Number of RX queues. */
  	uint16_t nb_tx_queues; /**< Number of TX queues. */
+	uint16_t switch_id; /**< Switch Domain Id */
  };
 
  /**
lib/librte_ether/rte_ethdev_core.h +1 -0
index e5681e466..caed7a4e6 100644
@@ -585,6 +585,7 @@ struct rte_eth_dev_data {
  	struct ether_addr* hash_mac_addrs;
  	/** Device Ethernet MAC addresses of hash filtering. */
  	uint16_t port_id;           /**< Device [external] port identifier. */
+	uint16_t switch_id;	    /**< Switch which port is associated with
 */
  	__extension__
  	uint8_t promiscuous   : 1, /**< RX promiscuous mode ON(1) / OFF(0).

*/
scattered_rx : 1, /**< RX of scattered packets is ON(1) /
OFF(0) */
--
2.14.3

#8 lore raw

Re: [PATCH v6 2/8] ethdev: add switch identifier parameter to port

Thursday, March 29, 2018 12:14 PM, Doherty, Declan:

Quoted 50 lines · Shahaf Shuler
Quoted 33 lines

Hi Declan,

Thanks for the series! See some comments below

Wednesday, March 28, 2018 4:54 PM, Declan Doherty:

Quoted 28 lines

Subject: [dpdk-dev][PATCH v6 2/8] ethdev: add switch identifier parameter to port

Introduces a new port attribute to ethdev port's which denotes the switch domain a port belongs to. By default all port's switch identifiers are the their port_id. Ports which share a common switch domain are configured with the same switch id.

---
  app/test-pmd/config.c              | 1 +
  lib/librte_ether/rte_ethdev.c      | 3 +++
  lib/librte_ether/rte_ethdev.h      | 1 +
  lib/librte_ether/rte_ethdev_core.h | 1 +
  4 files changed, 6 insertions(+)
app/test-pmd/config.c index renamed from app/test-pmd/config.c +0 -0

4bb255c62..e12f8c515 100644

app/test-pmd/config.c +1 -0
@@ -517,6 +517,7 @@ port_infos_display(portid_t port_id)
  	printf("Min possible number of TXDs per queue: %hu\n",
  		dev_info.tx_desc_lim.nb_min);
  	printf("TXDs number alignment: %hu\n",
 dev_info.tx_desc_lim.nb_align);
+	printf("Switch Id: %u\n", dev_info.switch_id);
  }
 
Quoted 8 lines

lib/librte_ether/rte_ethdev.c rte_eth_dev_allocate(const char *name) · line 291

Quoted 8 lines

void

(quoted diff) +0 -0

b/lib/librte_ether/rte_ethdev.c index 23857c91f..f32d18cad 100644

lib/librte_ether/rte_ethdev.c +0 -0
@@ -290,6 +290,8 @@ rte_eth_dev_allocate(const char *name)
  	eth_dev = eth_dev_get(port_id);
  	snprintf(eth_dev->data->name, sizeof(eth_dev->data->name),

"%s",

Quoted 6 lines

lib/librte_ether/rte_ethdev.c rte_eth_dev_allocate(const char *name) · line 294

Quoted 4 lines
lib/librte_ether/rte_ethdev.c +2 -0
 name);
  	eth_dev->data->port_id = port_id;
+	eth_dev->data->switch_id = port_id;
+	/**< Default switch_id is the port_id of the device */

Why such default is needed? Why not let the PMD to set it always?

Quoted 3 lines

I saw this a simple way to have a consistent default value (the port_id) for all PMDs, without the need to modify existing PMD which don't currently have any concept of a switch domain.

The default value don't makes much sense though. By default it would mean the application each port is on different switch domain. This is obviously not true in case of multiple VFs

Maybe we can define ETH_SWITCH_ID_INVALID (0) to emphasis 0 is not the switch_id for the PMDs which didn't implemented it.

Quoted 4 lines

Also taking the approach of just leaving it up to the PMD to decide the value would mean that some form of synchronisation would be required so that two device don't select the switch domain identifier.

What kind of knowledge ethdev layer has to set the switche_id? It should be based on the underlying capabilities of the device. Some devices will use the kernel sysfs to check that.

Maybe there are devices which are able to expose the same switch for multiple devices, passing the packet between them using peer2peer trough the PCI.

The point is we need to have APIs which will enable all the future flexibility.

Maybe we can have array of switch_id which are allready taken by the underlying devices, and PMD will register their switch_id to it atomically. To ease the synchronization.

Quoted 14 lines
Quoted 4 lines
Quoted 4 lines
lib/librte_ether/rte_ethdev.c +0 -0
  	eth_dev->data->mtu = ETHER_MTU;
 
Quoted 10 lines

lib/librte_ether/rte_ethdev.c rte_eth_dev_info_get(uint16_t port_id, struct · line 2401

Quoted 7 lines

unlock:

lib/librte_ether/rte_ethdev.c +1 -0
@@ -2395,6 +2397,7 @@ rte_eth_dev_info_get(uint16_t port_id, struct
 rte_eth_dev_info *dev_info)
  	dev_info->driver_name = dev->device->driver->name;
  	dev_info->nb_rx_queues = dev->data->nb_rx_queues;
  	dev_info->nb_tx_queues = dev->data->nb_tx_queues;
+	dev_info->switch_id = dev->data->switch_id;

Why there is a need to keep the switch_id on device data?
I think PMD to store it on its private structure and report it in dev_info is

Quoted 8 lines

enough.

Quoted 1 line

That way would require every PMD to be modified to maintain a switch_id structure, which I know isn't a big deal, as only the device which need to support it would need it, but we would need to change the dev_info-

Quoted 1 line

switch_id from being a uint16_t to being a signed value so we could have a

default of -1 for device which don't support switch domain.

We can say also 0 is the invalid switch id.

Quoted 36 lines

I thought the former approach was cleaner.

Quoted 34 lines
Quoted 33 lines
lib/librte_ether/rte_ethdev.c +0 -0
  }
 

int

(quoted diff) +0 -0

b/lib/librte_ether/rte_ethdev.h index 036153306..dced4fc41 100644

lib/librte_ether/rte_ethdev.h +1 -0
@@ -1029,6 +1029,7 @@ struct rte_eth_dev_info {
  	/** Configured number of rx/tx queues */
  	uint16_t nb_rx_queues; /**< Number of RX queues. */
  	uint16_t nb_tx_queues; /**< Number of TX queues. */
+	uint16_t switch_id; /**< Switch Domain Id */
  };
 
  /**
lib/librte_ether/rte_ethdev_core.h +1 -0
index e5681e466..caed7a4e6 100644
@@ -585,6 +585,7 @@ struct rte_eth_dev_data {
  	struct ether_addr* hash_mac_addrs;
  	/** Device Ethernet MAC addresses of hash filtering. */
  	uint16_t port_id;           /**< Device [external] port identifier. */
+	uint16_t switch_id;	    /**< Switch which port is associated with
 */
  	__extension__
  	uint8_t promiscuous   : 1, /**< RX promiscuous mode ON(1) / OFF(0).

*/
scattered_rx : 1, /**< RX of scattered packets is ON(1) /
OFF(0) */
--
2.14.3

#9 lore raw

Re: [PATCH v6 2/8] ethdev: add switch identifier parameter to port

Quoted 51 lines · Shahaf Shuler

Thursday, March 29, 2018 12:14 PM, Doherty, Declan:

Quoted 50 lines · Shahaf Shuler
Quoted 33 lines

Hi Declan,

Thanks for the series! See some comments below

Wednesday, March 28, 2018 4:54 PM, Declan Doherty:

Quoted 28 lines

Subject: [dpdk-dev][PATCH v6 2/8] ethdev: add switch identifier parameter to port

Introduces a new port attribute to ethdev port's which denotes the switch domain a port belongs to. By default all port's switch identifiers are the their port_id. Ports which share a common switch domain are configured with the same switch id.

---
   app/test-pmd/config.c              | 1 +
   lib/librte_ether/rte_ethdev.c      | 3 +++
   lib/librte_ether/rte_ethdev.h      | 1 +
   lib/librte_ether/rte_ethdev_core.h | 1 +
   4 files changed, 6 insertions(+)
app/test-pmd/config.c index renamed from app/test-pmd/config.c +0 -0

4bb255c62..e12f8c515 100644

app/test-pmd/config.c +1 -0
@@ -517,6 +517,7 @@ port_infos_display(portid_t port_id)
   	printf("Min possible number of TXDs per queue: %hu\n",
   		dev_info.tx_desc_lim.nb_min);
   	printf("TXDs number alignment: %hu\n",
 dev_info.tx_desc_lim.nb_align);
+	printf("Switch Id: %u\n", dev_info.switch_id);
   }
 
Quoted 8 lines

lib/librte_ether/rte_ethdev.c rte_eth_dev_allocate(const char *name) · line 291

Quoted 8 lines

void

(quoted diff) +0 -0

b/lib/librte_ether/rte_ethdev.c index 23857c91f..f32d18cad 100644

lib/librte_ether/rte_ethdev.c +0 -0
@@ -290,6 +290,8 @@ rte_eth_dev_allocate(const char *name)
   	eth_dev = eth_dev_get(port_id);
   	snprintf(eth_dev->data->name, sizeof(eth_dev->data->name),

"%s",

Quoted 6 lines

lib/librte_ether/rte_ethdev.c rte_eth_dev_allocate(const char *name) · line 294

Quoted 4 lines
lib/librte_ether/rte_ethdev.c +2 -0
 name);
   	eth_dev->data->port_id = port_id;
+	eth_dev->data->switch_id = port_id;
+	/**< Default switch_id is the port_id of the device */

Why such default is needed? Why not let the PMD to set it always?

Quoted 5 lines
Quoted 3 lines

I saw this a simple way to have a consistent default value (the port_id) for all PMDs, without the need to modify existing PMD which don't currently have any concept of a switch domain.

The default value don't makes much sense though. By default it would mean the application each port is on different switch domain. This is obviously not true in case of multiple VFs

But it is the case today for all ports, that they are assumed to be in separate switch domains or at least in unknowable switch domains by applications, with the exception of LAG groups, were it is implicit that they are in the same domain. Even if two ports were attached to the same switch, or if you where using multiple VFs from the same switch there is currently no way of telling the application that this is the case. What would be the use case for having multiple VFs from the same port/switch domain in a single data path application. It doesn't seem likely to me that you would use hardware switching to move traffic between 2 VFs in the same data path application.

If you are using port representors, I assumed that you would set a valid switch domain id, possibly picking up the port id of the first port created on that switch domain, but it would be completely up to the PMD how this was done, I have just shown the simplest model in which the port_id of the PF is used for all subsequent representor ports in that switch domain, but if you wanted to create multiple domains within the same device, you could just use subsequent port representors port_ids to setup further switch domains. A switch_id is only meaningful within the contex of DPDK process it is running in.

Quoted 79 lines

Maybe we can define ETH_SWITCH_ID_INVALID (0) to emphasis 0 is not the switch_id for the PMDs which didn't implemented it.

Quoted 4 lines

Also taking the approach of just leaving it up to the PMD to decide the value would mean that some form of synchronisation would be required so that two device don't select the switch domain identifier.

What kind of knowledge ethdev layer has to set the switche_id? It should be based on the underlying capabilities of the device. Some devices will use the kernel sysfs to check that.

Maybe there are devices which are able to expose the same switch for multiple devices, passing the packet between them using peer2peer trough the PCI.

The point is we need to have APIs which will enable all the future flexibility.

Maybe we can have array of switch_id which are allready taken by the underlying devices, and PMD will register their switch_id to it atomically. To ease the synchronization.

Quoted 14 lines
Quoted 4 lines
Quoted 4 lines
lib/librte_ether/rte_ethdev.c +0 -0
   	eth_dev->data->mtu = ETHER_MTU;
 
Quoted 10 lines

lib/librte_ether/rte_ethdev.c rte_eth_dev_info_get(uint16_t port_id, struct · line 2401

Quoted 7 lines

unlock:

lib/librte_ether/rte_ethdev.c +1 -0
@@ -2395,6 +2397,7 @@ rte_eth_dev_info_get(uint16_t port_id, struct
 rte_eth_dev_info *dev_info)
   	dev_info->driver_name = dev->device->driver->name;
   	dev_info->nb_rx_queues = dev->data->nb_rx_queues;
   	dev_info->nb_tx_queues = dev->data->nb_tx_queues;
+	dev_info->switch_id = dev->data->switch_id;

Why there is a need to keep the switch_id on device data?
I think PMD to store it on its private structure and report it in dev_info is

Quoted 8 lines

enough.

Quoted 1 line

That way would require every PMD to be modified to maintain a switch_id structure, which I know isn't a big deal, as only the device which need to support it would need it, but we would need to change the dev_info-

Quoted 1 line

switch_id from being a uint16_t to being a signed value so we could have a

default of -1 for device which don't support switch domain.

We can say also 0 is the invalid switch id.

Quoted 36 lines

I thought the former approach was cleaner.

Quoted 34 lines
Quoted 33 lines
lib/librte_ether/rte_ethdev.c +0 -0
   }
 

int

(quoted diff) +0 -0

b/lib/librte_ether/rte_ethdev.h index 036153306..dced4fc41 100644

lib/librte_ether/rte_ethdev.h +1 -0
@@ -1029,6 +1029,7 @@ struct rte_eth_dev_info {
   	/** Configured number of rx/tx queues */
   	uint16_t nb_rx_queues; /**< Number of RX queues. */
   	uint16_t nb_tx_queues; /**< Number of TX queues. */
+	uint16_t switch_id; /**< Switch Domain Id */
   };
 
   /**
lib/librte_ether/rte_ethdev_core.h +1 -0
index e5681e466..caed7a4e6 100644
@@ -585,6 +585,7 @@ struct rte_eth_dev_data {
   	struct ether_addr* hash_mac_addrs;
   	/** Device Ethernet MAC addresses of hash filtering. */
   	uint16_t port_id;           /**< Device [external] port identifier. */
+	uint16_t switch_id;	    /**< Switch which port is associated with
 */
   	__extension__
   	uint8_t promiscuous   : 1, /**< RX promiscuous mode ON(1) / OFF(0).

*/
scattered_rx : 1, /**< RX of scattered packets is ON(1) /
OFF(0) */
--
2.14.3

#10 lore raw

Re: [PATCH v6 2/8] ethdev: add switch identifier parameter to port

--Shahaf

Quoted 80 lines

-----Original Message-----
From: Doherty, Declan [mailto:[email protected]]
Sent: Thursday, March 29, 2018 6:13 PM
To: Shahaf Shuler <[email protected]>; [email protected]
Cc: Alex Rosenbaum <[email protected]>; Ferruh Yigit <[email protected]>; Thomas Monjalon <[email protected]>; Qi Zhang <[email protected]>; Alejandro Lucero <[email protected]>; Andrew Rybchenko <[email protected]>; Mohammad Abdul Awal <[email protected]>; Remy Horton <[email protected]>; John McNamara <[email protected]>; Rony Efraim <[email protected]>; Jingjing Wu <[email protected]>; Wenzhuo Lu <[email protected]>; Vincent Jardin <[email protected]>; Yuanhan Liu <[email protected]>; Bruce Richardson <[email protected]>; Konstantin Ananyev <[email protected]>; Zhihong Wang <[email protected]>
Subject: Re: [dpdk-dev][PATCH v6 2/8] ethdev: add switch identifier parameter to port

Quoted 51 lines · Shahaf Shuler

Thursday, March 29, 2018 12:14 PM, Doherty, Declan:

Quoted 50 lines · Shahaf Shuler
Quoted 33 lines

Hi Declan,

Thanks for the series! See some comments below

Wednesday, March 28, 2018 4:54 PM, Declan Doherty:

Quoted 28 lines

Subject: [dpdk-dev][PATCH v6 2/8] ethdev: add switch identifier parameter to port

Introduces a new port attribute to ethdev port's which denotes the switch domain a port belongs to. By default all port's switch identifiers are the their port_id. Ports which share a common switch domain are configured with the same switch id.

---
   app/test-pmd/config.c              | 1 +
   lib/librte_ether/rte_ethdev.c      | 3 +++
   lib/librte_ether/rte_ethdev.h      | 1 +
   lib/librte_ether/rte_ethdev_core.h | 1 +
   4 files changed, 6 insertions(+)
app/test-pmd/config.c index renamed from app/test-pmd/config.c +0 -0

4bb255c62..e12f8c515 100644

app/test-pmd/config.c +1 -0
@@ -517,6 +517,7 @@ port_infos_display(portid_t port_id)
   	printf("Min possible number of TXDs per queue: %hu\n",
   		dev_info.tx_desc_lim.nb_min);
   	printf("TXDs number alignment: %hu\n",
 dev_info.tx_desc_lim.nb_align);
+	printf("Switch Id: %u\n", dev_info.switch_id);
   }
 
Quoted 8 lines

lib/librte_ether/rte_ethdev.c rte_eth_dev_allocate(const char *name) · line 291

Quoted 8 lines

void

(quoted diff) +0 -0

b/lib/librte_ether/rte_ethdev.c index 23857c91f..f32d18cad 100644

lib/librte_ether/rte_ethdev.c +0 -0
@@ -290,6 +290,8 @@ rte_eth_dev_allocate(const char *name)
   	eth_dev = eth_dev_get(port_id);
   	snprintf(eth_dev->data->name, sizeof(eth_dev->data->name),

"%s",

Quoted 6 lines

lib/librte_ether/rte_ethdev.c rte_eth_dev_allocate(const char *name) · line 294

Quoted 4 lines
lib/librte_ether/rte_ethdev.c +2 -0
 name);
   	eth_dev->data->port_id = port_id;
+	eth_dev->data->switch_id = port_id;
+	/**< Default switch_id is the port_id of the device */

Why such default is needed? Why not let the PMD to set it always?

Quoted 7 lines
Quoted 3 lines

I saw this a simple way to have a consistent default value (the port_id) for all PMDs, without the need to modify existing PMD which don't currently have any concept of a switch domain.

The default value don't makes much sense though. By default it would mean the application each port is on different switch domain. This is obviously not true in case of multiple VFs

Quoted 6 lines

But it is the case today for all ports, that they are assumed to be in separate switch domains or at least in unknowable switch domains by applications, with the exception of LAG groups, were it is implicit that they are in the same domain. Even if two ports were attached to the same switch, or if you where using multiple VFs from the same switch there is currently no way of telling the application that this is the case.

Right, but I thought your new parameter is the way :

Uint16_t switch_domain -
"Introduces a new port attribute to ethdev port's which denotes the switch domain a port belongs to"

What would be the use case for having

Quoted 3 lines

multiple VFs from the same port/switch domain in a single data path application. It doesn't seem likely to me that you would use hardware switching to move traffic between 2 VFs in the same data path application.

It is not likely. However the parameter you defined is not true only for the representor case, but for the generic case (unless you state otherwise in the documentation of it).

Maybe it can also use application like VFd to understand the connectivity between the different VFs.

My point is - unless this parameter is valid only for the reprsentor case, the default value should be the correct one. I think it is better to not limit this field to representor only. Extra info for application is never a bad thing.

Quoted 100 lines

If you are using port representors, I assumed that you would set a valid switch domain id, possibly picking up the port id of the first port created on that switch domain, but it would be completely up to the PMD how this was done, I have just shown the simplest model in which the port_id of the PF is used for all subsequent representor ports in that switch domain, but if you wanted to create multiple domains within the same device, you could just use subsequent port representors port_ids to setup further switch domains. A switch_id is only meaningful within the contex of DPDK process it is running in.

Quoted 2 lines

Maybe we can define ETH_SWITCH_ID_INVALID (0) to emphasis 0 is not

the switch_id for the PMDs which didn't implemented it.

Quoted 7 lines
Quoted 5 lines

Also taking the approach of just leaving it up to the PMD to decide the value would mean that some form of synchronisation would be required so that two device don't select the switch domain identifier.

What kind of knowledge ethdev layer has to set the switche_id? It should

be based on the underlying capabilities of the device.

Quoted 3 lines

Some devices will use the kernel sysfs to check that.

Maybe there are devices which are able to expose the same switch for

multiple devices, passing the packet between them using peer2peer trough the PCI.

Quoted 4 lines

The point is we need to have APIs which will enable all the future flexibility.

Maybe we can have array of switch_id which are allready taken by the

underlying devices, and PMD will register their switch_id to it atomically. To ease the synchronization.

Quoted 7 lines
Quoted 7 lines
Quoted 7 lines

lib/librte_ether/rte_ethdev.c rte_eth_dev_info_get(uint16_t port_id,

Quoted 7 lines
lib/librte_ether/rte_ethdev.c +0 -0
   	eth_dev->data->mtu = ETHER_MTU;
 

unlock:

lib/librte_ether/rte_ethdev.c +0 -0
@@ -2395,6 +2397,7 @@ rte_eth_dev_info_get(uint16_t port_id,

struct

Quoted 59 lines
Quoted 12 lines
Quoted 9 lines

lib/librte_ether/rte_ethdev.c rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info) · line 2400

Quoted 5 lines
lib/librte_ether/rte_ethdev.c +1 -0
 rte_eth_dev_info *dev_info)
   	dev_info->driver_name = dev->device->driver->name;
   	dev_info->nb_rx_queues = dev->data->nb_rx_queues;
   	dev_info->nb_tx_queues = dev->data->nb_tx_queues;
+	dev_info->switch_id = dev->data->switch_id;

Why there is a need to keep the switch_id on device data? I think PMD to store it on its private structure and report it in dev_info is

enough.

Quoted 1 line
Quoted 7 lines

That way would require every PMD to be modified to maintain a switch_id structure, which I know isn't a big deal, as only the device which need to support it would need it, but we would need to change the dev_info-

Quoted 2 lines

switch_id from being a uint16_t to being a signed value so we could have a

default of -1 for device which don't support switch domain.

We can say also 0 is the invalid switch id.

Quoted 36 lines

I thought the former approach was cleaner.

Quoted 34 lines
Quoted 33 lines
lib/librte_ether/rte_ethdev.c +0 -0
   }
 

int

(quoted diff) +0 -0

b/lib/librte_ether/rte_ethdev.h index 036153306..dced4fc41 100644

lib/librte_ether/rte_ethdev.h +1 -0
@@ -1029,6 +1029,7 @@ struct rte_eth_dev_info {
   	/** Configured number of rx/tx queues */
   	uint16_t nb_rx_queues; /**< Number of RX queues. */
   	uint16_t nb_tx_queues; /**< Number of TX queues. */
+	uint16_t switch_id; /**< Switch Domain Id */
   };
 
   /**
lib/librte_ether/rte_ethdev_core.h +1 -0
index e5681e466..caed7a4e6 100644
@@ -585,6 +585,7 @@ struct rte_eth_dev_data {
   	struct ether_addr* hash_mac_addrs;
   	/** Device Ethernet MAC addresses of hash filtering. */
   	uint16_t port_id;           /**< Device [external] port identifier. */
+	uint16_t switch_id;	    /**< Switch which port is associated with
 */
   	__extension__
   	uint8_t promiscuous   : 1, /**< RX promiscuous mode ON(1) / OFF(0).

*/
scattered_rx : 1, /**< RX of scattered packets is ON(1) /
OFF(0) */
--
2.14.3

#11 lore raw

PATCH v6 3/8 ethdev: add generic create/destroy ethdev APIs

In reply to Declan Doherty

Add new bus generic ethdev create/destroy APIs which are bus independent and provide hooks for bus specific initialisation.

---
 lib/librte_ether/Makefile                 |  1 +
 lib/librte_ether/meson.build              |  1 +
 lib/librte_ether/rte_ethdev.c             | 96 ++++++++++++++++++++++++++++++-
 lib/librte_ether/rte_ethdev_driver.h      | 57 ++++++++++++++++++
 lib/librte_ether/rte_ethdev_pci.h         | 12 ++++
 lib/librte_ether/rte_ethdev_representor.h | 28 +++++++++
 lib/librte_ether/rte_ethdev_version.map   |  8 +++
 7 files changed, 202 insertions(+), 1 deletion(-)
 create mode 100644 lib/librte_ether/rte_ethdev_representor.h
lib/librte_ether/Makefile +1 -0
index 3ca5782bb..5698cd47b 100644
@@ -32,6 +32,7 @@ SYMLINK-y-include += rte_ethdev_driver.h
 SYMLINK-y-include += rte_ethdev_core.h
 SYMLINK-y-include += rte_ethdev_pci.h
 SYMLINK-y-include += rte_ethdev_vdev.h
+SYMLINK-y-include += rte_ethdev_representor.h
 SYMLINK-y-include += rte_eth_ctrl.h
 SYMLINK-y-include += rte_dev_info.h
 SYMLINK-y-include += rte_flow.h
lib/librte_ether/meson.build +1 -0
index 7fed86056..163891556 100644
@@ -15,6 +15,7 @@ headers = files('rte_ethdev.h',
 	'rte_ethdev_core.h',
 	'rte_ethdev_pci.h',
 	'rte_ethdev_vdev.h',
+	'rte_ethdev_representor.h',
 	'rte_eth_ctrl.h',
 	'rte_dev_info.h',
 	'rte_flow.h',
lib/librte_ether/rte_ethdev.c +95 -1

108 lines not on this page · raw message

lib/librte_ether/rte_ethdev_driver.h +57 -0

63 lines not on this page · raw message

lib/librte_ether/rte_ethdev_pci.h +12 -0
index 897ce5b41..8604a0474 100644
@@ -70,6 +70,18 @@ rte_eth_copy_pci_info(struct rte_eth_dev *eth_dev,
 	eth_dev->data->numa_node = pci_dev->device.numa_node;
 }
 
+static inline int
+eth_dev_pci_specific_init(struct rte_eth_dev *eth_dev, void *bus_device) {
+	struct rte_pci_device *pci_dev = bus_device;
+
+	if (!pci_dev)
+		return -ENODEV;
+
+	rte_eth_copy_pci_info(eth_dev, pci_dev);
+
+	return 0;
+}
+
 /**
  * @internal
  * Allocates a new ethdev slot for an ethernet device and returns the pointer
lib/librte_ether/rte_ethdev_representor.h new file +28 -0
new file mode 100644
index 000000000..cbc1f2855
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation.
+ */
+
+
+#ifndef _RTE_ETHDEV_REPRESENTOR_H_
+#define _RTE_ETHDEV_REPRESENTOR_H_
+
+#include <rte_ethdev_driver.h>
+
+static int
+eth_dev_representor_port_init(struct rte_eth_dev *ethdev, void *init_params)
+{
+	struct rte_eth_dev *base_ethdev = init_params;
+
+	if (!ethdev || !base_ethdev)
+		return -ENODEV;
+
+	/** representor shares same driver as it's base device */
+	ethdev->device->driver = base_ethdev->device->driver;
+
+	/** representor inherits the switch id of it's base device */
+	ethdev->data->switch_id = base_ethdev->data->switch_id;
+
+	return 0;
+}
+
+#endif /* _RTE_ETHDEV_REPRESENTOR_H_ */
lib/librte_ether/rte_ethdev_version.map +8 -0
index 87f02fb74..48b08bc36 100644
@@ -230,3 +230,11 @@ EXPERIMENTAL {
 	rte_mtr_stats_update;
 
 } DPDK_17.11;
+
+EXPERIMENTAL {
+	global:
+
+	rte_eth_dev_create;
+	rte_eth_dev_destroy;
+
+} DPDK_18.05;
Signature · 1 line
2.14.3
#12 lore raw

Re: [PATCH v6 3/8] ethdev: add generic create/destroy ethdev APIs

Wednesday, March 28, 2018 4:54 PM, Declan Doherty:

Quoted 275 lines

Subject: [dpdk-dev][PATCH v6 3/8] ethdev: add generic create/destroy ethdev APIs

Add new bus generic ethdev create/destroy APIs which are bus independent and provide hooks for bus specific initialisation.

---
 lib/librte_ether/Makefile                 |  1 +
 lib/librte_ether/meson.build              |  1 +
 lib/librte_ether/rte_ethdev.c             | 96
++++++++++++++++++++++++++++++-
 lib/librte_ether/rte_ethdev_driver.h      | 57 ++++++++++++++++++
 lib/librte_ether/rte_ethdev_pci.h         | 12 ++++
 lib/librte_ether/rte_ethdev_representor.h | 28 +++++++++
 lib/librte_ether/rte_ethdev_version.map   |  8 +++
 7 files changed, 202 insertions(+), 1 deletion(-)  create mode 100644

lib/librte_ether/rte_ethdev_representor.h

lib/librte_ether/Makefile index renamed from lib/librte_ether/Makefile +0 -0

3ca5782bb..5698cd47b 100644

lib/librte_ether/Makefile +0 -0
@@ -32,6 +32,7 @@ SYMLINK-y-include += rte_ethdev_driver.h  SYMLINK-y-

include += rte_ethdev_core.h SYMLINK-y-include += rte_ethdev_pci.h SYMLINK-y-include += rte_ethdev_vdev.h

lib/librte_ether/Makefile +1 -0
+SYMLINK-y-include += rte_ethdev_representor.h
 SYMLINK-y-include += rte_eth_ctrl.h
 SYMLINK-y-include += rte_dev_info.h
 SYMLINK-y-include += rte_flow.h
lib/librte_ether/meson.build +1 -0
index 7fed86056..163891556 100644
@@ -15,6 +15,7 @@ headers = files('rte_ethdev.h',
 	'rte_ethdev_core.h',
 	'rte_ethdev_pci.h',
 	'rte_ethdev_vdev.h',
+	'rte_ethdev_representor.h',
 	'rte_eth_ctrl.h',
 	'rte_dev_info.h',
 	'rte_flow.h',
lib/librte_ether/rte_ethdev.c +2 -1
index f32d18cad..c719f84a3 100644
@@ -345,7 +345,8 @@ rte_eth_dev_release_port(struct rte_eth_dev
 *eth_dev)
 	rte_eth_dev_shared_data_prepare();
 
 	rte_spinlock_lock(&rte_eth_dev_shared_data->ownership_lock);
-
+	eth_dev->device = NULL;
+	eth_dev->intr_handle = NULL;
 	eth_dev->state = RTE_ETH_DEV_UNUSED;
 

memset(eth_dev->data, 0, sizeof(struct rte_eth_dev_data)); @@ -
3403,6 +3404,99 @@ rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char *ring_name,
return rte_memzone_reserve_aligned(z_name, size, socket_id, 0,
align); }

lib/librte_ether/rte_ethdev.c +19 -0
+int __rte_experimental
+rte_eth_dev_create(struct rte_device *device, const char *name,
+	size_t priv_data_size,
+	ethdev_bus_specific_init ethdev_bus_specific_init,
+	void *bus_init_params,
+	ethdev_init_t ethdev_init, void *init_params) {
+	struct rte_eth_dev *ethdev;
+	int retval;
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		ethdev = rte_eth_dev_allocate(name);
+		if (!ethdev) {
+			retval = -ENODEV;
+			goto probe_failed;
+		}
+
+		if (priv_data_size) {
+			ethdev->data->dev_private = rte_zmalloc_socket(
+				name, priv_data_size,

RTE_CACHE_LINE_SIZE,

lib/librte_ether/rte_ethdev.c +4 -0
+				device->numa_node);
+
+			if (!ethdev->data->dev_private) {
+				RTE_LOG(ERR, EAL, "failed to allocate private

data");

lib/librte_ether/rte_ethdev.c +8 -0
+				retval = -ENOMEM;
+				goto probe_failed;
+			}
+		}
+	} else {
+		ethdev = rte_eth_dev_attach_secondary(name);
+		if (!ethdev) {
+			RTE_LOG(ERR, EAL, "secondary process attach failed,

"

lib/librte_ether/rte_ethdev.c +60 -0
+				"ethdev doesn't exist");
+			retval = -ENODEV;
+			goto probe_failed;
+		}
+	}
+
+	ethdev->device = device;
+
+	if (ethdev_bus_specific_init) {
+		retval = ethdev_bus_specific_init(ethdev, bus_init_params);
+		if (retval) {
+			RTE_LOG(ERR, EAL,
+				"ethdev bus specific initialisation failed");
+			goto probe_failed;
+		}
+	}
+
+	RTE_FUNC_PTR_OR_ERR_RET(*ethdev_init, -EINVAL);
+	retval = ethdev_init(ethdev, init_params);
+	if (retval) {
+		RTE_LOG(ERR, EAL, "ethdev initialisation failed");
+		goto probe_failed;
+	}
+
+	return retval;
+probe_failed:
+	/* free ports private data if primary process */
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(ethdev->data->dev_private);
+
+	rte_eth_dev_release_port(ethdev);
+
+	return retval;
+}
+
+int  __rte_experimental
+rte_eth_dev_destroy(struct rte_eth_dev *ethdev,
+	ethdev_uninit_t ethdev_uninit)
+{
+	int ret;
+
+	ethdev = rte_eth_dev_allocated(ethdev->data->name);
+	if (!ethdev)
+		return -ENODEV;
+
+	RTE_FUNC_PTR_OR_ERR_RET(*ethdev_uninit, -EINVAL);
+	if (ethdev_uninit) {
+		ret = ethdev_uninit(ethdev);
+		if (ret)
+			return ret;
+	}
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(ethdev->data->dev_private);
+
+	ethdev->data->dev_private = NULL;
+
+	return rte_eth_dev_release_port(ethdev); }
+
+
 int
 rte_eth_dev_rx_intr_ctl_q(uint16_t port_id, uint16_t queue_id,
 			  int epfd, int op, void *data)
lib/librte_ether/rte_ethdev_driver.h +58 -0
index 45f08c65e..4896cea93 100644
@@ -125,6 +125,63 @@ rte_eth_dma_zone_reserve(const struct
 rte_eth_dev *eth_dev, const char *name,
 			 uint16_t queue_id, size_t size,
 			 unsigned align, int socket_id);
 
+
+typedef int (*ethdev_init_t)(struct rte_eth_dev *ethdev, void
+*init_params); typedef int (*ethdev_bus_specific_init)(struct rte_eth_dev
 *ethdev,
+	void *bus_specific_init_params);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * PMD helper function for the creation of a new ethdev ports.
+ *
+ * @param device
+ *  rte_device handle.
+ * @param	name
+ *  port name.
+ * @param priv_data_size
+ *  size of private data required for port.
+ * @param bus_specific_init
+ *  port bus specific initialisation callback function
+ * @param bus_init_params
+ *  port bus specific initialisation parameters
+ * @param ethdev_init
+ *  device specific port initialization callback function
+ * @param init_params
+ *  port initialisation parameters
+ *
+ * @return
+ *   Negative errno value on error, 0 on success.
+ */
+int __rte_experimental
+rte_eth_dev_create(struct rte_device *device, const char *name,
+	size_t priv_data_size,
+	ethdev_bus_specific_init bus_specific_init, void *bus_init_params,
+	ethdev_init_t ethdev_init, void *init_params);
+
+
+typedef int (*ethdev_uninit_t)(struct rte_eth_dev *ethdev);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * PMD helper function for cleaing up the resources of a ethdev port on
+it's
+ * destruction.
+ *
+ * @param ethdev
+ *   ethdev handle of port.
+ * @param ethdev
+ *   device specific port un-initialise callback function
+ *
+ * @return
+ *   Negative errno value on error, 0 on success.
+ */
+int __rte_experimental
+rte_eth_dev_destroy(struct rte_eth_dev *ethdev,
+	ethdev_uninit_t ethdev_uninit);
+
 #ifdef __cplusplus
 }
 #endif
lib/librte_ether/rte_ethdev_pci.h +12 -0
index 897ce5b41..8604a0474 100644
@@ -70,6 +70,18 @@ rte_eth_copy_pci_info(struct rte_eth_dev *eth_dev,
 	eth_dev->data->numa_node = pci_dev->device.numa_node;  }
 
+static inline int
+eth_dev_pci_specific_init(struct rte_eth_dev *eth_dev, void *bus_device)
 {
+	struct rte_pci_device *pci_dev = bus_device;
+
+	if (!pci_dev)
+		return -ENODEV;
+
+	rte_eth_copy_pci_info(eth_dev, pci_dev);
+
+	return 0;
+}
+
 /**
  * @internal
  * Allocates a new ethdev slot for an ethernet device and returns the pointer
lib/librte_ether/rte_ethdev_representor.h new file +13 -0
new file mode 100644
index 000000000..cbc1f2855
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation.
+ */
+
+
+#ifndef _RTE_ETHDEV_REPRESENTOR_H_
+#define _RTE_ETHDEV_REPRESENTOR_H_
+
+#include <rte_ethdev_driver.h>
+
+static int
+eth_dev_representor_port_init(struct rte_eth_dev *ethdev, void
+*init_params) {

lib/librte_ether/rte_ethdev_representor.h line 23

Quoted 10 lines
lib/librte_ether/rte_ethdev_representor.h new file +10 -0
+	struct rte_eth_dev *base_ethdev = init_params;
+
+	if (!ethdev || !base_ethdev)
+		return -ENODEV;
+
+	/** representor shares same driver as it's base device */
+	ethdev->device->driver = base_ethdev->device->driver;
+
+	/** representor inherits the switch id of it's base device */
+	ethdev->data->switch_id = base_ethdev->data->switch_id;

Why not let the PMD to set it?

The PMD knows the specific port is a represntor port and to which switch it belongs.
Doing it on ethdev layer will block us in the future from having more complex model were, for example, there are multiple switch domain for a set of PF + representors.

Quoted 24 lines
lib/librte_ether/rte_ethdev_representor.h new file +5 -0
+
+	return 0;
+}
+
+#endif /* _RTE_ETHDEV_REPRESENTOR_H_ */
lib/librte_ether/rte_ethdev_version.map +8 -1
index 87f02fb74..48b08bc36 100644
@@ -230,3 +230,11 @@ EXPERIMENTAL {
 	rte_mtr_stats_update;
 
 } DPDK_17.11;
+
+EXPERIMENTAL {
+	global:
+
+	rte_eth_dev_create;
+	rte_eth_dev_destroy;
+
+} DPDK_18.05;
--

2.14.3

#13 lore raw

Re: [PATCH v6 3/8] ethdev: add generic create/destroy ethdev APIs

Quoted 289 lines · Shahaf Shuler

Wednesday, March 28, 2018 4:54 PM, Declan Doherty:

Quoted 275 lines

Subject: [dpdk-dev][PATCH v6 3/8] ethdev: add generic create/destroy ethdev APIs

Add new bus generic ethdev create/destroy APIs which are bus independent and provide hooks for bus specific initialisation.

---
  lib/librte_ether/Makefile                 |  1 +
  lib/librte_ether/meson.build              |  1 +
  lib/librte_ether/rte_ethdev.c             | 96
++++++++++++++++++++++++++++++-
  lib/librte_ether/rte_ethdev_driver.h      | 57 ++++++++++++++++++
  lib/librte_ether/rte_ethdev_pci.h         | 12 ++++
  lib/librte_ether/rte_ethdev_representor.h | 28 +++++++++
  lib/librte_ether/rte_ethdev_version.map   |  8 +++
  7 files changed, 202 insertions(+), 1 deletion(-)  create mode 100644

lib/librte_ether/rte_ethdev_representor.h

lib/librte_ether/Makefile index renamed from lib/librte_ether/Makefile +0 -0

3ca5782bb..5698cd47b 100644

lib/librte_ether/Makefile +0 -0
@@ -32,6 +32,7 @@ SYMLINK-y-include += rte_ethdev_driver.h  SYMLINK-y-

include += rte_ethdev_core.h SYMLINK-y-include += rte_ethdev_pci.h SYMLINK-y-include += rte_ethdev_vdev.h

lib/librte_ether/Makefile +1 -0
+SYMLINK-y-include += rte_ethdev_representor.h
  SYMLINK-y-include += rte_eth_ctrl.h
  SYMLINK-y-include += rte_dev_info.h
  SYMLINK-y-include += rte_flow.h
lib/librte_ether/meson.build +1 -0
index 7fed86056..163891556 100644
@@ -15,6 +15,7 @@ headers = files('rte_ethdev.h',
  	'rte_ethdev_core.h',
  	'rte_ethdev_pci.h',
  	'rte_ethdev_vdev.h',
+	'rte_ethdev_representor.h',
  	'rte_eth_ctrl.h',
  	'rte_dev_info.h',
  	'rte_flow.h',
lib/librte_ether/rte_ethdev.c +2 -1
index f32d18cad..c719f84a3 100644
@@ -345,7 +345,8 @@ rte_eth_dev_release_port(struct rte_eth_dev
 *eth_dev)
  	rte_eth_dev_shared_data_prepare();
 
  	rte_spinlock_lock(&rte_eth_dev_shared_data->ownership_lock);
-
+	eth_dev->device = NULL;
+	eth_dev->intr_handle = NULL;
  	eth_dev->state = RTE_ETH_DEV_UNUSED;
 

memset(eth_dev->data, 0, sizeof(struct rte_eth_dev_data)); @@ -
3403,6 +3404,99 @@ rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char *ring_name,
return rte_memzone_reserve_aligned(z_name, size, socket_id, 0,
align); }

lib/librte_ether/rte_ethdev.c +19 -0
+int __rte_experimental
+rte_eth_dev_create(struct rte_device *device, const char *name,
+	size_t priv_data_size,
+	ethdev_bus_specific_init ethdev_bus_specific_init,
+	void *bus_init_params,
+	ethdev_init_t ethdev_init, void *init_params) {
+	struct rte_eth_dev *ethdev;
+	int retval;
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		ethdev = rte_eth_dev_allocate(name);
+		if (!ethdev) {
+			retval = -ENODEV;
+			goto probe_failed;
+		}
+
+		if (priv_data_size) {
+			ethdev->data->dev_private = rte_zmalloc_socket(
+				name, priv_data_size,

RTE_CACHE_LINE_SIZE,

lib/librte_ether/rte_ethdev.c +4 -0
+				device->numa_node);
+
+			if (!ethdev->data->dev_private) {
+				RTE_LOG(ERR, EAL, "failed to allocate private

data");

lib/librte_ether/rte_ethdev.c +8 -0
+				retval = -ENOMEM;
+				goto probe_failed;
+			}
+		}
+	} else {
+		ethdev = rte_eth_dev_attach_secondary(name);
+		if (!ethdev) {
+			RTE_LOG(ERR, EAL, "secondary process attach failed,

"

lib/librte_ether/rte_ethdev.c +60 -0
+				"ethdev doesn't exist");
+			retval = -ENODEV;
+			goto probe_failed;
+		}
+	}
+
+	ethdev->device = device;
+
+	if (ethdev_bus_specific_init) {
+		retval = ethdev_bus_specific_init(ethdev, bus_init_params);
+		if (retval) {
+			RTE_LOG(ERR, EAL,
+				"ethdev bus specific initialisation failed");
+			goto probe_failed;
+		}
+	}
+
+	RTE_FUNC_PTR_OR_ERR_RET(*ethdev_init, -EINVAL);
+	retval = ethdev_init(ethdev, init_params);
+	if (retval) {
+		RTE_LOG(ERR, EAL, "ethdev initialisation failed");
+		goto probe_failed;
+	}
+
+	return retval;
+probe_failed:
+	/* free ports private data if primary process */
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(ethdev->data->dev_private);
+
+	rte_eth_dev_release_port(ethdev);
+
+	return retval;
+}
+
+int  __rte_experimental
+rte_eth_dev_destroy(struct rte_eth_dev *ethdev,
+	ethdev_uninit_t ethdev_uninit)
+{
+	int ret;
+
+	ethdev = rte_eth_dev_allocated(ethdev->data->name);
+	if (!ethdev)
+		return -ENODEV;
+
+	RTE_FUNC_PTR_OR_ERR_RET(*ethdev_uninit, -EINVAL);
+	if (ethdev_uninit) {
+		ret = ethdev_uninit(ethdev);
+		if (ret)
+			return ret;
+	}
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(ethdev->data->dev_private);
+
+	ethdev->data->dev_private = NULL;
+
+	return rte_eth_dev_release_port(ethdev); }
+
+
  int
  rte_eth_dev_rx_intr_ctl_q(uint16_t port_id, uint16_t queue_id,
  			  int epfd, int op, void *data)
lib/librte_ether/rte_ethdev_driver.h +58 -0
index 45f08c65e..4896cea93 100644
@@ -125,6 +125,63 @@ rte_eth_dma_zone_reserve(const struct
 rte_eth_dev *eth_dev, const char *name,
  			 uint16_t queue_id, size_t size,
  			 unsigned align, int socket_id);
 
+
+typedef int (*ethdev_init_t)(struct rte_eth_dev *ethdev, void
+*init_params); typedef int (*ethdev_bus_specific_init)(struct rte_eth_dev
 *ethdev,
+	void *bus_specific_init_params);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * PMD helper function for the creation of a new ethdev ports.
+ *
+ * @param device
+ *  rte_device handle.
+ * @param	name
+ *  port name.
+ * @param priv_data_size
+ *  size of private data required for port.
+ * @param bus_specific_init
+ *  port bus specific initialisation callback function
+ * @param bus_init_params
+ *  port bus specific initialisation parameters
+ * @param ethdev_init
+ *  device specific port initialization callback function
+ * @param init_params
+ *  port initialisation parameters
+ *
+ * @return
+ *   Negative errno value on error, 0 on success.
+ */
+int __rte_experimental
+rte_eth_dev_create(struct rte_device *device, const char *name,
+	size_t priv_data_size,
+	ethdev_bus_specific_init bus_specific_init, void *bus_init_params,
+	ethdev_init_t ethdev_init, void *init_params);
+
+
+typedef int (*ethdev_uninit_t)(struct rte_eth_dev *ethdev);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * PMD helper function for cleaing up the resources of a ethdev port on
+it's
+ * destruction.
+ *
+ * @param ethdev
+ *   ethdev handle of port.
+ * @param ethdev
+ *   device specific port un-initialise callback function
+ *
+ * @return
+ *   Negative errno value on error, 0 on success.
+ */
+int __rte_experimental
+rte_eth_dev_destroy(struct rte_eth_dev *ethdev,
+	ethdev_uninit_t ethdev_uninit);
+
  #ifdef __cplusplus
  }
  #endif
lib/librte_ether/rte_ethdev_pci.h +12 -0
index 897ce5b41..8604a0474 100644
@@ -70,6 +70,18 @@ rte_eth_copy_pci_info(struct rte_eth_dev *eth_dev,
  	eth_dev->data->numa_node = pci_dev->device.numa_node;  }
 
+static inline int
+eth_dev_pci_specific_init(struct rte_eth_dev *eth_dev, void *bus_device)
 {
+	struct rte_pci_device *pci_dev = bus_device;
+
+	if (!pci_dev)
+		return -ENODEV;
+
+	rte_eth_copy_pci_info(eth_dev, pci_dev);
+
+	return 0;
+}
+
  /**
   * @internal
   * Allocates a new ethdev slot for an ethernet device and returns the pointer
lib/librte_ether/rte_ethdev_representor.h new file +13 -0
new file mode 100644
index 000000000..cbc1f2855
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation.
+ */
+
+
+#ifndef _RTE_ETHDEV_REPRESENTOR_H_
+#define _RTE_ETHDEV_REPRESENTOR_H_
+
+#include <rte_ethdev_driver.h>
+
+static int
+eth_dev_representor_port_init(struct rte_eth_dev *ethdev, void
+*init_params) {

lib/librte_ether/rte_ethdev_representor.h line 23

Quoted 10 lines
lib/librte_ether/rte_ethdev_representor.h new file +10 -0
+	struct rte_eth_dev *base_ethdev = init_params;
+
+	if (!ethdev || !base_ethdev)
+		return -ENODEV;
+
+	/** representor shares same driver as it's base device */
+	ethdev->device->driver = base_ethdev->device->driver;
+
+	/** representor inherits the switch id of it's base device */
+	ethdev->data->switch_id = base_ethdev->data->switch_id;

Why not let the PMD to set it?

Quoted 3 lines

The PMD knows the specific port is a represntor port and to which switch it belongs.
Doing it on ethdev layer will block us in the future from having more complex model were, for example, there are multiple switch domain for a set of PF + representors.

This is only a generic helper function for a representor port bus specific initialisation, and can be passed as the bus_specific_init parameter in the rte_eth_dev_create function, but whether or not to use it is complete up to the PMD. It only handles the simple case of a single function device with multiple representors on a single switch domain. For more complex use cases, like multiple switch domains, the PMD can provide it's own implementation of this. I thought it was useful to provide as a common function as for the ixgbe, i40e it fulfills there requirements, and will probably be sufficient for many other devices too.

Quoted 25 lines
Quoted 24 lines
lib/librte_ether/rte_ethdev_representor.h new file +5 -0
+
+	return 0;
+}
+
+#endif /* _RTE_ETHDEV_REPRESENTOR_H_ */
lib/librte_ether/rte_ethdev_version.map +8 -1
index 87f02fb74..48b08bc36 100644
@@ -230,3 +230,11 @@ EXPERIMENTAL {
  	rte_mtr_stats_update;
 
  } DPDK_17.11;
+
+EXPERIMENTAL {
+	global:
+
+	rte_eth_dev_create;
+	rte_eth_dev_destroy;
+
+} DPDK_18.05;
--

2.14.3

#14 lore raw

PATCH v6 4/8 ethdev: Add port representor device flag

In reply to Declan Doherty

Add new device flag to specify that ethdev port is a port representor. Extend rte_eth_dev_info structure to expose device flags to user which enable applications to discover if a port is a representor port.

---
 lib/librte_ether/rte_ethdev.c             | 1 +
 lib/librte_ether/rte_ethdev.h             | 9 ++++++---
 lib/librte_ether/rte_ethdev_representor.h | 3 +++
 3 files changed, 10 insertions(+), 3 deletions(-)
lib/librte_ether/rte_ethdev.c +1 -0
index c719f84a3..163246433 100644
@@ -2399,6 +2399,7 @@ rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info)
 	dev_info->nb_rx_queues = dev->data->nb_rx_queues;
 	dev_info->nb_tx_queues = dev->data->nb_tx_queues;
 	dev_info->switch_id = dev->data->switch_id;
+	dev_info->dev_flags = dev->data->dev_flags;
 }
 
 int
lib/librte_ether/rte_ethdev.h +6 -3
index dced4fc41..226acc8b1 100644
@@ -996,6 +996,7 @@ struct rte_eth_dev_info {
 	const char *driver_name; /**< Device Driver name. */
 	unsigned int if_index; /**< Index to bound host interface, or 0 if none.
 		Use if_indextoname() to translate into an interface name. */
+	uint32_t dev_flags; /**< Device flags */
 	uint32_t min_rx_bufsize; /**< Minimum size of RX buffer. */
 	uint32_t max_rx_pktlen; /**< Maximum configurable length of RX pkt. */
 	uint16_t max_rx_queues; /**< Maximum number of RX queues. */
@@ -1229,11 +1230,13 @@ struct rte_eth_dev_owner {
 };
 
 /** Device supports link state interrupt */
-#define RTE_ETH_DEV_INTR_LSC     0x0002
+#define RTE_ETH_DEV_INTR_LSC		0x0002
 /** Device is a bonded slave */
-#define RTE_ETH_DEV_BONDED_SLAVE 0x0004
+#define RTE_ETH_DEV_BONDED_SLAVE	0x0004
 /** Device supports device removal interrupt */
-#define RTE_ETH_DEV_INTR_RMV     0x0008
+#define RTE_ETH_DEV_INTR_RMV		0x0008
+/** Device is port representor */
+#define RTE_ETH_DEV_REPRESENTOR		0x0010
 
 /**
  * @warning
lib/librte_ether/rte_ethdev_representor.h +3 -0
index cbc1f2855..f3726d0ba 100644
@@ -22,6 +22,9 @@ eth_dev_representor_port_init(struct rte_eth_dev *ethdev, void *init_params)
 	/** representor inherits the switch id of it's base device */
 	ethdev->data->switch_id = base_ethdev->data->switch_id;
 
+	/** Set device flags to specify that device is a representor port */
+	ethdev->data->dev_flags |= RTE_ETH_DEV_REPRESENTOR;
+
 	return 0;
 }
 
Signature · 1 line
2.14.3
#15 lore raw

Re: [PATCH v6 4/8] ethdev: Add port representor device flag

Wednesday, March 28, 2018 4:54 PM, Declan Doherty:

Quoted 43 lines

Subject: [dpdk-dev][PATCH v6 4/8] ethdev: Add port representor device flag

Add new device flag to specify that ethdev port is a port representor. Extend rte_eth_dev_info structure to expose device flags to user which enable applications to discover if a port is a representor port.

---
 lib/librte_ether/rte_ethdev.c             | 1 +
 lib/librte_ether/rte_ethdev.h             | 9 ++++++---
 lib/librte_ether/rte_ethdev_representor.h | 3 +++
 3 files changed, 10 insertions(+), 3 deletions(-)
lib/librte_ether/rte_ethdev.c +1 -0
index c719f84a3..163246433 100644
@@ -2399,6 +2399,7 @@ rte_eth_dev_info_get(uint16_t port_id, struct
 rte_eth_dev_info *dev_info)
 	dev_info->nb_rx_queues = dev->data->nb_rx_queues;
 	dev_info->nb_tx_queues = dev->data->nb_tx_queues;
 	dev_info->switch_id = dev->data->switch_id;
+	dev_info->dev_flags = dev->data->dev_flags;
 }
 

int

lib/librte_ether/rte_ethdev.h +0 -0
index dced4fc41..226acc8b1 100644
@@ -996,6 +996,7 @@ struct rte_eth_dev_info {
 	const char *driver_name; /**< Device Driver name. */
 	unsigned int if_index; /**< Index to bound host interface, or 0 if

none.

lib/librte_ether/rte_ethdev.h +1 -0
 		Use if_indextoname() to translate into an interface name. */
+	uint32_t dev_flags; /**< Device flags */
 	uint32_t min_rx_bufsize; /**< Minimum size of RX buffer. */
 	uint32_t max_rx_pktlen; /**< Maximum configurable length of RX

pkt. */

lib/librte_ether/rte_ethdev.h +0 -0
 	uint16_t max_rx_queues; /**< Maximum number of RX queues. */
@@ -1229,11 +1230,13 @@ struct rte_eth_dev_owner {  };
 
 /** Device supports link state interrupt */

lib/librte_ether/rte_ethdev.h struct rte_eth_dev_owner { }; · line 1238

Quoted 10 lines
lib/librte_ether/rte_ethdev.h +5 -3
-#define RTE_ETH_DEV_INTR_LSC     0x0002
+#define RTE_ETH_DEV_INTR_LSC		0x0002
 /** Device is a bonded slave */
-#define RTE_ETH_DEV_BONDED_SLAVE 0x0004
+#define RTE_ETH_DEV_BONDED_SLAVE	0x0004
 /** Device supports device removal interrupt */
-#define RTE_ETH_DEV_INTR_RMV     0x0008
+#define RTE_ETH_DEV_INTR_RMV		0x0008
+/** Device is port representor */
+#define RTE_ETH_DEV_REPRESENTOR		0x0010

Maybe it is a good time to make some order here.
I understand the decision to use flags instead of bit-field. It is better.

However there is a mix here of device capabilities like : RTE_ETH_DEV_INTR_LSC and RTE_ETH_DEV_INTR_RMV
And device attributes like : RTE_ETH_DEV_BONDED_SLAVE and RTE_ETH_DEV_REPRESENTOR. I don't think they belong together under the genetic name of dev_flags.

Moreover, I am not sure the fact device is bonded slave should be exposed to the application. It should be internal to ethdev and its port iterators.

Finally I think representor port may need more info now (and in the future), for example the associated vf id. For that, I think it is better it to be exposed as a dedicated struct on device info.

Quoted 9 lines
lib/librte_ether/rte_ethdev.h +0 -0
 /**
  * @warning
lib/librte_ether/rte_ethdev_representor.h +0 -0
index cbc1f2855..f3726d0ba 100644

lib/librte_ether/rte_ethdev_representor.h eth_dev_representor_port_init(struct rte_eth_dev · line 27

Quoted 6 lines
lib/librte_ether/rte_ethdev_representor.h +2 -0
@@ -22,6 +22,9 @@ eth_dev_representor_port_init(struct rte_eth_dev
 *ethdev, void *init_params)
 	/** representor inherits the switch id of it's base device */
 	ethdev->data->switch_id = base_ethdev->data->switch_id;
 
+	/** Set device flags to specify that device is a representor port */
+	ethdev->data->dev_flags |= RTE_ETH_DEV_REPRESENTOR;

Should be set in the PMD, not in ethdev layer.

Quoted 6 lines
lib/librte_ether/rte_ethdev_representor.h +1 -1
+
 	return 0;
 }
 
--

2.14.3

#16 lore raw

Re: [PATCH v6 4/8] ethdev: Add port representor device flag

29/03/2018 08:13, Shahaf Shuler:

Quoted 4 lines

And device attributes like : RTE_ETH_DEV_BONDED_SLAVE and RTE_ETH_DEV_REPRESENTOR. I don't think they belong together under the genetic name of dev_flags.

Moreover, I am not sure the fact device is bonded slave should be exposed to the application. It should be internal to ethdev and its port iterators.

RTE_ETH_DEV_BONDED_SLAVE flag is used to prevent a manual detach of a slave. I think it is wrong.
The bonding PMD should be able to manage any detach at any time, because a real hardware plug-out can happen.

So I am in favor of removing RTE_ETH_DEV_BONDED_SLAVE.

#17 lore raw

Re: [PATCH v6 4/8] ethdev: Add port representor device flag

In reply to Shahaf Shuler
Quoted 58 lines · Shahaf Shuler

Wednesday, March 28, 2018 4:54 PM, Declan Doherty:

Quoted 43 lines

Subject: [dpdk-dev][PATCH v6 4/8] ethdev: Add port representor device flag

Add new device flag to specify that ethdev port is a port representor. Extend rte_eth_dev_info structure to expose device flags to user which enable applications to discover if a port is a representor port.

---
  lib/librte_ether/rte_ethdev.c             | 1 +
  lib/librte_ether/rte_ethdev.h             | 9 ++++++---
  lib/librte_ether/rte_ethdev_representor.h | 3 +++
  3 files changed, 10 insertions(+), 3 deletions(-)
lib/librte_ether/rte_ethdev.c +1 -0
index c719f84a3..163246433 100644
@@ -2399,6 +2399,7 @@ rte_eth_dev_info_get(uint16_t port_id, struct
 rte_eth_dev_info *dev_info)
  	dev_info->nb_rx_queues = dev->data->nb_rx_queues;
  	dev_info->nb_tx_queues = dev->data->nb_tx_queues;
  	dev_info->switch_id = dev->data->switch_id;
+	dev_info->dev_flags = dev->data->dev_flags;
  }
 

int

lib/librte_ether/rte_ethdev.h +0 -0
index dced4fc41..226acc8b1 100644
@@ -996,6 +996,7 @@ struct rte_eth_dev_info {
  	const char *driver_name; /**< Device Driver name. */
  	unsigned int if_index; /**< Index to bound host interface, or 0 if

none.
Use if_indextoname() to translate into an interface name. */

lib/librte_ether/rte_ethdev.h +1 -0
+	uint32_t dev_flags; /**< Device flags */
  	uint32_t min_rx_bufsize; /**< Minimum size of RX buffer. */
  	uint32_t max_rx_pktlen; /**< Maximum configurable length of RX

pkt. */
uint16_t max_rx_queues; /**< Maximum number of RX queues. */

lib/librte_ether/rte_ethdev.h +0 -0
@@ -1229,11 +1230,13 @@ struct rte_eth_dev_owner {  };
 
  /** Device supports link state interrupt */

lib/librte_ether/rte_ethdev.h struct rte_eth_dev_owner { }; · line 1238

Quoted 10 lines
lib/librte_ether/rte_ethdev.h +5 -3
-#define RTE_ETH_DEV_INTR_LSC     0x0002
+#define RTE_ETH_DEV_INTR_LSC		0x0002
  /** Device is a bonded slave */
-#define RTE_ETH_DEV_BONDED_SLAVE 0x0004
+#define RTE_ETH_DEV_BONDED_SLAVE	0x0004
  /** Device supports device removal interrupt */
-#define RTE_ETH_DEV_INTR_RMV     0x0008
+#define RTE_ETH_DEV_INTR_RMV		0x0008
+/** Device is port representor */
+#define RTE_ETH_DEV_REPRESENTOR		0x0010

Maybe it is a good time to make some order here.
I understand the decision to use flags instead of bit-field. It is better.

Quoted 5 lines

However there is a mix here of device capabilities like : RTE_ETH_DEV_INTR_LSC and RTE_ETH_DEV_INTR_RMV
And device attributes like : RTE_ETH_DEV_BONDED_SLAVE and RTE_ETH_DEV_REPRESENTOR. I don't think they belong together under the genetic name of dev_flags.

Moreover, I am not sure the fact device is bonded slave should be exposed to the application. It should be internal to ethdev and its port iterators.

That's a good point on the bonded slave flag, I'll look at fixing that for the next release. I don't think changing it should effect ABI but I'll need to have a closer look.

Do you think that we should have a separate device attributes field, which the representor flag is contained in.

Quoted 3 lines

Finally I think representor port may need more info now (and in the future), for example the associated vf id. For that, I think it is better it to be exposed as a dedicated struct on device info.

I think a switch port id should suffice for that, for SR-IOV devices it would map to the vf_id.

Quoted 14 lines
Quoted 14 lines
lib/librte_ether/rte_ethdev.h +0 -0
  /**
   * @warning
lib/librte_ether/rte_ethdev_representor.h +0 -0
index cbc1f2855..f3726d0ba 100644
@@ -22,6 +22,9 @@ eth_dev_representor_port_init(struct rte_eth_dev
 *ethdev, void *init_params)
  	/** representor inherits the switch id of it's base device */
  	ethdev->data->switch_id = base_ethdev->data->switch_id;
 
Quoted 4 lines

lib/librte_ether/rte_ethdev_representor.h eth_dev_representor_port_init(struct rte_eth_dev *ethdev, void *init_params) · line 26

Quoted 2 lines
lib/librte_ether/rte_ethdev_representor.h +2 -0
+	/** Set device flags to specify that device is a representor port */
+	ethdev->data->dev_flags |= RTE_ETH_DEV_REPRESENTOR;

Should be set in the PMD, not in ethdev layer

As in the previous patch this is just a generic port bus init function which meets the simplest use case of representor port with a single switch domain, a PMD doesn't need to use it but having it here saves duplicating the same code across multiple PMD which are only supporting the basic mode.

Quoted 8 lines
Quoted 7 lines
lib/librte_ether/rte_ethdev_representor.h +1 -1
+
  	return 0;
  }
 
--

2.14.3

#18 lore raw

Re: [PATCH v6 4/8] ethdev: Add port representor device flag

Thursday, March 29, 2018 5:53 PM, Doherty, Declan:

Quoted 78 lines · Shahaf Shuler
Quoted 27 lines

Wednesday, March 28, 2018 4:54 PM, Declan Doherty:

Quoted 26 lines

Subject: [dpdk-dev][PATCH v6 4/8] ethdev: Add port representor device flag

Add new device flag to specify that ethdev port is a port representor. Extend rte_eth_dev_info structure to expose device flags to user which enable applications to discover if a port is a representor port.

---
  lib/librte_ether/rte_ethdev.c             | 1 +
  lib/librte_ether/rte_ethdev.h             | 9 ++++++---
  lib/librte_ether/rte_ethdev_representor.h | 3 +++
  3 files changed, 10 insertions(+), 3 deletions(-)
(quoted diff) +0 -0

b/lib/librte_ether/rte_ethdev.c index c719f84a3..163246433 100644

lib/librte_ether/rte_ethdev.c +1 -0
@@ -2399,6 +2399,7 @@ rte_eth_dev_info_get(uint16_t port_id, struct
 rte_eth_dev_info *dev_info)
  	dev_info->nb_rx_queues = dev->data->nb_rx_queues;
  	dev_info->nb_tx_queues = dev->data->nb_tx_queues;
  	dev_info->switch_id = dev->data->switch_id;
+	dev_info->dev_flags = dev->data->dev_flags;
  }
 
Quoted 15 lines
Quoted 13 lines

int

(quoted diff) +0 -0

b/lib/librte_ether/rte_ethdev.h index dced4fc41..226acc8b1 100644

lib/librte_ether/rte_ethdev.h +0 -0
@@ -996,6 +996,7 @@ struct rte_eth_dev_info {
  	const char *driver_name; /**< Device Driver name. */
  	unsigned int if_index; /**< Index to bound host interface, or 0 if

none.
Use if_indextoname() to translate into an interface name. */

lib/librte_ether/rte_ethdev.h +1 -0
+	uint32_t dev_flags; /**< Device flags */
  	uint32_t min_rx_bufsize; /**< Minimum size of RX buffer. */
  	uint32_t max_rx_pktlen; /**< Maximum configurable length of RX
Quoted 2 lines

pkt. */
uint16_t max_rx_queues; /**< Maximum number of RX queues. */

@@

Quoted 17 lines

lib/librte_ether/rte_ethdev.h struct rte_eth_dev_owner { · line 1239

Quoted 13 lines

-1229,11 +1230,13 @@ struct rte_eth_dev_owner { };

/** Device supports link state interrupt */

lib/librte_ether/rte_ethdev.h +5 -3
-#define RTE_ETH_DEV_INTR_LSC     0x0002
+#define RTE_ETH_DEV_INTR_LSC		0x0002
  /** Device is a bonded slave */
-#define RTE_ETH_DEV_BONDED_SLAVE 0x0004
+#define RTE_ETH_DEV_BONDED_SLAVE	0x0004
  /** Device supports device removal interrupt */
-#define RTE_ETH_DEV_INTR_RMV     0x0008
+#define RTE_ETH_DEV_INTR_RMV		0x0008
+/** Device is port representor */
+#define RTE_ETH_DEV_REPRESENTOR		0x0010

Maybe it is a good time to make some order here.
I understand the decision to use flags instead of bit-field. It is better.

Quoted 1 line

However there is a mix here of device capabilities like :

RTE_ETH_DEV_INTR_LSC and RTE_ETH_DEV_INTR_RMV

Quoted 1 line

And device attributes like : RTE_ETH_DEV_BONDED_SLAVE and

RTE_ETH_DEV_REPRESENTOR.

Quoted 3 lines

I don't think they belong together under the genetic name of dev_flags.

Moreover, I am not sure the fact device is bonded slave should be exposed

to the application. It should be internal to ethdev and its port iterators.

That's a good point on the bonded slave flag, I'll look at fixing that for the next release. I don't think changing it should effect ABI but I'll need to have a closer look.

Do you think that we should have a separate device attributes field, which the representor flag is contained in.

Quoted 1 line
Quoted 7 lines
Quoted 1 line

Finally I think representor port may need more info now (and in the

future), for example the associated vf id.

Quoted 1 line

For that, I think it is better it to be exposed as a dedicated struct on device

info.

I think a switch port id should suffice for that, for SR-IOV devices it would map to the vf_id.

I think we need both switch_domain and vf_id.
Because for representors, the application should know which VFs can be reached from this representor and which VF it represent.

Quoted 33 lines
Quoted 15 lines
Quoted 15 lines

/**
* @warning

lib/librte_ether/rte_ethdev_representor.h +0 -0
index cbc1f2855..f3726d0ba 100644
@@ -22,6 +22,9 @@ eth_dev_representor_port_init(struct rte_eth_dev
 *ethdev, void *init_params)
  	/** representor inherits the switch id of it's base device */
  	ethdev->data->switch_id = base_ethdev->data->switch_id;
 
Quoted 4 lines

lib/librte_ether/rte_ethdev_representor.h eth_dev_representor_port_init(struct rte_eth_dev *ethdev, void *init_params) · line 26

Quoted 2 lines
lib/librte_ether/rte_ethdev_representor.h +2 -0
+	/** Set device flags to specify that device is a representor port */
+	ethdev->data->dev_flags |= RTE_ETH_DEV_REPRESENTOR;

Should be set in the PMD, not in ethdev layer

As in the previous patch this is just a generic port bus init function which meets the simplest use case of representor port with a single switch domain, a PMD doesn't need to use it but having it here saves duplicating the same code across multiple PMD which are only supporting the basic mode.

Quoted 8 lines
Quoted 7 lines
lib/librte_ether/rte_ethdev_representor.h +1 -1
+
  	return 0;
  }
 
--

2.14.3

#19 lore raw

PATCH v6 5/8 app/testpmd: add port name to device info

In reply to Declan Doherty

Add the port name to information printed by show port info <port_id>

---
 app/test-pmd/config.c | 3 +++
 1 file changed, 3 insertions(+)
app/test-pmd/config.c +3 -0
index e12f8c515..0fbdfdcdd 100644
@@ -407,6 +407,7 @@ port_infos_display(portid_t port_id)
 	static const char *info_border = "*********************";
 	portid_t pid;
 	uint16_t mtu;
+	char name[RTE_ETH_NAME_MAX_LEN];
 
 	if (port_id_is_invalid(port_id, ENABLED_WARN)) {
 		printf("Valid port range is [0");
@@ -423,6 +424,8 @@ port_infos_display(portid_t port_id)
 	       info_border, port_id, info_border);
 	rte_eth_macaddr_get(port_id, &mac_addr);
 	print_ethaddr("MAC address: ", &mac_addr);
+	rte_eth_dev_get_name_by_port(port_id, name);
+	printf("\nDevice name: %s", name);
 	printf("\nDriver name: %s", dev_info.driver_name);
 	printf("\nConnect to socket: %u", port->socket_id);
 
Signature · 1 line
2.14.3
#20 lore raw

PATCH v6 6/8 ethdev: add common devargs parser

In reply to Declan Doherty

From: Remy Horton <[email protected]>

Introduces a new structure, rte_eth_devargs, to support generic ethdev arguments common across NET PMDs, with a new API rte_eth_devargs_parse API to support PMD parsing these arguments.

---
 lib/Makefile                            |   1 +
 lib/librte_ether/rte_ethdev.c           | 191 ++++++++++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev_driver.h    |  30 +++++
 lib/librte_ether/rte_ethdev_version.map |   1 +
 4 files changed, 223 insertions(+)
lib/Makefile +1 -0
index ec965a606..4144d99f9 100644
@@ -21,6 +21,7 @@ DEPDIRS-librte_cmdline := librte_eal
 DIRS-$(CONFIG_RTE_LIBRTE_ETHER) += librte_ether
 DEPDIRS-librte_ether := librte_net librte_eal librte_mempool librte_ring
 DEPDIRS-librte_ether += librte_mbuf
+DEPDIRS-librte_ether += librte_kvargs
 DIRS-$(CONFIG_RTE_LIBRTE_BBDEV) += librte_bbdev
 DEPDIRS-librte_bbdev := librte_eal librte_mempool librte_mbuf
 DIRS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += librte_cryptodev
lib/librte_ether/rte_ethdev.c +191 -0

200 lines not on this page · raw message

lib/librte_ether/rte_ethdev_driver.h +30 -0
index 4896cea93..2e9ce96a6 100644
@@ -126,6 +126,36 @@ rte_eth_dma_zone_reserve(const struct rte_eth_dev *eth_dev, const char *name,
 			 unsigned align, int socket_id);
 
 
+/** Generic Ethernet device arguments  */
+struct rte_eth_devargs {
+	uint16_t ports[RTE_MAX_ETHPORTS];
+	/** port/s number to enable on a multi-port single function */
+	uint16_t nb_ports;
+	/** number of ports in ports field */
+	uint16_t representor_ports[RTE_MAX_ETHPORTS];
+	/** representor port/s identifier to enable on device */
+	uint16_t nb_representor_ports;
+	/** number of ports in representor port field */
+};
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * PMD helper function to parse ethdev arguments
+ *
+ * @param devargs
+ *  device arguments
+ * @param eth_devargs
+ *  parsed ethdev specific arguments.
+ *
+ * @return
+ *   Negative errno value on error, 0 on success.
+ */
+int __rte_experimental
+rte_eth_devargs_parse(const struct rte_devargs * const devargs,
+	struct rte_eth_devargs *eth_devargs);
+
 typedef int (*ethdev_init_t)(struct rte_eth_dev *ethdev, void *init_params);
 typedef int (*ethdev_bus_specific_init)(struct rte_eth_dev *ethdev,
 	void *bus_specific_init_params);
lib/librte_ether/rte_ethdev_version.map +1 -0
index 48b08bc36..99d396c5f 100644
@@ -234,6 +234,7 @@ EXPERIMENTAL {
 EXPERIMENTAL {
 	global:
 
+	rt_eth_devargs_parse;
 	rte_eth_dev_create;
 	rte_eth_dev_destroy;
 
Signature · 1 line
2.14.3
#21 lore raw

Re: [PATCH v6 6/8] ethdev: add common devargs parser

Hi,

Quoted 6 lines · Declan Doherty

From: Remy Horton <[email protected]>

Introduces a new structure, rte_eth_devargs, to support generic ethdev arguments common across NET PMDs, with a new API rte_eth_devargs_parse API to support PMD parsing these arguments.

Here is the future layout of rte_devargs:

1. The rte_class introduced by [1], should be expanded with a "find_device" function, equivalent to that of the rte_bus interface.

2. Class and Bus should export a match function as well as a parse function. The match function would be used for device querying, parsing would serve for device declaration.

3. The match function is already implemented by [1]. The parse function for bus already exists and should now be expanded to classes as well. Its expected input should change to be a list of kvargs.

4. Accompanying those changes, the rte_devargs lib would now divide the device string in the three layers identified, use the class parse function to identify the intended class, and be able to feed each layers with its proper input.

This way, this API should be generic to all layers.

Now, this work in underway but takes time.
The current patch I think is an attempt to go in the right direction, but in the end is only a compromise between the simple way and the generic way.

Instead of having rte_eth_devargs_parse, you could have had a simple rte_eth_representor_set(uint16_t *pid_list, size_t len);

That would have set the proper info within the rte_eth_dev_data. The port_id list would have been parsed by your PMD by reading the representor option.

The current version, that feeds directly the devargs to the eth layer, makes conflicts inevitable (with PMDs having potential representor as their parameter, or for future ether parameters such as "mac" that will conflicts with current existing PMD parameters).

I would say that this implementation should be simple at first, for the current work on representor. If the generic API is ready for this release, then we might integrate afterward.

[1]: https://dpdk.org/ml/archives/dev/2018-March/092891.html

Quoted 3 lines

---

Regards,

Signature · 2 lines
Gaëtan Rivet
6WIND
#22 lore raw

PATCH v6 7/8 net/i40e: add support for representor ports

In reply to Declan Doherty

Add support for virtual function representor ports to the i40e PF driver. When SR-IOV virtual functions devices are enabled a corresponding representor port for each VF can be enabled in the process in which the i40e PMD is running within, by specifying the representor devarg with the list of VF ports that representors are to be created for.

An example of the devargs which would create VF representor for virtual functions 0,2,4,5,6 and 7 is:

-w pci:D:B:D.F,representor=[0,2,4-7]

---
 drivers/net/i40e/Makefile              |   3 +
 drivers/net/i40e/i40e_ethdev.c         |  71 +++++-
 drivers/net/i40e/i40e_ethdev.h         |  12 +
 drivers/net/i40e/i40e_vf_representor.c | 392 +++++++++++++++++++++++++++++++++
 drivers/net/i40e/meson.build           |   4 +-
 drivers/net/i40e/rte_pmd_i40e.c        |  43 ++++
 drivers/net/i40e/rte_pmd_i40e.h        |  18 ++
 7 files changed, 535 insertions(+), 8 deletions(-)
 create mode 100644 drivers/net/i40e/i40e_vf_representor.c
drivers/net/i40e/Makefile +3 -0
index 5663f5b1c..6184b38f3 100644
@@ -11,6 +11,8 @@ LIB = librte_pmd_i40e.a
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS) -DPF_DRIVER -DVF_DRIVER -DINTEGRATED_VF
 CFLAGS += -DX722_A0_SUPPORT
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs -lrte_hash
 LDLIBS += -lrte_bus_pci
@@ -85,6 +87,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_fdir.c
 SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_flow.c
 SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += rte_pmd_i40e.c
 SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_tm.c
+SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_vf_representor.c
 
 ifeq ($(findstring RTE_MACHINE_CPUFLAG_AVX2,$(CFLAGS)),RTE_MACHINE_CPUFLAG_AVX2)
 	CC_AVX2_SUPPORT=1
drivers/net/i40e/i40e_ethdev.c +64 -7

107 lines not on this page · raw message

drivers/net/i40e/i40e_ethdev.h +12 -0
index 99efb6707..2d3666e39 100644
@@ -1058,6 +1058,16 @@ struct i40e_adapter {
 	uint64_t pctypes_mask;
 };
 
+/**
+ * Strucute to store private data for each VF representor instance
+ */
+struct i40e_vf_representor {
+	uint16_t vf_id;
+	/**< Virtual Function ID */
+	struct i40e_adapter *adapter;
+	/**< Private data store of assocaiated physical function */
+};
+
 extern const struct rte_flow_ops i40e_flow_ops;
 
 union i40e_filter_t {
@@ -1216,6 +1226,8 @@ int i40e_set_rss_key(struct i40e_vsi *vsi, uint8_t *key, uint8_t key_len);
 int i40e_set_rss_lut(struct i40e_vsi *vsi, uint8_t *lut, uint16_t lut_size);
 int i40e_config_rss_filter(struct i40e_pf *pf,
 		struct i40e_rte_flow_rss_conf *conf, bool add);
+int i40e_vf_representor_init(struct rte_eth_dev *ethdev, void *init_params);
+int i40e_vf_representor_uninit(struct rte_eth_dev *ethdev);
 
 #define I40E_DEV_TO_PCI(eth_dev) \
 	RTE_DEV_TO_PCI((eth_dev)->device)
drivers/net/i40e/i40e_vf_representor.c new file +392 -0

392 lines not on this page · raw message

drivers/net/i40e/meson.build +3 -1
index 8764b0e5b..706b5fce4 100644
@@ -4,7 +4,8 @@
 cflags += ['-DPF_DRIVER',
 	'-DVF_DRIVER',
 	'-DINTEGRATED_VF',
-	'-DX722_A0_SUPPORT']
+	'-DX722_A0_SUPPORT',
+	'-DALLOW_EXPERIMENTAL_API']
 
 subdir('base')
 objs = [base_objs]
@@ -17,6 +18,7 @@ sources = files(
 	'i40e_fdir.c',
 	'i40e_flow.c',
 	'i40e_tm.c',
+	'i40e_vf_representor.c',
 	'rte_pmd_i40e.c'
 	)
 
drivers/net/i40e/rte_pmd_i40e.c +43 -0

49 lines not on this page · raw message

drivers/net/i40e/rte_pmd_i40e.h +18 -0
index d248adb1a..be4a6024a 100644
@@ -455,6 +455,24 @@ int rte_pmd_i40e_set_vf_multicast_promisc(uint16_t port,
 int rte_pmd_i40e_set_vf_mac_addr(uint16_t port, uint16_t vf_id,
 				 struct ether_addr *mac_addr);
 
+/**
+ * Remove the VF MAC address.
+ *
+ * @param port
+ *   The port identifier of the Ethernet device.
+ * @param vf_id
+ *   VF id.
+ * @param mac_addr
+ *   VF MAC address.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if *vf* or *mac_addr* is invalid.
+ */
+int
+rte_pmd_i40e_remove_vf_mac_addr(uint16_t port, uint16_t vf_id,
+	struct ether_addr *mac_addr);
+
 /**
  * Enable/Disable vf vlan strip for all queues in a pool
  *
Signature · 1 line
2.14.3
#23 lore raw

PATCH v6 8/8 net/ixgbe: add support for representor ports

In reply to Declan Doherty

Add support for virtual function representor ports to the ixgbe PF driver. When SR-IOV virtual functions devices are enabled a corresponding representor port for each VF can be enabled in the process in which the i40e PMD is running within, by specifying the representor devarg with the list of VF ports that representors are to be created for.

An example of the devargs which would create VF representor for virtual functions 0,2,4,5,6 and 7 is:

-w pci:D:B:D.F,representor=[0,2,4-7]

---
 drivers/net/ixgbe/Makefile               |   1 +
 drivers/net/ixgbe/ixgbe_ethdev.c         |  70 +++++++++--
 drivers/net/ixgbe/ixgbe_ethdev.h         |  12 ++
 drivers/net/ixgbe/ixgbe_vf_representor.c | 210 +++++++++++++++++++++++++++++++
 drivers/net/ixgbe/meson.build            |   4 +-
 5 files changed, 288 insertions(+), 9 deletions(-)
 create mode 100644 drivers/net/ixgbe/ixgbe_vf_representor.c
drivers/net/ixgbe/Makefile +1 -0
index d0804fc5b..f8725aebb 100644
@@ -103,6 +103,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += ixgbe_ipsec.c
 endif
 SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += rte_pmd_ixgbe.c
 SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += ixgbe_tm.c
+SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += ixgbe_vf_representor.c
 
 # install this header file
 SYMLINK-$(CONFIG_RTE_LIBRTE_IXGBE_PMD)-include := rte_pmd_ixgbe.h
drivers/net/ixgbe/ixgbe_ethdev.c +62 -8

112 lines not on this page · raw message

drivers/net/ixgbe/ixgbe_ethdev.h +12 -0
index c56d65244..cee87ca1f 100644
@@ -480,6 +480,14 @@ struct ixgbe_adapter {
  	struct ixgbe_tm_conf        tm_conf;
 };
 
+struct ixgbe_vf_representor {
+	uint16_t vf_id;
+	struct rte_eth_dev *pf_ethdev;
+};
+
+int ixgbe_vf_representor_init(struct rte_eth_dev *ethdev, void *init_params);
+int ixgbe_vf_representor_uninit(struct rte_eth_dev *ethdev);
+
 #define IXGBE_DEV_PRIVATE_TO_HW(adapter)\
 	(&((struct ixgbe_adapter *)adapter)->hw)
 
@@ -652,6 +660,10 @@ int ixgbe_fdir_filter_program(struct rte_eth_dev *dev,
 
 void ixgbe_configure_dcb(struct rte_eth_dev *dev);
 
+int
+ixgbe_dev_link_update_share(struct rte_eth_dev *dev,
+			    int wait_to_complete, int vf);
+
 /*
  * misc function prototypes
  */
drivers/net/ixgbe/ixgbe_vf_representor.c new file +210 -0

210 lines not on this page · raw message

drivers/net/ixgbe/meson.build +3 -1
index 60af0baef..6862e7ed0 100644
@@ -1,7 +1,8 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2017 Intel Corporation
 
-cflags += ['-DRTE_LIBRTE_IXGBE_BYPASS']
+cflags += ['-DRTE_LIBRTE_IXGBE_BYPASS',
+	'-DALLOW_EXPERIMENTAL_API']
 
 subdir('base')
 objs = [base_objs]
@@ -17,6 +18,7 @@ sources = files(
 	'ixgbe_pf.c',
 	'ixgbe_rxtx.c',
 	'ixgbe_tm.c',
+	'ixgbe_vf_rerpesentor.c',
 	'rte_pmd_ixgbe.c'
 )
 
Signature · 1 line
2.14.3
#24 lore raw

v7 cover switching devices representation

In reply to Declan Doherty

This patchset follows on from the port rerpesentor patchsets and the community discussion that resulted. It outlines the model for representing and controlling switching capable devices in a new programmer's guide entry based upon the excellent summary by Adrien Mazarguil in
(http://dpdk.org/ml/archives/dev/2018-March/092513.html).

The next patches introduce changes to librte_ether to:
1, support the definition of a switch domain and make it public to application through the rte_eth_dev_info structure.
2, Add generic ethdev create/destroy APIs to facilitate and generalise the creation of ethdev's on different bus types.
3, Add ethdev attribute to dev_flags to specify that a port is a representor port and make public through the rte_eth_dev_info structure.
4, Add devargs parsing for generic eth_devargs to facilate parsing in NET PMDs. This will be refactored to take account of the changes in
(http://dpdk.org/ml/archives/dev/2018-March/092513.html)
5, Add new API to allocate switch domain ids to devices which support this feature.

This patchset also includes the enablement of vf port representor for ixgbe and i40e PF devices.

V7:
This patch address the following changes:
- fixes in documentation patch
- changes the default value of switch domain id to be INVALID to allow applications to easily identify devices which can/cannot support the concept. Updates the switch information available through the rte_eth_dev_info structure.
- remove the rte_ethdev_representor.h header and leave representor specific initialisation to driver
- add new APIs for allocating and freeing switch domain identifier to enable PMDs to have unique switch domaind ids without the ethdev infrastructure placing any restriction on how theses are managed by devices.
- bug fix in ethdev args parsing code.

Declan Doherty (8):
doc: add switch representation documentation
ethdev: add switch identifier parameter to port
ethdev: add generic create/destroy ethdev APIs
ethdev: Add port representor device flag
app/testpmd: add port name to device info
ethdev: add switch domain allocator
net/i40e: add support for representor ports
net/ixgbe: add support for representor ports

Remy Horton (1):
ethdev: add common devargs parser

 app/test-pmd/config.c                           |  15 +
 doc/guides/prog_guide/index.rst                 |   1 +
 doc/guides/prog_guide/switch_representation.rst | 837 ++++++++++++++++++++++++
 drivers/net/i40e/Makefile                       |   3 +
 drivers/net/i40e/i40e_ethdev.c                  |  82 ++-
 drivers/net/i40e/i40e_ethdev.h                  |  16 +
 drivers/net/i40e/i40e_vf_representor.c          | 405 ++++++++++++
 drivers/net/i40e/meson.build                    |   4 +-
 drivers/net/i40e/rte_pmd_i40e.c                 |  43 ++
 drivers/net/i40e/rte_pmd_i40e.h                 |  18 +
 drivers/net/ixgbe/Makefile                      |   1 +
 drivers/net/ixgbe/ixgbe_ethdev.c                |  73 ++-
 drivers/net/ixgbe/ixgbe_ethdev.h                |  14 +
 drivers/net/ixgbe/ixgbe_pf.c                    |   7 +
 drivers/net/ixgbe/ixgbe_vf_representor.c        | 217 ++++++
 drivers/net/ixgbe/meson.build                   |   1 +
 lib/Makefile                                    |   1 +
 lib/librte_ether/rte_ethdev.c                   | 345 +++++++++-
 lib/librte_ether/rte_ethdev.h                   |  26 +-
 lib/librte_ether/rte_ethdev_driver.h            | 126 ++++
 lib/librte_ether/rte_ethdev_pci.h               |  12 +
 lib/librte_ether/rte_ethdev_version.map         |  12 +
 22 files changed, 2239 insertions(+), 20 deletions(-)
 create mode 100644 doc/guides/prog_guide/switch_representation.rst
 create mode 100644 drivers/net/i40e/i40e_vf_representor.c
 create mode 100644 drivers/net/ixgbe/ixgbe_vf_representor.c
Signature · 1 line
2.14.3
#25 lore raw

PATCH v7 1/9 doc: add switch representation documentation

Add document to describe the model for representing switching capable devices in DPDK, using a general ethdev port model and through port representors. This document also details the port model and the rte_flow semantics required for flow programming, as well as listing some example use cases.

---
 doc/guides/prog_guide/index.rst                 |   1 +
 doc/guides/prog_guide/switch_representation.rst | 837 ++++++++++++++++++++++++
 2 files changed, 838 insertions(+)
 create mode 100644 doc/guides/prog_guide/switch_representation.rst
doc/guides/prog_guide/index.rst +1 -0
index bbbe7895d..09224af2e 100644
@@ -17,6 +17,7 @@ Programmer's Guide
     mbuf_lib
     poll_mode_drv
     rte_flow
+    switch_representation
     traffic_metering_and_policing
     traffic_management
     bbdev
doc/guides/prog_guide/switch_representation.rst new file +837 -0

837 lines not on this page · raw message

Signature · 1 line
2.14.3
Reviewed-by on v7 1/9
#26 lore raw

Re: [PATCH v7 1/9] doc: add switch representation documentation

Small changes commented below.

Quoted 13 lines

Add document to describe the model for representing switching capable devices in DPDK, using a general ethdev port model and through port representors. This document also details the port model and the rte_flow semantics required for flow programming, as well as listing some example use cases.

---
 doc/guides/prog_guide/index.rst                 |   1 +
 doc/guides/prog_guide/switch_representation.rst | 837
++++++++++++++++++++++++
 2 files changed, 838 insertions(+)

<...>

doc/guides/prog_guide/switch_representation.rst line 75

Quoted 11 lines

+- As virtual devices, they may be more limited than their physical

doc/guides/prog_guide/switch_representation.rst new file +10 -0
+  counterparts, for instance by exposing only a subset of device
+  configuration callbacks and/or by not necessarily having Rx/Tx capability.
+
+- Among other things, they can be used to assign MAC addresses to the
+  resource they represent.
+
+- Applications can tell port representors apart from other physcial of
+virtual
+  port by checking the dev_flags field within their device information
+  structure for the RTE_ETH_DEV_REPRESENTOR bit-field.

physcial / physical

doc/guides/prog_guide/switch_representation.rst line 83

Quoted 7 lines

+.. code-block:: c

doc/guides/prog_guide/switch_representation.rst new file +6 -0
+
+  struct rte_eth_dev_info {
+	..
+	uint32_t dev_flags; /**< Device flags */
+	..
+  };

In the code block above tabs were used you can use spaces instead

<...>

Quoted 14 lines
doc/guides/prog_guide/switch_representation.rst new file +14 -0
+Extensions
+~~~~~~~~~~
+
+Compared to creating a brand new dedicated interface, **rte_flow** was
+deemed flexible enough to manage representor traffic only with minor
+extensions:
+
+- Using physical ports, PF, VF or port representors as targets.
+
+- Affecting traffic that is not necessarily addressed to the DPDK port
+ID a
+  flow rule is associated with (e.g. forcing VF traffic redirection to PF).
+
+For advanced uses:

doc/guides/prog_guide/switch_representation.rst line 378

Quoted 10 lines
doc/guides/prog_guide/switch_representation.rst new file +10 -0
+
+- Rule-based packet counters.
+
+- The ability to combine several identical actions for traffic
+duplication
+  (e.g. VF representor in addition to a physical port).
+
+- Dedicated actions for traffic encapsulation / decapsulation before
+  reaching a endpoint.
+

^^^^^^^^^^^^^
reaching an endpoint

<...>

Quoted 52 lines
doc/guides/prog_guide/switch_representation.rst new file +51 -0
+Switching Examples
+------------------
+
+This section provides practical examples based on the established
+Testpmd flow command syntax [2]_, in the context described in `traffic
+steering`_
+
+::
+
+      .-------------.                 .-------------. .-------------.
+      | hypervisor  |                 |    VM 1     | |    VM 2     |
+      | application |                 | application | | application |
+      `--+---+---+--'                 `----------+--' `--+----------'
+         |   |   |                               |       |
+         |   |   `-------------------.           |       |
+         |   `---------.             |           |       |
+         |             |             |           |       |
+   .----(A)----. .----(B)----. .----(C)----.     |       |
+   | port_id 3 | | port_id 4 | | port_id 5 |     |       |
+   `-----+-----' `-----+-----' `-----+-----'     |       |
+         |             |             |           |       |
+       .-+--.    .-----+-----. .-----+-----. .---+--. .--+---.
+       | PF |    | VF 1 rep. | | VF 2 rep. | | VF 1 | | VF 2 |
+       `-+--'    `-----+-----' `-----+-----' `--(D)-' `-(E)--'
+         |             |             |           |       |
+         |             |   .---------'           |       |
+         `-----.       |   |   .-----------------'       |
+               |       |   |   |   .---------------------'
+               |       |   |   |   |
+            .--|-------|---|---|---|--.
+            |  |       |   `---|---'  |
+            |  |       `-------'      |
+            |  `---------.            |
+            `------------|------------'
+                         |
+                    .---(F)----.
+                    | physical |
+                    |  port 0  |
+                    `----------'
+
+By default, PF (**A**) can communicate with the physical port it is
+associated with (**F**), while VF 1 (**D**) and VF 2 (**E**) are
+isolated and restricted to communicate with the hypervisor application
+through their respective representors (**B** and **C**) if supported.
+
+Examples in subsequent sections apply to hypervisor applications only
+and are based on port representors **A**, **B** and **C**.
+
+.. [2] `Flow syntax
+
+<http://dpdk.org/doc/guides/testpmd_app_ug/testpmd_funcs.html#flow-

synt

Review

Quoted 2 lines
(quoted diff) +2 -0
+ax>`
+

^^^^^^^^^^^^^^^^^^^^^^^^^
You're missing an underscore to complete the link for the case above its not clickable at the moment

<...>

#27 lore raw

PATCH v7 2/9 ethdev: add switch identifier parameter to port

In reply to Declan Doherty

Introduces a new port attribute to ethdev port's which denotes the switch domain a port belongs to. By default all port's switch identifiers are set to RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID. Ports which supported the concept of switch domains can be configured with the same switch domain id.

---
 app/test-pmd/config.c         | 12 ++++++++++++
 lib/librte_ether/rte_ethdev.h | 17 +++++++++++++++++
 2 files changed, 29 insertions(+)
app/test-pmd/config.c +12 -0
index dd051f5ca..884bcb3b6 100644
@@ -517,6 +517,18 @@ port_infos_display(portid_t port_id)
 	printf("Min possible number of TXDs per queue: %hu\n",
 		dev_info.tx_desc_lim.nb_min);
 	printf("TXDs number alignment: %hu\n", dev_info.tx_desc_lim.nb_align);
+
+	/* Show switch info only if valid switch domain and port id is set */
+	if (dev_info.switch_info.domain_id !=
+		RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID) {
+		if (dev_info.switch_info.name)
+			printf("Switch name: %s\n", dev_info.switch_info.name);
+
+		printf("Switch domain Id: %u\n",
+			dev_info.switch_info.domain_id);
+		printf("Switch Port Id: %u\n",
+			dev_info.switch_info.port_id);
+	}
 }
 
 void
lib/librte_ether/rte_ethdev.h +17 -0
index 4f417f573..b5e5fc52a 100644
@@ -1009,6 +1009,21 @@ struct rte_eth_dev_portconf {
 	uint16_t nb_queues; /**< Device-preferred number of queues */
 };
 
+/**
+ * Default values for switch domain id when ethdev does not support switch
+ * domain definitions.
+ */
+#define RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID	(0)
+
+/**
+ * Ethernet device associated switch information
+ */
+struct rte_eth_switch_info {
+	const char *name;	/**< switch name */
+	uint16_t domain_id;	/**< switch domain id */
+	uint16_t port_id;	/**< switch port id */
+};
+
 /**
  * Ethernet device information
  */
@@ -1054,6 +1069,8 @@ struct rte_eth_dev_info {
 	struct rte_eth_dev_portconf default_rxportconf;
 	/** Tx parameter recommendations */
 	struct rte_eth_dev_portconf default_txportconf;
+	/** ethdev switch information */
+	struct rte_eth_switch_info switch_info;
 };
 
 /**
Signature · 1 line
2.14.3
#28 lore raw

Re: [PATCH v7 2/9] ethdev: add switch identifier parameter to port

16/04/2018 15:05, Declan Doherty:

lib/librte_ether/rte_ethdev.h struct rte_eth_dev_portconf { · line 1014

Quoted 5 lines
lib/librte_ether/rte_ethdev.h +3 -0
+/**
+ * Default values for switch domain id when ethdev does not support switch
+ * domain definitions.

values -> value

lib/librte_ether/rte_ethdev.h struct rte_eth_dev_portconf { · line 1024

Quoted 10 lines

+ */

lib/librte_ether/rte_ethdev.h +9 -0
+#define RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID	(0)
+
+/**
+ * Ethernet device associated switch information
+ */
+struct rte_eth_switch_info {
+	const char *name;	/**< switch name */
+	uint16_t domain_id;	/**< switch domain id */
+	uint16_t port_id;	/**< switch port id */

I feel we need more details about what is the "switch port id".

[...]

lib/librte_ether/rte_ethdev.h struct rte_eth_dev_info { · line 1072

Quoted 5 lines
lib/librte_ether/rte_ethdev.h +1 -0
@@ -1054,6 +1069,8 @@ struct rte_eth_dev_info {
 	struct rte_eth_dev_portconf default_rxportconf;
 	/** Tx parameter recommendations */
 	struct rte_eth_dev_portconf default_txportconf;
+	/** ethdev switch information */

Can we reword it to express that it is about the hardware built-in switch hard wired to this port?

Quoted 2 lines
lib/librte_ether/rte_ethdev.h +1 -0
+	struct rte_eth_switch_info switch_info;
 };
#29 lore raw

PATCH v7 3/9 ethdev: add generic create/destroy ethdev APIs

In reply to Declan Doherty

Add new bus generic ethdev create/destroy APIs which are bus independent and provide hooks for bus specific initialisation.

---
 lib/librte_ether/rte_ethdev.c           | 95 ++++++++++++++++++++++++++++++++-
 lib/librte_ether/rte_ethdev_driver.h    | 57 ++++++++++++++++++++
 lib/librte_ether/rte_ethdev_pci.h       | 12 +++++
 lib/librte_ether/rte_ethdev_version.map |  8 +++
 4 files changed, 171 insertions(+), 1 deletion(-)
lib/librte_ether/rte_ethdev.c +94 -1
index 3c049ef43..b16d23b9a 100644
@@ -348,7 +348,8 @@ rte_eth_dev_release_port(struct rte_eth_dev *eth_dev)
 	rte_eth_dev_shared_data_prepare();
 
 	rte_spinlock_lock(&rte_eth_dev_shared_data->ownership_lock);
-
+	eth_dev->device = NULL;
+	eth_dev->intr_handle = NULL;
 	eth_dev->state = RTE_ETH_DEV_UNUSED;
 
 	memset(eth_dev->data, 0, sizeof(struct rte_eth_dev_data));
@@ -3439,6 +3440,98 @@ rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char *ring_name,
 			RTE_MEMZONE_IOVA_CONTIG, align);
 }
 
+int __rte_experimental
+rte_eth_dev_create(struct rte_device *device, const char *name,
+	size_t priv_data_size,
+	ethdev_bus_specific_init ethdev_bus_specific_init,
+	void *bus_init_params,
+	ethdev_init_t ethdev_init, void *init_params)
+{
+	struct rte_eth_dev *ethdev;
+	int retval;
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		ethdev = rte_eth_dev_allocate(name);
+		if (!ethdev) {
+			retval = -ENODEV;
+			goto probe_failed;
+		}
+
+		if (priv_data_size) {
+			ethdev->data->dev_private = rte_zmalloc_socket(
+				name, priv_data_size, RTE_CACHE_LINE_SIZE,
+				device->numa_node);
+
+			if (!ethdev->data->dev_private) {
+				RTE_LOG(ERR, EAL, "failed to allocate private data");
+				retval = -ENOMEM;
+				goto probe_failed;
+			}
+		}
+	} else {
+		ethdev = rte_eth_dev_attach_secondary(name);
+		if (!ethdev) {
+			RTE_LOG(ERR, EAL, "secondary process attach failed, "
+				"ethdev doesn't exist");
+			retval = -ENODEV;
+			goto probe_failed;
+		}
+	}
+
+	ethdev->device = device;
+
+	if (ethdev_bus_specific_init) {
+		retval = ethdev_bus_specific_init(ethdev, bus_init_params);
+		if (retval) {
+			RTE_LOG(ERR, EAL,
+				"ethdev bus specific initialisation failed");
+			goto probe_failed;
+		}
+	}
+
+	RTE_FUNC_PTR_OR_ERR_RET(*ethdev_init, -EINVAL);
+	retval = ethdev_init(ethdev, init_params);
+	if (retval) {
+		RTE_LOG(ERR, EAL, "ethdev initialisation failed");
+		goto probe_failed;
+	}
+
+	return retval;
+probe_failed:
+	/* free ports private data if primary process */
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(ethdev->data->dev_private);
+
+	rte_eth_dev_release_port(ethdev);
+
+	return retval;
+}
+
+int  __rte_experimental
+rte_eth_dev_destroy(struct rte_eth_dev *ethdev,
+	ethdev_uninit_t ethdev_uninit)
+{
+	int ret;
+
+	ethdev = rte_eth_dev_allocated(ethdev->data->name);
+	if (!ethdev)
+		return -ENODEV;
+
+	RTE_FUNC_PTR_OR_ERR_RET(*ethdev_uninit, -EINVAL);
+	if (ethdev_uninit) {
+		ret = ethdev_uninit(ethdev);
+		if (ret)
+			return ret;
+	}
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(ethdev->data->dev_private);
+
+	ethdev->data->dev_private = NULL;
+
+	return rte_eth_dev_release_port(ethdev);
+}
+
 int
 rte_eth_dev_rx_intr_ctl_q(uint16_t port_id, uint16_t queue_id,
 			  int epfd, int op, void *data)
lib/librte_ether/rte_ethdev_driver.h +57 -0

63 lines not on this page · raw message

lib/librte_ether/rte_ethdev_pci.h +12 -0
index 6565ae7d3..603287c28 100644
@@ -70,6 +70,18 @@ rte_eth_copy_pci_info(struct rte_eth_dev *eth_dev,
 	eth_dev->data->numa_node = pci_dev->device.numa_node;
 }
 
+static inline int
+eth_dev_pci_specific_init(struct rte_eth_dev *eth_dev, void *bus_device) {
+	struct rte_pci_device *pci_dev = bus_device;
+
+	if (!pci_dev)
+		return -ENODEV;
+
+	rte_eth_copy_pci_info(eth_dev, pci_dev);
+
+	return 0;
+}
+
 /**
  * @internal
  * Allocates a new ethdev slot for an ethernet device and returns the pointer
lib/librte_ether/rte_ethdev_version.map +8 -0
index 34df6c8b5..bd7232923 100644
@@ -229,3 +229,11 @@ EXPERIMENTAL {
 	rte_mtr_stats_update;
 
 } DPDK_17.11;
+
+EXPERIMENTAL {
+	global:
+
+	rte_eth_dev_create;
+	rte_eth_dev_destroy;
+
+} DPDK_18.05;
Signature · 1 line
2.14.3
#30 lore raw

Re: [PATCH v7 3/9] ethdev: add generic create/destroy ethdev APIs

Hi Declan,

Quoted 69 lines

Add new bus generic ethdev create/destroy APIs which are bus independent and provide hooks for bus specific initialisation.

---
 lib/librte_ether/rte_ethdev.c           | 95 ++++++++++++++++++++++++++++++++-
 lib/librte_ether/rte_ethdev_driver.h    | 57 ++++++++++++++++++++
 lib/librte_ether/rte_ethdev_pci.h       | 12 +++++
 lib/librte_ether/rte_ethdev_version.map |  8 +++
 4 files changed, 171 insertions(+), 1 deletion(-)
lib/librte_ether/rte_ethdev.c +42 -1
index 3c049ef43..b16d23b9a 100644
@@ -348,7 +348,8 @@ rte_eth_dev_release_port(struct rte_eth_dev *eth_dev)
 	rte_eth_dev_shared_data_prepare();
 
 	rte_spinlock_lock(&rte_eth_dev_shared_data->ownership_lock);
-
+	eth_dev->device = NULL;
+	eth_dev->intr_handle = NULL;
 	eth_dev->state = RTE_ETH_DEV_UNUSED;
 
 	memset(eth_dev->data, 0, sizeof(struct rte_eth_dev_data));
@@ -3439,6 +3440,98 @@ rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char *ring_name,
 			RTE_MEMZONE_IOVA_CONTIG, align);
 }
 
+int __rte_experimental
+rte_eth_dev_create(struct rte_device *device, const char *name,
+	size_t priv_data_size,
+	ethdev_bus_specific_init ethdev_bus_specific_init,
+	void *bus_init_params,
+	ethdev_init_t ethdev_init, void *init_params)
+{
+	struct rte_eth_dev *ethdev;
+	int retval;
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		ethdev = rte_eth_dev_allocate(name);
+		if (!ethdev) {
+			retval = -ENODEV;
+			goto probe_failed;
+		}
+
+		if (priv_data_size) {
+			ethdev->data->dev_private = rte_zmalloc_socket(
+				name, priv_data_size, RTE_CACHE_LINE_SIZE,
+				device->numa_node);
+
+			if (!ethdev->data->dev_private) {
+				RTE_LOG(ERR, EAL, "failed to allocate private data");
+				retval = -ENOMEM;
+				goto probe_failed;
+			}
+		}
+	} else {
+		ethdev = rte_eth_dev_attach_secondary(name);
+		if (!ethdev) {
+			RTE_LOG(ERR, EAL, "secondary process attach failed, "
+				"ethdev doesn't exist");
+			retval = -ENODEV;
+			goto probe_failed;
+		}
+	}
+
+	ethdev->device = device;
+

lib/librte_ether/rte_ethdev.c rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char *ring_name, · line 3492

Quoted 10 lines
lib/librte_ether/rte_ethdev.c +10 -0
+	if (ethdev_bus_specific_init) {
+		retval = ethdev_bus_specific_init(ethdev, bus_init_params);
+		if (retval) {
+			RTE_LOG(ERR, EAL,
+				"ethdev bus specific initialisation failed");
+			goto probe_failed;
+		}
+	}
+
+	RTE_FUNC_PTR_OR_ERR_RET(*ethdev_init, -EINVAL);

You probably have to do it at the start - before allocating ethdev, etc.

Quoted 154 lines
lib/librte_ether/rte_ethdev.c +42 -0
+	retval = ethdev_init(ethdev, init_params);
+	if (retval) {
+		RTE_LOG(ERR, EAL, "ethdev initialisation failed");
+		goto probe_failed;
+	}
+
+	return retval;
+probe_failed:
+	/* free ports private data if primary process */
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(ethdev->data->dev_private);
+
+	rte_eth_dev_release_port(ethdev);
+
+	return retval;
+}
+
+int  __rte_experimental
+rte_eth_dev_destroy(struct rte_eth_dev *ethdev,
+	ethdev_uninit_t ethdev_uninit)
+{
+	int ret;
+
+	ethdev = rte_eth_dev_allocated(ethdev->data->name);
+	if (!ethdev)
+		return -ENODEV;
+
+	RTE_FUNC_PTR_OR_ERR_RET(*ethdev_uninit, -EINVAL);
+	if (ethdev_uninit) {
+		ret = ethdev_uninit(ethdev);
+		if (ret)
+			return ret;
+	}
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(ethdev->data->dev_private);
+
+	ethdev->data->dev_private = NULL;
+
+	return rte_eth_dev_release_port(ethdev);
+}
+
 int
 rte_eth_dev_rx_intr_ctl_q(uint16_t port_id, uint16_t queue_id,
 			  int epfd, int op, void *data)
lib/librte_ether/rte_ethdev_driver.h +57 -0
index a406ef123..e52add0ad 100644
@@ -188,6 +188,63 @@ rte_eth_linkstatus_get(const struct rte_eth_dev *dev,
 #endif
 }
 
+
+typedef int (*ethdev_init_t)(struct rte_eth_dev *ethdev, void *init_params);
+typedef int (*ethdev_bus_specific_init)(struct rte_eth_dev *ethdev,
+	void *bus_specific_init_params);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * PMD helper function for the creation of a new ethdev ports.
+ *
+ * @param device
+ *  rte_device handle.
+ * @param	name
+ *  port name.
+ * @param priv_data_size
+ *  size of private data required for port.
+ * @param bus_specific_init
+ *  port bus specific initialisation callback function
+ * @param bus_init_params
+ *  port bus specific initialisation parameters
+ * @param ethdev_init
+ *  device specific port initialization callback function
+ * @param init_params
+ *  port initialisation parameters
+ *
+ * @return
+ *   Negative errno value on error, 0 on success.
+ */
+int __rte_experimental
+rte_eth_dev_create(struct rte_device *device, const char *name,
+	size_t priv_data_size,
+	ethdev_bus_specific_init bus_specific_init, void *bus_init_params,
+	ethdev_init_t ethdev_init, void *init_params);
+
+
+typedef int (*ethdev_uninit_t)(struct rte_eth_dev *ethdev);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * PMD helper function for cleaing up the resources of a ethdev port on it's
+ * destruction.
+ *
+ * @param ethdev
+ *   ethdev handle of port.
+ * @param ethdev
+ *   device specific port un-initialise callback function
+ *
+ * @return
+ *   Negative errno value on error, 0 on success.
+ */
+int __rte_experimental
+rte_eth_dev_destroy(struct rte_eth_dev *ethdev,
+	ethdev_uninit_t ethdev_uninit);
+
 #ifdef __cplusplus
 }
 #endif
lib/librte_ether/rte_ethdev_pci.h +12 -0
index 6565ae7d3..603287c28 100644
@@ -70,6 +70,18 @@ rte_eth_copy_pci_info(struct rte_eth_dev *eth_dev,
 	eth_dev->data->numa_node = pci_dev->device.numa_node;
 }
 
+static inline int
+eth_dev_pci_specific_init(struct rte_eth_dev *eth_dev, void *bus_device) {
+	struct rte_pci_device *pci_dev = bus_device;
+
+	if (!pci_dev)
+		return -ENODEV;
+
+	rte_eth_copy_pci_info(eth_dev, pci_dev);
+
+	return 0;
+}
+
 /**
  * @internal
  * Allocates a new ethdev slot for an ethernet device and returns the pointer
lib/librte_ether/rte_ethdev_version.map +8 -1
index 34df6c8b5..bd7232923 100644
@@ -229,3 +229,11 @@ EXPERIMENTAL {
 	rte_mtr_stats_update;
 
 } DPDK_17.11;
+
+EXPERIMENTAL {
+	global:
+
+	rte_eth_dev_create;
+	rte_eth_dev_destroy;
+
+} DPDK_18.05;
--

2.14.3

#31 lore raw

Re: [PATCH v7 3/9] ethdev: add generic create/destroy ethdev APIs

In reply to Declan Doherty

16/04/2018 15:05, Declan Doherty:

lib/librte_ether/rte_ethdev.c rte_eth_dev_release_port(struct rte_eth_dev *eth_dev) · line 353

Quoted 10 lines
lib/librte_ether/rte_ethdev.c +2 -1
@@ -348,7 +348,8 @@ rte_eth_dev_release_port(struct rte_eth_dev *eth_dev)
 	rte_eth_dev_shared_data_prepare();
 
 	rte_spinlock_lock(&rte_eth_dev_shared_data->ownership_lock);
-
+	eth_dev->device = NULL;
+	eth_dev->intr_handle = NULL;
 	eth_dev->state = RTE_ETH_DEV_UNUSED;

Shouldn't it be in a separate patch with a proper explanation?

lib/librte_ether/rte_ethdev.c rte_eth_dev_release_port(struct rte_eth_dev *eth_dev)

Quoted 3 lines
lib/librte_ether/rte_ethdev.c +3 -0
+ * @param device
+ *  rte_device handle.
+ * @param	name

There is a tab between param and name.

Quoted 4 lines
lib/librte_ether/rte_ethdev_version.map +0 -0
@@ -229,3 +229,11 @@ EXPERIMENTAL {
 	rte_mtr_stats_update;

lib/librte_ether/rte_ethdev_version.map EXPERIMENTAL { · line 239

Quoted 10 lines
lib/librte_ether/rte_ethdev_version.map +8 -0
 
 } DPDK_17.11;
+
+EXPERIMENTAL {
+	global:
+
+	rte_eth_dev_create;
+	rte_eth_dev_destroy;
+
+} DPDK_18.05;

There is already an EXPERIMENTAL block.
Maybe you need to rebase.

#32 lore raw

PATCH v7 4/9 ethdev: Add port representor device flag

In reply to Declan Doherty

Add new device flag to specify that an ethdev port is a port representor. Extend rte_eth_dev_info structure to expose device flags to the user which enables applications to discover if a port is a representor port.

---
 lib/librte_ether/rte_ethdev.c | 2 ++
 lib/librte_ether/rte_ethdev.h | 9 ++++++---
 2 files changed, 8 insertions(+), 3 deletions(-)
lib/librte_ether/rte_ethdev.c +2 -0
index b16d23b9a..1d38d8e75 100644
@@ -2431,6 +2431,8 @@ rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info)
 	dev_info->driver_name = dev->device->driver->name;
 	dev_info->nb_rx_queues = dev->data->nb_rx_queues;
 	dev_info->nb_tx_queues = dev->data->nb_tx_queues;
+
+	dev_info->dev_flags = dev->data->dev_flags;
 }
 
 int
lib/librte_ether/rte_ethdev.h +6 -3
index b5e5fc52a..0a52067d3 100644
@@ -1032,6 +1032,7 @@ struct rte_eth_dev_info {
 	const char *driver_name; /**< Device Driver name. */
 	unsigned int if_index; /**< Index to bound host interface, or 0 if none.
 		Use if_indextoname() to translate into an interface name. */
+	uint32_t dev_flags; /**< Device flags */
 	uint32_t min_rx_bufsize; /**< Minimum size of RX buffer. */
 	uint32_t max_rx_pktlen; /**< Maximum configurable length of RX pkt. */
 	uint16_t max_rx_queues; /**< Maximum number of RX queues. */
@@ -1268,11 +1269,13 @@ struct rte_eth_dev_owner {
 };
 
 /** Device supports link state interrupt */
-#define RTE_ETH_DEV_INTR_LSC     0x0002
+#define RTE_ETH_DEV_INTR_LSC		0x0002
 /** Device is a bonded slave */
-#define RTE_ETH_DEV_BONDED_SLAVE 0x0004
+#define RTE_ETH_DEV_BONDED_SLAVE	0x0004
 /** Device supports device removal interrupt */
-#define RTE_ETH_DEV_INTR_RMV     0x0008
+#define RTE_ETH_DEV_INTR_RMV		0x0008
+/** Device is port representor */
+#define RTE_ETH_DEV_REPRESENTOR		0x0010
 
 /**
  * @warning
Signature · 1 line
2.14.3
#33 lore raw

Re: [PATCH v7 4/9] ethdev: Add port representor device flag

16/04/2018 15:06, Declan Doherty:

Quoted 3 lines

Add new device flag to specify that an ethdev port is a port representor. Extend rte_eth_dev_info structure to expose device flags to the user which enables applications to discover if a port is a representor port.

[...]

Quoted 9 lines
lib/librte_ether/rte_ethdev.c +2 -0
@@ -2431,6 +2431,8 @@ rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info)
 	dev_info->driver_name = dev->device->driver->name;
 	dev_info->nb_rx_queues = dev->data->nb_rx_queues;
 	dev_info->nb_tx_queues = dev->data->nb_tx_queues;
+
+	dev_info->dev_flags = dev->data->dev_flags;
 }

[...]

lib/librte_ether/rte_ethdev.h struct rte_eth_dev_info { · line 1035

Quoted 7 lines
lib/librte_ether/rte_ethdev.h +1 -0
@@ -1032,6 +1032,7 @@ struct rte_eth_dev_info {
 	const char *driver_name; /**< Device Driver name. */
 	unsigned int if_index; /**< Index to bound host interface, or 0 if none.
 		Use if_indextoname() to translate into an interface name. */
+	uint32_t dev_flags; /**< Device flags */

A similar field has been added recently:

	http://dpdk.org/browse/next/dpdk-next-net/tree/lib/librte_ether/rte_ethdev.h#n1074

	/** Generic device capabilities */
	uint64_t dev_capa;

It is for flags DEV_CAPA_*
Note that the prefix should be fixed to RTE_ETH_DEV, and the doxygen comment should mention the flags prefix. Qi, please fix.

I think dev_capa and dev_flags are the same thing. They could be merged.

lib/librte_ether/rte_ethdev.h struct rte_eth_dev_owner { · line 1278

Quoted 11 lines
lib/librte_ether/rte_ethdev.h +5 -3
 /** Device supports link state interrupt */
-#define RTE_ETH_DEV_INTR_LSC     0x0002
+#define RTE_ETH_DEV_INTR_LSC		0x0002
 /** Device is a bonded slave */
-#define RTE_ETH_DEV_BONDED_SLAVE 0x0004
+#define RTE_ETH_DEV_BONDED_SLAVE	0x0004
 /** Device supports device removal interrupt */
-#define RTE_ETH_DEV_INTR_RMV     0x0008
+#define RTE_ETH_DEV_INTR_RMV		0x0008
+/** Device is port representor */
+#define RTE_ETH_DEV_REPRESENTOR		0x0010

It seems you tried to re-align but it fails. Better to use spaces for alignment.

#34 lore raw

Re: [PATCH v7 4/9] ethdev: Add port representor device flag

Quoted 30 lines · Thomas Monjalon

16/04/2018 15:06, Declan Doherty:

Quoted 3 lines

Add new device flag to specify that an ethdev port is a port representor. Extend rte_eth_dev_info structure to expose device flags to the user which enables applications to discover if a port is a representor port.

[...]

Quoted 9 lines
lib/librte_ether/rte_ethdev.c +2 -0
@@ -2431,6 +2431,8 @@ rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info)
  	dev_info->driver_name = dev->device->driver->name;
  	dev_info->nb_rx_queues = dev->data->nb_rx_queues;
  	dev_info->nb_tx_queues = dev->data->nb_tx_queues;
+
+	dev_info->dev_flags = dev->data->dev_flags;
  }

[...]

lib/librte_ether/rte_ethdev.h struct rte_eth_dev_info { · line 1035

Quoted 7 lines
lib/librte_ether/rte_ethdev.h +1 -0
@@ -1032,6 +1032,7 @@ struct rte_eth_dev_info {
  	const char *driver_name; /**< Device Driver name. */
  	unsigned int if_index; /**< Index to bound host interface, or 0 if none.
  		Use if_indextoname() to translate into an interface name. */
+	uint32_t dev_flags; /**< Device flags */

A similar field has been added recently:

	http://dpdk.org/browse/next/dpdk-next-net/tree/lib/librte_ether/rte_ethdev.h#n1074

	/** Generic device capabilities */
	uint64_t dev_capa;
Quoted 7 lines

It is for flags DEV_CAPA_*
Note that the prefix should be fixed to RTE_ETH_DEV, and the doxygen comment should mention the flags prefix. Qi, please fix.

I think dev_capa and dev_flags are the same thing. They could be merged.

Do you have a preference for which one to keep, as dev_flags within
rte_eth_dev_data is widely used by PMDs and passing this same information out through rte_eth_dev_info makes sense to me?

Quoted 16 lines

lib/librte_ether/rte_ethdev.h struct rte_eth_dev_owner { · line 1278

Quoted 12 lines
lib/librte_ether/rte_ethdev.h +5 -3
  /** Device supports link state interrupt */
-#define RTE_ETH_DEV_INTR_LSC     0x0002
+#define RTE_ETH_DEV_INTR_LSC		0x0002
  /** Device is a bonded slave */
-#define RTE_ETH_DEV_BONDED_SLAVE 0x0004
+#define RTE_ETH_DEV_BONDED_SLAVE	0x0004
  /** Device supports device removal interrupt */
-#define RTE_ETH_DEV_INTR_RMV     0x0008
+#define RTE_ETH_DEV_INTR_RMV		0x0008
+/** Device is port representor */
+#define RTE_ETH_DEV_REPRESENTOR		0x0010

It seems you tried to re-align but it fails. Better to use spaces for alignment.

sure will fix.

Quoted 2 lines
#35 lore raw

Re: [PATCH v7 4/9] ethdev: Add port representor device flag

25/04/2018 14:17, Doherty, Declan:

Quoted 7 lines · Thomas Monjalon
Quoted 2 lines

I think dev_capa and dev_flags are the same thing. They could be merged.

Do you have a preference for which one to keep, as dev_flags within rte_eth_dev_data is widely used by PMDs and passing this same information out through rte_eth_dev_info makes sense to me?

I think a big cleanup in ethdev structures is required. We could avoid copying fields from one struct to the other. But I don't want to block this patch, so go ahead and we will clean this mess later.

#36 lore raw

PATCH v7 5/9 app/testpmd: add port name to device info

In reply to Declan Doherty

Add the port name to information printed by show port info <port_id>

---
 app/test-pmd/config.c | 3 +++
 1 file changed, 3 insertions(+)
app/test-pmd/config.c +3 -0
index 884bcb3b6..1b985056a 100644
@@ -407,6 +407,7 @@ port_infos_display(portid_t port_id)
 	static const char *info_border = "*********************";
 	portid_t pid;
 	uint16_t mtu;
+	char name[RTE_ETH_NAME_MAX_LEN];
 
 	if (port_id_is_invalid(port_id, ENABLED_WARN)) {
 		printf("Valid port range is [0");
@@ -423,6 +424,8 @@ port_infos_display(portid_t port_id)
 	       info_border, port_id, info_border);
 	rte_eth_macaddr_get(port_id, &mac_addr);
 	print_ethaddr("MAC address: ", &mac_addr);
+	rte_eth_dev_get_name_by_port(port_id, name);
+	printf("\nDevice name: %s", name);
 	printf("\nDriver name: %s", dev_info.driver_name);
 	printf("\nConnect to socket: %u", port->socket_id);
 
Signature · 1 line
2.14.3
#37 lore raw

PATCH v7 6/9 ethdev: add common devargs parser

In reply to Declan Doherty

From: Remy Horton <[email protected]>

Introduces a new structure, rte_eth_devargs, to support generic ethdev arguments common across NET PMDs, with a new API rte_eth_devargs_parse API to support PMD parsing these arguments.

---
 lib/Makefile                            |   1 +
 lib/librte_ether/rte_ethdev.c           | 195 ++++++++++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev_driver.h    |  30 +++++
 lib/librte_ether/rte_ethdev_version.map |   1 +
 4 files changed, 227 insertions(+)
lib/Makefile +1 -0
index ec965a606..4144d99f9 100644
@@ -21,6 +21,7 @@ DEPDIRS-librte_cmdline := librte_eal
 DIRS-$(CONFIG_RTE_LIBRTE_ETHER) += librte_ether
 DEPDIRS-librte_ether := librte_net librte_eal librte_mempool librte_ring
 DEPDIRS-librte_ether += librte_mbuf
+DEPDIRS-librte_ether += librte_kvargs
 DIRS-$(CONFIG_RTE_LIBRTE_BBDEV) += librte_bbdev
 DEPDIRS-librte_bbdev := librte_eal librte_mempool librte_mbuf
 DIRS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += librte_cryptodev
lib/librte_ether/rte_ethdev.c +195 -0

207 lines not on this page · raw message

lib/librte_ether/rte_ethdev_driver.h +30 -0
index e52add0ad..3bce5747d 100644
@@ -189,6 +189,36 @@ rte_eth_linkstatus_get(const struct rte_eth_dev *dev,
 }
 
 
+/** Generic Ethernet device arguments  */
+struct rte_eth_devargs {
+	uint16_t ports[RTE_MAX_ETHPORTS];
+	/** port/s number to enable on a multi-port single function */
+	uint16_t nb_ports;
+	/** number of ports in ports field */
+	uint16_t representor_ports[RTE_MAX_ETHPORTS];
+	/** representor port/s identifier to enable on device */
+	uint16_t nb_representor_ports;
+	/** number of ports in representor port field */
+};
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * PMD helper function to parse ethdev arguments
+ *
+ * @param devargs
+ *  device arguments
+ * @param eth_devargs
+ *  parsed ethdev specific arguments.
+ *
+ * @return
+ *   Negative errno value on error, 0 on success.
+ */
+int __rte_experimental
+rte_eth_devargs_parse(const char *dargs, struct rte_eth_devargs *eth_devargs);
+
+
 typedef int (*ethdev_init_t)(struct rte_eth_dev *ethdev, void *init_params);
 typedef int (*ethdev_bus_specific_init)(struct rte_eth_dev *ethdev,
 	void *bus_specific_init_params);
lib/librte_ether/rte_ethdev_version.map +1 -0
index bd7232923..62ecbdb8a 100644
@@ -233,6 +233,7 @@ EXPERIMENTAL {
 EXPERIMENTAL {
 	global:
 
+	rt_eth_devargs_parse;
 	rte_eth_dev_create;
 	rte_eth_dev_destroy;
 
Signature · 1 line
2.14.3
#38 lore raw

Re: [PATCH v7 6/9] ethdev: add common devargs parser

Quoted 39 lines

Introduces a new structure, rte_eth_devargs, to support generic ethdev arguments common across NET PMDs, with a new API rte_eth_devargs_parse API to support PMD parsing these arguments.

---
 lib/Makefile                            |   1 +
 lib/librte_ether/rte_ethdev.c           | 195 ++++++++++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev_driver.h    |  30 +++++
 lib/librte_ether/rte_ethdev_version.map |   1 +
 4 files changed, 227 insertions(+)
lib/Makefile +1 -0
index ec965a606..4144d99f9 100644
@@ -21,6 +21,7 @@ DEPDIRS-librte_cmdline := librte_eal
 DIRS-$(CONFIG_RTE_LIBRTE_ETHER) += librte_ether
 DEPDIRS-librte_ether := librte_net librte_eal librte_mempool librte_ring
 DEPDIRS-librte_ether += librte_mbuf
+DEPDIRS-librte_ether += librte_kvargs
 DIRS-$(CONFIG_RTE_LIBRTE_BBDEV) += librte_bbdev
 DEPDIRS-librte_bbdev := librte_eal librte_mempool librte_mbuf
 DIRS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += librte_cryptodev
lib/librte_ether/rte_ethdev.c +1 -0
index 1d38d8e75..a082b211c 100644
@@ -34,6 +34,7 @@
 #include <rte_errno.h>
 #include <rte_spinlock.h>
 #include <rte_string_fns.h>
++#include <rte_kvargs.h>
 
 #include "rte_ether.h"
 #include "rte_ethdev.h"
@@ -4149,6 +4150,200 @@ rte_eth_dev_pool_ops_supported(uint16_t port_id, const char *pool)
 	return (*dev->dev_ops->pool_ops_supported)(dev, pool);

lib/librte_ether/rte_ethdev.c rte_eth_dev_pool_ops_supported(uint16_t port_id, const char *pool) · line 4160

Quoted 10 lines
lib/librte_ether/rte_ethdev.c +8 -0
 }
 
+typedef int (*rte_eth_devargs_callback_t)(char *str, void *data);
+
+static int
+rte_eth_devargs_tokenise(struct rte_kvargs *arglist, const char *str_in)
+{
+	int state;
+	struct rte_kvargs_pair *pair;
+	char *letter;

Hmm, so that extends rte_kvarrgs to be able to parse something like: "key=[val1,val2,...,valn]", right? If so shouldn't it be in rte_kvargs then?
BTW, as I remember rte_kvargs allows you to have multiple identical key, i.e: "key=val1,key=val2,...,key=valn". I suppose that approach would allow you to avoid rte_kvargs modifications.

lib/librte_ether/rte_ethdev.c rte_eth_dev_pool_ops_supported(uint16_t port_id, const char *pool) · line 4162

Quoted 2 lines
lib/librte_ether/rte_ethdev.c +2 -0
+
+	arglist->str = strdup(str_in);

Who is going to free it?

Quoted 104 lines
lib/librte_ether/rte_ethdev.c +104 -0
+	if (arglist->str == NULL)
+		return -ENOMEM;
+
+	letter = arglist->str;
+	state = 0;
+	arglist->count = 0;
+	pair = &arglist->pairs[0];
+	while (1) {
+		switch (state) {
+		case 0: /* Initial */
+			if (*letter == '=')
+				return -EINVAL;
+			else if (*letter == '\0')
+				return 0;
+
+			state = 1;
+			pair->key = letter;
+			/* fall-thru */
+
+		case 1: /* Parsing key */
+			if (*letter == '=') {
+				*letter = '\0';
+				pair->value = letter + 1;
+				state = 2;
+			} else if (*letter == ',' || *letter == '\0')
+				return -EINVAL;
+			break;
+
+
+		case 2: /* Parsing value */
+			if (*letter == '[')
+				state = 3;
+			else if (*letter == ',') {
+				*letter = '\0';
+				arglist->count++;
+				pair = &arglist->pairs[arglist->count];
+				state = 0;
+			} else if (*letter == '\0') {
+				letter--;
+				arglist->count++;
+				pair = &arglist->pairs[arglist->count];
+				state = 0;
+			}
+			break;
+
+		case 3: /* Parsing list */
+			if (*letter == ']')
+				state = 2;
+			else if (*letter == '\0')
+				return -EINVAL;
+			break;
+		}
+		letter++;
+	}
+}
+
+static int
+rte_eth_devargs_parse_list(char *str, rte_eth_devargs_callback_t callback,
+	void *data)
+{
+	char *str_start;
+	int state;
+	int result;
+
+	if (*str != '[')
+		/* Single element, not a list */
+		return callback(str, data);
+
+	/* Sanity check, then strip the brackets */
+	str_start = &str[strlen(str) - 1];
+	if (*str_start != ']') {
+		RTE_LOG(ERR, EAL, "(%s): List does not end with ']'", str);
+		return -EINVAL;
+	}
+	str++;
+	*str_start = '\0';
+
+	/* Process list elements */
+	state = 0;
+	while (1) {
+		if (state == 0) {
+			if (*str == '\0')
+				break;
+			if (*str != ',') {
+				str_start = str;
+				state = 1;
+			}
+		} else if (state == 1) {
+			if (*str == ',' || *str == '\0') {
+				if (str > str_start) {
+					/* Non-empty string fragment */
+					*str = '\0';
+					result = callback(str_start, data);
+					if (result < 0)
+						return result;
+				}
+				state = 0;
+			}
+		}
+		str++;
+	}
+	return 0;
+}
+

lib/librte_ether/rte_ethdev.c rte_eth_dev_pool_ops_supported(uint16_t port_id, const char *pool) · line 4276

Quoted 10 lines
lib/librte_ether/rte_ethdev.c +10 -0
+static int
+rte_eth_devargs_process_range(char *str, uint16_t *list, uint16_t *len_list,
+	const uint16_t max_list)
+{
+	unsigned int lo;
+	unsigned int hi;
+	unsigned int value;
+	int result;
+
+	result = sscanf(str, "%u-%u", &lo, &hi);

Should probably be %hu.
And probably check that lo and hi values are less than MAX_PORTS.

Quoted 128 lines
lib/librte_ether/rte_ethdev.c +70 -0
+	if (result == 1) {
+		if (*len_list >= max_list)
+			return -ENOMEM;
+		list[(*len_list)++] = lo;
+	} else if (result == 2) {
+		if (lo >= hi)
+			return -EINVAL;
+		for (value = lo; value <= hi; value++) {
+			if (*len_list >= max_list)
+				return -ENOMEM;
+			list[(*len_list)++] = value;
+		}
+	} else
+		return -EINVAL;
+	return 0;
+}
+
+static int
+rte_eth_devargs_parse_ports(char *str, void *data)
+{
+	struct rte_eth_devargs *eth_da = data;
+
+	return rte_eth_devargs_process_range(str, eth_da->ports,
+		&eth_da->nb_ports, RTE_MAX_ETHPORTS);
+}
+
+
+static int
+rte_eth_devargs_parse_representor_ports(char *str, void *data)
+{
+	struct rte_eth_devargs *eth_da = data;
+
+	return rte_eth_devargs_process_range(str, eth_da->representor_ports,
+		&eth_da->nb_representor_ports, RTE_MAX_ETHPORTS);
+}
+
+int __rte_experimental
+rte_eth_devargs_parse(const char *dargs, struct rte_eth_devargs *eth_da)
+{
+	struct rte_kvargs args;
+	struct rte_kvargs_pair *pair;
+	unsigned int i;
+	int result;
+
+	memset(eth_da, 0, sizeof(*eth_da));
+
+	result = rte_eth_devargs_tokenise(&args, dargs);
+	if (result < 0)
+		return result;
+
+	for (i = 0; i < args.count; i++) {
+		pair = &args.pairs[i];
+
+		if (strcmp("port", pair->key) == 0) {
+			result = rte_eth_devargs_parse_list(pair->value,
+				rte_eth_devargs_parse_ports, eth_da);
+			if (result < 0)
+				return result;
+		} else if (strcmp("representor", pair->key) == 0) {
+			result = rte_eth_devargs_parse_list(pair->value,
+				rte_eth_devargs_parse_representor_ports,
+				eth_da);
+			if (result < 0)
+				return result;
+		}
+	}
+
+	return 0;
+}
+
 RTE_INIT(ethdev_init_log);
 static void
 ethdev_init_log(void)
lib/librte_ether/rte_ethdev_driver.h +30 -0
index e52add0ad..3bce5747d 100644
@@ -189,6 +189,36 @@ rte_eth_linkstatus_get(const struct rte_eth_dev *dev,
 }
 
 
+/** Generic Ethernet device arguments  */
+struct rte_eth_devargs {
+	uint16_t ports[RTE_MAX_ETHPORTS];
+	/** port/s number to enable on a multi-port single function */
+	uint16_t nb_ports;
+	/** number of ports in ports field */
+	uint16_t representor_ports[RTE_MAX_ETHPORTS];
+	/** representor port/s identifier to enable on device */
+	uint16_t nb_representor_ports;
+	/** number of ports in representor port field */
+};
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * PMD helper function to parse ethdev arguments
+ *
+ * @param devargs
+ *  device arguments
+ * @param eth_devargs
+ *  parsed ethdev specific arguments.
+ *
+ * @return
+ *   Negative errno value on error, 0 on success.
+ */
+int __rte_experimental
+rte_eth_devargs_parse(const char *dargs, struct rte_eth_devargs *eth_devargs);
+
+
 typedef int (*ethdev_init_t)(struct rte_eth_dev *ethdev, void *init_params);
 typedef int (*ethdev_bus_specific_init)(struct rte_eth_dev *ethdev,
 	void *bus_specific_init_params);
lib/librte_ether/rte_ethdev_version.map +1 -1
index bd7232923..62ecbdb8a 100644
@@ -233,6 +233,7 @@ EXPERIMENTAL {
 EXPERIMENTAL {
 	global:
 
+	rt_eth_devargs_parse;
 	rte_eth_dev_create;
 	rte_eth_dev_destroy;
 
--

2.14.3

#39 lore raw

Re: [PATCH v7 6/9] ethdev: add common devargs parser

In reply to Declan Doherty

16/04/2018 15:06, Declan Doherty:

Quoted 5 lines

From: Remy Horton <[email protected]>

Introduces a new structure, rte_eth_devargs, to support generic ethdev arguments common across NET PMDs, with a new API rte_eth_devargs_parse API to support PMD parsing these arguments.

Most of the parsing functions should be removed when the new devargs framework will be ready.
So I won't look specifically at this code.

But I would like to review the devargs you are standardizing. Unfortunately, I cannot find a documentation about it. How users are supposed to use it?
Can you, at least, describe the syntax in the commit log, please?

#40 lore raw

Re: [PATCH v7 6/9] ethdev: add common devargs parser

On 24/04/2018 20:53, Thomas Monjalon wrote:
[..]

Quoted 4 lines

But I would like to review the devargs you are standardizing. Unfortunately, I cannot find a documentation about it. How users are supposed to use it?
Can you, at least, describe the syntax in the commit log, please?

The patch follows this pseudo-BNF:

cfg   := pair (',' pair)*
pair  := (key '=' value)
key   := 'port' | 'representor'

value := range | list
range := int ('-' int)?
int := [0-9]+
list := '[' range (',' range)* ']'

#41 lore raw

Re: [PATCH v7 6/9] ethdev: add common devargs parser

25/04/2018 11:40, Remy Horton:

Quoted 10 lines · Thomas Monjalon

[..]

Quoted 4 lines

But I would like to review the devargs you are standardizing. Unfortunately, I cannot find a documentation about it. How users are supposed to use it?
Can you, at least, describe the syntax in the commit log, please?

The patch follows this pseudo-BNF:

Quoted 7 lines
cfg   := pair (',' pair)*
pair  := (key '=' value)
key   := 'port' | 'representor'

value := range | list
range := int ('-' int)?
int := [0-9]+
list := '[' range (',' range)* ']'

OK
Please can you add it as a comment in the parsing code?

We will need one or two examples in the commit message too.

Can you show a complete command line please?
How do you give ethdev properties without the new devargs syntax (in progress by Gaetan)?

#42 lore raw

Re: [PATCH v7 6/9] ethdev: add common devargs parser

Quoted 3 lines · Thomas Monjalon

25/04/2018 11:40, Remy Horton:

Quoted 2 lines · Thomas Monjalon

[..]

Quoted 4 lines

OK
Please can you add it as a comment in the parsing code?

We will need one or two examples in the commit message too.

Docs are being updated, so it should be in the v8 patchset.

#43 lore raw

PATCH v7 7/9 ethdev: add switch domain allocator

In reply to Declan Doherty
---
 lib/librte_ether/rte_ethdev.c           | 53 +++++++++++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev_driver.h    | 39 ++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev_version.map |  3 ++
 3 files changed, 95 insertions(+)
lib/librte_ether/rte_ethdev.c +53 -0
index a082b211c..d1f95161f 100644
@@ -4300,6 +4300,59 @@ rte_eth_devargs_parse_ports(char *str, void *data)
 		&eth_da->nb_ports, RTE_MAX_ETHPORTS);
 }
 
+/**
+ * A set of values to describe the possible states of a switch domain.
+ */
+enum rte_eth_switch_domain_state {
+	RTE_ETH_SWITCH_DOMAIN_UNUSED = 0,
+	RTE_ETH_SWITCH_DOMAIN_ALLOCATED
+};
+
+/**
+ * Array of switch domains available for allocation. Array is sized to
+ * RTE_MAX_ETHPORTS elements as there cannot be more active switch domains than
+ * ethdev ports in a single process.
+ */
+struct rte_eth_dev_switch {
+	enum rte_eth_switch_domain_state state;
+} rte_eth_switch_domains[RTE_MAX_ETHPORTS];
+
+int __rte_experimental
+rte_eth_switch_domain_alloc(uint16_t *domain_id)
+{
+	unsigned int i;
+
+	*domain_id = RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID;
+
+	for (i = RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID + 1;
+		i < RTE_MAX_ETHPORTS; i++) {
+		if (rte_eth_switch_domains[i].state ==
+			RTE_ETH_SWITCH_DOMAIN_UNUSED) {
+			rte_eth_switch_domains[i].state =
+				RTE_ETH_SWITCH_DOMAIN_ALLOCATED;
+			*domain_id = i;
+			return 0;
+		}
+	}
+
+	return -ENOSPC;
+}
+
+int __rte_experimental
+rte_eth_switch_domain_free(uint16_t domain_id)
+{
+	if (domain_id == RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID ||
+		domain_id >= RTE_MAX_ETHPORTS)
+		return -EINVAL;
+
+	if (rte_eth_switch_domains[domain_id].state !=
+		RTE_ETH_SWITCH_DOMAIN_ALLOCATED)
+		return -EINVAL;
+
+	rte_eth_switch_domains[domain_id].state = RTE_ETH_SWITCH_DOMAIN_UNUSED;
+
+	return 0;
+}
 
 static int
 rte_eth_devargs_parse_representor_ports(char *str, void *data)
lib/librte_ether/rte_ethdev_driver.h +39 -0
index 3bce5747d..c22fcbde1 100644
@@ -188,6 +188,45 @@ rte_eth_linkstatus_get(const struct rte_eth_dev *dev,
 #endif
 }
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Allocate an unique switch domain identifier.
+ *
+ * A pool of switch domain identifiers which can be allocated on request. This
+ * will enabled devices which support the concept of switch domains to request
+ * a switch domain id which is guaranteed to be unique from other devices
+ * running in the same process.
+ *
+ * @param domain_id
+ *  switch domain identifier parameter to pass back to application
+ *
+ * @return
+ *   Negative errno value on error, 0 on success.
+ */
+int __rte_experimental
+rte_eth_switch_domain_alloc(uint16_t *domain_id);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Free switch domain.
+ *
+ * Return a switch domain identifier to the pool of free identifiers after it is
+ * no longer in use by device.
+ *
+ * @param domain_id
+ *  switch domain identifier to free
+ *
+ * @return
+ *   Negative errno value on error, 0 on success.
+ */
+int __rte_experimental
+rte_eth_switch_domain_free(uint16_t domain_id);
+
+
 
 /** Generic Ethernet device arguments  */
 struct rte_eth_devargs {
lib/librte_ether/rte_ethdev_version.map +3 -0
index 62ecbdb8a..6601ef106 100644
@@ -236,5 +236,8 @@ EXPERIMENTAL {
 	rt_eth_devargs_parse;
 	rte_eth_dev_create;
 	rte_eth_dev_destroy;
+	rte_eth_switch_domain_alloc;
+	rte_eth_switch_domain_free;
+	rte_eth_switch_domains;
 
 } DPDK_18.05;
Signature · 1 line
2.14.3
#44 lore raw

Re: [PATCH v7 7/9] ethdev: add switch domain allocator

Quoted 31 lines

-----Original Message-----
From: dev [mailto:[email protected]] On Behalf Of Declan Doherty
Sent: Monday, April 16, 2018 2:06 PM
To: [email protected]
Cc: Adrien Mazarguil <[email protected]>; Yigit, Ferruh <[email protected]>; Thomas Monjalon <[email protected]>; Shahaf Shuler <[email protected]>; Doherty, Declan <[email protected]>
Subject: [dpdk-dev] [PATCH v7 7/9] ethdev: add switch domain allocator

---
 lib/librte_ether/rte_ethdev.c           | 53 +++++++++++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev_driver.h    | 39 ++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev_version.map |  3 ++
 3 files changed, 95 insertions(+)
lib/librte_ether/rte_ethdev.c +6 -0
index a082b211c..d1f95161f 100644
@@ -4300,6 +4300,59 @@ rte_eth_devargs_parse_ports(char *str, void *data)
 		&eth_da->nb_ports, RTE_MAX_ETHPORTS);
 }
 
+/**
+ * A set of values to describe the possible states of a switch domain.
+ */
+enum rte_eth_switch_domain_state {
+	RTE_ETH_SWITCH_DOMAIN_UNUSED = 0,
+	RTE_ETH_SWITCH_DOMAIN_ALLOCATED

lib/librte_ether/rte_ethdev.c rte_eth_devargs_parse_ports(char *str, void *data) · line 4318

Quoted 10 lines
lib/librte_ether/rte_ethdev.c +10 -0
+};
+
+/**
+ * Array of switch domains available for allocation. Array is sized to
+ * RTE_MAX_ETHPORTS elements as there cannot be more active switch domains than
+ * ethdev ports in a single process.
+ */
+struct rte_eth_dev_switch {
+	enum rte_eth_switch_domain_state state;
+} rte_eth_switch_domains[RTE_MAX_ETHPORTS];

Probably already discussed before, but if we can't have more than one switch_id per port, while we can't use port_id as switch_id?

Quoted 8 lines
lib/librte_ether/rte_ethdev.c +8 -0
+
+int __rte_experimental
+rte_eth_switch_domain_alloc(uint16_t *domain_id)
+{
+	unsigned int i;
+
+	*domain_id = RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID;
+

lib/librte_ether/rte_ethdev.c rte_eth_devargs_parse_ports(char *str, void *data) · line 4336

Quoted 10 lines
lib/librte_ether/rte_ethdev.c +10 -0
+	for (i = RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID + 1;
+		i < RTE_MAX_ETHPORTS; i++) {
+		if (rte_eth_switch_domains[i].state ==
+			RTE_ETH_SWITCH_DOMAIN_UNUSED) {
+			rte_eth_switch_domains[i].state =
+				RTE_ETH_SWITCH_DOMAIN_ALLOCATED;
+			*domain_id = i;
+			return 0;
+		}
+	}

So all we need for state is just one status bit (occupied/free)? Wouldn't bitmap do then?

Quoted 87 lines
lib/librte_ether/rte_ethdev.c +19 -0
+
+	return -ENOSPC;
+}
+
+int __rte_experimental
+rte_eth_switch_domain_free(uint16_t domain_id)
+{
+	if (domain_id == RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID ||
+		domain_id >= RTE_MAX_ETHPORTS)
+		return -EINVAL;
+
+	if (rte_eth_switch_domains[domain_id].state !=
+		RTE_ETH_SWITCH_DOMAIN_ALLOCATED)
+		return -EINVAL;
+
+	rte_eth_switch_domains[domain_id].state = RTE_ETH_SWITCH_DOMAIN_UNUSED;
+
+	return 0;
+}
 
 static int
 rte_eth_devargs_parse_representor_ports(char *str, void *data)
lib/librte_ether/rte_ethdev_driver.h +39 -0
index 3bce5747d..c22fcbde1 100644
@@ -188,6 +188,45 @@ rte_eth_linkstatus_get(const struct rte_eth_dev *dev,
 #endif
 }
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Allocate an unique switch domain identifier.
+ *
+ * A pool of switch domain identifiers which can be allocated on request. This
+ * will enabled devices which support the concept of switch domains to request
+ * a switch domain id which is guaranteed to be unique from other devices
+ * running in the same process.
+ *
+ * @param domain_id
+ *  switch domain identifier parameter to pass back to application
+ *
+ * @return
+ *   Negative errno value on error, 0 on success.
+ */
+int __rte_experimental
+rte_eth_switch_domain_alloc(uint16_t *domain_id);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Free switch domain.
+ *
+ * Return a switch domain identifier to the pool of free identifiers after it is
+ * no longer in use by device.
+ *
+ * @param domain_id
+ *  switch domain identifier to free
+ *
+ * @return
+ *   Negative errno value on error, 0 on success.
+ */
+int __rte_experimental
+rte_eth_switch_domain_free(uint16_t domain_id);
+
+
 
 /** Generic Ethernet device arguments  */
 struct rte_eth_devargs {
lib/librte_ether/rte_ethdev_version.map +3 -1
index 62ecbdb8a..6601ef106 100644
@@ -236,5 +236,8 @@ EXPERIMENTAL {
 	rt_eth_devargs_parse;
 	rte_eth_dev_create;
 	rte_eth_dev_destroy;
+	rte_eth_switch_domain_alloc;
+	rte_eth_switch_domain_free;
+	rte_eth_switch_domains;
 
 } DPDK_18.05;
--

2.14.3

#45 lore raw

Re: [PATCH v7 7/9] ethdev: add switch domain allocator

In reply to Declan Doherty

16/04/2018 15:06, Declan Doherty:

Quoted 8 lines
lib/librte_ether/rte_ethdev.c +8 -0
+/**
+ * Array of switch domains available for allocation. Array is sized to
+ * RTE_MAX_ETHPORTS elements as there cannot be more active switch domains than
+ * ethdev ports in a single process.
+ */
+struct rte_eth_dev_switch {
+	enum rte_eth_switch_domain_state state;
+} rte_eth_switch_domains[RTE_MAX_ETHPORTS];

[...]

lib/librte_ether/rte_ethdev_version.map EXPERIMENTAL { · line 241

Quoted 9 lines
lib/librte_ether/rte_ethdev_version.map +3 -0
@@ -236,5 +236,8 @@ EXPERIMENTAL {
 	rt_eth_devargs_parse;
 	rte_eth_dev_create;
 	rte_eth_dev_destroy;
+	rte_eth_switch_domain_alloc;
+	rte_eth_switch_domain_free;
+	rte_eth_switch_domains;

Why the table rte_eth_switch_domains is exported?
Can we use an iterator function + macro instead?

#46 lore raw

PATCH v7 8/9 net/i40e: add support for representor ports

In reply to Declan Doherty

Add support for virtual function representor ports to the i40e PF driver. When SR-IOV virtual functions devices are enabled a corresponding representor port for each VF can be enabled, in the process in which the i40e PMD is running, by specifying the representor devargs with the list of VF ports that representors are to be created for.

An example of the devargs which would create VF representor for virtual functions 0,2,4,5,6 and 7 is:

-w pci:D:B:D.F,representor=[0,2,4-7]

---
 drivers/net/i40e/Makefile              |   3 +
 drivers/net/i40e/i40e_ethdev.c         |  82 ++++++-
 drivers/net/i40e/i40e_ethdev.h         |  16 ++
 drivers/net/i40e/i40e_vf_representor.c | 405 +++++++++++++++++++++++++++++++++
 drivers/net/i40e/meson.build           |   4 +-
 drivers/net/i40e/rte_pmd_i40e.c        |  43 ++++
 drivers/net/i40e/rte_pmd_i40e.h        |  18 ++
 lib/librte_ether/rte_ethdev.c          |   2 +-
 8 files changed, 564 insertions(+), 9 deletions(-)
 create mode 100644 drivers/net/i40e/i40e_vf_representor.c
drivers/net/i40e/Makefile +3 -0
index 5663f5b1c..6184b38f3 100644
@@ -11,6 +11,8 @@ LIB = librte_pmd_i40e.a
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS) -DPF_DRIVER -DVF_DRIVER -DINTEGRATED_VF
 CFLAGS += -DX722_A0_SUPPORT
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs -lrte_hash
 LDLIBS += -lrte_bus_pci
@@ -85,6 +87,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_fdir.c
 SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_flow.c
 SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += rte_pmd_i40e.c
 SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_tm.c
+SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_vf_representor.c
 
 ifeq ($(findstring RTE_MACHINE_CPUFLAG_AVX2,$(CFLAGS)),RTE_MACHINE_CPUFLAG_AVX2)
 	CC_AVX2_SUPPORT=1
drivers/net/i40e/i40e_ethdev.c +75 -7

124 lines not on this page · raw message

drivers/net/i40e/i40e_ethdev.h +16 -0
index d33b255e7..7aaae71c0 100644
@@ -957,6 +957,8 @@ struct i40e_pf {
 	bool gtp_support; /* 1 - support GTP-C and GTP-U */
 	/* customer customized pctype */
 	struct i40e_customized_pctype customized_pctype[I40E_CUSTOMIZED_MAX];
+	/* Switch Domain Id */
+	uint16_t switch_domain_id;
 };
 
 enum pending_msg {
@@ -1062,6 +1064,18 @@ struct i40e_adapter {
 	uint64_t pctypes_mask;
 };
 
+/**
+ * Strucute to store private data for each VF representor instance
+ */
+struct i40e_vf_representor {
+	uint16_t switch_domain_id;
+	/**< Virtual Function ID */
+	uint16_t vf_id;
+	/**< Virtual Function ID */
+	struct i40e_adapter *adapter;
+	/**< Private data store of assocaiated physical function */
+};
+
 extern const struct rte_flow_ops i40e_flow_ops;
 
 union i40e_filter_t {
@@ -1221,6 +1235,8 @@ int i40e_set_rss_key(struct i40e_vsi *vsi, uint8_t *key, uint8_t key_len);
 int i40e_set_rss_lut(struct i40e_vsi *vsi, uint8_t *lut, uint16_t lut_size);
 int i40e_config_rss_filter(struct i40e_pf *pf,
 		struct i40e_rte_flow_rss_conf *conf, bool add);
+int i40e_vf_representor_init(struct rte_eth_dev *ethdev, void *init_params);
+int i40e_vf_representor_uninit(struct rte_eth_dev *ethdev);
 
 #define I40E_DEV_TO_PCI(eth_dev) \
 	RTE_DEV_TO_PCI((eth_dev)->device)
drivers/net/i40e/i40e_vf_representor.c new file +405 -0

405 lines not on this page · raw message

drivers/net/i40e/meson.build +3 -1
index 197e611d8..f2129df07 100644
@@ -6,7 +6,8 @@ version = 2
 cflags += ['-DPF_DRIVER',
 	'-DVF_DRIVER',
 	'-DINTEGRATED_VF',
-	'-DX722_A0_SUPPORT']
+	'-DX722_A0_SUPPORT',
+	'-DALLOW_EXPERIMENTAL_API']
 
 subdir('base')
 objs = [base_objs]
@@ -19,6 +20,7 @@ sources = files(
 	'i40e_fdir.c',
 	'i40e_flow.c',
 	'i40e_tm.c',
+	'i40e_vf_representor.c',
 	'rte_pmd_i40e.c'
 	)
 
drivers/net/i40e/rte_pmd_i40e.c +43 -0

49 lines not on this page · raw message

drivers/net/i40e/rte_pmd_i40e.h +18 -0
index d248adb1a..be4a6024a 100644
@@ -455,6 +455,24 @@ int rte_pmd_i40e_set_vf_multicast_promisc(uint16_t port,
 int rte_pmd_i40e_set_vf_mac_addr(uint16_t port, uint16_t vf_id,
 				 struct ether_addr *mac_addr);
 
+/**
+ * Remove the VF MAC address.
+ *
+ * @param port
+ *   The port identifier of the Ethernet device.
+ * @param vf_id
+ *   VF id.
+ * @param mac_addr
+ *   VF MAC address.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if *vf* or *mac_addr* is invalid.
+ */
+int
+rte_pmd_i40e_remove_vf_mac_addr(uint16_t port, uint16_t vf_id,
+	struct ether_addr *mac_addr);
+
 /**
  * Enable/Disable vf vlan strip for all queues in a pool
  *
lib/librte_ether/rte_ethdev.c +1 -1
index d1f95161f..7a4bde127 100644
@@ -34,7 +34,7 @@
 #include <rte_errno.h>
 #include <rte_spinlock.h>
 #include <rte_string_fns.h>
-+#include <rte_kvargs.h>
+#include <rte_kvargs.h>
 
 #include "rte_ether.h"
 #include "rte_ethdev.h"
Signature · 1 line
2.14.3
#47 lore raw

PATCH v7 9/9 net/ixgbe: add support for representor ports

In reply to Declan Doherty

Add support for virtual function representor ports to the ixgbe PF driver. When SR-IOV virtual functions devices are enabled a corresponding representor port for each VF can be enabled in the process in which the i40e PMD is running within, by specifying the representor devargs with the list of VF ports that representors are to be created for.

An example of the devargs which would create VF representor for virtual functions 0,2,4,5,6 and 7 is:

-w pci:D:B:D.F,representor=[0,2,4-7]

---
 drivers/net/ixgbe/Makefile               |   1 +
 drivers/net/ixgbe/ixgbe_ethdev.c         |  73 +++++++++--
 drivers/net/ixgbe/ixgbe_ethdev.h         |  14 ++
 drivers/net/ixgbe/ixgbe_pf.c             |   7 +
 drivers/net/ixgbe/ixgbe_vf_representor.c | 217 +++++++++++++++++++++++++++++++
 drivers/net/ixgbe/meson.build            |   1 +
 6 files changed, 305 insertions(+), 8 deletions(-)
 create mode 100644 drivers/net/ixgbe/ixgbe_vf_representor.c
drivers/net/ixgbe/Makefile +1 -0
index d0804fc5b..f8725aebb 100644
@@ -103,6 +103,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += ixgbe_ipsec.c
 endif
 SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += rte_pmd_ixgbe.c
 SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += ixgbe_tm.c
+SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += ixgbe_vf_representor.c
 
 # install this header file
 SYMLINK-$(CONFIG_RTE_LIBRTE_IXGBE_PMD)-include := rte_pmd_ixgbe.h
drivers/net/ixgbe/ixgbe_ethdev.c +2 -2
index a5e2fc0ca..0d81db008 100644
@@ -132,7 +132,7 @@
 #define IXGBE_EXVET_VET_EXT_SHIFT              16
 #define IXGBE_DMATXCTL_VT_MASK                 0xFFFF0000
 
-static int eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev);
+static int eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params);
 static int eth_ixgbe_dev_uninit(struct rte_eth_dev *eth_dev);
 static int ixgbe_fdir_filter_init(struct rte_eth_dev *eth_dev);
 static int ixgbe_fdir_filter_uninit(struct rte_eth_dev *eth_dev);
@@ -1043,7 +1043,7 @@ ixgbe_swfw_lock_reset(struct ixgbe_hw *hw)
 
  * It returns 0 on success.
  */
 static int
-eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev)
+eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused)
 {
 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);

struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
@@ -1226,6 +1226,7 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev)
/* initialize PF if max_vfs not zero */ ixgbe_pf_host_init(eth_dev);

+
ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT);
/* let hardware know driver is loaded */
ctrl_ext |= IXGBE_CTRL_EXT_DRV_LOAD;
@@ -1716,16 +1717,72 @@ eth_ixgbevf_dev_uninit(struct rte_eth_dev *eth_dev)
return 0;
}

-static int eth_ixgbe_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, +static int
+eth_ixgbe_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
struct rte_pci_device *pci_dev)
{
- return rte_eth_dev_pci_generic_probe(pci_dev,
- sizeof(struct ixgbe_adapter), eth_ixgbe_dev_init);
+ char name[RTE_ETH_NAME_MAX_LEN];
+
+ struct rte_eth_devargs eth_da;
+ int i, retval;
+
+ retval = rte_eth_devargs_parse(pci_dev->device.devargs->args, &eth_da);
+ if (retval)
+ return retval;
+
+ /* physical port net_bdf_port */
+ snprintf(name, sizeof(name), "net_%s_%d", pci_dev->device.name, 0);
+
+ retval = rte_eth_dev_create(&pci_dev->device, name,
+ sizeof(struct ixgbe_adapter),
+ eth_dev_pci_specific_init, pci_dev,
+ eth_ixgbe_dev_init, NULL);
+
+ if (retval || eth_da.nb_representor_ports < 1)
+ return retval;
+
+ /* probe VF representor ports */
+ struct rte_eth_dev *pf_ethdev = rte_eth_dev_allocated(name);
+
+ for (i = 0; i < eth_da.nb_representor_ports; i++) {
+ struct ixgbe_vf_info *vfinfo = *IXGBE_DEV_PRIVATE_TO_P_VFDATA(
+ pf_ethdev->data->dev_private);
+
+ struct ixgbe_vf_representor representor = {
+ .vf_id = eth_da.representor_ports[i],
+ .switch_domain_id = vfinfo->switch_domain_id,
+ .pf_ethdev = pf_ethdev
+ };
+
+ /* representor port net_bdf_port */
+ snprintf(name, sizeof(name), "net_%s_representor_%d",
+ pci_dev->device.name,
+ eth_da.representor_ports[i]);
+
+ retval = rte_eth_dev_create(&pci_dev->device, name,
+ sizeof(struct ixgbe_vf_representor), NULL, NULL,
+ ixgbe_vf_representor_init, &representor);
+
+ if (retval)
+ PMD_DRV_LOG(ERR, "failed to create ixgbe vf "
+ "representor %s.", name);
+ }
+
+ return 0;
}

static int eth_ixgbe_pci_remove(struct rte_pci_device *pci_dev) {
- return rte_eth_dev_pci_generic_remove(pci_dev, eth_ixgbe_dev_uninit);
+ struct rte_eth_dev *ethdev;
+
+ ethdev = rte_eth_dev_allocated(pci_dev->device.name);
+ if (!ethdev)
+ return -ENODEV;
+
+ if (ethdev->data->dev_flags & RTE_ETH_DEV_REPRESENTOR)
+ return rte_eth_dev_destroy(ethdev, ixgbe_vf_representor_uninit);
+ else
+ return rte_eth_dev_destroy(ethdev, eth_ixgbe_dev_uninit);
}

static struct rte_pci_driver rte_ixgbe_pmd = {
@@ -2868,7 +2925,7 @@ ixgbe_dev_reset(struct rte_eth_dev *dev)
if (ret)
return ret;

- ret = eth_ixgbe_dev_init(dev);
+ ret = eth_ixgbe_dev_init(dev, NULL);

return ret;
}
@@ -3883,7 +3940,7 @@ ixgbevf_check_link(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
}

/* return 0 means link status changed, -1 means not changed */
-static int
+int
ixgbe_dev_link_update_share(struct rte_eth_dev *dev,
int wait_to_complete, int vf)
{

drivers/net/ixgbe/ixgbe_ethdev.h +14 -0
index 655077700..1947442d9 100644
@@ -253,6 +253,7 @@ struct ixgbe_vf_info {
 	uint16_t vlan_count;
 	uint8_t spoofchk_enabled;
 	uint8_t api_version;
+	uint16_t switch_domain_id;
 };
 
 /*
@@ -480,6 +481,15 @@ struct ixgbe_adapter {
  	struct ixgbe_tm_conf        tm_conf;
 };
 
+struct ixgbe_vf_representor {
+	uint16_t vf_id;
+	uint16_t switch_domain_id;
+	struct rte_eth_dev *pf_ethdev;
+};
+
+int ixgbe_vf_representor_init(struct rte_eth_dev *ethdev, void *init_params);
+int ixgbe_vf_representor_uninit(struct rte_eth_dev *ethdev);
+
 #define IXGBE_DEV_PRIVATE_TO_HW(adapter)\
 	(&((struct ixgbe_adapter *)adapter)->hw)
 
@@ -652,6 +662,10 @@ int ixgbe_fdir_filter_program(struct rte_eth_dev *dev,
 
 void ixgbe_configure_dcb(struct rte_eth_dev *dev);
 
+int
+ixgbe_dev_link_update_share(struct rte_eth_dev *dev,
+			    int wait_to_complete, int vf);
+
 /*
  * misc function prototypes
  */
drivers/net/ixgbe/ixgbe_pf.c +7 -0
index 4e61310af..4d199c802 100644
@@ -90,6 +90,8 @@ void ixgbe_pf_host_init(struct rte_eth_dev *eth_dev)
 	if (*vfinfo == NULL)
 		rte_panic("Cannot allocate memory for private VF data\n");
 
+	rte_eth_switch_domain_alloc(&(*vfinfo)->switch_domain_id);
+
 	memset(mirror_info, 0, sizeof(struct ixgbe_mirror_info));
 	memset(uta_info, 0, sizeof(struct ixgbe_uta_info));
 	hw->mac.mc_filter_type = 0;
@@ -122,6 +124,7 @@ void ixgbe_pf_host_uninit(struct rte_eth_dev *eth_dev)
 {
 	struct ixgbe_vf_info **vfinfo;
 	uint16_t vf_num;
+	int ret;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -132,6 +135,10 @@ void ixgbe_pf_host_uninit(struct rte_eth_dev *eth_dev)
 	RTE_ETH_DEV_SRIOV(eth_dev).def_vmdq_idx = 0;
 	RTE_ETH_DEV_SRIOV(eth_dev).def_pool_q_idx = 0;
 
+	ret = rte_eth_switch_domain_free((*vfinfo)->switch_domain_id);
+	if (ret)
+		PMD_INIT_LOG(WARNING, "failed to free switch domain: %d", ret);
+
 	vf_num = dev_num_vf(eth_dev);
 	if (vf_num == 0)
 		return;
drivers/net/ixgbe/ixgbe_vf_representor.c new file +217 -0

217 lines not on this page · raw message

drivers/net/ixgbe/meson.build +1 -0
index f649e659d..5c3a8ca9f 100644
@@ -19,6 +19,7 @@ sources = files(
 	'ixgbe_pf.c',
 	'ixgbe_rxtx.c',
 	'ixgbe_tm.c',
+	'ixgbe_vf_rerpesentor.c',
 	'rte_pmd_ixgbe.c'
 )
 
Signature · 1 line
2.14.3
#48 lore raw

Re: [PATCH v7 9/9] net/ixgbe: add support for representor ports

Quoted 49 lines
drivers/net/ixgbe/ixgbe_vf_representor.c new file +45 -0
@@ -0,0 +1,217 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation.
+ */
+
+#include <rte_ethdev.h>
+#include <rte_pci.h>
+#include <rte_malloc.h>
+
+#include "base/ixgbe_type.h"
+#include "base/ixgbe_vf.h"
+#include "ixgbe_ethdev.h"
+#include "ixgbe_rxtx.h"
+#include "rte_pmd_ixgbe.h"
+
+
+static int
+ixgbe_vf_representor_link_update(struct rte_eth_dev *ethdev,
+	int wait_to_complete)
+{
+	struct ixgbe_vf_representor *representor = ethdev->data->dev_private;
+
+	return ixgbe_dev_link_update_share(representor->pf_ethdev,
+		wait_to_complete, 1);
+}
+
+static int
+ixgbe_vf_representor_mac_addr_set(struct rte_eth_dev *ethdev,
+	struct ether_addr *mac_addr)
+{
+	struct ixgbe_vf_representor *representor = ethdev->data->dev_private;
+
+	return rte_pmd_ixgbe_set_vf_mac_addr(
+		representor->pf_ethdev->data->port_id,
+		representor->vf_id, mac_addr);
+}
+
+static void
+ixgbe_vf_representor_dev_infos_get(struct rte_eth_dev *ethdev,
+	struct rte_eth_dev_info *dev_info)
+{
+	struct ixgbe_vf_representor *representor = ethdev->data->dev_private;
+
+	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(
+		representor->pf_ethdev->data->dev_private);
+

drivers/net/ixgbe/ixgbe_vf_representor.c line 55

Quoted 10 lines
drivers/net/ixgbe/ixgbe_vf_representor.c new file +10 -0
+	dev_info->device = representor->pf_ethdev->device;
+
+	dev_info->min_rx_bufsize = 1024;
+	/**< Minimum size of RX buffer. */
+	dev_info->max_rx_pktlen = 9728;
+	/**< Maximum configurable length of RX pkt. */
+	dev_info->max_rx_queues = IXGBE_VF_MAX_RX_QUEUES;
+	/**< Maximum number of RX queues. */
+	dev_info->max_tx_queues = IXGBE_VF_MAX_TX_QUEUES;
+	/**< Maximum number of TX queues. */

Sort of generic question - for representor ports that do only control path - shouldn't we have max_rx_queues=max_tx_queues=0, zero and make queue_setup/rx_burst/tx_burst, etc. to return an error?

Quoted 52 lines
drivers/net/ixgbe/ixgbe_vf_representor.c new file +52 -0
+
+	dev_info->max_mac_addrs = hw->mac.num_rar_entries;
+	/**< Maximum number of MAC addresses. */
+
+	dev_info->rx_offload_capa = DEV_RX_OFFLOAD_VLAN_STRIP |
+		DEV_RX_OFFLOAD_IPV4_CKSUM |	DEV_RX_OFFLOAD_UDP_CKSUM  |
+		DEV_RX_OFFLOAD_TCP_CKSUM;
+	/**< Device RX offload capabilities. */
+
+	dev_info->tx_offload_capa = DEV_TX_OFFLOAD_VLAN_INSERT |
+		DEV_TX_OFFLOAD_IPV4_CKSUM | DEV_TX_OFFLOAD_UDP_CKSUM |
+		DEV_TX_OFFLOAD_TCP_CKSUM | DEV_TX_OFFLOAD_SCTP_CKSUM |
+		DEV_TX_OFFLOAD_TCP_TSO;
+	/**< Device TX offload capabilities. */
+
+	dev_info->speed_capa =
+		representor->pf_ethdev->data->dev_link.link_speed;
+	/**< Supported speeds bitmap (ETH_LINK_SPEED_). */
+
+	dev_info->switch_info.name =
+		representor->pf_ethdev->device->name;
+	dev_info->switch_info.domain_id = representor->switch_domain_id;
+	dev_info->switch_info.port_id = representor->vf_id;
+}
+
+static int ixgbe_vf_representor_dev_configure(
+		__rte_unused struct rte_eth_dev *dev)
+{
+	return 0;
+}
+
+static int ixgbe_vf_representor_rx_queue_setup(
+	__rte_unused struct rte_eth_dev *dev,
+	__rte_unused uint16_t rx_queue_id,
+	__rte_unused uint16_t nb_rx_desc,
+	__rte_unused unsigned int socket_id,
+	__rte_unused const struct rte_eth_rxconf *rx_conf,
+	__rte_unused struct rte_mempool *mb_pool)
+{
+	return 0;
+}
+
+static int ixgbe_vf_representor_tx_queue_setup(
+	__rte_unused struct rte_eth_dev *dev,
+	__rte_unused uint16_t rx_queue_id,
+	__rte_unused uint16_t nb_rx_desc,
+	__rte_unused unsigned int socket_id,
+	__rte_unused const struct rte_eth_txconf *tx_conf)
+{
+	return 0;
+}
+
#49 lore raw

v8 cover switching devices representation

In reply to Declan Doherty

This patchset follows on from the port rerpesentor patchsets and the community discussion that resulted. It outlines the model for representing and controlling switching capable devices in a new programmer's guide entry based upon the excellent summary by Adrien Mazarguil in
(http://dpdk.org/ml/archives/dev/2018-March/092513.html).

The next patches introduce changes to librte_ether to:
1, support the definition of a switch domain and make it public to application through the rte_eth_dev_info structure.
2, Add generic ethdev create/destroy APIs to facilitate and generalise the creation of ethdev's on different bus types.
3, Add ethdev attribute to dev_flags to specify that a port is a representor port and make public through the rte_eth_dev_info structure.
4, Add devargs parsing for generic eth_devargs to facilate parsing in NET PMDs. This will be refactored to take account of the changes in
(http://dpdk.org/ml/archives/dev/2018-March/092513.html)
5, Add new API to allocate switch domain ids to devices which support this feature.

This patchset also includes the enablement of vf port representor for ixgbe and i40e PF devices.

V8:
- add detailed descriptions to switch information structures
- fix err condition checking ethdev create helper function
- fix devargs memory leak and error checking + add documentation on ethdev args.
- remove rte_eth_switch_domains structure from export items.

V7:

This patch address the following changes:
- fixes in documentation patch
- changes the default value of switch domain id to be INVALID to allow applications to easily identify devices which can/cannot support the concept. Updates the switch information available through the rte_eth_dev_info structure.
- remove the rte_ethdev_representor.h header and leave representor specific initialisation to driver
- add new APIs for allocating and freeing switch domain identifier to enable PMDs to have unique switch domaind ids without the ethdev infrastructure placing any restriction on how theses are managed by devices.
- bug fix in ethdev args parsing code.

Declan Doherty (8):
doc: add switch representation documentation
ethdev: add switch identifier parameter to port
ethdev: add generic create/destroy ethdev APIs
ethdev: Add port representor device flag
app/testpmd: add port name to device info
ethdev: add switch domain allocator
net/i40e: add support for representor ports
net/ixgbe: add support for representor ports

Remy Horton (1):
ethdev: add common devargs parser

 app/test-pmd/config.c                           |  15 +
 doc/guides/nics/i40e.rst                        |  15 +
 doc/guides/nics/ixgbe.rst                       |  14 +
 doc/guides/prog_guide/index.rst                 |   1 +
 doc/guides/prog_guide/poll_mode_drv.rst         |  19 +
 doc/guides/prog_guide/switch_representation.rst | 837 ++++++++++++++++++++++++
 drivers/net/i40e/Makefile                       |   3 +
 drivers/net/i40e/i40e_ethdev.c                  |  82 ++-
 drivers/net/i40e/i40e_ethdev.h                  |  16 +
 drivers/net/i40e/i40e_vf_representor.c          | 405 ++++++++++++
 drivers/net/i40e/meson.build                    |   4 +-
 drivers/net/i40e/rte_pmd_i40e.c                 |  43 ++
 drivers/net/i40e/rte_pmd_i40e.h                 |  18 +
 drivers/net/ixgbe/Makefile                      |   1 +
 drivers/net/ixgbe/ixgbe_ethdev.c                |  80 ++-
 drivers/net/ixgbe/ixgbe_ethdev.h                |  14 +
 drivers/net/ixgbe/ixgbe_pf.c                    |   7 +
 drivers/net/ixgbe/ixgbe_vf_representor.c        | 217 ++++++
 drivers/net/ixgbe/meson.build                   |   1 +
 lib/Makefile                                    |   1 +
 lib/librte_ether/rte_ethdev.c                   | 331 ++++++++++
 lib/librte_ether/rte_ethdev.h                   |  30 +
 lib/librte_ether/rte_ethdev_driver.h            | 126 ++++
 lib/librte_ether/rte_ethdev_pci.h               |  12 +
 lib/librte_ether/rte_ethdev_version.map         |   5 +
 25 files changed, 2280 insertions(+), 17 deletions(-)
 create mode 100644 doc/guides/prog_guide/switch_representation.rst
 create mode 100644 drivers/net/i40e/i40e_vf_representor.c
 create mode 100644 drivers/net/ixgbe/ixgbe_vf_representor.c
Signature · 1 line
2.14.3
#50 lore raw

PATCH v8 1/9 doc: add switch representation documentation

Add document to describe the model for representing switching capable devices in DPDK, using a general ethdev port model and through port representors. This document also details the port model and the rte_flow semantics required for flow programming, as well as listing some example use cases.

---
 doc/guides/prog_guide/index.rst                 |   1 +
 doc/guides/prog_guide/switch_representation.rst | 837 ++++++++++++++++++++++++
 2 files changed, 838 insertions(+)
 create mode 100644 doc/guides/prog_guide/switch_representation.rst
doc/guides/prog_guide/index.rst +1 -0
index 589c05d96..235ad0201 100644
@@ -17,6 +17,7 @@ Programmer's Guide
     mbuf_lib
     poll_mode_drv
     rte_flow
+    switch_representation
     traffic_metering_and_policing
     traffic_management
     bbdev
doc/guides/prog_guide/switch_representation.rst new file +837 -0

837 lines not on this page · raw message

Signature · 1 line
2.14.3
#51 lore raw

PATCH v8 2/9 ethdev: add switch identifier parameter to port

In reply to Declan Doherty

Introduces a new port attribute to ethdev port's which denotes the switch domain a port belongs to. By default all port's switch identifiers are set to RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID. Ports which supported the concept of switch domains can be configured with the same switch domain id.

---
 app/test-pmd/config.c         | 12 ++++++++++++
 lib/librte_ether/rte_ethdev.h | 27 +++++++++++++++++++++++++++
 2 files changed, 39 insertions(+)
app/test-pmd/config.c +12 -0
index 216a7eb4e..26f416100 100644
@@ -517,6 +517,18 @@ port_infos_display(portid_t port_id)
 	printf("Min possible number of TXDs per queue: %hu\n",
 		dev_info.tx_desc_lim.nb_min);
 	printf("TXDs number alignment: %hu\n", dev_info.tx_desc_lim.nb_align);
+
+	/* Show switch info only if valid switch domain and port id is set */
+	if (dev_info.switch_info.domain_id !=
+		RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID) {
+		if (dev_info.switch_info.name)
+			printf("Switch name: %s\n", dev_info.switch_info.name);
+
+		printf("Switch domain Id: %u\n",
+			dev_info.switch_info.domain_id);
+		printf("Switch Port Id: %u\n",
+			dev_info.switch_info.port_id);
+	}
 }
 
 void
lib/librte_ether/rte_ethdev.h +27 -0
index efd84bb7b..06d9b288b 100644
@@ -1026,6 +1026,28 @@ struct rte_eth_dev_portconf {
 	uint16_t nb_queues; /**< Device-preferred number of queues */
 };
 
+/**
+ * Default values for switch domain id when ethdev does not support switch
+ * domain definitions.
+ */
+#define RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID	(0)
+
+/**
+ * Ethernet device associated switch information
+ */
+struct rte_eth_switch_info {
+	const char *name;	/**< switch name */
+	uint16_t domain_id;	/**< switch domain id */
+	uint16_t port_id;
+	/**<
+	 * mapping to the devices physical switch port as enumerated from the
+	 * perspective of the embedded interconnect/switch. For SR-IOV enabled
+	 * device this may correspond to the VF_ID of each virtual function,
+	 * but each driver should explicitly define the mapping of switch
+	 * port identifier to that physical interconnect/switch
+	 */
+};
+
 /**
  * Ethernet device information
  */
@@ -1073,6 +1095,11 @@ struct rte_eth_dev_info {
 	struct rte_eth_dev_portconf default_txportconf;
 	/** Generic device capabilities (RTE_ETH_DEV_CAPA_). */
 	uint64_t dev_capa;
+	/**
+	 * Switching information for ports on a device with a
+	 * embedded managed interconnect/switch.
+	 */
+	struct rte_eth_switch_info switch_info;
 };
 
 /**
Signature · 1 line
2.14.3
Acked-by on v8 2/9
#52 lore raw

Re: [PATCH v8 2/9] ethdev: add switch identifier parameter to port

26/04/2018 12:40, Declan Doherty:

Quoted 7 lines

Introduces a new port attribute to ethdev port's which denotes the switch domain a port belongs to. By default all port's switch identifiers are set to RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID. Ports which supported the concept of switch domains can be configured with the same switch domain id.

It's very well detailed now :)

#53 lore raw

Re: [PATCH v8 2/9] ethdev: add switch identifier parameter to port

26/04/2018 14:02, Thomas Monjalon:

Quoted 7 lines

26/04/2018 12:40, Declan Doherty:

Quoted 6 lines

Introduces a new port attribute to ethdev port's which denotes the switch domain a port belongs to. By default all port's switch identifiers are set to RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID. Ports which supported the concept of switch domains can be configured with the same switch domain id.

Quoted 5 lines
Quoted 1 line

It's very well detailed now :)

One miss: you forgot to remove the deprecation notice in this patch.

#54 lore raw

Re: [PATCH v8 2/9] ethdev: add switch identifier parameter to port

In reply to Declan Doherty
Quoted 10 lines · Declan Doherty

Introduces a new port attribute to ethdev port's which denotes the switch domain a port belongs to. By default all port's switch identifiers are set to RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID. Ports which supported the concept of switch domains can be configured with the same switch domain id.

---
 app/test-pmd/config.c         | 12 ++++++++++++
 lib/librte_ether/rte_ethdev.h | 27 +++++++++++++++++++++++++++

Patch updated in next-net to remove deprecation notice:

diff --git a/doc/guides/rel_notes/deprecation.rst
b/doc/guides/rel_notes/deprecation.rst
index fd85a141b..c3b79a22f 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -59,12 +59,6 @@ Deprecation Notices
Target release for removal of the legacy API will be defined once most
PMDs have switched to rte_flow.

-* ethdev: A work is being planned for 18.05 to expose VF port representors

  -  as a mean to perform control and data path operation on the different VFs.
  -  As VF representor is an ethdev port, new fields are needed in order to map
  -  between the VF representor and the VF or the parent PF. Those new fields
  -  are to be included in ``rte_eth_dev_info`` struct.

-
* i40e: The default flexible payload configuration which extracts the first 16 bytes of the payload for RSS will be deprecated starting from 18.02. If required the previous behavior can be configured using existing flow

#55 lore raw

PATCH v8 3/9 ethdev: add generic create/destroy ethdev APIs

In reply to Declan Doherty

Add new bus generic ethdev create/destroy APIs which are bus independent and provide hooks for bus specific initialisation.

---
 lib/librte_ether/rte_ethdev.c           | 93 +++++++++++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev_driver.h    | 57 ++++++++++++++++++++
 lib/librte_ether/rte_ethdev_pci.h       | 12 +++++
 lib/librte_ether/rte_ethdev_version.map |  2 +
 4 files changed, 164 insertions(+)
lib/librte_ether/rte_ethdev.c +93 -0
index 5f1a1bf2b..6f7695ab3 100644
@@ -3391,6 +3391,99 @@ rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char *ring_name,
 			RTE_MEMZONE_IOVA_CONTIG, align);
 }
 
+int __rte_experimental
+rte_eth_dev_create(struct rte_device *device, const char *name,
+	size_t priv_data_size,
+	ethdev_bus_specific_init ethdev_bus_specific_init,
+	void *bus_init_params,
+	ethdev_init_t ethdev_init, void *init_params)
+{
+	struct rte_eth_dev *ethdev;
+	int retval;
+
+	RTE_FUNC_PTR_OR_ERR_RET(*ethdev_init, -EINVAL);
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		ethdev = rte_eth_dev_allocate(name);
+		if (!ethdev) {
+			retval = -ENODEV;
+			goto probe_failed;
+		}
+
+		if (priv_data_size) {
+			ethdev->data->dev_private = rte_zmalloc_socket(
+				name, priv_data_size, RTE_CACHE_LINE_SIZE,
+				device->numa_node);
+
+			if (!ethdev->data->dev_private) {
+				RTE_LOG(ERR, EAL, "failed to allocate private data");
+				retval = -ENOMEM;
+				goto probe_failed;
+			}
+		}
+	} else {
+		ethdev = rte_eth_dev_attach_secondary(name);
+		if (!ethdev) {
+			RTE_LOG(ERR, EAL, "secondary process attach failed, "
+				"ethdev doesn't exist");
+			retval = -ENODEV;
+			goto probe_failed;
+		}
+	}
+
+	ethdev->device = device;
+
+	if (ethdev_bus_specific_init) {
+		retval = ethdev_bus_specific_init(ethdev, bus_init_params);
+		if (retval) {
+			RTE_LOG(ERR, EAL,
+				"ethdev bus specific initialisation failed");
+			goto probe_failed;
+		}
+	}
+
+	retval = ethdev_init(ethdev, init_params);
+	if (retval) {
+		RTE_LOG(ERR, EAL, "ethdev initialisation failed");
+		goto probe_failed;
+	}
+
+	return retval;
+probe_failed:
+	/* free ports private data if primary process */
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(ethdev->data->dev_private);
+
+	rte_eth_dev_release_port(ethdev);
+
+	return retval;
+}
+
+int  __rte_experimental
+rte_eth_dev_destroy(struct rte_eth_dev *ethdev,
+	ethdev_uninit_t ethdev_uninit)
+{
+	int ret;
+
+	ethdev = rte_eth_dev_allocated(ethdev->data->name);
+	if (!ethdev)
+		return -ENODEV;
+
+	RTE_FUNC_PTR_OR_ERR_RET(*ethdev_uninit, -EINVAL);
+	if (ethdev_uninit) {
+		ret = ethdev_uninit(ethdev);
+		if (ret)
+			return ret;
+	}
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(ethdev->data->dev_private);
+
+	ethdev->data->dev_private = NULL;
+
+	return rte_eth_dev_release_port(ethdev);
+}
+
 int
 rte_eth_dev_rx_intr_ctl_q(uint16_t port_id, uint16_t queue_id,
 			  int epfd, int op, void *data)
lib/librte_ether/rte_ethdev_driver.h +57 -0

63 lines not on this page · raw message

lib/librte_ether/rte_ethdev_pci.h +12 -0
index 6565ae7d3..603287c28 100644
@@ -70,6 +70,18 @@ rte_eth_copy_pci_info(struct rte_eth_dev *eth_dev,
 	eth_dev->data->numa_node = pci_dev->device.numa_node;
 }
 
+static inline int
+eth_dev_pci_specific_init(struct rte_eth_dev *eth_dev, void *bus_device) {
+	struct rte_pci_device *pci_dev = bus_device;
+
+	if (!pci_dev)
+		return -ENODEV;
+
+	rte_eth_copy_pci_info(eth_dev, pci_dev);
+
+	return 0;
+}
+
 /**
  * @internal
  * Allocates a new ethdev slot for an ethernet device and returns the pointer
lib/librte_ether/rte_ethdev_version.map +2 -0
index 8fe07880f..c4380aa31 100644
@@ -208,6 +208,8 @@ EXPERIMENTAL {
 
 	rte_eth_dev_count_avail;
 	rte_eth_dev_count_total;
+	rte_eth_dev_create;
+	rte_eth_dev_destroy;
 	rte_eth_dev_is_removed;
 	rte_eth_dev_owner_delete;
 	rte_eth_dev_owner_get;
Signature · 1 line
2.14.3
#56 lore raw

Re: [PATCH v8 3/9] ethdev: add generic create/destroy ethdev APIs

Quoted 4 lines · Declan Doherty

Add new bus generic ethdev create/destroy APIs which are bus independent and provide hooks for bus specific initialisation.

<...>

Quoted 8 lines
lib/librte_ether/rte_ethdev_driver.h +8 -0
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * PMD helper function for cleaing up the resources of a ethdev port on it's
+ * destruction.
+ *
+ * @param ethdev

lib/librte_ether/rte_ethdev_driver.h rte_eth_linkstatus_get(const struct rte_eth_dev *dev, · line 246

Quoted 10 lines
lib/librte_ether/rte_ethdev_driver.h +10 -0
+ *   ethdev handle of port.
+ * @param ethdev
+ *   device specific port un-initialise callback function
+ *
+ * @return
+ *   Negative errno value on error, 0 on success.
+ */
+int __rte_experimental
+rte_eth_dev_destroy(struct rte_eth_dev *ethdev,
+	ethdev_uninit_t ethdev_uninit);

Will fix doxygen warning while applying, ethdev vs ethdev_uninit

#57 lore raw

PATCH v8 4/9 ethdev: Add port representor device flag

In reply to Declan Doherty

Add new device flag to specify that an ethdev port is a port representor. Extend rte_eth_dev_info structure to expose device flags to the user which enables applications to discover if a port is a representor port.

---
 lib/librte_ether/rte_ethdev.c | 2 ++
 lib/librte_ether/rte_ethdev.h | 3 +++
 2 files changed, 5 insertions(+)
lib/librte_ether/rte_ethdev.c +2 -0
index 6f7695ab3..621f8af7f 100644
@@ -2380,6 +2380,8 @@ rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info)
 	dev_info->driver_name = dev->device->driver->name;
 	dev_info->nb_rx_queues = dev->data->nb_rx_queues;
 	dev_info->nb_tx_queues = dev->data->nb_tx_queues;
+
+	dev_info->dev_flags = &dev->data->dev_flags;
 }
 
 int
lib/librte_ether/rte_ethdev.h +3 -0
index 06d9b288b..0f28ee50d 100644
@@ -1056,6 +1056,7 @@ struct rte_eth_dev_info {
 	const char *driver_name; /**< Device Driver name. */
 	unsigned int if_index; /**< Index to bound host interface, or 0 if none.
 		Use if_indextoname() to translate into an interface name. */
+	const uint32_t *dev_flags; /**< Device flags */
 	uint32_t min_rx_bufsize; /**< Minimum size of RX buffer. */
 	uint32_t max_rx_pktlen; /**< Maximum configurable length of RX pkt. */
 	uint16_t max_rx_queues; /**< Maximum number of RX queues. */
@@ -1302,6 +1303,8 @@ struct rte_eth_dev_owner {
 #define RTE_ETH_DEV_BONDED_SLAVE 0x0004
 /** Device supports device removal interrupt */
 #define RTE_ETH_DEV_INTR_RMV     0x0008
+/** Device is port representor */
+#define RTE_ETH_DEV_REPRESENTOR  0x0010
 
 /**
  * @warning
Signature · 1 line
2.14.3
#58 lore raw

PATCH v8 5/9 app/testpmd: add port name to device info

In reply to Declan Doherty

Add the port name to information printed by show port info <port_id>

---
 app/test-pmd/config.c | 3 +++
 1 file changed, 3 insertions(+)
app/test-pmd/config.c +3 -0
index 26f416100..57853e58f 100644
@@ -407,6 +407,7 @@ port_infos_display(portid_t port_id)
 	static const char *info_border = "*********************";
 	portid_t pid;
 	uint16_t mtu;
+	char name[RTE_ETH_NAME_MAX_LEN];
 
 	if (port_id_is_invalid(port_id, ENABLED_WARN)) {
 		printf("Valid port range is [0");
@@ -423,6 +424,8 @@ port_infos_display(portid_t port_id)
 	       info_border, port_id, info_border);
 	rte_eth_macaddr_get(port_id, &mac_addr);
 	print_ethaddr("MAC address: ", &mac_addr);
+	rte_eth_dev_get_name_by_port(port_id, name);
+	printf("\nDevice name: %s", name);
 	printf("\nDriver name: %s", dev_info.driver_name);
 	printf("\nConnect to socket: %u", port->socket_id);
 
Signature · 1 line
2.14.3
#59 lore raw

PATCH v8 6/9 ethdev: add common devargs parser

In reply to Declan Doherty

From: Remy Horton <[email protected]>

Introduces a new structure, rte_eth_devargs, to support generic ethdev arguments common across NET PMDs, with a new API rte_eth_devargs_parse API to support PMD parsing these arguments. The patch add support for a representor argument passed with passed with the EAL -w option. The representor parameter allows the user to specify which representor ports to initialise on a device.

The argument supports passing a single representor port, a list of port values or a range of port values.

-w BDF,representor=1 # create representor port 1 on pci device BDF -w BDF,representor=[1,2,5,6,10] # create representor ports in list -w BDF,representor=[0-31] # create representor ports in range

---
 doc/guides/prog_guide/poll_mode_drv.rst |  19 ++++
 lib/Makefile                            |   1 +
 lib/librte_ether/rte_ethdev.c           | 182 ++++++++++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev_driver.h    |  30 ++++++
 lib/librte_ether/rte_ethdev_version.map |   1 +
 5 files changed, 233 insertions(+)
doc/guides/prog_guide/poll_mode_drv.rst +19 -0
index e5d01874e..09a93baec 100644
@@ -345,6 +345,25 @@ Ethernet Device API
 
 The Ethernet device API exported by the Ethernet PMDs is described in the *DPDK API Reference*.
 
+Ethernet Device Standard Device Arguments
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Standard Ethernet device arguments allow for a set of commonly used arguments/
+parameters which are applicable to all Ethernet devices to be available to for
+specification of specific device and for passing common configuration
+parameters to those ports.
+
+* ``representor`` for a device which supports the creation of representor ports
+  this argument allows user to specify which switch ports to enable port
+  representors for.::
+
+   -w BDBF,representor=0
+   -w BDBF,representor=[0,4,6,9]
+   -w BDBF,representor=[0-31]
+
+Note: PMDs are not required to support the standard device arguments and users
+should consult the relevant PMD documentation to see support devargs.
+
 Extended Statistics API
 ~~~~~~~~~~~~~~~~~~~~~~~
 
lib/Makefile +1 -0
index 965be6c8d..536775e59 100644
@@ -21,6 +21,7 @@ DEPDIRS-librte_cmdline := librte_eal
 DIRS-$(CONFIG_RTE_LIBRTE_ETHER) += librte_ether
 DEPDIRS-librte_ether := librte_net librte_eal librte_mempool librte_ring
 DEPDIRS-librte_ether += librte_mbuf
+DEPDIRS-librte_ether += librte_kvargs
 DIRS-$(CONFIG_RTE_LIBRTE_BBDEV) += librte_bbdev
 DEPDIRS-librte_bbdev := librte_eal librte_mempool librte_mbuf
 DIRS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += librte_cryptodev
lib/librte_ether/rte_ethdev.c +182 -0

194 lines not on this page · raw message

lib/librte_ether/rte_ethdev_driver.h +30 -0
index 8c61ab2f4..492da754a 100644
@@ -189,6 +189,36 @@ rte_eth_linkstatus_get(const struct rte_eth_dev *dev,
 }
 
 
+/** Generic Ethernet device arguments  */
+struct rte_eth_devargs {
+	uint16_t ports[RTE_MAX_ETHPORTS];
+	/** port/s number to enable on a multi-port single function */
+	uint16_t nb_ports;
+	/** number of ports in ports field */
+	uint16_t representor_ports[RTE_MAX_ETHPORTS];
+	/** representor port/s identifier to enable on device */
+	uint16_t nb_representor_ports;
+	/** number of ports in representor port field */
+};
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * PMD helper function to parse ethdev arguments
+ *
+ * @param devargs
+ *  device arguments
+ * @param eth_devargs
+ *  parsed ethdev specific arguments.
+ *
+ * @return
+ *   Negative errno value on error, 0 on success.
+ */
+int __rte_experimental
+rte_eth_devargs_parse(const char *dargs, struct rte_eth_devargs *eth_devargs);
+
+
 typedef int (*ethdev_init_t)(struct rte_eth_dev *ethdev, void *init_params);
 typedef int (*ethdev_bus_specific_init)(struct rte_eth_dev *ethdev,
 	void *bus_specific_init_params);
lib/librte_ether/rte_ethdev_version.map +1 -0
index c4380aa31..41c3d2699 100644
@@ -206,6 +206,7 @@ DPDK_18.02 {
 EXPERIMENTAL {
 	global:
 
+	rte_eth_devargs_parse;
 	rte_eth_dev_count_avail;
 	rte_eth_dev_count_total;
 	rte_eth_dev_create;
Signature · 1 line
2.14.3
#60 lore raw

Re: [PATCH v8 6/9] ethdev: add common devargs parser

Quoted 92 lines

-----Original Message-----
From: Doherty, Declan
Sent: Thursday, April 26, 2018 11:41 AM
To: [email protected]
Cc: Adrien Mazarguil <[email protected]>; Yigit, Ferruh <[email protected]>; Thomas Monjalon <[email protected]>; Shahaf Shuler <[email protected]>; Ananyev, Konstantin <[email protected]>; Horton, Remy <[email protected]>; Doherty, Declan <[email protected]>
Subject: [dpdk-dev][PATCH v8 6/9] ethdev: add common devargs parser

From: Remy Horton <[email protected]>

Introduces a new structure, rte_eth_devargs, to support generic ethdev arguments common across NET PMDs, with a new API rte_eth_devargs_parse API to support PMD parsing these arguments. The patch add support for a representor argument passed with passed with the EAL -w option. The representor parameter allows the user to specify which representor ports to initialise on a device.

The argument supports passing a single representor port, a list of port values or a range of port values.

(quoted diff) +0 -3
-w BDF,representor=1  # create representor port 1 on pci device BDF
-w BDF,representor=[1,2,5,6,10] # create representor ports in list
-w BDF,representor=[0-31] # create representor ports in range
---
 doc/guides/prog_guide/poll_mode_drv.rst |  19 ++++
 lib/Makefile                            |   1 +
 lib/librte_ether/rte_ethdev.c           | 182 ++++++++++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev_driver.h    |  30 ++++++
 lib/librte_ether/rte_ethdev_version.map |   1 +
 5 files changed, 233 insertions(+)
doc/guides/prog_guide/poll_mode_drv.rst +19 -0
index e5d01874e..09a93baec 100644
@@ -345,6 +345,25 @@ Ethernet Device API
 
 The Ethernet device API exported by the Ethernet PMDs is described in the *DPDK API Reference*.
 
+Ethernet Device Standard Device Arguments
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Standard Ethernet device arguments allow for a set of commonly used arguments/
+parameters which are applicable to all Ethernet devices to be available to for
+specification of specific device and for passing common configuration
+parameters to those ports.
+
+* ``representor`` for a device which supports the creation of representor ports
+  this argument allows user to specify which switch ports to enable port
+  representors for.::
+
+   -w BDBF,representor=0
+   -w BDBF,representor=[0,4,6,9]
+   -w BDBF,representor=[0-31]
+
+Note: PMDs are not required to support the standard device arguments and users
+should consult the relevant PMD documentation to see support devargs.
+
 Extended Statistics API
 ~~~~~~~~~~~~~~~~~~~~~~~
 
lib/Makefile +1 -0
index 965be6c8d..536775e59 100644
@@ -21,6 +21,7 @@ DEPDIRS-librte_cmdline := librte_eal
 DIRS-$(CONFIG_RTE_LIBRTE_ETHER) += librte_ether
 DEPDIRS-librte_ether := librte_net librte_eal librte_mempool librte_ring
 DEPDIRS-librte_ether += librte_mbuf
+DEPDIRS-librte_ether += librte_kvargs
 DIRS-$(CONFIG_RTE_LIBRTE_BBDEV) += librte_bbdev
 DEPDIRS-librte_bbdev := librte_eal librte_mempool librte_mbuf
 DIRS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += librte_cryptodev
lib/librte_ether/rte_ethdev.c +1 -0
index 621f8af7f..cb85d8bb7 100644
@@ -34,6 +34,7 @@
 #include <rte_errno.h>
 #include <rte_spinlock.h>
 #include <rte_string_fns.h>
++#include <rte_kvargs.h>
 
 #include "rte_ether.h"
 #include "rte_ethdev.h"

lib/librte_ether/rte_ethdev.c rte_eth_dev_pool_ops_supported(uint16_t port_id, const char *pool) · line 4109

Quoted 8 lines
lib/librte_ether/rte_ethdev.c +5 -0
@@ -4101,6 +4102,187 @@ rte_eth_dev_pool_ops_supported(uint16_t port_id, const char *pool)
 	return (*dev->dev_ops->pool_ops_supported)(dev, pool);
 }
 
+typedef int (*rte_eth_devargs_callback_t)(char *str, void *data);
+
+static int
+rte_eth_devargs_tokenise(struct rte_kvargs *arglist, const char *str_in)
+{

I still think that if you'd like to extend rte_kvarrgs to be able to parse something like: "key=[val1,val2,...,valn]", you have to make it generic kvargs ability and put it into librte_kvargs, not try to introduce your own new parser here. Imagine that in addition to your 'port=[val1,val2, ..valn]' devargs string would contain some extra (let say device specific) parameters.
What would happen, when PMD will try to use rte_kvargs_parse() on such string?
My understanding - it would fail, correct?

As an alternative - as I remember rte_kvargs allows you to have multiple identical key, i.e: "key=val1,key=val2,...,key=valn". Why not to use that way, if you don't want to introduce extra code in rte_kvargs?

Quoted 113 lines
lib/librte_ether/rte_ethdev.c +113 -0
+	int state;
+	struct rte_kvargs_pair *pair;
+	char *letter;
+
+	arglist->str = strdup(str_in);
+	if (arglist->str == NULL)
+		return -ENOMEM;
+
+	letter = arglist->str;
+	state = 0;
+	arglist->count = 0;
+	pair = &arglist->pairs[0];
+	while (1) {
+		switch (state) {
+		case 0: /* Initial */
+			if (*letter == '=')
+				return -EINVAL;
+			else if (*letter == '\0')
+				return 0;
+
+			state = 1;
+			pair->key = letter;
+			/* fall-thru */
+
+		case 1: /* Parsing key */
+			if (*letter == '=') {
+				*letter = '\0';
+				pair->value = letter + 1;
+				state = 2;
+			} else if (*letter == ',' || *letter == '\0')
+				return -EINVAL;
+			break;
+
+
+		case 2: /* Parsing value */
+			if (*letter == '[')
+				state = 3;
+			else if (*letter == ',') {
+				*letter = '\0';
+				arglist->count++;
+				pair = &arglist->pairs[arglist->count];
+				state = 0;
+			} else if (*letter == '\0') {
+				letter--;
+				arglist->count++;
+				pair = &arglist->pairs[arglist->count];
+				state = 0;
+			}
+			break;
+
+		case 3: /* Parsing list */
+			if (*letter == ']')
+				state = 2;
+			else if (*letter == '\0')
+				return -EINVAL;
+			break;
+		}
+		letter++;
+	}
+}
+
+static int
+rte_eth_devargs_parse_list(char *str, rte_eth_devargs_callback_t callback,
+	void *data)
+{
+	char *str_start;
+	int state;
+	int result;
+
+	if (*str != '[')
+		/* Single element, not a list */
+		return callback(str, data);
+
+	/* Sanity check, then strip the brackets */
+	str_start = &str[strlen(str) - 1];
+	if (*str_start != ']') {
+		RTE_LOG(ERR, EAL, "(%s): List does not end with ']'", str);
+		return -EINVAL;
+	}
+	str++;
+	*str_start = '\0';
+
+	/* Process list elements */
+	state = 0;
+	while (1) {
+		if (state == 0) {
+			if (*str == '\0')
+				break;
+			if (*str != ',') {
+				str_start = str;
+				state = 1;
+			}
+		} else if (state == 1) {
+			if (*str == ',' || *str == '\0') {
+				if (str > str_start) {
+					/* Non-empty string fragment */
+					*str = '\0';
+					result = callback(str_start, data);
+					if (result < 0)
+						return result;
+				}
+				state = 0;
+			}
+		}
+		str++;
+	}
+	return 0;
+}
+
+static int
+rte_eth_devargs_process_range(char *str, uint16_t *list, uint16_t *len_list,
+	const uint16_t max_list)
+{

lib/librte_ether/rte_ethdev.c rte_eth_dev_pool_ops_supported(uint16_t port_id, const char *pool) · line 4232

Quoted 10 lines
lib/librte_ether/rte_ethdev.c +10 -0
+	uint16_t lo, hi, val;
+	int result;
+
+	result = sscanf(str, "%hu-%hu", &lo, &hi);
+	if (result == 1) {
+		if (*len_list >= max_list)
+			return -ENOMEM;
+		list[(*len_list)++] = lo;
+	} else if (result == 2) {
+		if (lo >= hi || lo > RTE_MAX_ETHPORTS || hi > RTE_MAX_ETHPORTS)

lo > RTE_MAX_ETHPORTS is redundant here.

Quoted 111 lines
lib/librte_ether/rte_ethdev.c +53 -0
+			return -EINVAL;
+		for (val = lo; val <= hi; val++) {
+			if (*len_list >= max_list)
+				return -ENOMEM;
+			list[(*len_list)++] = val;
+		}
+	} else
+		return -EINVAL;
+	return 0;
+}
+
+
+static int
+rte_eth_devargs_parse_representor_ports(char *str, void *data)
+{
+	struct rte_eth_devargs *eth_da = data;
+
+	return rte_eth_devargs_process_range(str, eth_da->representor_ports,
+		&eth_da->nb_representor_ports, RTE_MAX_ETHPORTS);
+}
+
+int __rte_experimental
+rte_eth_devargs_parse(const char *dargs, struct rte_eth_devargs *eth_da)
+{
+	struct rte_kvargs args;
+	struct rte_kvargs_pair *pair;
+	unsigned int i;
+	int result = 0;
+
+	memset(eth_da, 0, sizeof(*eth_da));
+
+	result = rte_eth_devargs_tokenise(&args, dargs);
+	if (result < 0)
+		goto parse_cleanup;
+
+	for (i = 0; i < args.count; i++) {
+		pair = &args.pairs[i];
+		if (strcmp("representor", pair->key) == 0) {
+			result = rte_eth_devargs_parse_list(pair->value,
+				rte_eth_devargs_parse_representor_ports,
+				eth_da);
+			if (result < 0)
+				goto parse_cleanup;
+		}
+	}
+
+parse_cleanup:
+	if (args.str)
+		free(args.str);
+
+	return result;
+}
+
 RTE_INIT(ethdev_init_log);
 static void
 ethdev_init_log(void)
lib/librte_ether/rte_ethdev_driver.h +30 -0
index 8c61ab2f4..492da754a 100644
@@ -189,6 +189,36 @@ rte_eth_linkstatus_get(const struct rte_eth_dev *dev,
 }
 
 
+/** Generic Ethernet device arguments  */
+struct rte_eth_devargs {
+	uint16_t ports[RTE_MAX_ETHPORTS];
+	/** port/s number to enable on a multi-port single function */
+	uint16_t nb_ports;
+	/** number of ports in ports field */
+	uint16_t representor_ports[RTE_MAX_ETHPORTS];
+	/** representor port/s identifier to enable on device */
+	uint16_t nb_representor_ports;
+	/** number of ports in representor port field */
+};
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * PMD helper function to parse ethdev arguments
+ *
+ * @param devargs
+ *  device arguments
+ * @param eth_devargs
+ *  parsed ethdev specific arguments.
+ *
+ * @return
+ *   Negative errno value on error, 0 on success.
+ */
+int __rte_experimental
+rte_eth_devargs_parse(const char *dargs, struct rte_eth_devargs *eth_devargs);
+
+
 typedef int (*ethdev_init_t)(struct rte_eth_dev *ethdev, void *init_params);
 typedef int (*ethdev_bus_specific_init)(struct rte_eth_dev *ethdev,
 	void *bus_specific_init_params);
lib/librte_ether/rte_ethdev_version.map +1 -1
index c4380aa31..41c3d2699 100644
@@ -206,6 +206,7 @@ DPDK_18.02 {
 EXPERIMENTAL {
 	global:
 
+	rte_eth_devargs_parse;
 	rte_eth_dev_count_avail;
 	rte_eth_dev_count_total;
 	rte_eth_dev_create;
--

2.14.3

#61 lore raw

Re: [PATCH v8 6/9] ethdev: add common devargs parser

Quoted 108 lines · Konstantin
Quoted 92 lines

-----Original Message-----
From: Doherty, Declan
Sent: Thursday, April 26, 2018 11:41 AM
To: [email protected]
Cc: Adrien Mazarguil <[email protected]>; Yigit, Ferruh <[email protected]>; Thomas Monjalon <[email protected]>; Shahaf Shuler <[email protected]>; Ananyev, Konstantin <[email protected]>; Horton, Remy <[email protected]>; Doherty, Declan <[email protected]>
Subject: [dpdk-dev][PATCH v8 6/9] ethdev: add common devargs parser

From: Remy Horton <[email protected]>

Introduces a new structure, rte_eth_devargs, to support generic ethdev arguments common across NET PMDs, with a new API rte_eth_devargs_parse API to support PMD parsing these arguments. The patch add support for a representor argument passed with passed with the EAL -w option. The representor parameter allows the user to specify which representor ports to initialise on a device.

The argument supports passing a single representor port, a list of port values or a range of port values.

(quoted diff) +0 -3
-w BDF,representor=1  # create representor port 1 on pci device BDF
-w BDF,representor=[1,2,5,6,10] # create representor ports in list
-w BDF,representor=[0-31] # create representor ports in range
---
 doc/guides/prog_guide/poll_mode_drv.rst |  19 ++++
 lib/Makefile                            |   1 +
 lib/librte_ether/rte_ethdev.c           | 182 ++++++++++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev_driver.h    |  30 ++++++
 lib/librte_ether/rte_ethdev_version.map |   1 +
 5 files changed, 233 insertions(+)
doc/guides/prog_guide/poll_mode_drv.rst +19 -0
index e5d01874e..09a93baec 100644
@@ -345,6 +345,25 @@ Ethernet Device API
 
 The Ethernet device API exported by the Ethernet PMDs is described in the *DPDK API Reference*.
 
+Ethernet Device Standard Device Arguments
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Standard Ethernet device arguments allow for a set of commonly used arguments/
+parameters which are applicable to all Ethernet devices to be available to for
+specification of specific device and for passing common configuration
+parameters to those ports.
+
+* ``representor`` for a device which supports the creation of representor ports
+  this argument allows user to specify which switch ports to enable port
+  representors for.::
+
+   -w BDBF,representor=0
+   -w BDBF,representor=[0,4,6,9]
+   -w BDBF,representor=[0-31]
+
+Note: PMDs are not required to support the standard device arguments and users
+should consult the relevant PMD documentation to see support devargs.
+
 Extended Statistics API
 ~~~~~~~~~~~~~~~~~~~~~~~
 
lib/Makefile +1 -0
index 965be6c8d..536775e59 100644
@@ -21,6 +21,7 @@ DEPDIRS-librte_cmdline := librte_eal
 DIRS-$(CONFIG_RTE_LIBRTE_ETHER) += librte_ether
 DEPDIRS-librte_ether := librte_net librte_eal librte_mempool librte_ring
 DEPDIRS-librte_ether += librte_mbuf
+DEPDIRS-librte_ether += librte_kvargs
 DIRS-$(CONFIG_RTE_LIBRTE_BBDEV) += librte_bbdev
 DEPDIRS-librte_bbdev := librte_eal librte_mempool librte_mbuf
 DIRS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += librte_cryptodev
lib/librte_ether/rte_ethdev.c +1 -0
index 621f8af7f..cb85d8bb7 100644
@@ -34,6 +34,7 @@
 #include <rte_errno.h>
 #include <rte_spinlock.h>
 #include <rte_string_fns.h>
++#include <rte_kvargs.h>
 
 #include "rte_ether.h"
 #include "rte_ethdev.h"

lib/librte_ether/rte_ethdev.c rte_eth_dev_pool_ops_supported(uint16_t port_id, const char *pool) · line 4109

Quoted 8 lines
lib/librte_ether/rte_ethdev.c +5 -0
@@ -4101,6 +4102,187 @@ rte_eth_dev_pool_ops_supported(uint16_t port_id, const char *pool)
 	return (*dev->dev_ops->pool_ops_supported)(dev, pool);
 }
 
+typedef int (*rte_eth_devargs_callback_t)(char *str, void *data);
+
+static int
+rte_eth_devargs_tokenise(struct rte_kvargs *arglist, const char *str_in)
+{

I still think that if you'd like to extend rte_kvarrgs to be able to parse something like: "key=[val1,val2,...,valn]", you have to make it generic kvargs ability and put it into librte_kvargs, not try to introduce your own new parser here. Imagine that in addition to your 'port=[val1,val2, ..valn]' devargs string would contain some extra (let say device specific) parameters.
What would happen, when PMD will try to use rte_kvargs_parse() on such string?
My understanding - it would fail, correct?

Quoted 2 lines

As an alternative - as I remember rte_kvargs allows you to have multiple identical key, i.e: "key=val1,key=val2,...,key=valn". Why not to use that way, if you don't want to introduce extra code in rte_kvargs?

Hi Declan, Remy,

I will continue with existing patchset, for the sake of the rc1, can you please address these comments as incremental updates to the set?

Quoted 8 lines
Quoted 8 lines
lib/librte_ether/rte_ethdev.c +8 -0
+static int
+rte_eth_devargs_process_range(char *str, uint16_t *list, uint16_t *len_list,
+	const uint16_t max_list)
+{
+	uint16_t lo, hi, val;
+	int result;
+
+	result = sscanf(str, "%hu-%hu", &lo, &hi);
Quoted 8 lines

lib/librte_ether/rte_ethdev.c rte_eth_dev_pool_ops_supported(uint16_t port_id, const char *pool) · line 4232

Quoted 6 lines
lib/librte_ether/rte_ethdev.c +6 -0
+	if (result == 1) {
+		if (*len_list >= max_list)
+			return -ENOMEM;
+		list[(*len_list)++] = lo;
+	} else if (result == 2) {
+		if (lo >= hi || lo > RTE_MAX_ETHPORTS || hi > RTE_MAX_ETHPORTS)

lo > RTE_MAX_ETHPORTS is redundant here.

Same here, thanks.

#62 lore raw

Re: [PATCH v8 6/9] ethdev: add common devargs parser

In reply to Ananyev, Konstantin
Quoted 108 lines · Konstantin
Quoted 92 lines

-----Original Message-----
From: Doherty, Declan
Sent: Thursday, April 26, 2018 11:41 AM
To: [email protected]
Cc: Adrien Mazarguil <[email protected]>; Yigit, Ferruh <[email protected]>; Thomas Monjalon <[email protected]>; Shahaf Shuler <[email protected]>; Ananyev, Konstantin <[email protected]>; Horton, Remy <[email protected]>; Doherty, Declan <[email protected]>
Subject: [dpdk-dev][PATCH v8 6/9] ethdev: add common devargs parser

From: Remy Horton <[email protected]>

Introduces a new structure, rte_eth_devargs, to support generic ethdev arguments common across NET PMDs, with a new API rte_eth_devargs_parse API to support PMD parsing these arguments. The patch add support for a representor argument passed with passed with the EAL -w option. The representor parameter allows the user to specify which representor ports to initialise on a device.

The argument supports passing a single representor port, a list of port values or a range of port values.

(quoted diff) +0 -3
-w BDF,representor=1  # create representor port 1 on pci device BDF
-w BDF,representor=[1,2,5,6,10] # create representor ports in list
-w BDF,representor=[0-31] # create representor ports in range
---
  doc/guides/prog_guide/poll_mode_drv.rst |  19 ++++
  lib/Makefile                            |   1 +
  lib/librte_ether/rte_ethdev.c           | 182 ++++++++++++++++++++++++++++++++
  lib/librte_ether/rte_ethdev_driver.h    |  30 ++++++
  lib/librte_ether/rte_ethdev_version.map |   1 +
  5 files changed, 233 insertions(+)
doc/guides/prog_guide/poll_mode_drv.rst +19 -0
index e5d01874e..09a93baec 100644
@@ -345,6 +345,25 @@ Ethernet Device API
 
  The Ethernet device API exported by the Ethernet PMDs is described in the *DPDK API Reference*.
 
+Ethernet Device Standard Device Arguments
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Standard Ethernet device arguments allow for a set of commonly used arguments/
+parameters which are applicable to all Ethernet devices to be available to for
+specification of specific device and for passing common configuration
+parameters to those ports.
+
+* ``representor`` for a device which supports the creation of representor ports
+  this argument allows user to specify which switch ports to enable port
+  representors for.::
+
+   -w BDBF,representor=0
+   -w BDBF,representor=[0,4,6,9]
+   -w BDBF,representor=[0-31]
+
+Note: PMDs are not required to support the standard device arguments and users
+should consult the relevant PMD documentation to see support devargs.
+
  Extended Statistics API
  ~~~~~~~~~~~~~~~~~~~~~~~
 
lib/Makefile +1 -0
index 965be6c8d..536775e59 100644
@@ -21,6 +21,7 @@ DEPDIRS-librte_cmdline := librte_eal
  DIRS-$(CONFIG_RTE_LIBRTE_ETHER) += librte_ether
  DEPDIRS-librte_ether := librte_net librte_eal librte_mempool librte_ring
  DEPDIRS-librte_ether += librte_mbuf
+DEPDIRS-librte_ether += librte_kvargs
  DIRS-$(CONFIG_RTE_LIBRTE_BBDEV) += librte_bbdev
  DEPDIRS-librte_bbdev := librte_eal librte_mempool librte_mbuf
  DIRS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += librte_cryptodev
lib/librte_ether/rte_ethdev.c +1 -0
index 621f8af7f..cb85d8bb7 100644
@@ -34,6 +34,7 @@
  #include <rte_errno.h>
  #include <rte_spinlock.h>
  #include <rte_string_fns.h>
++#include <rte_kvargs.h>
 
  #include "rte_ether.h"
  #include "rte_ethdev.h"

lib/librte_ether/rte_ethdev.c rte_eth_dev_pool_ops_supported(uint16_t port_id, const char *pool) · line 4109

Quoted 8 lines
lib/librte_ether/rte_ethdev.c +5 -0
@@ -4101,6 +4102,187 @@ rte_eth_dev_pool_ops_supported(uint16_t port_id, const char *pool)
  	return (*dev->dev_ops->pool_ops_supported)(dev, pool);
  }
 
+typedef int (*rte_eth_devargs_callback_t)(char *str, void *data);
+
+static int
+rte_eth_devargs_tokenise(struct rte_kvargs *arglist, const char *str_in)
+{

I still think that if you'd like to extend rte_kvarrgs to be able to parse something like: "key=[val1,val2,...,valn]", you have to make it generic kvargs ability and put it into librte_kvargs, not try to introduce your own new parser here. Imagine that in addition to your 'port=[val1,val2, ..valn]' devargs string would contain some extra (let say device specific) parameters.
What would happen, when PMD will try to use rte_kvargs_parse() on such string?
My understanding - it would fail, correct?

Quoted 3 lines

As an alternative - as I remember rte_kvargs allows you to have multiple identical key, i.e: "key=val1,key=val2,...,key=valn". Why not to use that way, if you don't want to introduce extra code in rte_kvargs?

Hey Konstantin, the rationale for keeping this independent from librte_kvargs was that it is likely that the implementation of parsing devarfs will change in the next release due the proposed rework on the whole devargs infrastructure. I hadn't considered the potential issue with rte_kvargs_parse() on string using the proposed syntax here. I'll send a patch for alignment with librte_kvargs for the next release candidate.

Quoted 238 lines
Quoted 113 lines
lib/librte_ether/rte_ethdev.c +113 -0
+	int state;
+	struct rte_kvargs_pair *pair;
+	char *letter;
+
+	arglist->str = strdup(str_in);
+	if (arglist->str == NULL)
+		return -ENOMEM;
+
+	letter = arglist->str;
+	state = 0;
+	arglist->count = 0;
+	pair = &arglist->pairs[0];
+	while (1) {
+		switch (state) {
+		case 0: /* Initial */
+			if (*letter == '=')
+				return -EINVAL;
+			else if (*letter == '\0')
+				return 0;
+
+			state = 1;
+			pair->key = letter;
+			/* fall-thru */
+
+		case 1: /* Parsing key */
+			if (*letter == '=') {
+				*letter = '\0';
+				pair->value = letter + 1;
+				state = 2;
+			} else if (*letter == ',' || *letter == '\0')
+				return -EINVAL;
+			break;
+
+
+		case 2: /* Parsing value */
+			if (*letter == '[')
+				state = 3;
+			else if (*letter == ',') {
+				*letter = '\0';
+				arglist->count++;
+				pair = &arglist->pairs[arglist->count];
+				state = 0;
+			} else if (*letter == '\0') {
+				letter--;
+				arglist->count++;
+				pair = &arglist->pairs[arglist->count];
+				state = 0;
+			}
+			break;
+
+		case 3: /* Parsing list */
+			if (*letter == ']')
+				state = 2;
+			else if (*letter == '\0')
+				return -EINVAL;
+			break;
+		}
+		letter++;
+	}
+}
+
+static int
+rte_eth_devargs_parse_list(char *str, rte_eth_devargs_callback_t callback,
+	void *data)
+{
+	char *str_start;
+	int state;
+	int result;
+
+	if (*str != '[')
+		/* Single element, not a list */
+		return callback(str, data);
+
+	/* Sanity check, then strip the brackets */
+	str_start = &str[strlen(str) - 1];
+	if (*str_start != ']') {
+		RTE_LOG(ERR, EAL, "(%s): List does not end with ']'", str);
+		return -EINVAL;
+	}
+	str++;
+	*str_start = '\0';
+
+	/* Process list elements */
+	state = 0;
+	while (1) {
+		if (state == 0) {
+			if (*str == '\0')
+				break;
+			if (*str != ',') {
+				str_start = str;
+				state = 1;
+			}
+		} else if (state == 1) {
+			if (*str == ',' || *str == '\0') {
+				if (str > str_start) {
+					/* Non-empty string fragment */
+					*str = '\0';
+					result = callback(str_start, data);
+					if (result < 0)
+						return result;
+				}
+				state = 0;
+			}
+		}
+		str++;
+	}
+	return 0;
+}
+
+static int
+rte_eth_devargs_process_range(char *str, uint16_t *list, uint16_t *len_list,
+	const uint16_t max_list)
+{

lib/librte_ether/rte_ethdev.c rte_eth_dev_pool_ops_supported(uint16_t port_id, const char *pool) · line 4232

Quoted 10 lines
lib/librte_ether/rte_ethdev.c +10 -0
+	uint16_t lo, hi, val;
+	int result;
+
+	result = sscanf(str, "%hu-%hu", &lo, &hi);
+	if (result == 1) {
+		if (*len_list >= max_list)
+			return -ENOMEM;
+		list[(*len_list)++] = lo;
+	} else if (result == 2) {
+		if (lo >= hi || lo > RTE_MAX_ETHPORTS || hi > RTE_MAX_ETHPORTS)

lo > RTE_MAX_ETHPORTS is redundant here.

Quoted 111 lines
lib/librte_ether/rte_ethdev.c +53 -0
+			return -EINVAL;
+		for (val = lo; val <= hi; val++) {
+			if (*len_list >= max_list)
+				return -ENOMEM;
+			list[(*len_list)++] = val;
+		}
+	} else
+		return -EINVAL;
+	return 0;
+}
+
+
+static int
+rte_eth_devargs_parse_representor_ports(char *str, void *data)
+{
+	struct rte_eth_devargs *eth_da = data;
+
+	return rte_eth_devargs_process_range(str, eth_da->representor_ports,
+		&eth_da->nb_representor_ports, RTE_MAX_ETHPORTS);
+}
+
+int __rte_experimental
+rte_eth_devargs_parse(const char *dargs, struct rte_eth_devargs *eth_da)
+{
+	struct rte_kvargs args;
+	struct rte_kvargs_pair *pair;
+	unsigned int i;
+	int result = 0;
+
+	memset(eth_da, 0, sizeof(*eth_da));
+
+	result = rte_eth_devargs_tokenise(&args, dargs);
+	if (result < 0)
+		goto parse_cleanup;
+
+	for (i = 0; i < args.count; i++) {
+		pair = &args.pairs[i];
+		if (strcmp("representor", pair->key) == 0) {
+			result = rte_eth_devargs_parse_list(pair->value,
+				rte_eth_devargs_parse_representor_ports,
+				eth_da);
+			if (result < 0)
+				goto parse_cleanup;
+		}
+	}
+
+parse_cleanup:
+	if (args.str)
+		free(args.str);
+
+	return result;
+}
+
  RTE_INIT(ethdev_init_log);
  static void
  ethdev_init_log(void)
lib/librte_ether/rte_ethdev_driver.h +30 -0
index 8c61ab2f4..492da754a 100644
@@ -189,6 +189,36 @@ rte_eth_linkstatus_get(const struct rte_eth_dev *dev,
  }
 
 
+/** Generic Ethernet device arguments  */
+struct rte_eth_devargs {
+	uint16_t ports[RTE_MAX_ETHPORTS];
+	/** port/s number to enable on a multi-port single function */
+	uint16_t nb_ports;
+	/** number of ports in ports field */
+	uint16_t representor_ports[RTE_MAX_ETHPORTS];
+	/** representor port/s identifier to enable on device */
+	uint16_t nb_representor_ports;
+	/** number of ports in representor port field */
+};
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * PMD helper function to parse ethdev arguments
+ *
+ * @param devargs
+ *  device arguments
+ * @param eth_devargs
+ *  parsed ethdev specific arguments.
+ *
+ * @return
+ *   Negative errno value on error, 0 on success.
+ */
+int __rte_experimental
+rte_eth_devargs_parse(const char *dargs, struct rte_eth_devargs *eth_devargs);
+
+
  typedef int (*ethdev_init_t)(struct rte_eth_dev *ethdev, void *init_params);
  typedef int (*ethdev_bus_specific_init)(struct rte_eth_dev *ethdev,
  	void *bus_specific_init_params);
lib/librte_ether/rte_ethdev_version.map +1 -1
index c4380aa31..41c3d2699 100644
@@ -206,6 +206,7 @@ DPDK_18.02 {
  EXPERIMENTAL {
  	global:
 
+	rte_eth_devargs_parse;
  	rte_eth_dev_count_avail;
  	rte_eth_dev_count_total;
  	rte_eth_dev_create;
--

2.14.3

#63 lore raw

Re: [PATCH v8 6/9] ethdev: add common devargs parser

26/04/2018 16:28, Doherty, Declan:

Quoted 19 lines · Konstantin
Quoted 14 lines

From: Doherty, Declan

lib/librte_ether/rte_ethdev.c rte_eth_dev_pool_ops_supported(uint16_t port_id, const char *pool) · line 4109

Quoted 5 lines
lib/librte_ether/rte_ethdev.c +5 -0
+typedef int (*rte_eth_devargs_callback_t)(char *str, void *data);
+
+static int
+rte_eth_devargs_tokenise(struct rte_kvargs *arglist, const char *str_in)
+{

I still think that if you'd like to extend rte_kvarrgs to be able to parse something like: "key=[val1,val2,...,valn]", you have to make it generic kvargs ability and put it into librte_kvargs, not try to introduce your own new parser here. Imagine that in addition to your 'port=[val1,val2, ..valn]' devargs string would contain some extra (let say device specific) parameters.
What would happen, when PMD will try to use rte_kvargs_parse() on such string?
My understanding - it would fail, correct?

Quoted 3 lines

As an alternative - as I remember rte_kvargs allows you to have multiple identical key, i.e: "key=val1,key=val2,...,key=valn". Why not to use that way, if you don't want to introduce extra code in rte_kvargs?

Quoted 7 lines

Hey Konstantin, the rationale for keeping this independent from librte_kvargs was that it is likely that the implementation of parsing devarfs will change in the next release due the proposed rework on the whole devargs infrastructure. I hadn't considered the potential issue with rte_kvargs_parse() on string using the proposed syntax here. I'll send a patch for alignment with librte_kvargs for the next release candidate.

The new devargs infra will rely on librte_kvargs.
So improving kvargs is the right way here.

#64 lore raw

Re: [PATCH v8 6/9] ethdev: add common devargs parser

In reply to Doherty, Declan
Quoted 125 lines

-----Original Message-----
From: Doherty, Declan
Sent: Thursday, April 26, 2018 3:29 PM
To: Ananyev, Konstantin <[email protected]>; [email protected]
Cc: Adrien Mazarguil <[email protected]>; Yigit, Ferruh <[email protected]>; Thomas Monjalon <[email protected]>; Shahaf Shuler <[email protected]>; Horton, Remy <[email protected]>
Subject: Re: [dpdk-dev][PATCH v8 6/9] ethdev: add common devargs parser

Quoted 7 lines · Konstantin
Quoted 7 lines

-----Original Message-----
From: Doherty, Declan
Sent: Thursday, April 26, 2018 11:41 AM
To: [email protected]
Cc: Adrien Mazarguil <[email protected]>; Yigit, Ferruh <[email protected]>; Thomas Monjalon

<[email protected]>;

Quoted 1 line
Quoted 1 line

Shahaf Shuler <[email protected]>; Ananyev, Konstantin <[email protected]>; Horton, Remy

<[email protected]>;

Quoted 100 lines
Quoted 84 lines

Doherty, Declan <[email protected]>
Subject: [dpdk-dev][PATCH v8 6/9] ethdev: add common devargs parser

From: Remy Horton <[email protected]>

Introduces a new structure, rte_eth_devargs, to support generic ethdev arguments common across NET PMDs, with a new API rte_eth_devargs_parse API to support PMD parsing these arguments. The patch add support for a representor argument passed with passed with the EAL -w option. The representor parameter allows the user to specify which representor ports to initialise on a device.

The argument supports passing a single representor port, a list of port values or a range of port values.

(quoted diff) +0 -3
-w BDF,representor=1  # create representor port 1 on pci device BDF
-w BDF,representor=[1,2,5,6,10] # create representor ports in list
-w BDF,representor=[0-31] # create representor ports in range
---
  doc/guides/prog_guide/poll_mode_drv.rst |  19 ++++
  lib/Makefile                            |   1 +
  lib/librte_ether/rte_ethdev.c           | 182 ++++++++++++++++++++++++++++++++
  lib/librte_ether/rte_ethdev_driver.h    |  30 ++++++
  lib/librte_ether/rte_ethdev_version.map |   1 +
  5 files changed, 233 insertions(+)
doc/guides/prog_guide/poll_mode_drv.rst +19 -0
index e5d01874e..09a93baec 100644
@@ -345,6 +345,25 @@ Ethernet Device API
 
  The Ethernet device API exported by the Ethernet PMDs is described in the *DPDK API Reference*.
 
+Ethernet Device Standard Device Arguments
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Standard Ethernet device arguments allow for a set of commonly used arguments/
+parameters which are applicable to all Ethernet devices to be available to for
+specification of specific device and for passing common configuration
+parameters to those ports.
+
+* ``representor`` for a device which supports the creation of representor ports
+  this argument allows user to specify which switch ports to enable port
+  representors for.::
+
+   -w BDBF,representor=0
+   -w BDBF,representor=[0,4,6,9]
+   -w BDBF,representor=[0-31]
+
+Note: PMDs are not required to support the standard device arguments and users
+should consult the relevant PMD documentation to see support devargs.
+
  Extended Statistics API
  ~~~~~~~~~~~~~~~~~~~~~~~
 
lib/Makefile +1 -0
index 965be6c8d..536775e59 100644
@@ -21,6 +21,7 @@ DEPDIRS-librte_cmdline := librte_eal
  DIRS-$(CONFIG_RTE_LIBRTE_ETHER) += librte_ether
  DEPDIRS-librte_ether := librte_net librte_eal librte_mempool librte_ring
  DEPDIRS-librte_ether += librte_mbuf
+DEPDIRS-librte_ether += librte_kvargs
  DIRS-$(CONFIG_RTE_LIBRTE_BBDEV) += librte_bbdev
  DEPDIRS-librte_bbdev := librte_eal librte_mempool librte_mbuf
  DIRS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += librte_cryptodev
lib/librte_ether/rte_ethdev.c +1 -0
index 621f8af7f..cb85d8bb7 100644
@@ -34,6 +34,7 @@
  #include <rte_errno.h>
  #include <rte_spinlock.h>
  #include <rte_string_fns.h>
++#include <rte_kvargs.h>
 
  #include "rte_ether.h"
  #include "rte_ethdev.h"

lib/librte_ether/rte_ethdev.c rte_eth_dev_pool_ops_supported(uint16_t port_id, const char *pool) · line 4109

Quoted 8 lines
lib/librte_ether/rte_ethdev.c +5 -0
@@ -4101,6 +4102,187 @@ rte_eth_dev_pool_ops_supported(uint16_t port_id, const char *pool)
  	return (*dev->dev_ops->pool_ops_supported)(dev, pool);
  }
 
+typedef int (*rte_eth_devargs_callback_t)(char *str, void *data);
+
+static int
+rte_eth_devargs_tokenise(struct rte_kvargs *arglist, const char *str_in)
+{

I still think that if you'd like to extend rte_kvarrgs to be able to parse something like: "key=[val1,val2,...,valn]", you have to make it generic kvargs ability and put it into librte_kvargs, not try to introduce your own new parser here. Imagine that in addition to your 'port=[val1,val2, ..valn]' devargs string would contain some extra (let say device specific) parameters.
What would happen, when PMD will try to use rte_kvargs_parse() on such string?
My understanding - it would fail, correct?

Quoted 3 lines

As an alternative - as I remember rte_kvargs allows you to have multiple identical key, i.e: "key=val1,key=val2,...,key=valn". Why not to use that way, if you don't want to introduce extra code in rte_kvargs?

Quoted 7 lines

Hey Konstantin, the rationale for keeping this independent from librte_kvargs was that it is likely that the implementation of parsing devarfs will change in the next release due the proposed rework on the whole devargs infrastructure. I hadn't considered the potential issue with rte_kvargs_parse() on string using the proposed syntax here. I'll send a patch for alignment with librte_kvargs for the next release candidate.

Ok, thanks Declan.
Konstantin

#65 lore raw

Re: [PATCH v8 6/9] ethdev: add common devargs parser

In reply to Ananyev, Konstantin

On 26/04/2018 13:03, Ananyev, Konstantin wrote:
[..]

Quoted 6 lines

I still think that if you'd like to extend rte_kvarrgs to be able to parse something like: "key=[val1,val2,...,valn]", you have to make it generic kvargs ability and put it into librte_kvargs, not try to introduce your own new parser here. Imagine that in addition to your 'port=[val1,val2, ..valn]' devargs string would contain some extra (let say device specific) parameters.
What would happen, when PMD will try to use rte_kvargs_parse() on such string?
My understanding - it would fail, correct?

This is partly dependent on what will (and won't) devargs provide when it is finalised. It was insourced in order to unblock the rest of the patchset in the meantime.

#66 lore raw

Re: [PATCH v8 6/9] ethdev: add common devargs parser

In reply to Declan Doherty
Quoted 18 lines · Declan Doherty

From: Remy Horton <[email protected]>

Introduces a new structure, rte_eth_devargs, to support generic ethdev arguments common across NET PMDs, with a new API rte_eth_devargs_parse API to support PMD parsing these arguments. The patch add support for a representor argument passed with passed with the EAL -w option. The representor parameter allows the user to specify which representor ports to initialise on a device.

The argument supports passing a single representor port, a list of port values or a range of port values.

(quoted diff) +0 -3
-w BDF,representor=1  # create representor port 1 on pci device BDF
-w BDF,representor=[1,2,5,6,10] # create representor ports in list
-w BDF,representor=[0-31] # create representor ports in range

<...>

Quoted 6 lines
lib/librte_ether/rte_ethdev_driver.h +6 -0
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * PMD helper function to parse ethdev arguments
+ *

lib/librte_ether/rte_ethdev_driver.h rte_eth_linkstatus_get(const struct rte_eth_dev *dev, · line 219

Quoted 10 lines
lib/librte_ether/rte_ethdev_driver.h +10 -0
+ * @param devargs
+ *  device arguments
+ * @param eth_devargs
+ *  parsed ethdev specific arguments.
+ *
+ * @return
+ *   Negative errno value on error, 0 on success.
+ */
+int __rte_experimental
+rte_eth_devargs_parse(const char *dargs, struct rte_eth_devargs *eth_devargs);

API doc build giving warning because of doxygen comments, devargs vs dargs, I will fix while applying as "devargs"

#67 lore raw

PATCH v8 7/9 ethdev: add switch domain allocator

In reply to Declan Doherty

Add switch domain allocate and free API to enable NET devices to synchronise switch domain allocation.

---
 lib/librte_ether/rte_ethdev.c           | 54 +++++++++++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev_driver.h    | 39 ++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev_version.map |  2 ++
 3 files changed, 95 insertions(+)
lib/librte_ether/rte_ethdev.c +54 -0
index cb85d8bb7..a09c7e5b3 100644
@@ -4102,6 +4102,60 @@ rte_eth_dev_pool_ops_supported(uint16_t port_id, const char *pool)
 	return (*dev->dev_ops->pool_ops_supported)(dev, pool);
 }
 
+/**
+ * A set of values to describe the possible states of a switch domain.
+ */
+enum rte_eth_switch_domain_state {
+	RTE_ETH_SWITCH_DOMAIN_UNUSED = 0,
+	RTE_ETH_SWITCH_DOMAIN_ALLOCATED
+};
+
+/**
+ * Array of switch domains available for allocation. Array is sized to
+ * RTE_MAX_ETHPORTS elements as there cannot be more active switch domains than
+ * ethdev ports in a single process.
+ */
+struct rte_eth_dev_switch {
+	enum rte_eth_switch_domain_state state;
+} rte_eth_switch_domains[RTE_MAX_ETHPORTS];
+
+int __rte_experimental
+rte_eth_switch_domain_alloc(uint16_t *domain_id)
+{
+	unsigned int i;
+
+	*domain_id = RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID;
+
+	for (i = RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID + 1;
+		i < RTE_MAX_ETHPORTS; i++) {
+		if (rte_eth_switch_domains[i].state ==
+			RTE_ETH_SWITCH_DOMAIN_UNUSED) {
+			rte_eth_switch_domains[i].state =
+				RTE_ETH_SWITCH_DOMAIN_ALLOCATED;
+			*domain_id = i;
+			return 0;
+		}
+	}
+
+	return -ENOSPC;
+}
+
+int __rte_experimental
+rte_eth_switch_domain_free(uint16_t domain_id)
+{
+	if (domain_id == RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID ||
+		domain_id >= RTE_MAX_ETHPORTS)
+		return -EINVAL;
+
+	if (rte_eth_switch_domains[domain_id].state !=
+		RTE_ETH_SWITCH_DOMAIN_ALLOCATED)
+		return -EINVAL;
+
+	rte_eth_switch_domains[domain_id].state = RTE_ETH_SWITCH_DOMAIN_UNUSED;
+
+	return 0;
+}
+
 typedef int (*rte_eth_devargs_callback_t)(char *str, void *data);
 
 static int
lib/librte_ether/rte_ethdev_driver.h +39 -0
index 492da754a..f428afa72 100644
@@ -188,6 +188,45 @@ rte_eth_linkstatus_get(const struct rte_eth_dev *dev,
 #endif
 }
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Allocate an unique switch domain identifier.
+ *
+ * A pool of switch domain identifiers which can be allocated on request. This
+ * will enabled devices which support the concept of switch domains to request
+ * a switch domain id which is guaranteed to be unique from other devices
+ * running in the same process.
+ *
+ * @param domain_id
+ *  switch domain identifier parameter to pass back to application
+ *
+ * @return
+ *   Negative errno value on error, 0 on success.
+ */
+int __rte_experimental
+rte_eth_switch_domain_alloc(uint16_t *domain_id);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Free switch domain.
+ *
+ * Return a switch domain identifier to the pool of free identifiers after it is
+ * no longer in use by device.
+ *
+ * @param domain_id
+ *  switch domain identifier to free
+ *
+ * @return
+ *   Negative errno value on error, 0 on success.
+ */
+int __rte_experimental
+rte_eth_switch_domain_free(uint16_t domain_id);
+
+
 
 /** Generic Ethernet device arguments  */
 struct rte_eth_devargs {
lib/librte_ether/rte_ethdev_version.map +2 -0
index 41c3d2699..86f06769a 100644
@@ -220,6 +220,8 @@ EXPERIMENTAL {
 	rte_eth_dev_rx_offload_name;
 	rte_eth_dev_tx_offload_name;
 	rte_eth_find_next_owned_by;
+	rte_eth_switch_domain_alloc;
+	rte_eth_switch_domain_free;
 	rte_mtr_capabilities_get;
 	rte_mtr_create;
 	rte_mtr_destroy;
Signature · 1 line
2.14.3
#68 lore raw

Re: [PATCH v8 7/9] ethdev: add switch domain allocator

Quoted 32 lines

-----Original Message-----
From: Doherty, Declan
Sent: Thursday, April 26, 2018 11:41 AM
To: [email protected]
Cc: Adrien Mazarguil <[email protected]>; Yigit, Ferruh <[email protected]>; Thomas Monjalon <[email protected]>; Shahaf Shuler <[email protected]>; Ananyev, Konstantin <[email protected]>; Doherty, Declan <[email protected]>
Subject: [dpdk-dev][PATCH v8 7/9] ethdev: add switch domain allocator

Add switch domain allocate and free API to enable NET devices to synchronise switch domain allocation.

---
 lib/librte_ether/rte_ethdev.c           | 54 +++++++++++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev_driver.h    | 39 ++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev_version.map |  2 ++
 3 files changed, 95 insertions(+)
lib/librte_ether/rte_ethdev.c +3 -0
index cb85d8bb7..a09c7e5b3 100644
@@ -4102,6 +4102,60 @@ rte_eth_dev_pool_ops_supported(uint16_t port_id, const char *pool)
 	return (*dev->dev_ops->pool_ops_supported)(dev, pool);
 }
 
+/**
+ * A set of values to describe the possible states of a switch domain.
+ */

lib/librte_ether/rte_ethdev.c rte_eth_dev_pool_ops_supported(uint16_t port_id, const char *pool) · line 4117

Quoted 10 lines
lib/librte_ether/rte_ethdev.c +10 -0
+enum rte_eth_switch_domain_state {
+	RTE_ETH_SWITCH_DOMAIN_UNUSED = 0,
+	RTE_ETH_SWITCH_DOMAIN_ALLOCATED
+};
+
+/**
+ * Array of switch domains available for allocation. Array is sized to
+ * RTE_MAX_ETHPORTS elements as there cannot be more active switch domains than
+ * ethdev ports in a single process.
+ */

Question from previous version review:
Probably already discussed before, but if we can't have more than one switch_id per port, while we can't use port_id as switch_id?
Or switch_id can represent some other entity (not rte_ethdev)?
Konstantin

Quoted 109 lines
lib/librte_ether/rte_ethdev.c +41 -0
+struct rte_eth_dev_switch {
+	enum rte_eth_switch_domain_state state;
+} rte_eth_switch_domains[RTE_MAX_ETHPORTS];
+
+int __rte_experimental
+rte_eth_switch_domain_alloc(uint16_t *domain_id)
+{
+	unsigned int i;
+
+	*domain_id = RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID;
+
+	for (i = RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID + 1;
+		i < RTE_MAX_ETHPORTS; i++) {
+		if (rte_eth_switch_domains[i].state ==
+			RTE_ETH_SWITCH_DOMAIN_UNUSED) {
+			rte_eth_switch_domains[i].state =
+				RTE_ETH_SWITCH_DOMAIN_ALLOCATED;
+			*domain_id = i;
+			return 0;
+		}
+	}
+
+	return -ENOSPC;
+}
+
+int __rte_experimental
+rte_eth_switch_domain_free(uint16_t domain_id)
+{
+	if (domain_id == RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID ||
+		domain_id >= RTE_MAX_ETHPORTS)
+		return -EINVAL;
+
+	if (rte_eth_switch_domains[domain_id].state !=
+		RTE_ETH_SWITCH_DOMAIN_ALLOCATED)
+		return -EINVAL;
+
+	rte_eth_switch_domains[domain_id].state = RTE_ETH_SWITCH_DOMAIN_UNUSED;
+
+	return 0;
+}
+
 typedef int (*rte_eth_devargs_callback_t)(char *str, void *data);
 
 static int
lib/librte_ether/rte_ethdev_driver.h +39 -0
index 492da754a..f428afa72 100644
@@ -188,6 +188,45 @@ rte_eth_linkstatus_get(const struct rte_eth_dev *dev,
 #endif
 }
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Allocate an unique switch domain identifier.
+ *
+ * A pool of switch domain identifiers which can be allocated on request. This
+ * will enabled devices which support the concept of switch domains to request
+ * a switch domain id which is guaranteed to be unique from other devices
+ * running in the same process.
+ *
+ * @param domain_id
+ *  switch domain identifier parameter to pass back to application
+ *
+ * @return
+ *   Negative errno value on error, 0 on success.
+ */
+int __rte_experimental
+rte_eth_switch_domain_alloc(uint16_t *domain_id);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Free switch domain.
+ *
+ * Return a switch domain identifier to the pool of free identifiers after it is
+ * no longer in use by device.
+ *
+ * @param domain_id
+ *  switch domain identifier to free
+ *
+ * @return
+ *   Negative errno value on error, 0 on success.
+ */
+int __rte_experimental
+rte_eth_switch_domain_free(uint16_t domain_id);
+
+
 
 /** Generic Ethernet device arguments  */
 struct rte_eth_devargs {
lib/librte_ether/rte_ethdev_version.map +2 -1
index 41c3d2699..86f06769a 100644
@@ -220,6 +220,8 @@ EXPERIMENTAL {
 	rte_eth_dev_rx_offload_name;
 	rte_eth_dev_tx_offload_name;
 	rte_eth_find_next_owned_by;
+	rte_eth_switch_domain_alloc;
+	rte_eth_switch_domain_free;
 	rte_mtr_capabilities_get;
 	rte_mtr_create;
 	rte_mtr_destroy;
--

2.14.3

#69 lore raw

PATCH v8 8/9 net/i40e: add support for representor ports

In reply to Declan Doherty

Add support for virtual function representor ports to the i40e PF driver. When SR-IOV virtual functions devices are enabled a corresponding representor port for each VF can be enabled, in the process in which the i40e PMD is running, by specifying the representor devargs with the list of VF ports that representors are to be created for.

An example of the devargs which would create VF representor for virtual functions 0,2,4,5,6 and 7 is:

-w DBDF,representor=[0,2,4-7]

and to just specify a single representor on virtual function 3 (switch port id):

-w DBDF,representor=3

---
 doc/guides/nics/i40e.rst               |  15 ++
 drivers/net/i40e/Makefile              |   3 +
 drivers/net/i40e/i40e_ethdev.c         |  82 ++++++-
 drivers/net/i40e/i40e_ethdev.h         |  16 ++
 drivers/net/i40e/i40e_vf_representor.c | 405 +++++++++++++++++++++++++++++++++
 drivers/net/i40e/meson.build           |   4 +-
 drivers/net/i40e/rte_pmd_i40e.c        |  43 ++++
 drivers/net/i40e/rte_pmd_i40e.h        |  18 ++
 lib/librte_ether/rte_ethdev.c          |   2 +-
 9 files changed, 579 insertions(+), 9 deletions(-)
 create mode 100644 drivers/net/i40e/i40e_vf_representor.c
doc/guides/nics/i40e.rst +15 -0
index e1b8083c1..212faf4b4 100644
@@ -40,6 +40,7 @@ Features of the I40E PMD are:
 - VF Daemon (VFD) - EXPERIMENTAL
 - Dynamic Device Personalization (DDP)
 - Queue region configuration
+- Vitrual Function Port Representors
 
 Prerequisites
 -------------
@@ -121,6 +122,20 @@ Runtime Config Options
   will switch PF interrupt from IntN to Int0 to avoid interrupt conflict between
   DPDK and Linux Kernel.
 
+- ``Support VF Port Representor`` (default ``not enabled``)
+
+  The i40e PF PMD supports the creation of VF port representors for the control
+  and monitoring of i40e virtual function devices. Each port representor
+  corresponds to a single virtual function of that device. Using the ``devargs``
+  option ``representor`` the user can specify which virtual functions to create
+  port representors for on initialization of the PF PMD by passing the VF IDs of
+  the VFs which are required.::
+
+  -w DBDF,representor=[0,1,4]
+
+  Currently hot-plugging of representor ports is not supported so all required
+  representors must be specified on the creation of the PF.
+
 Driver compilation and testing
 ------------------------------
 
drivers/net/i40e/Makefile +3 -0
index 7e34b50a7..3f869a8d6 100644
@@ -11,6 +11,8 @@ LIB = librte_pmd_i40e.a
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS) -DPF_DRIVER -DVF_DRIVER -DINTEGRATED_VF
 CFLAGS += -DX722_A0_SUPPORT
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs -lrte_hash
 LDLIBS += -lrte_bus_pci
@@ -85,6 +87,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_fdir.c
 SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_flow.c
 SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += rte_pmd_i40e.c
 SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_tm.c
+SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_vf_representor.c
 
 ifeq ($(findstring RTE_MACHINE_CPUFLAG_AVX2,$(CFLAGS)),RTE_MACHINE_CPUFLAG_AVX2)
 	CC_AVX2_SUPPORT=1
drivers/net/i40e/i40e_ethdev.c +75 -7

124 lines not on this page · raw message

drivers/net/i40e/i40e_ethdev.h +16 -0
index d33b255e7..7aaae71c0 100644
@@ -957,6 +957,8 @@ struct i40e_pf {
 	bool gtp_support; /* 1 - support GTP-C and GTP-U */
 	/* customer customized pctype */
 	struct i40e_customized_pctype customized_pctype[I40E_CUSTOMIZED_MAX];
+	/* Switch Domain Id */
+	uint16_t switch_domain_id;
 };
 
 enum pending_msg {
@@ -1062,6 +1064,18 @@ struct i40e_adapter {
 	uint64_t pctypes_mask;
 };
 
+/**
+ * Strucute to store private data for each VF representor instance
+ */
+struct i40e_vf_representor {
+	uint16_t switch_domain_id;
+	/**< Virtual Function ID */
+	uint16_t vf_id;
+	/**< Virtual Function ID */
+	struct i40e_adapter *adapter;
+	/**< Private data store of assocaiated physical function */
+};
+
 extern const struct rte_flow_ops i40e_flow_ops;
 
 union i40e_filter_t {
@@ -1221,6 +1235,8 @@ int i40e_set_rss_key(struct i40e_vsi *vsi, uint8_t *key, uint8_t key_len);
 int i40e_set_rss_lut(struct i40e_vsi *vsi, uint8_t *lut, uint16_t lut_size);
 int i40e_config_rss_filter(struct i40e_pf *pf,
 		struct i40e_rte_flow_rss_conf *conf, bool add);
+int i40e_vf_representor_init(struct rte_eth_dev *ethdev, void *init_params);
+int i40e_vf_representor_uninit(struct rte_eth_dev *ethdev);
 
 #define I40E_DEV_TO_PCI(eth_dev) \
 	RTE_DEV_TO_PCI((eth_dev)->device)
drivers/net/i40e/i40e_vf_representor.c new file +405 -0

405 lines not on this page · raw message

drivers/net/i40e/meson.build +3 -1
index 197e611d8..f2129df07 100644
@@ -6,7 +6,8 @@ version = 2
 cflags += ['-DPF_DRIVER',
 	'-DVF_DRIVER',
 	'-DINTEGRATED_VF',
-	'-DX722_A0_SUPPORT']
+	'-DX722_A0_SUPPORT',
+	'-DALLOW_EXPERIMENTAL_API']
 
 subdir('base')
 objs = [base_objs]
@@ -19,6 +20,7 @@ sources = files(
 	'i40e_fdir.c',
 	'i40e_flow.c',
 	'i40e_tm.c',
+	'i40e_vf_representor.c',
 	'rte_pmd_i40e.c'
 	)
 
drivers/net/i40e/rte_pmd_i40e.c +43 -0

49 lines not on this page · raw message

drivers/net/i40e/rte_pmd_i40e.h +18 -0
index d248adb1a..be4a6024a 100644
@@ -455,6 +455,24 @@ int rte_pmd_i40e_set_vf_multicast_promisc(uint16_t port,
 int rte_pmd_i40e_set_vf_mac_addr(uint16_t port, uint16_t vf_id,
 				 struct ether_addr *mac_addr);
 
+/**
+ * Remove the VF MAC address.
+ *
+ * @param port
+ *   The port identifier of the Ethernet device.
+ * @param vf_id
+ *   VF id.
+ * @param mac_addr
+ *   VF MAC address.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if *vf* or *mac_addr* is invalid.
+ */
+int
+rte_pmd_i40e_remove_vf_mac_addr(uint16_t port, uint16_t vf_id,
+	struct ether_addr *mac_addr);
+
 /**
  * Enable/Disable vf vlan strip for all queues in a pool
  *
lib/librte_ether/rte_ethdev.c +1 -1
index a09c7e5b3..6ed0ffa49 100644
@@ -34,7 +34,7 @@
 #include <rte_errno.h>
 #include <rte_spinlock.h>
 #include <rte_string_fns.h>
-+#include <rte_kvargs.h>
+#include <rte_kvargs.h>
 
 #include "rte_ether.h"
 #include "rte_ethdev.h"
Signature · 1 line
2.14.3
#70 lore raw

PATCH v8 9/9 net/ixgbe: add support for representor ports

In reply to Declan Doherty

Add support for virtual function representor ports to the ixgbe PF driver. When SR-IOV virtual functions devices are enabled a corresponding representor port for each VF can be enabled in the process in which the i40e PMD is running within, by specifying the representor devargs with the list of VF ports that representors are to be created for.

An example of the devargs which would create VF representor for virtual functions 0,2,4,5,6 and 7 is:

-w DBDF,representor=[0,2,4-7]

---
 doc/guides/nics/ixgbe.rst                |  14 ++
 drivers/net/ixgbe/Makefile               |   1 +
 drivers/net/ixgbe/ixgbe_ethdev.c         |  80 ++++++++++--
 drivers/net/ixgbe/ixgbe_ethdev.h         |  14 ++
 drivers/net/ixgbe/ixgbe_pf.c             |   7 +
 drivers/net/ixgbe/ixgbe_vf_representor.c | 217 +++++++++++++++++++++++++++++++
 drivers/net/ixgbe/meson.build            |   1 +
 7 files changed, 325 insertions(+), 9 deletions(-)
 create mode 100644 drivers/net/ixgbe/ixgbe_vf_representor.c
doc/guides/nics/ixgbe.rst +14 -0
index 0c660f298..5512e0b08 100644
@@ -228,6 +228,20 @@ For more details see the IPsec Security Gateway Sample Application and Security
 library documentation.
 
 
+Virtual Function Port Representors
+----------------------------------
+The IXGBE PF PMD supports the creation of VF port representors for the control
+and monitoring of IXGBE virtual function devices. Each port representor
+corresponds to a single virtual function of that device. Using the ``devargs``
+option ``representor`` the user can specify which virtual functions to create
+port representors for on initialization of the PF PMD by passing the VF IDs of
+the VFs which are required.::
+
+  -w DBDF,representor=[0,1,4]
+
+Currently hot-plugging of representor ports is not supported so all required
+representors must be specified on the creation of the PF.
+
 Supported Chipsets and NICs
 ---------------------------
 
drivers/net/ixgbe/Makefile +1 -0
index f8cad125b..7b6af3532 100644
@@ -104,6 +104,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += ixgbe_ipsec.c
 endif
 SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += rte_pmd_ixgbe.c
 SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += ixgbe_tm.c
+SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += ixgbe_vf_representor.c
 
 # install this header file
 SYMLINK-$(CONFIG_RTE_LIBRTE_IXGBE_PMD)-include := rte_pmd_ixgbe.h
drivers/net/ixgbe/ixgbe_ethdev.c +71 -9

115 lines not on this page · raw message

drivers/net/ixgbe/ixgbe_ethdev.h +14 -0
index 655077700..1947442d9 100644
@@ -253,6 +253,7 @@ struct ixgbe_vf_info {
 	uint16_t vlan_count;
 	uint8_t spoofchk_enabled;
 	uint8_t api_version;
+	uint16_t switch_domain_id;
 };
 
 /*
@@ -480,6 +481,15 @@ struct ixgbe_adapter {
  	struct ixgbe_tm_conf        tm_conf;
 };
 
+struct ixgbe_vf_representor {
+	uint16_t vf_id;
+	uint16_t switch_domain_id;
+	struct rte_eth_dev *pf_ethdev;
+};
+
+int ixgbe_vf_representor_init(struct rte_eth_dev *ethdev, void *init_params);
+int ixgbe_vf_representor_uninit(struct rte_eth_dev *ethdev);
+
 #define IXGBE_DEV_PRIVATE_TO_HW(adapter)\
 	(&((struct ixgbe_adapter *)adapter)->hw)
 
@@ -652,6 +662,10 @@ int ixgbe_fdir_filter_program(struct rte_eth_dev *dev,
 
 void ixgbe_configure_dcb(struct rte_eth_dev *dev);
 
+int
+ixgbe_dev_link_update_share(struct rte_eth_dev *dev,
+			    int wait_to_complete, int vf);
+
 /*
  * misc function prototypes
  */
drivers/net/ixgbe/ixgbe_pf.c +7 -0
index 4e61310af..4d199c802 100644
@@ -90,6 +90,8 @@ void ixgbe_pf_host_init(struct rte_eth_dev *eth_dev)
 	if (*vfinfo == NULL)
 		rte_panic("Cannot allocate memory for private VF data\n");
 
+	rte_eth_switch_domain_alloc(&(*vfinfo)->switch_domain_id);
+
 	memset(mirror_info, 0, sizeof(struct ixgbe_mirror_info));
 	memset(uta_info, 0, sizeof(struct ixgbe_uta_info));
 	hw->mac.mc_filter_type = 0;
@@ -122,6 +124,7 @@ void ixgbe_pf_host_uninit(struct rte_eth_dev *eth_dev)
 {
 	struct ixgbe_vf_info **vfinfo;
 	uint16_t vf_num;
+	int ret;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -132,6 +135,10 @@ void ixgbe_pf_host_uninit(struct rte_eth_dev *eth_dev)
 	RTE_ETH_DEV_SRIOV(eth_dev).def_vmdq_idx = 0;
 	RTE_ETH_DEV_SRIOV(eth_dev).def_pool_q_idx = 0;
 
+	ret = rte_eth_switch_domain_free((*vfinfo)->switch_domain_id);
+	if (ret)
+		PMD_INIT_LOG(WARNING, "failed to free switch domain: %d", ret);
+
 	vf_num = dev_num_vf(eth_dev);
 	if (vf_num == 0)
 		return;
drivers/net/ixgbe/ixgbe_vf_representor.c new file +217 -0

217 lines not on this page · raw message

drivers/net/ixgbe/meson.build +1 -0
index f649e659d..02d5ef5e4 100644
@@ -19,6 +19,7 @@ sources = files(
 	'ixgbe_pf.c',
 	'ixgbe_rxtx.c',
 	'ixgbe_tm.c',
+	'ixgbe_vf_representor.c',
 	'rte_pmd_ixgbe.c'
 )
 
Signature · 1 line
2.14.3
Reviewed-by on the v8 series
#71 lore raw

Re: [dpdk=-dev][PATCH v8 0/9] switching devices representation

In reply to Declan Doherty
Quoted 57 lines · Declan Doherty

This patchset follows on from the port rerpesentor patchsets and the community discussion that resulted. It outlines the model for representing and controlling switching capable devices in a new programmer's guide entry based upon the excellent summary by Adrien Mazarguil in
(http://dpdk.org/ml/archives/dev/2018-March/092513.html).

The next patches introduce changes to librte_ether to:
1, support the definition of a switch domain and make it public to application through the rte_eth_dev_info structure.
2, Add generic ethdev create/destroy APIs to facilitate and generalise the creation of ethdev's on different bus types.
3, Add ethdev attribute to dev_flags to specify that a port is a representor port and make public through the rte_eth_dev_info structure.
4, Add devargs parsing for generic eth_devargs to facilate parsing in NET PMDs. This will be refactored to take account of the changes in
(http://dpdk.org/ml/archives/dev/2018-March/092513.html)
5, Add new API to allocate switch domain ids to devices which support this feature.

This patchset also includes the enablement of vf port representor for ixgbe and i40e PF devices.

V8:
- add detailed descriptions to switch information structures
- fix err condition checking ethdev create helper function
- fix devargs memory leak and error checking + add documentation on ethdev args.
- remove rte_eth_switch_domains structure from export items.

V7:

This patch address the following changes:
- fixes in documentation patch
- changes the default value of switch domain id to be INVALID to allow applications to easily identify devices which can/cannot support the concept. Updates the switch information available through the rte_eth_dev_info structure.
- remove the rte_ethdev_representor.h header and leave representor specific initialisation to driver
- add new APIs for allocating and freeing switch domain identifier to enable PMDs to have unique switch domaind ids without the ethdev infrastructure placing any restriction on how theses are managed by devices.
- bug fix in ethdev args parsing code.

Declan Doherty (8):
doc: add switch representation documentation
ethdev: add switch identifier parameter to port
ethdev: add generic create/destroy ethdev APIs
ethdev: Add port representor device flag
app/testpmd: add port name to device info
ethdev: add switch domain allocator
net/i40e: add support for representor ports
net/ixgbe: add support for representor ports

Quoted 2 lines

Remy Horton (1):
ethdev: add common devargs parser

For series,

#72 lore raw

Re: [dpdk=-dev][PATCH v8 0/9] switching devices representation

Quoted 58 lines · Ferruh Yigit
Quoted 57 lines · Declan Doherty

This patchset follows on from the port rerpesentor patchsets and the community discussion that resulted. It outlines the model for representing and controlling switching capable devices in a new programmer's guide entry based upon the excellent summary by Adrien Mazarguil in
(http://dpdk.org/ml/archives/dev/2018-March/092513.html).

The next patches introduce changes to librte_ether to:
1, support the definition of a switch domain and make it public to application through the rte_eth_dev_info structure.
2, Add generic ethdev create/destroy APIs to facilitate and generalise the creation of ethdev's on different bus types.
3, Add ethdev attribute to dev_flags to specify that a port is a representor port and make public through the rte_eth_dev_info structure.
4, Add devargs parsing for generic eth_devargs to facilate parsing in NET PMDs. This will be refactored to take account of the changes in
(http://dpdk.org/ml/archives/dev/2018-March/092513.html)
5, Add new API to allocate switch domain ids to devices which support this feature.

This patchset also includes the enablement of vf port representor for ixgbe and i40e PF devices.

V8:
- add detailed descriptions to switch information structures
- fix err condition checking ethdev create helper function
- fix devargs memory leak and error checking + add documentation on ethdev args.
- remove rte_eth_switch_domains structure from export items.

V7:

This patch address the following changes:
- fixes in documentation patch
- changes the default value of switch domain id to be INVALID to allow applications to easily identify devices which can/cannot support the concept. Updates the switch information available through the rte_eth_dev_info structure.
- remove the rte_ethdev_representor.h header and leave representor specific initialisation to driver
- add new APIs for allocating and freeing switch domain identifier to enable PMDs to have unique switch domaind ids without the ethdev infrastructure placing any restriction on how theses are managed by devices.
- bug fix in ethdev args parsing code.

Declan Doherty (8):
doc: add switch representation documentation
ethdev: add switch identifier parameter to port
ethdev: add generic create/destroy ethdev APIs
ethdev: Add port representor device flag
app/testpmd: add port name to device info
ethdev: add switch domain allocator
net/i40e: add support for representor ports
net/ixgbe: add support for representor ports

Quoted 6 lines
Quoted 2 lines

Remy Horton (1):
ethdev: add common devargs parser

For series,

Series applied to dpdk-next-net/master, thanks.