ethdev: add siblings iterators
authorThomas Monjalon <thomas@monjalon.net>
Mon, 1 Apr 2019 02:26:58 +0000 (04:26 +0200)
committerFerruh Yigit <ferruh.yigit@intel.com>
Fri, 5 Apr 2019 15:45:22 +0000 (17:45 +0200)
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 <thomas@monjalon.net>
Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
Tested-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>
lib/librte_ethdev/rte_ethdev.c
lib/librte_ethdev/rte_ethdev.h
lib/librte_ethdev/rte_ethdev_version.map

index b262190..243beb4 100644 (file)
@@ -339,6 +339,25 @@ rte_eth_find_next(uint16_t port_id)
        return port_id;
 }
 
+uint16_t
+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_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)
 {
index b6023c0..2065f54 100644 (file)
@@ -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.
+ */
+uint16_t __rte_experimental
+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.
+ */
+uint16_t __rte_experimental
+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
index 92ac3de..b37a416 100644 (file)
@@ -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;