Introduce an API for allocating flow marks, replacing the previous
approach that relied on per-thread pools tied to DPDK offload threads.

With recent changes moving thread management to the per-offload provider
layer, the previous model no longer applies, as flow mark allocation is
now needed at a higher level.

To maintain low contention during allocation, we retain a fixed number
of pools and use the current thread ID to select a pool. This approach
works well in practice, as threads are typically created in a loop with
incrementing thread IDs, which helps distribute the load evenly.

Signed-off-by: Eelco Chaudron <echau...@redhat.com>
---
 lib/dpif-offload.c | 36 ++++++++++++++++++++++++++++++++++++
 lib/dpif-offload.h |  4 ++++
 2 files changed, 40 insertions(+)

diff --git a/lib/dpif-offload.c b/lib/dpif-offload.c
index 5e3e57590..6faf7b58f 100644
--- a/lib/dpif-offload.c
+++ b/lib/dpif-offload.c
@@ -20,6 +20,7 @@
 #include "dpif-offload.h"
 #include "dpif-offload-provider.h"
 #include "dpif-provider.h"
+#include "id-fpool.h"
 #include "netdev-provider.h"
 #include "unixctl.h"
 #include "util.h"
@@ -1317,6 +1318,41 @@ dpif_offload_operate(struct dpif *dpif, struct dpif_op 
**ops, size_t n_ops,
     return n_ops_left;
 }
 
+#define MAX_FLOW_MARK       (UINT32_MAX - 1)
+#define MAX_FLOW_MARK_USERS 8
+static struct id_fpool *flow_mark_pool;
+
+uint32_t
+dpif_offload_allocate_flow_mark(void)
+{
+    static struct ovsthread_once init_once = OVSTHREAD_ONCE_INITIALIZER;
+    unsigned int uid = ovsthread_id_self() % MAX_FLOW_MARK_USERS;
+    uint32_t flow_mark;
+
+    if (ovsthread_once_start(&init_once)) {
+        /* Haven't initiated yet, do it here. */
+        flow_mark_pool = id_fpool_create(MAX_FLOW_MARK_USERS, 1,
+                                         MAX_FLOW_MARK);
+        ovsthread_once_done(&init_once);
+    }
+
+    if (id_fpool_new_id(flow_mark_pool, uid, &flow_mark)) {
+        return flow_mark;
+    }
+
+    return INVALID_FLOW_MARK;
+}
+
+void
+dpif_offload_free_flow_mark(uint32_t flow_mark)
+{
+    if (flow_mark != INVALID_FLOW_MARK) {
+        unsigned int uid = ovsthread_id_self() % MAX_FLOW_MARK_USERS;
+
+        id_fpool_free_id(flow_mark_pool, uid, flow_mark);
+    }
+}
+
 
 bool
 dpif_offload_netdev_same_offload(const struct netdev *a,
diff --git a/lib/dpif-offload.h b/lib/dpif-offload.h
index e316a8508..07e47068e 100644
--- a/lib/dpif-offload.h
+++ b/lib/dpif-offload.h
@@ -47,11 +47,15 @@ enum dpif_offload_impl_type {
     DPIF_OFFLOAD_IMPL_HW_ONLY,
 };
 
+#define INVALID_FLOW_MARK 0
+
 
 /* Global functions. */
 void dpif_offload_set_global_cfg(const struct ovsrec_open_vswitch *);
 bool dpif_offload_is_offload_enabled(void);
 bool dpif_offload_is_offload_rebalance_policy_enabled(void);
+uint32_t dpif_offload_allocate_flow_mark(void);
+void dpif_offload_free_flow_mark(uint32_t flow_mark);
 
 
 /* Per dpif specific functions. */
-- 
2.50.1

_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to