diff mbox series

[ovs-dev,v16,05/10] dpif-netdev: Add command to get dpif implementations.

Message ID 20210709155824.506447-6-harry.van.haaren@intel.com
State Accepted
Headers show
Series DPIF Framework + Optimizations | expand

Checks

Context Check Description
ovsrobot/apply-robot success apply and check: success
ovsrobot/github-robot success github build: passed

Commit Message

Van Haaren, Harry July 9, 2021, 3:58 p.m. UTC
This commit adds a new command to retrieve the list of available
DPIF implementations. This can be used by to check what implementations
of the DPIF are available in any given OVS binary. It also returns which
implementations are in use by the OVS PMD threads.

Usage:
 $ ovs-appctl dpif-netdev/dpif-impl-get

Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
Co-authored-by: Cian Ferriter <cian.ferriter@intel.com>
Signed-off-by: Cian Ferriter <cian.ferriter@intel.com>
Acked-by: Flavio Leitner <fbl@sysclose.org>

---

v16:
- Include Flavio's Ack from ML

v15:
- Address Flavio's comments from the v14 review.

v14:
- Rename command to dpif-impl-get.
- Hide more of the dpif impl details from lib/dpif-netdev.c. Pass a
  dynamic_string to return the dpif-impl-get CMD output.
- Add information about which DPIF impl is currently in use by each PMD
  thread.

v13:
- Add NEWS item about DPIF get and set commands here rather than in a
  later commit.
- Add documentation items about DPIF set commands here rather than in a
  later commit.
---
 Documentation/topics/dpdk/bridge.rst |  8 +++++++
 NEWS                                 |  1 +
 lib/dpif-netdev-private-dpif.c       | 31 ++++++++++++++++++++++++++++
 lib/dpif-netdev-private-dpif.h       |  6 ++++++
 lib/dpif-netdev-unixctl.man          |  3 +++
 lib/dpif-netdev.c                    | 26 +++++++++++++++++++++++
 6 files changed, 75 insertions(+)
diff mbox series

Patch

diff --git a/Documentation/topics/dpdk/bridge.rst b/Documentation/topics/dpdk/bridge.rst
index 06d1f943c1..2d0850836f 100644
--- a/Documentation/topics/dpdk/bridge.rst
+++ b/Documentation/topics/dpdk/bridge.rst
@@ -226,6 +226,14 @@  stats associated with the datapath.
 Just like with the SIMD DPCLS feature above, SIMD can be applied to the DPIF to
 improve performance.
 
+OVS provides multiple implementations of the DPIF. The available
+implementations can be listed with the following command ::
+
+    $ ovs-appctl dpif-netdev/dpif-impl-get
+    Available DPIF implementations:
+      dpif_scalar (pmds: none)
+      dpif_avx512 (pmds: 1,2,6,7)
+
 By default, dpif_scalar is used. The DPIF implementation can be selected by
 name ::
 
diff --git a/NEWS b/NEWS
index 2625cabc85..471f3a1a28 100644
--- a/NEWS
+++ b/NEWS
@@ -23,6 +23,7 @@  Post-v2.15.0
      * Refactor lib/dpif-netdev.c to multiple header files.
      * Add avx512 implementation of dpif which can process non recirculated
        packets. It supports partial HWOL, EMC, SMC and DPCLS lookups.
+     * Add commands to get and set the dpif implementations.
    - ovs-ctl:
      * New option '--no-record-hostname' to disable hostname configuration
        in ovsdb on startup.
diff --git a/lib/dpif-netdev-private-dpif.c b/lib/dpif-netdev-private-dpif.c
index a05a82fa11..84d4ec156e 100644
--- a/lib/dpif-netdev-private-dpif.c
+++ b/lib/dpif-netdev-private-dpif.c
@@ -79,6 +79,37 @@  dp_netdev_impl_get_default(void)
     return default_dpif_func;
 }
 
+void
+dp_netdev_impl_get(struct ds *reply, struct dp_netdev_pmd_thread **pmd_list,
+                   size_t n)
+{
+    /* Add all dpif functions to reply string. */
+    ds_put_cstr(reply, "Available DPIF implementations:\n");
+
+    for (uint32_t i = 0; i < ARRAY_SIZE(dpif_impls); i++) {
+        ds_put_format(reply, "  %s (pmds: ", dpif_impls[i].name);
+
+        for (size_t j = 0; j < n; j++) {
+            struct dp_netdev_pmd_thread *pmd = pmd_list[j];
+            if (pmd->core_id == NON_PMD_CORE_ID) {
+                continue;
+            }
+
+            if (pmd->netdev_input_func == dpif_impls[i].input_func) {
+                ds_put_format(reply, "%u,", pmd->core_id);
+            }
+        }
+
+        ds_chomp(reply, ',');
+
+        if (ds_last(reply) == ' ') {
+            ds_put_cstr(reply, "none");
+        }
+
+        ds_put_cstr(reply, ")\n");
+    }
+}
+
 /* This function checks all available DPIF implementations, and selects the
  * returns the function pointer to the one requested by "name".
  */
diff --git a/lib/dpif-netdev-private-dpif.h b/lib/dpif-netdev-private-dpif.h
index 7880647ad3..0da639c55a 100644
--- a/lib/dpif-netdev-private-dpif.h
+++ b/lib/dpif-netdev-private-dpif.h
@@ -22,6 +22,7 @@ 
 /* Forward declarations to avoid including files. */
 struct dp_netdev_pmd_thread;
 struct dp_packet_batch;
+struct ds;
 
 /* Typedef for DPIF functions.
  * Returns whether all packets were processed successfully.
@@ -48,6 +49,11 @@  struct dpif_netdev_impl_info_t {
     const char *name;
 };
 
+/* This function returns all available implementations to the caller. */
+void
+dp_netdev_impl_get(struct ds *reply, struct dp_netdev_pmd_thread **pmd_list,
+                   size_t n);
+
 /* Returns the default DPIF which is first ./configure selected, but can be
  * overridden at runtime. */
 dp_netdev_input_func dp_netdev_impl_get_default(void);
diff --git a/lib/dpif-netdev-unixctl.man b/lib/dpif-netdev-unixctl.man
index 76cc949f9b..5f92562157 100644
--- a/lib/dpif-netdev-unixctl.man
+++ b/lib/dpif-netdev-unixctl.man
@@ -227,5 +227,8 @@  When this is the case, the above command prints the load-balancing information
 of the bonds configured in datapath \fIdp\fR showing the interface associated
 with each bucket (hash).
 .
+.IP "\fBdpif-netdev/dpif-impl-get\fR
+Lists the DPIF implementations that are available.
+.
 .IP "\fBdpif-netdev/dpif-impl-set\fR \fIdpif_impl\fR"
 Sets the DPIF to be used to \fIdpif_impl\fR. By default "dpif_scalar" is used.
diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index 6cdeb93de9..f7b2163bf7 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -965,6 +965,29 @@  dpif_netdev_subtable_lookup_set(struct unixctl_conn *conn, int argc OVS_UNUSED,
     ds_destroy(&reply);
 }
 
+static void
+dpif_netdev_impl_get(struct unixctl_conn *conn, int argc OVS_UNUSED,
+                     const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED)
+{
+    struct ds reply = DS_EMPTY_INITIALIZER;
+    struct shash_node *node;
+
+    ovs_mutex_lock(&dp_netdev_mutex);
+    SHASH_FOR_EACH (node, &dp_netdevs) {
+        struct dp_netdev_pmd_thread **pmd_list;
+        struct dp_netdev *dp = node->data;
+        size_t n;
+
+        /* Get PMD threads list, required to get the DPIF impl used by each PMD
+         * thread. */
+        sorted_poll_thread_list(dp, &pmd_list, &n);
+        dp_netdev_impl_get(&reply, pmd_list, n);
+    }
+    ovs_mutex_unlock(&dp_netdev_mutex);
+    unixctl_command_reply(conn, ds_cstr(&reply));
+    ds_destroy(&reply);
+}
+
 static void
 dpif_netdev_impl_set(struct unixctl_conn *conn, int argc OVS_UNUSED,
                      const char *argv[], void *aux OVS_UNUSED)
@@ -1251,6 +1274,9 @@  dpif_netdev_init(void)
                              "dpif_implementation_name",
                              1, 1, dpif_netdev_impl_set,
                              NULL);
+    unixctl_command_register("dpif-netdev/dpif-impl-get", "",
+                             0, 0, dpif_netdev_impl_get,
+                             NULL);
     return 0;
 }