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