> -----Original Message----- > From: dev <dev-boun...@dpdk.org> On Behalf Of Thomas Monjalon > Sent: Monday, April 1, 2019 5:27 > To: gaetan.ri...@6wind.com; Ferruh Yigit <ferruh.yi...@intel.com>; Andrew > Rybchenko <arybche...@solarflare.com> > Cc: dev@dpdk.org > Subject: [dpdk-dev] [PATCH v3 2/4] ethdev: add siblings iterators > > If multiple ports share the same hardware device (rte_device), they are > siblings and can be found thanks to the new functions and loop macros. > One iterator takes a port id as reference, while the other one directly refers > to the parent device. > > The ownership is not checked because siblings may have different owners. > > Signed-off-by: Thomas Monjalon <tho...@monjalon.net> Tested-by: Viacheslav Ovsiienko <mellanox.com>
> --- > v2: Reviewed-by: Andrew Rybchenko - not kept because of changes in v3 > > v3: > - fix logic + re-use rte_eth_find_next() > - longer parameter names > - more and better doxygen comments > --- > lib/librte_ethdev/rte_ethdev.c | 19 +++++++ > lib/librte_ethdev/rte_ethdev.h | 63 ++++++++++++++++++++++++ > lib/librte_ethdev/rte_ethdev_version.map | 2 + > 3 files changed, 84 insertions(+) > > diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c > index 33cffc498..3b125a642 100644 > --- a/lib/librte_ethdev/rte_ethdev.c > +++ b/lib/librte_ethdev/rte_ethdev.c > @@ -339,6 +339,25 @@ rte_eth_find_next(uint16_t port_id) > return port_id; > } > > +uint16_t __rte_experimental > +rte_eth_find_next_of(uint16_t port_id, const struct rte_device *parent) > +{ > + port_id = rte_eth_find_next(port_id); > + while (port_id < RTE_MAX_ETHPORTS && > + rte_eth_devices[port_id].device != parent) > + port_id = rte_eth_find_next(port_id + 1); > + > + return port_id; > +} > + > +uint16_t __rte_experimental > +rte_eth_find_next_sibling(uint16_t port_id, uint16_t ref_port_id) { > + RTE_ETH_VALID_PORTID_OR_ERR_RET(ref_port_id, > RTE_MAX_ETHPORTS); > + return rte_eth_find_next_of(port_id, > + rte_eth_devices[ref_port_id].device); > +} > + > static void > rte_eth_dev_shared_data_prepare(void) > { > diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h > index b6023c050..3d5bacaee 100644 > --- a/lib/librte_ethdev/rte_ethdev.h > +++ b/lib/librte_ethdev/rte_ethdev.h > @@ -1387,6 +1387,69 @@ uint16_t rte_eth_find_next(uint16_t port_id); > #define RTE_ETH_FOREACH_DEV(p) \ > RTE_ETH_FOREACH_DEV_OWNED_BY(p, > RTE_ETH_DEV_NO_OWNER) > > +/** > + * @warning > + * @b EXPERIMENTAL: this API may change without prior notice. > + * > + * Iterates over ethdev ports of a specified device. > + * > + * @param port_id_start > + * The id of the next possible valid port. > + * @param parent > + * The generic device behind the ports to iterate. > + * @return > + * Next port id of the device, possibly port_id_start, > + * RTE_MAX_ETHPORTS if there is none. > + */ > +__rte_experimental > +uint16_t rte_eth_find_next_of(uint16_t port_id_start, > + const struct rte_device *parent); > + > +/** > + * Macro to iterate over all ethdev ports of a specified device. > + * > + * @param port_id > + * The id of the matching port being iterated. > + * @param parent > + * The rte_device pointer matching the iterated ports. > + */ > +#define RTE_ETH_FOREACH_DEV_OF(port_id, parent) \ > + for (port_id = rte_eth_find_next_of(0, parent); \ > + port_id < RTE_MAX_ETHPORTS; \ > + port_id = rte_eth_find_next_of(port_id + 1, parent)) > + > +/** > + * @warning > + * @b EXPERIMENTAL: this API may change without prior notice. > + * > + * Iterates over sibling ethdev ports (i.e. sharing the same rte_device). > + * > + * @param port_id_start > + * The id of the next possible valid sibling port. > + * @param ref_port_id > + * The id of a reference port to compare rte_device with. > + * @return > + * Next sibling port id, possibly port_id_start or ref_port_id itself, > + * RTE_MAX_ETHPORTS if there is none. > + */ > +__rte_experimental > +uint16_t rte_eth_find_next_sibling(uint16_t port_id_start, > + uint16_t ref_port_id); > + > +/** > + * Macro to iterate over all ethdev ports sharing the same rte_device > + * as the specified port. > + * Note: the specified reference port is part of the loop iterations. > + * > + * @param port_id > + * The id of the matching port being iterated. > + * @param ref_port_id > + * The id of the port being compared. > + */ > +#define RTE_ETH_FOREACH_DEV_SIBLING(port_id, ref_port_id) \ > + for (port_id = rte_eth_find_next_sibling(0, ref_port_id); \ > + port_id < RTE_MAX_ETHPORTS; \ > + port_id = rte_eth_find_next_sibling(port_id + 1, ref_port_id)) > > /** > * @warning > diff --git a/lib/librte_ethdev/rte_ethdev_version.map > b/lib/librte_ethdev/rte_ethdev_version.map > index 92ac3de25..b37a4167d 100644 > --- a/lib/librte_ethdev/rte_ethdev_version.map > +++ b/lib/librte_ethdev/rte_ethdev_version.map > @@ -245,6 +245,8 @@ EXPERIMENTAL { > rte_eth_dev_owner_set; > rte_eth_dev_owner_unset; > rte_eth_dev_rx_intr_ctl_q_get_fd; > + rte_eth_find_next_of; > + rte_eth_find_next_sibling; > rte_eth_switch_domain_alloc; > rte_eth_switch_domain_free; > rte_flow_conv; > -- > 2.21.0