Hi Eelco,

Don’t know the formatting keeps breaking . replies are inline.

<Snip>

+optimal implementation. If no packet count is provided then the default value
+128 is chosen.

Not a native speaker, but I think the sentence need some commas?

“If no packet count is provided, then the default value,
128, is chosen.”

Fixed.

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.
+
+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 study 1024 3
+
+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


+ if ((strcmp(miniflow_funcs[MFEX_IMPL_STUDY].name, name) == 0) &&
+ (pkt_cmp_count != 0)) {
+
+ mfex_study_pkts_count = pkt_cmp_count;

Do we need to set/read this atomically?

Using set in v7.

+ return 0;
+ }
+
+ mfex_study_pkts_count = MFEX_MAX_COUNT;
+ return -EINVAL;
+}
+
uint32_t
mfex_study_traffic(struct dp_packet_batch *packets,
struct netdev_flow_key *keys,
@@ -86,7 +107,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_MAX;
uint32_t max_hits = 0;
for (int i = MFEX_IMPL_MAX; i < impl_count; i++) {
diff --git a/lib/dpif-netdev-private-extract.c 
b/lib/dpif-netdev-private-extract.c
index 6ae91a24d..c1239b319 100644
--- a/lib/dpif-netdev-private-extract.c
+++ b/lib/dpif-netdev-private-extract.c
@@ -118,7 +118,7 @@ dp_mfex_impl_get(struct ds *reply, struct 
dp_netdev_pmd_thread **pmd_list,

for (uint32_t i = 0; i < ARRAY_SIZE(mfex_impls); i++) {

- ds_put_format(reply, " %s (available: %s)(pmds: ",
+ ds_put_format(reply, " %s (available: %s, pmds: ",

Rather than changing the format here, we set it correctly in patch introducing 
this?

Yes .

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 cd46c94dd..a1f48d870 100644
--- a/lib/dpif-netdev-private-extract.h
+++ b/lib/dpif-netdev-private-extract.h
@@ -135,4 +135,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 175d8699f..6bcb24a73 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -1103,9 +1103,13 @@ 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 second optional parameter can set the packet count to match in study.
+ * A third optional paramter PMD thread ID can be also provided which
+ * allows users to set miniflow implementation on a particular pmd.
*/
const char *mfex_name = argv[1];
struct shash_node *node;
+ struct ds reply = DS_EMPTY_INITIALIZER;

static const char *error_description[2] = {
"Unknown miniflow implementation",

It’s not shown here, but I think the Mutex on line 1105 does not need to be 
taken until 1158, which makes the error path more clean.

Fixed at the right place in v7.

@@ -1116,7 +1120,6 @@ dpif_miniflow_extract_impl_set(struct unixctl_conn *conn, 
int argc,
int32_t err = dp_mfex_impl_set_default_by_name(mfex_name);

if (err) {
- struct ds reply = DS_EMPTY_INITIALIZER;
ds_put_format(&reply,
"Miniflow implementation not available: %s %s.\n",
error_description[ (err == EINVAL) ], mfex_name);
@@ -1128,6 +1131,44 @@ dpif_miniflow_extract_impl_set(struct unixctl_conn 
*conn, int argc,
return;
}

+ /* argv[2] 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 == 3) || (argc == 4)) {
+ if (str_to_uint(argv[2], 10, &pkt_cmp_count)) {
+ study_ret = mfex_set_study_pkt_cnt(pkt_cmp_count, mfex_name);
+ } else {
+ study_ret = -EINVAL;

An invalid input was given so we should error out.

The error is handled later and since we already have a fallback to default 
value we just fall-back.

+ }
+ } else {
+ /* Default packet compare count when packets count not provided. */
+ study_ret = mfex_set_study_pkt_cnt(0, mfex_name);
+ }
+
+ uint32_t pmd_thread_specified = 0;
+ uint32_t pmd_thread_to_change = 0;
+ uint32_t pmd_thread_update_ok = 0;
+ if (argc == 4) {
+ if (str_to_uint(argv[3], 10, &pmd_thread_to_change)) {
+ pmd_thread_specified = 1;
+ } else {
+ /* argv[3] isn't even a uint. return without changing anything. */
+ ovs_mutex_unlock(&dp_netdev_mutex);
+ 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[3]);
+ const char *reply_str = ds_cstr(&reply);
+ VLOG_INFO("%s", reply_str);
+ unixctl_command_reply_error(conn, reply_str);
+ ds_destroy(&reply);
+ return;
+ }
+ }
+
SHASH_FOR_EACH (node, &dp_netdevs) {
struct dp_netdev *dp = node->data;

@@ -1142,8 +1183,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;
miniflow_extract_func default_func = dp_mfex_impl_get_default();
atomic_uintptr_t *pmd_func = (void *) &pmd->miniflow_extract_opt;
atomic_store_relaxed(pmd_func, (uintptr_t) default_func);
@@ -1152,9 +1199,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;

Not sure what the new code will look like, but with all these error conditions 
may be a goto error_exit/mutex_error_exit, will be cleaner?

Well True but all the erro displays different each for each type of condition 
and is more useful in that way to user.

+ }
+
/* 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) {

Maybe always show the number of packets? I’m fine either way, but I remember 
discussions to avoid conditional output as much as possible.

It’s a fallback where we display that we set to default or to the packet count 
more user-friendly

+ ds_put_format(&reply, ", studing %d packets", pkt_cmp_count);

“studying”



Fixed.

+ }
+
+ ds_put_format(&reply, "\n");

Maybe “.\n”

Fixed.

+
const char *reply_str = ds_cstr(&reply);
VLOG_INFO("%s", reply_str);
unixctl_command_reply(conn, reply_str);
@@ -1391,8 +1459,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,
+ "miniflow_implementation_name [study_pkt_cnt]"
+ " [pmd_core]",
+ 1, 3, dpif_miniflow_extract_impl_set,
NULL);
unixctl_command_register("dpif-netdev/miniflow-parser-get", "",
0, 0, dpif_miniflow_extract_impl_get,
--
2.32.0
_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to