From: Tonghao Zhang <xiangxia.m....@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....@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 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev