[ovs-dev] [PATCH ovs-dev v1 2/2] dpctl-netdev: Add the option "pmd" for dump-flows

xiangxia.m.yue at gmail.com xiangxia.m.yue at gmail.com
Thu Jul 16 11:14:45 UTC 2020


From: Tonghao Zhang <xiangxia.m.yue at gmail.com>

"ovs-appctl dpctl/dump-flows" added the option
"pmd" which allow user to dump pmd specified.

That option is useful to dump rules of pmd
when we have a large number of rules in dp.

Signed-off-by: Tonghao Zhang <xiangxia.m.yue at gmail.com>
---
 NEWS                |  2 ++
 lib/dpctl.c         | 28 +++++++++++++++++++++++-----
 lib/dpif-netdev.c   | 25 +++++++++++++++++++++++++
 lib/dpif-provider.h |  2 ++
 4 files changed, 52 insertions(+), 5 deletions(-)

diff --git a/NEWS b/NEWS
index ac992d17feab..6ef5d2e5a041 100644
--- a/NEWS
+++ b/NEWS
@@ -23,6 +23,8 @@ Post-v2.13.0
      * New configuration knob 'other_config:lb-output-action' for bond ports
        that enables new datapath action 'lb_output' to avoid recirculation
        in balance-tcp mode.  Disabled by default.
+     * Command "ovs-appctl dpctl/dump-flows" added option "pmd" which allow
+       user to dump pmd specified.
    - Tunnels: TC Flower offload
      * Tunnel Local endpoint address masked match are supported.
      * Tunnel Romte endpoint address masked match are supported.
diff --git a/lib/dpctl.c b/lib/dpctl.c
index 09ae97f25cf3..a76e3e520804 100644
--- a/lib/dpctl.c
+++ b/lib/dpctl.c
@@ -979,6 +979,7 @@ dpctl_dump_flows(int argc, const char *argv[], struct dpctl_params *dpctl_p)
     struct dpif_flow_dump_thread *flow_dump_thread;
     struct dpif_flow_dump *flow_dump;
     struct dpif_flow f;
+    int pmd_id_filter = PMD_ID_NULL;
     int pmd_id = PMD_ID_NULL;
     int lastargc = 0;
     int error;
@@ -996,6 +997,12 @@ dpctl_dump_flows(int argc, const char *argv[], struct dpctl_params *dpctl_p)
                 goto out_free;
             }
             types_list = xstrdup(argv[--argc] + 5);
+        } else if (pmd_id_filter == PMD_ID_NULL &&
+                   !strncmp(argv[argc - 1], "pmd=", 4)) {
+            if (!ovs_scan(argv[--argc], "pmd=%"SCNu32, &pmd_id_filter)) {
+                error = EINVAL;
+                goto out_free;
+            }
         }
     }
 
@@ -1044,7 +1051,13 @@ dpctl_dump_flows(int argc, const char *argv[], struct dpctl_params *dpctl_p)
     ds_init(&ds);
     memset(&f, 0, sizeof f);
     flow_dump = dpif_flow_dump_create(dpif, false, &dpif_dump_types);
+    flow_dump->pmd_id = pmd_id_filter;
     flow_dump_thread = dpif_flow_dump_thread_create(flow_dump);
+    if (!flow_dump_thread) {
+        error = ENOENT;
+        goto out_dump_destroy;
+    }
+
     while (dpif_flow_dump_next(flow_dump_thread, &f, 1)) {
         if (filter) {
             struct flow flow;
@@ -1085,11 +1098,16 @@ dpctl_dump_flows(int argc, const char *argv[], struct dpctl_params *dpctl_p)
         }
     }
     dpif_flow_dump_thread_destroy(flow_dump_thread);
-    error = dpif_flow_dump_destroy(flow_dump);
 
-    if (error) {
-        dpctl_error(dpctl_p, error, "Failed to dump flows from datapath");
+out_dump_destroy:
+    {
+        int ret = dpif_flow_dump_destroy(flow_dump);
+        if (ret) {
+            dpctl_error(dpctl_p, ret, "Failed to dump flows from datapath");
+            error = ret;
+        }
     }
+
     ds_destroy(&ds);
 
 out_dpifclose:
@@ -2503,8 +2521,8 @@ static const struct dpctl_command all_commands[] = {
     { "set-if", "dp iface...", 2, INT_MAX, dpctl_set_if, DP_RW },
     { "dump-dps", "", 0, 0, dpctl_dump_dps, DP_RO },
     { "show", "[dp...]", 0, INT_MAX, dpctl_show, DP_RO },
-    { "dump-flows", "[dp] [filter=..] [type=..]",
-      0, 3, dpctl_dump_flows, DP_RO },
+    { "dump-flows", "[dp] [filter=..] [type=..] [pmd=..]",
+      0, 4, dpctl_dump_flows, DP_RO },
     { "add-flow", "[dp] flow actions", 2, 3, dpctl_add_flow, DP_RW },
     { "mod-flow", "[dp] flow actions", 2, 3, dpctl_mod_flow, DP_RW },
     { "get-flow", "[dp] ufid", 1, 2, dpctl_get_flow, DP_RO },
diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index cd349c4a47c4..4992a9a26855 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -3776,6 +3776,21 @@ dpif_netdev_flow_dump_thread_create(struct dpif_flow_dump *dump_)
     struct dpif_netdev_flow_dump *dump = dpif_netdev_flow_dump_cast(dump_);
     struct dpif_netdev_flow_dump_thread *thread;
 
+    dump->cur_pmd = NULL;
+    if (dump->up.pmd_id != PMD_ID_NULL) {
+        struct dp_netdev *dp = get_dp_netdev(dump->up.dpif);
+        struct dp_netdev_pmd_thread *pmd;
+
+        pmd = dp_netdev_get_pmd(dp, dump->up.pmd_id);
+        if (!pmd || !dp_netdev_pmd_try_ref(pmd)) {
+            VLOG_DBG("The PMD ID (%u) not found or ref.\n",
+                      dump->up.pmd_id);
+            return NULL;
+        }
+
+        dump->cur_pmd = pmd;
+    }
+
     thread = xmalloc(sizeof *thread);
     dpif_flow_dump_thread_init(&thread->up, &dump->up);
     thread->dump = dump;
@@ -3787,6 +3802,11 @@ dpif_netdev_flow_dump_thread_destroy(struct dpif_flow_dump_thread *thread_)
 {
     struct dpif_netdev_flow_dump_thread *thread
         = dpif_netdev_flow_dump_thread_cast(thread_);
+    struct dpif_netdev_flow_dump *dump = thread->dump;
+
+    if (dump->up.pmd_id != PMD_ID_NULL && dump->cur_pmd) {
+        dp_netdev_pmd_unref(dump->cur_pmd);
+    }
 
     free(thread);
 }
@@ -3832,6 +3852,11 @@ dpif_netdev_flow_dump_next(struct dpif_flow_dump_thread *thread_,
                                                      struct dp_netdev_flow,
                                                      node);
             }
+
+            if (dump->up.pmd_id != PMD_ID_NULL) {
+                break;
+            }
+
             /* When finishing dumping the current pmd thread, moves to
              * the next. */
             if (n_flows < flow_limit) {
diff --git a/lib/dpif-provider.h b/lib/dpif-provider.h
index 0e024c1c9851..aef96277d4d7 100644
--- a/lib/dpif-provider.h
+++ b/lib/dpif-provider.h
@@ -57,6 +57,7 @@ static inline void dpif_assert_class(const struct dpif *dpif,
 
 struct dpif_flow_dump {
     struct dpif *dpif;
+    unsigned pmd_id;    /* As a filter for PMD flows. */
     bool terse;         /* If true, key/mask/actions may be omitted. */
 };
 
@@ -64,6 +65,7 @@ static inline void
 dpif_flow_dump_init(struct dpif_flow_dump *dump, const struct dpif *dpif)
 {
     dump->dpif = CONST_CAST(struct dpif *, dpif);
+    dump->pmd_id = PMD_ID_NULL;
 }
 
 struct dpif_flow_dump_thread {
-- 
2.26.1



More information about the dev mailing list