diff mbox series

[ovs-dev,v2] dpcls: Add the dpcls subtable lookup function in flow dump.

Message ID 20220411131331.597825-1-kumar.amber@intel.com
State Deferred
Headers show
Series [ovs-dev,v2] dpcls: Add the dpcls subtable lookup function in flow dump. | expand

Checks

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

Commit Message

Kumar Amber April 11, 2022, 1:13 p.m. UTC
The patch adds the subtable lookup name to the existing
dp-extra-info mentioned below:

dp-extra-info:miniflow_bits(18,4), lookup(generic)
dp-extra-info:miniflow_bits(9,4), lookup(avx512_gather)

Suggested-by: Ilya Maximets <i.maximets@ovn.org>
Signed-off-by: Kumar Amber <kumar.amber@intel.com>

---
v2:
- Add RCU protection for ds_extra_info.
- Add string regeneration for dpcls reprobe.
---
---
 lib/dpif-netdev-lookup.c        | 39 +++++++++++++++++++++++++++++----
 lib/dpif-netdev-lookup.h        | 14 +++++++++++-
 lib/dpif-netdev-private-dpcls.h |  3 +++
 lib/dpif-netdev-private-flow.h  |  6 +++--
 lib/dpif-netdev.c               | 26 +++++++++++++++++-----
 5 files changed, 76 insertions(+), 12 deletions(-)
diff mbox series

Patch

diff --git a/lib/dpif-netdev-lookup.c b/lib/dpif-netdev-lookup.c
index bd0a99abe..e20a45589 100644
--- a/lib/dpif-netdev-lookup.c
+++ b/lib/dpif-netdev-lookup.c
@@ -20,6 +20,8 @@ 
 
 #include "openvswitch/vlog.h"
 
+#define SUBTABLE_STRING_OFFSET 18
+
 VLOG_DEFINE_THIS_MODULE(dpif_netdev_lookup);
 
 /* Actual list of implementations goes here */
@@ -93,11 +95,11 @@  dpcls_subtable_set_prio(const char *name, uint8_t priority)
 }
 
 dpcls_subtable_lookup_func
-dpcls_subtable_get_best_impl(uint32_t u0_bit_count, uint32_t u1_bit_count)
+dpcls_subtable_get_best_impl(uint32_t u0_bit_count, uint32_t u1_bit_count,
+                             const char **name)
 {
     /* Iter over each subtable impl, and get highest priority one. */
     int32_t prio = -1;
-    const char *name = NULL;
     dpcls_subtable_lookup_func best_func = NULL;
 
     for (int i = 0; i < ARRAY_SIZE(subtable_lookups); i++) {
@@ -109,16 +111,45 @@  dpcls_subtable_get_best_impl(uint32_t u0_bit_count, uint32_t u1_bit_count)
             if (probed_func) {
                 best_func = probed_func;
                 prio = probed_prio;
-                name = subtable_lookups[i].name;
+                if (name) {
+                    *name = subtable_lookups[i].name;
+                }
             }
         }
     }
 
     VLOG_DBG("Subtable lookup function '%s' with units (%d,%d), priority %d\n",
-             name, u0_bit_count, u1_bit_count, prio);
+             *name, u0_bit_count, u1_bit_count, prio);
 
     /* Programming error - we must always return a valid func ptr. */
     ovs_assert(best_func != NULL);
 
     return best_func;
 }
+
+void
+dpcls_update_flow_dump(struct cmap flow_table,
+                       struct dpcls_subtable_lookup_info_t *lookup_funcs,
+                       int impls_count)
+{
+    struct dp_netdev_flow *flow;
+    const char *name = NULL;
+    int32_t prio = -1;
+
+    for (int i = 0; i < impls_count; i++) {
+        int32_t probed_prio = lookup_funcs[i].prio;
+        if (probed_prio > prio) {
+            name = lookup_funcs[i].name;
+            prio = probed_prio;
+        }
+    }
+    CMAP_FOR_EACH (flow, node, &flow_table) {
+        struct ds info = DS_EMPTY_INITIALIZER;
+        char *extra_info = ovsrcu_get(char *, &flow->dp_extra_info);
+        ds_put_cstr(&info, extra_info);
+        ds_truncate(&info, SUBTABLE_STRING_OFFSET);
+        ds_put_format(&info,",lookup(%s)", name);
+        ovsrcu_set(&flow->dp_extra_info, ds_steal_cstr(&info));
+        ds_destroy(&info);
+    }
+}
diff --git a/lib/dpif-netdev-lookup.h b/lib/dpif-netdev-lookup.h
index 59f51faa0..a8a83d9a9 100644
--- a/lib/dpif-netdev-lookup.h
+++ b/lib/dpif-netdev-lookup.h
@@ -20,6 +20,7 @@ 
 #include <config.h>
 #include "dpif-netdev.h"
 #include "dpif-netdev-private-dpcls.h"
+#include "dpif-netdev-private-flow.h"
 
 /* Function to perform a probe for the subtable bit fingerprint.
  * Returns NULL if not valid, or a valid function pointer to call for this
@@ -66,8 +67,14 @@  struct dpcls_subtable_lookup_info_t {
 
 int32_t dpcls_subtable_set_prio(const char *name, uint8_t priority);
 
+/* Retrieve the best implementation for dpcls subtable.
+ * Name parameter is used to fetch the name of dpcls subtable
+ * selected by the function.
+ * The function can also be called with name as NULL.
+ */
 dpcls_subtable_lookup_func
-dpcls_subtable_get_best_impl(uint32_t u0_bit_count, uint32_t u1_bit_count);
+dpcls_subtable_get_best_impl(uint32_t u0_bit_count, uint32_t u1_bit_count,
+                             const char **name);
 
 /* Retrieve the array of lookup implementations for iteration.
  * On error, returns a negative number.
@@ -76,4 +83,9 @@  dpcls_subtable_get_best_impl(uint32_t u0_bit_count, uint32_t u1_bit_count);
 int32_t
 dpcls_subtable_lookup_info_get(struct dpcls_subtable_lookup_info_t **out_ptr);
 
+void
+dpcls_update_flow_dump(struct cmap flow_table,
+                       struct dpcls_subtable_lookup_info_t *lookup_funcs,
+                       int impls_count);
+
 #endif /* dpif-netdev-lookup.h */
diff --git a/lib/dpif-netdev-private-dpcls.h b/lib/dpif-netdev-private-dpcls.h
index 0d5da73c7..d17ef32af 100644
--- a/lib/dpif-netdev-private-dpcls.h
+++ b/lib/dpif-netdev-private-dpcls.h
@@ -88,6 +88,9 @@  struct dpcls_subtable {
      * here to prevent garbage from being read. */
     ATOMIC(dpcls_subtable_lookup_func) lookup_func;
 
+    /* Holds the name of the DPCLS implementation slected. */
+    const char *subtable_lookup_name;
+
     /* Caches the masks to match a packet to, reducing runtime calculations. */
     uint64_t *mf_masks;
 
diff --git a/lib/dpif-netdev-private-flow.h b/lib/dpif-netdev-private-flow.h
index 7425dd44e..e1fc7b648 100644
--- a/lib/dpif-netdev-private-flow.h
+++ b/lib/dpif-netdev-private-flow.h
@@ -123,8 +123,10 @@  struct dp_netdev_flow {
      * packet_batch_per_flow_init() and packet_batch_per_flow_execute()). */
     struct packet_batch_per_flow *batch;
 
-    /* Packet classification. */
-    char *dp_extra_info;         /* String to return in a flow dump/get. */
+    /* Packet classification.
+     * String to return in a flow dump/get.
+     */
+    OVSRCU_TYPE(char *) dp_extra_info;
     struct dpcls_rule cr;        /* In owning dp_netdev's 'cls'. */
     /* 'cr' must be the last member. */
 };
diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index 676434308..48845b629 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -623,6 +623,8 @@  static int dpif_netdev_xps_get_tx_qid(const struct dp_netdev_pmd_thread *pmd,
 inline struct dpcls *
 dp_netdev_pmd_lookup_dpcls(struct dp_netdev_pmd_thread *pmd,
                            odp_port_t in_port);
+static inline struct dpcls_subtable *
+dpcls_find_subtable(struct dpcls *cls, const struct netdev_flow_key *mask);
 
 static void dp_netdev_request_reconfigure(struct dp_netdev *dp);
 static inline bool
@@ -1034,6 +1036,7 @@  dpif_netdev_subtable_lookup_set(struct unixctl_conn *conn, int argc OVS_UNUSED,
     uint32_t new_prio = strtoul(argv[2], &err_char, 10);
     uint32_t lookup_dpcls_changed = 0;
     uint32_t lookup_subtable_changed = 0;
+    struct dpcls_subtable_lookup_info_t *lookup_funcs = NULL;
     struct shash_node *node;
     if (errno != 0 || new_prio > UINT8_MAX) {
         unixctl_command_reply_error(conn,
@@ -1075,6 +1078,11 @@  dpif_netdev_subtable_lookup_set(struct unixctl_conn *conn, int argc OVS_UNUSED,
                 }
                 ovs_mutex_lock(&pmd->flow_mutex);
                 uint32_t subtbl_changes = dpcls_subtable_lookup_reprobe(cls);
+                if (subtbl_changes) {
+                    int count = dpcls_subtable_lookup_info_get(&lookup_funcs);
+                    dpcls_update_flow_dump(pmd->flow_table, lookup_funcs,
+                                           count);
+                }
                 ovs_mutex_unlock(&pmd->flow_mutex);
                 if (subtbl_changes) {
                     lookup_dpcls_changed++;
@@ -2380,7 +2388,8 @@  static void
 dp_netdev_flow_free(struct dp_netdev_flow *flow)
 {
     dp_netdev_actions_free(dp_netdev_flow_get_actions(flow));
-    free(flow->dp_extra_info);
+        ovsrcu_postpone(free,
+                     ovsrcu_get_protected(char *, &flow->dp_extra_info));
     free(flow);
 }
 
@@ -3746,7 +3755,8 @@  dp_netdev_flow_to_dpif_flow(const struct dp_netdev *dp,
     flow->pmd_id = netdev_flow->pmd_id;
 
     get_dpif_flow_status(dp, netdev_flow, &flow->stats, &flow->attrs);
-    flow->attrs.dp_extra_info = netdev_flow->dp_extra_info;
+    flow->attrs.dp_extra_info = ovsrcu_get(char *,
+                                           &netdev_flow->dp_extra_info);
 }
 
 static int
@@ -4116,7 +4126,11 @@  dp_netdev_flow_add(struct dp_netdev_pmd_thread *pmd,
                       count_1bits(flow->cr.mask->mf.map.bits[unit]));
     }
     ds_put_char(&extra_info, ')');
-    flow->dp_extra_info = ds_steal_cstr(&extra_info);
+    struct dpcls_subtable *subtable = dpcls_find_subtable(cls, &mask);
+    ds_put_format(&extra_info, ",lookup(%s)", subtable->subtable_lookup_name);
+
+    ovsrcu_set(&flow->dp_extra_info, ds_steal_cstr(&extra_info));
+
     ds_destroy(&extra_info);
 
     cmap_insert(&pmd->flow_table, CONST_CAST(struct cmap_node *, &flow->node),
@@ -9753,7 +9767,8 @@  dpcls_create_subtable(struct dpcls *cls, const struct netdev_flow_key *mask)
      * by the PMD thread.
      */
     atomic_init(&subtable->lookup_func,
-                dpcls_subtable_get_best_impl(unit0, unit1));
+                dpcls_subtable_get_best_impl(unit0, unit1,
+                                             &subtable->subtable_lookup_name));
 
     cmap_insert(&cls->subtables_map, &subtable->cmap_node, mask->hash);
     /* Add the new subtable at the end of the pvector (with no hits yet) */
@@ -9802,7 +9817,8 @@  dpcls_subtable_lookup_reprobe(struct dpcls *cls)
         /* Set the subtable lookup function atomically to avoid garbage data
          * being read by the PMD thread. */
         atomic_store_relaxed(&subtable->lookup_func,
-                    dpcls_subtable_get_best_impl(u0_bits, u1_bits));
+                            dpcls_subtable_get_best_impl(u0_bits, u1_bits,
+                                            &subtable->subtable_lookup_name));
         subtables_changed += (old_func != subtable->lookup_func);
     }