diff mbox series

[ovs-dev,v1,03/10] dpif-netdev: Add function pointer for dpif re-circulate.

Message ID 20220321061441.1833575-4-kumar.amber@intel.com
State Deferred
Headers show
Series DPIF + MFEX Inner Vxlan AVX512 Opts | expand

Checks

Context Check Description
ovsrobot/apply-robot success apply and check: success
ovsrobot/github-robot-_Build_and_Test success github build: passed
ovsrobot/intel-ovs-compilation fail test: fail

Commit Message

Kumar Amber March 21, 2022, 6:14 a.m. UTC
The patch adds and re-uses the dpif set command to set the
function pointers to be used to switch between different inner
dpifs.

Signed-off-by: Kumar Amber <kumar.amber@intel.com>
Signed-off-by: Cian Ferriter <cian.ferriter@intel.com>
Co-authored-by: Cian Ferriter <cian.ferriter@intel.com>
---
 lib/dpif-netdev-private-dpif.c   | 53 +++++++++++++++++++++++++++-----
 lib/dpif-netdev-private-dpif.h   | 14 +++++++++
 lib/dpif-netdev-private-thread.h |  3 ++
 lib/dpif-netdev.c                | 22 +++++++++++--
 4 files changed, 83 insertions(+), 9 deletions(-)
diff mbox series

Patch

diff --git a/lib/dpif-netdev-private-dpif.c b/lib/dpif-netdev-private-dpif.c
index afce6947a..70281203b 100644
--- a/lib/dpif-netdev-private-dpif.c
+++ b/lib/dpif-netdev-private-dpif.c
@@ -37,18 +37,21 @@  enum dpif_netdev_impl_info_idx {
 static struct dpif_netdev_impl_info_t dpif_impls[] = {
     /* The default scalar C code implementation. */
     [DPIF_NETDEV_IMPL_SCALAR] = { .input_func = dp_netdev_input,
+      .recirc_func = dp_netdev_recirculate,
       .probe = NULL,
       .name = "dpif_scalar", },
 
 #if (__x86_64__ && HAVE_AVX512F && HAVE_LD_AVX512_GOOD && __SSE4_2__)
     /* Only available on x86_64 bit builds with SSE 4.2 used for OVS core. */
     [DPIF_NETDEV_IMPL_AVX512] = { .input_func = dp_netdev_input_avx512,
+      .recirc_func = dp_netdev_input_avx512_recirc,
       .probe = dp_netdev_input_avx512_probe,
       .name = "dpif_avx512", },
 #endif
 };
 
 static dp_netdev_input_func default_dpif_func;
+static dp_netdev_recirc_func default_dpif_recirc_func;
 
 dp_netdev_input_func
 dp_netdev_impl_get_default(void)
@@ -79,6 +82,35 @@  dp_netdev_impl_get_default(void)
     return default_dpif_func;
 }
 
+dp_netdev_recirc_func
+dp_netdev_recirc_impl_get_default(void)
+{
+    /* For the first call, this will be NULL. Compute the compile time default.
+     */
+    if (!default_dpif_recirc_func) {
+        int dpif_idx = DPIF_NETDEV_IMPL_SCALAR;
+
+/* Configure-time overriding to run test suite on all implementations. */
+#if (__x86_64__ && HAVE_AVX512F && HAVE_LD_AVX512_GOOD && __SSE4_2__)
+#ifdef DPIF_AVX512_DEFAULT
+        dp_netdev_input_func_probe probe;
+
+        /* Check if the compiled default is compatible. */
+        probe = dpif_impls[DPIF_NETDEV_IMPL_AVX512].probe;
+        if (!probe || !probe()) {
+            dpif_idx = DPIF_NETDEV_IMPL_AVX512;
+        }
+#endif
+#endif
+
+        VLOG_INFO("Default re-circulate DPIF implementation is %s.\n",
+                  dpif_impls[dpif_idx].name);
+        default_dpif_recirc_func = dpif_impls[dpif_idx].recirc_func;
+    }
+
+    return default_dpif_recirc_func;
+}
+
 void
 dp_netdev_impl_get(struct ds *reply, struct dp_netdev_pmd_thread **pmd_list,
                    size_t n)
@@ -114,10 +146,12 @@  dp_netdev_impl_get(struct ds *reply, struct dp_netdev_pmd_thread **pmd_list,
  * returns the function pointer to the one requested by "name".
  */
 static int32_t
-dp_netdev_impl_get_by_name(const char *name, dp_netdev_input_func *out_func)
+dp_netdev_impl_get_by_name(const char *name, dp_netdev_input_func *dpif_func,
+                           dp_netdev_recirc_func *dpif_recirc_func)
 {
     ovs_assert(name);
-    ovs_assert(out_func);
+    ovs_assert(dpif_func);
+    ovs_assert(dpif_recirc_func);
 
     uint32_t i;
 
@@ -127,11 +161,13 @@  dp_netdev_impl_get_by_name(const char *name, dp_netdev_input_func *out_func)
             if (dpif_impls[i].probe) {
                 int probe_err = dpif_impls[i].probe();
                 if (probe_err) {
-                    *out_func = NULL;
+                    *dpif_func = NULL;
+                    *dpif_recirc_func = NULL;
                     return probe_err;
                 }
             }
-            *out_func = dpif_impls[i].input_func;
+            *dpif_func = dpif_impls[i].input_func;
+            *dpif_recirc_func = dpif_impls[i].recirc_func;
             return 0;
         }
     }
@@ -142,12 +178,15 @@  dp_netdev_impl_get_by_name(const char *name, dp_netdev_input_func *out_func)
 int32_t
 dp_netdev_impl_set_default_by_name(const char *name)
 {
-    dp_netdev_input_func new_default;
+    dp_netdev_input_func new_dpif_default;
+    dp_netdev_recirc_func new_dpif_recirc_default;
 
-    int32_t err = dp_netdev_impl_get_by_name(name, &new_default);
+    int32_t err = dp_netdev_impl_get_by_name(name, &new_dpif_default,
+                                             &new_dpif_recirc_default);
 
     if (!err) {
-        default_dpif_func = new_default;
+        default_dpif_func = new_dpif_default;
+        default_dpif_recirc_func = new_dpif_recirc_default;
     }
 
     return err;
diff --git a/lib/dpif-netdev-private-dpif.h b/lib/dpif-netdev-private-dpif.h
index 0d18b748e..dcd5273f2 100644
--- a/lib/dpif-netdev-private-dpif.h
+++ b/lib/dpif-netdev-private-dpif.h
@@ -36,6 +36,12 @@  typedef int32_t (*dp_netdev_input_func)(struct dp_netdev_pmd_thread *pmd,
                                         struct dp_packet_batch *packets,
                                         odp_port_t port_no);
 
+/* Typedef for DPIF re-circulate functions.
+ * Returns whether all packets were processed successfully.
+ */
+typedef int32_t (*dp_netdev_recirc_func)(struct dp_netdev_pmd_thread *pmd,
+                                         struct dp_packet_batch *packets);
+
 /* Probe a DPIF implementation. This allows the implementation to validate CPU
  * ISA availability. Returns -ENOTSUP if not available, returns 0 if valid to
  * use.
@@ -46,6 +52,10 @@  typedef int32_t (*dp_netdev_input_func_probe)(void);
 struct dpif_netdev_impl_info_t {
     /* Function pointer to execute to have this DPIF implementation run. */
     dp_netdev_input_func input_func;
+
+    /* Function pointer to execute recirc DPIF implementation. */
+    dp_netdev_recirc_func recirc_func;
+
     /* Function pointer to execute to check the CPU ISA is available to run. If
      * not necessary, it must be set to NULL which implies that it is always
      * valid to use. */
@@ -63,6 +73,10 @@  dp_netdev_impl_get(struct ds *reply, struct dp_netdev_pmd_thread **pmd_list,
  * overridden at runtime. */
 dp_netdev_input_func dp_netdev_impl_get_default(void);
 
+/* Returns the default recirculate DPIF which is first ./configure selected,
+ * but can be overridden at runtime. */
+dp_netdev_recirc_func dp_netdev_recirc_impl_get_default(void);
+
 /* Overrides the default DPIF with the user set DPIF. */
 int32_t dp_netdev_impl_set_default_by_name(const char *name);
 
diff --git a/lib/dpif-netdev-private-thread.h b/lib/dpif-netdev-private-thread.h
index 4472b199d..bce91358b 100644
--- a/lib/dpif-netdev-private-thread.h
+++ b/lib/dpif-netdev-private-thread.h
@@ -124,6 +124,9 @@  struct dp_netdev_pmd_thread {
     /* Function pointer to call for dp_netdev_input() functionality. */
     ATOMIC(dp_netdev_input_func) netdev_input_func;
 
+    /* Function pointer to call for dp_netdev_recirculate() functionality. */
+    ATOMIC(dp_netdev_recirc_func) netdev_input_recirc_func;
+
     /* Pointer for per-DPIF implementation scratch space. */
     void *netdev_input_func_userdata;
 
diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index 829f1dedf..5378fcad4 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -1165,6 +1165,10 @@  dpif_netdev_impl_set(struct unixctl_conn *conn, int argc OVS_UNUSED,
              * default. */
             atomic_store_relaxed(&pmd->netdev_input_func,
                                  dp_netdev_impl_get_default());
+            /* Initialize recirc DPIF function pointer to the newly configured
+             * default. */
+            atomic_store_relaxed(&pmd->netdev_input_recirc_func,
+                                 dp_netdev_recirc_impl_get_default());
         };
 
         free(pmd_list);
@@ -7455,6 +7459,14 @@  dp_netdev_configure_pmd(struct dp_netdev_pmd_thread *pmd, struct dp_netdev *dp,
     /* Initialize DPIF function pointer to the default configured version. */
     atomic_init(&pmd->netdev_input_func, dp_netdev_impl_get_default());
 
+    /* Initialize recirculate DPIF function pointer to the default configured
+     * version. */
+    dp_netdev_recirc_func default_dpif_recirc_func =
+                                        dp_netdev_recirc_impl_get_default();
+    atomic_uintptr_t *pmd_recirc_func =
+                                    (void *) &pmd->netdev_input_recirc_func;
+    atomic_init(pmd_recirc_func, (uintptr_t) default_dpif_recirc_func);
+
     /* Init default miniflow_extract function */
     atomic_init(&pmd->miniflow_extract_opt, dp_mfex_impl_get_default());
 
@@ -8799,7 +8811,10 @@  dp_execute_cb(void *aux_, struct dp_packet_batch *packets_,
                 }
 
                 (*depth)++;
-                dp_netdev_recirculate(pmd, packets_);
+                int ret = pmd->netdev_input_recirc_func(pmd, packets_);
+                if (ret) {
+                    dp_netdev_recirculate(pmd, packets_);
+                }
                 (*depth)--;
                 return;
             }
@@ -8871,7 +8886,10 @@  dp_execute_cb(void *aux_, struct dp_packet_batch *packets_,
             }
 
             (*depth)++;
-            dp_netdev_recirculate(pmd, packets_);
+            int ret = pmd->netdev_input_recirc_func(pmd, packets_);
+            if (ret) {
+                dp_netdev_recirculate(pmd, packets_);
+            }
             (*depth)--;
 
             return;