Hi Flavio, > -----Original Message----- > From: Flavio Leitner <f...@sysclose.org> > Sent: Sunday, July 11, 2021 6:14 AM > To: Amber, Kumar <kumar.am...@intel.com> > Cc: ovs-dev@openvswitch.org; i.maxim...@ovn.org > Subject: Re: [ovs-dev] [v8 06/12] dpif-netdev: Add packet count and core id > paramters for study > > > Hi, > > On Fri, Jul 09, 2021 at 05:35:56PM +0530, kumar Amber wrote: > > From: Kumar Amber <kumar.am...@intel.com> > > > > This commit introduces additional command line paramter > > Parameter. >
Fixed. > > for mfex study function. If user provides additional packet out it is > > used in study to compare minimum packets which must be processed else > > a default value is choosen. > > Also introduces a third paramter for choosing a particular pmd core. > > > > $ ovs-appctl dpif-netdev/miniflow-parser-set study 500 3 > > > > Signed-off-by: Kumar Amber <kumar.am...@intel.com> > > > > --- > > v7: > > - change the command paramters for core_id and study_pkt_cnt > > v5: > > - fix review comments(Ian, Flavio, Eelco) > > - introucde pmd core id parameter > > --- > > --- > > Documentation/topics/dpdk/bridge.rst | 39 +++++++- > > lib/dpif-netdev-extract-study.c | 26 ++++- > > lib/dpif-netdev-private-extract.c | 2 +- > > lib/dpif-netdev-private-extract.h | 9 ++ > > lib/dpif-netdev.c | 138 +++++++++++++++++++++++++-- > > 5 files changed, 200 insertions(+), 14 deletions(-) > > > > diff --git a/Documentation/topics/dpdk/bridge.rst > > b/Documentation/topics/dpdk/bridge.rst > > index 4db416ddd..8ed810f34 100644 > > --- a/Documentation/topics/dpdk/bridge.rst > > +++ b/Documentation/topics/dpdk/bridge.rst > > @@ -284,12 +284,47 @@ command also shows whether the CPU supports > each implementation :: > > > > An implementation can be selected manually by the following command :: > > > > - $ ovs-appctl dpif-netdev/miniflow-parser-set study > > + $ ovs-appctl dpif-netdev/miniflow-parser-set [-pmd core_id] [name] > > + [study_cnt] > > + > > +The above command has two optional parameters study_cnt and core_id > > +which can be set optionally. The first parameter core_id to set a > > +particular miniflow > > The above command has two optional parameters: study_cnt and core_id. The > core_id set a particular miniflow... > > > +extract function to a specific pmd thread on the core. Third > > +parameter study_cnt is specific to study where how many packets > > +needed to choose best implementation can be provided.. In case of any > > +other implementation other than study third parameter [study_cnt] can > > +pe provided with any arbitatry number and is ignored. > > Third parameter study_cnt, which is specific to study and ignored by other > implementations, means how many packets are needed to choose the best > implementation. > > > > > > > Also user can select the study implementation which studies the > > traffic for > > The user can select... > > > a specific number of packets by applying all available implementaions > > of miniflow extract and than chooses the one with most optimal result > > for that -traffic pattern. > > +traffic pattern. A user can also provide an additional packet count > > +parameter > > The user can optionally provide an packet count [study_cnt] parameter... > Fixed all the comments . > > +which is the minimum number of packets that OVS must study before > > +choosing an optimal implementation. If no packet count is provided, > > +then the default value, > > +128 is chosen. Also, as there is no synchronization point between > > +threads, one PMD thread might still be running a previous round, and > > +can now decide on earlier data. > > + > > +The per packet count is a global value, and parallel `study()` > > +executions with differing packet counts will use the most recent count > > value > provided by usser. > > + > > +Study can be selected with packet count by the following command :: > > + > > + $ ovs-appctl dpif-netdev/miniflow-parser-set study 1024 > > + > > +Study can be selected with packet count and explicit PMD selection by > > +the following command :: > > + > > + $ ovs-appctl dpif-netdev/miniflow-parser-set -pmd 3 study 1024 > > + > > +In the above command the last parameter is the CORE ID of the PMD > > +thread and this can also be used to explicitly set the miniflow > > +extraction function pointer on different PMD threads. > > + > > +Scalar can be selected on core 3 by the following command where study > > +count can be put as any arbitary number or left blank:: > > + > > + $ ovs-appctl dpif-netdev/miniflow-parser-set -pmd 3 scalar > > > > Miniflow Extract Validation > > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > diff --git a/lib/dpif-netdev-extract-study.c > > b/lib/dpif-netdev-extract-study.c index f14464b2b..d29523db0 100644 > > --- a/lib/dpif-netdev-extract-study.c > > +++ b/lib/dpif-netdev-extract-study.c > > @@ -28,7 +28,7 @@ > VLOG_DEFINE_THIS_MODULE(dpif_mfex_extract_study); > > /* Max count of packets to be compared. */ #define MFEX_MAX_COUNT > > (128) > > > > -static uint32_t mfex_study_pkts_count = 0; > > +static uint32_t mfex_study_pkts_count = MFEX_MAX_COUNT; > > > > /* Struct to hold miniflow study stats. */ struct study_stats { @@ > > -51,6 +51,28 @@ mfex_study_get_study_stats_ptr(void) > > return stats; > > } > > > > +uint32_t mfex_set_study_pkt_cnt(uint32_t pkt_cmp_count, > > + const char *name) { > > + struct dpif_miniflow_extract_impl *miniflow_funcs; > > + dpif_mfex_impl_info_get(&miniflow_funcs); > > + > > + /* If the packet count is set and implementation called is study then > > + * set packet counter to requested number else set the packet counter > > + * to default number. > > + */ > > + if ((strcmp(miniflow_funcs[MFEX_IMPL_STUDY].name, name) == 0) && > > + (pkt_cmp_count != 0)) { > > + > > + atomic_uintptr_t *study_pck_cnt = (void *)&mfex_study_pkts_count; > > + atomic_store_relaxed(study_pck_cnt, (uintptr_t) pkt_cmp_count > > + ); > > + > > + return 0; > > + } > > + > > + return -EINVAL; > > +} > > + > > uint32_t > > mfex_study_traffic(struct dp_packet_batch *packets, > > struct netdev_flow_key *keys, @@ -93,7 +115,7 @@ > > mfex_study_traffic(struct dp_packet_batch *packets, > > /* Choose the best implementation after a minimum packets have been > > * processed. > > */ > > - if (stats->pkt_count >= MFEX_MAX_COUNT) { > > + if (stats->pkt_count >= mfex_study_pkts_count) { > > uint32_t best_func_index = MFEX_IMPL_START_IDX; > > uint32_t max_hits = 0; > > for (int i = MFEX_IMPL_START_IDX; i < impl_count; i++) { diff > > --git a/lib/dpif-netdev-private-extract.c > > b/lib/dpif-netdev-private-extract.c > > index be8c69408..f3d593d39 100644 > > --- a/lib/dpif-netdev-private-extract.c > > +++ b/lib/dpif-netdev-private-extract.c > > @@ -122,7 +122,7 @@ dp_mfex_impl_get(struct ds *reply, struct > > dp_netdev_pmd_thread **pmd_list, > > > > for (int i = 0; i < ARRAY_SIZE(mfex_impls); i++) { > > > > - ds_put_format(reply, " %s (available: %s)(pmds: ", > > + ds_put_format(reply, " %s (available: %s, pmds: ", > > This should be in the patch introducing that line to avoid the issue in the > first > place. > > > > mfex_impls[i].name, mfex_impls[i].available ? > > "True" : "False"); > > Fixed at right place. > > diff --git a/lib/dpif-netdev-private-extract.h > > b/lib/dpif-netdev-private-extract.h > > index 802496cb9..bea532115 100644 > > --- a/lib/dpif-netdev-private-extract.h > > +++ b/lib/dpif-netdev-private-extract.h > > @@ -146,4 +146,13 @@ mfex_study_traffic(struct dp_packet_batch > *packets, > > uint32_t keys_size, odp_port_t in_port, > > struct dp_netdev_pmd_thread *pmd_handle); > > > > +/* Sets the packet count from user to the stats for use in > > + * study function to match against the classified packets to choose > > + * the optimal implementation. > > + * On error, returns EINVAL. > > + * On success, returns 0. > > + */ > > +uint32_t mfex_set_study_pkt_cnt(uint32_t pkt_cmp_count, > > + const char *name); > > + > > #endif /* MFEX_AVX512_EXTRACT */ > > diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index > > b416dc80c..87156fc69 100644 > > --- a/lib/dpif-netdev.c > > +++ b/lib/dpif-netdev.c > > @@ -1079,17 +1079,49 @@ static void > > dpif_miniflow_extract_impl_set(struct unixctl_conn *conn, int argc, > > const char *argv[], void *aux OVS_UNUSED) { > > - /* This function requires just one parameter, the miniflow name. > > + /* A First optional paramter PMD thread ID can be also provided which > > + * allows users to set miniflow implementation on a particular pmd. > > + * The second paramter is the name of the function and if -pmd > > + corr_id > > parameter, core_id, name of the implementation. > > > + * is not provided this is the first paramter and only mandatory one. > > parameter > Fixed. > > + * The third and last one is the study-cnt which is only provided for > > + * study function to set the packet count. > > */ > > - const char *mfex_name = argv[1]; > > + const char *mfex_name = NULL; > > struct shash_node *node; > > + bool pmd_core_param_set = false; > > + struct ds reply = DS_EMPTY_INITIALIZER; > > + > > + if (strcmp("-pmd", argv[1]) == 0) { > > + mfex_name = argv[3]; > > + pmd_core_param_set = true; > > + } else { > > + mfex_name = argv[1]; > > + } > > + > > + uint32_t pmd_thread_specified = 0; > > That is boolean > > > + uint32_t pmd_thread_to_change = 0; > > + uint32_t pmd_thread_update_ok = 0; > > Also boolean > Fixed both. > > + > > + if (pmd_core_param_set) { > > + if (str_to_uint(argv[2], 10, &pmd_thread_to_change)) { > > + pmd_thread_specified = 1; > > + } else { > > + /* argv[2] isn't even a uint. return without changing > > anything. */ > > + ds_put_format(&reply, > > + "Error: Miniflow parser not changed, PMD thread argument" > > + " passed is not valid: '%s'. Pass a valid pmd thread > > ID.\n", > > + argv[2]); > > + const char *reply_str = ds_cstr(&reply); > > + VLOG_INFO("%s", reply_str); > > + unixctl_command_reply_error(conn, reply_str); > > + ds_destroy(&reply); > > + return; > > + } > > + } > > > > - ovs_mutex_lock(&dp_netdev_mutex); > > int err = dp_mfex_impl_set_default_by_name(mfex_name); > > > > if (err) { > > - ovs_mutex_unlock(&dp_netdev_mutex); > > - struct ds reply = DS_EMPTY_INITIALIZER; > > char *error_desc = NULL; > > if (err == -EINVAL) { > > error_desc = "Unknown miniflow extract implementation:"; > > @@ -1106,6 +1138,66 @@ dpif_miniflow_extract_impl_set(struct > unixctl_conn *conn, int argc, > > return; > > } > > > > + /* argv[4] is optional packet count, which user can provide along with > > + * study function to set the minimum packet that must be matched in > > order > > + * to choose the optimal function. */ > > + uint32_t pkt_cmp_count = 0; > > + uint32_t study_ret = 0; > > + > > + if (argc == 5) { > > + if (str_to_uint(argv[4], 10, &pkt_cmp_count)) { > > + study_ret = mfex_set_study_pkt_cnt(pkt_cmp_count, > > + mfex_name); > > + > > + if (study_ret == -EINVAL) { > > + ds_put_format(&reply, "The study_pkt_cnt option is not > > valid" > > The parameter is called study_cnt. > Fixed. > > + " for the %s implementation.\n", > > + mfex_name); > > + const char *reply_str = ds_cstr(&reply); > > + unixctl_command_reply_error(conn, reply_str); > > + VLOG_INFO("%s", reply_str); > > + ds_destroy(&reply); > > + return; > > + } > > + } else { > > + ds_put_format(&reply, "Invalid study_pkt_cnt value: : %s.\n", > > + argv[4]); > > + const char *reply_str = ds_cstr(&reply); > > + unixctl_command_reply_error(conn, reply_str); > > + VLOG_INFO("%s", reply_str); > > + ds_destroy(&reply); > > + return; > > + } > > + } else if ((!pmd_core_param_set) && (argc == 3)) { > > + if (str_to_uint(argv[2], 10, &pkt_cmp_count)) { > > + study_ret = mfex_set_study_pkt_cnt(pkt_cmp_count, > > + mfex_name); > > + > > + if (study_ret == -EINVAL) { > > + ds_put_format(&reply, "The study_pkt_cnt option is not > > valid" > > + " for the %s implementation.\n", > > + mfex_name); > > + const char *reply_str = ds_cstr(&reply); > > + unixctl_command_reply_error(conn, reply_str); > > + VLOG_INFO("%s", reply_str); > > + ds_destroy(&reply); > > + return; > > + } > > + } else { > > + ds_put_format(&reply, "Invalid study_pkt_cnt value: %s.\n", > > + argv[2]); > > + const char *reply_str = ds_cstr(&reply); > > + unixctl_command_reply_error(conn, reply_str); > > + VLOG_INFO("%s", reply_str); > > + ds_destroy(&reply); > > + return; > > + } > > + } else { > > + /* Default packet compare count when packets count not provided. */ > > + study_ret = mfex_set_study_pkt_cnt(0, mfex_name); > > Setting to zero returns an error. Should that be MFEX_MAX_COUNT? > > > + > > + } > > Perhaps we could avoid repeating using the approach below: > Fixed. > char *study_cnt_param = NULL; > if (argc == 5) { > study_cnt_param = argv[4]; > } else if ((!pmd_core_param_set) && (argc == 3)) { > study_cnt_param = argv[2]; > } > > if (study_cnt_param) { > uint32_t pkt_cmp_count; > > if (str_to_uint(study_cnt_param, 10, &pkt_cmp_count)) { > study_ret = mfex_set_study_pkt_cnt(pkt_cmp_count, mfex_name); > [...] > } else { > [...] > } > } else { > /* Default packet compare count when packets count not * provided. */ > study_ret = mfex_set_study_pkt_cnt(MFEX_MAX_PKT_COUNT, > mfex_name); > } > Actually yes thanks 😊 > > + > > + ovs_mutex_lock(&dp_netdev_mutex); > > + > > SHASH_FOR_EACH (node, &dp_netdevs) { > > struct dp_netdev *dp = node->data; > > > > @@ -1122,8 +1214,14 @@ dpif_miniflow_extract_impl_set(struct > unixctl_conn *conn, int argc, > > continue; > > } > > > > + if ((pmd_thread_specified) && > > + (pmd->core_id != pmd_thread_to_change)) { > > + continue; > > + } > > + > > /* Initialize MFEX function pointer to the newly configured > > * default. */ > > + pmd_thread_update_ok = 1; > > atomic_uintptr_t *pmd_func = (void *) > > &pmd->miniflow_extract_opt; > > atomic_store_relaxed(pmd_func, (uintptr_t) default_func); > > }; > > @@ -1131,9 +1229,30 @@ dpif_miniflow_extract_impl_set(struct > > unixctl_conn *conn, int argc, > > > > ovs_mutex_unlock(&dp_netdev_mutex); > > > > + /* If PMD thread was specified, but it wasn't found, return error. */ > > + if (pmd_thread_specified && !pmd_thread_update_ok) { > > + ds_put_format(&reply, > > + "Error: Miniflow parser not changed, PMD thread %d not in > > use," > > + " pass a valid pmd thread ID.\n", > > + pmd_thread_to_change); > > + const char *reply_str = ds_cstr(&reply); > > + VLOG_INFO("%s", reply_str); > > + unixctl_command_reply_error(conn, reply_str); > > + ds_destroy(&reply); > > + return; > > + } > > + > > /* Reply with success to command. */ > > - struct ds reply = DS_EMPTY_INITIALIZER; > > - ds_put_format(&reply, "Miniflow implementation set to %s.\n", > mfex_name); > > + ds_put_format(&reply, "Miniflow implementation set to %s", mfex_name); > > + if (pmd_thread_specified) { > > + ds_put_format(&reply, ", on pmd thread %d", pmd_thread_to_change); > > + } > > + if (study_ret == 0) { > > + ds_put_format(&reply, ", studying %d packets", pkt_cmp_count); > > + } > > + > > + ds_put_format(&reply, ".\n"); > > + > > const char *reply_str = ds_cstr(&reply); > > VLOG_INFO("%s", reply_str); > > unixctl_command_reply(conn, reply_str); @@ -1370,8 +1489,9 @@ > > dpif_netdev_init(void) > > 0, 0, dpif_netdev_impl_get, > > NULL); > > unixctl_command_register("dpif-netdev/miniflow-parser-set", > > - "miniflow_implementation_name", > > - 1, 1, dpif_miniflow_extract_impl_set, > > + "[-pmd core] miniflow_implementation_name" > > + " [study_pkt_cnt]", > > + 1, 5, dpif_miniflow_extract_impl_set, > > NULL); > > unixctl_command_register("dpif-netdev/miniflow-parser-get", "", > > 0, 0, dpif_miniflow_extract_impl_get, > > -- > > 2.25.1 > > > > _______________________________________________ > > dev mailing list > > d...@openvswitch.org > > https://mail.openvswitch.org/mailman/listinfo/ovs-dev > > -- > fbl _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev