Secondary process support in the 'test-pmd' application now requires that
the driver expose the 'dev_infos_get' method within that context. Use the
cached dev info from the primary process in order to meet the requirement.

Signed-off-by: Ivan Malov <[email protected]>
Reviewed-by: Viacheslav Galaktionov <[email protected]>
---
 drivers/net/sfc/sfc.h        | 19 ++++++++++++++
 drivers/net/sfc/sfc_ethdev.c | 48 ++++++++++++++++++++++++++++++++++++
 2 files changed, 67 insertions(+)

diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index 629578549f..809ad59148 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -156,6 +156,25 @@ struct sfc_adapter_shared {
        unsigned int                    nb_repr_txq;
 
        struct sfc_nic_dma_info         nic_dma_info;
+
+       /*
+        * Snapshot of the 'rte_eth_dev_info_get' output created by the primary
+        * process attach path for the secondary process to use in its own
+        * implementation of the 'dev_infos_get' method.
+        *
+        * Some driver-computed fields derived from mutable post-attach state
+        * are knowingly stale, which is acceptable for the secondary process.
+        *
+        * This also contains a handful of stale fields which are normally
+        * set by the ethdev layer upon invocation of the 'dev_infos_get',
+        * so they will be overridden anyway in the secondary process.
+        */
+       struct rte_eth_dev_info         dev_info_cache;
+       /*
+        * Set to 'true' by the probe function from the primary process. The
+        * secondary 'dev_infos_get' returns '-EAGAIN' when this is 'false'.
+        */
+       RTE_ATOMIC(bool)                dev_info_cache_is_valid;
 };
 
 /* Adapter process private data */
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 13619b4b9a..02231e4bce 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -16,7 +16,9 @@
 #include <bus_pci_driver.h>
 #include <rte_errno.h>
 #include <rte_string_fns.h>
+#include <rte_stdatomic.h>
 #include <rte_bitops.h>
+#include <rte_ethdev.h>
 #include <rte_ether.h>
 
 #include "efx.h"
@@ -3163,7 +3165,32 @@ sfc_eth_dev_clear_ops(struct rte_eth_dev *dev)
        sa->priv.dp_rx = NULL;
 }
 
+static int
+sfc_dev_infos_get_secondary(struct rte_eth_dev *dev,
+                           struct rte_eth_dev_info *dev_info)
+{
+       const struct sfc_adapter_shared *sas =
+               sfc_adapter_shared_by_eth_dev(dev);
+       bool valid = rte_atomic_load_explicit(&sas->dev_info_cache_is_valid,
+                                             rte_memory_order_acquire);
+
+       if (!valid)
+               return -EAGAIN;
+
+       *dev_info = sas->dev_info_cache;
+
+       /*
+        * The cache holds stale primary-process pointers; restore
+        * the process-local values from the caller-supplied 'dev'.
+        */
+       if (dev_info->switch_info.name != NULL)
+               dev_info->switch_info.name = dev->device->driver->name;
+       dev_info->device = dev->device;
+       return 0;
+}
+
 static const struct eth_dev_ops sfc_eth_dev_secondary_ops = {
+       .dev_infos_get                  = sfc_dev_infos_get_secondary,
        .dev_supported_ptypes_get       = sfc_dev_supported_ptypes_get,
        .reta_query                     = sfc_dev_rss_reta_query,
        .rss_hash_conf_get              = sfc_dev_rss_hash_conf_get,
@@ -3787,6 +3814,27 @@ static int sfc_eth_dev_pci_probe(struct rte_pci_driver 
*pci_drv __rte_unused,
        if (rc != 0)
                return rc;
 
+       if (dev_created && rte_eal_process_type() == RTE_PROC_PRIMARY) {
+               struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev);
+               struct sfc_adapter_shared *sas =
+                       sfc_adapter_shared_by_eth_dev(dev);
+
+               /*
+                * Pre-fill the dev info cache for the secondary
+                * process. The port has been registered at this
+                * point, allowing use of the public API.
+                */
+               rc = rte_eth_dev_info_get(dev->data->port_id,
+                                         &sas->dev_info_cache);
+               if (rc == 0) {
+                       sas->dev_info_cache.device = NULL;
+                       rte_atomic_store_explicit(&sas->dev_info_cache_is_valid,
+                               true, rte_memory_order_release);
+               } else {
+                       sfc_warn(sa, "failed to cache dev info for the 
secondary process");
+               }
+       }
+
        rc = sfc_eth_dev_create_representors(dev, &eth_da);
        if (rc != 0) {
                if (dev_created)
-- 
2.47.3

Reply via email to