[ovs-dev] [v8 06/12] dpif-netdev: Add packet count and core id paramters for study
Flavio Leitner
fbl at sysclose.org
Sun Jul 11 00:44:07 UTC 2021
Hi,
On Fri, Jul 09, 2021 at 05:35:56PM +0530, kumar Amber wrote:
> From: Kumar Amber <kumar.amber at intel.com>
>
> This commit introduces additional command line paramter
Parameter.
> 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.amber at 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...
> +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");
>
> 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
> + * 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
> +
> + 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.
> + " 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:
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);
}
> +
> + 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
> dev at openvswitch.org
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
--
fbl
More information about the dev
mailing list