[ovs-dev] [PATCH v2 25/28] dpif-netdev: Make megaflow and mark mappings thread objects

Gaetan Rivet grive at u256.net
Mon Apr 12 15:20:11 UTC 2021


In later commits hardware offloads are managed in several threads.
Each offload is managed by a thread determined by its flow's 'mega_ufid'.

As megaflow to mark and mark to flow mappings are 1:1 and 1:N
respectively, then a single mark exists for a single 'mega_ufid', and
multiple flows uses the same 'mega_ufid'. Because the managing thread will
be choosen using the 'mega_ufid', then each mapping does not need to be
shared with other offload threads.

The mappings are kept as cmap as upcalls will sometimes query them before
enqueuing orders to the offload threads.

To prepare this change, move the mappings within the offload thread
structure.

Signed-off-by: Gaetan Rivet <grive at u256.net>
Reviewed-by: Eli Britstein <elibr at nvidia.com>
---
 lib/dpif-netdev.c | 41 +++++++++++++++++++----------------------
 1 file changed, 19 insertions(+), 22 deletions(-)

diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index bc87b368b..f0c33efca 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -462,12 +462,16 @@ struct dp_offload_thread_item {
 struct dp_offload_thread {
     struct mpsc_queue queue;
     atomic_uint64_t enqueued_item;
+    struct cmap megaflow_to_mark;
+    struct cmap mark_to_flow;
     struct mov_avg_cma cma;
     struct mov_avg_ema ema;
 };
 
 static struct dp_offload_thread dp_offload_thread = {
     .queue = MPSC_QUEUE_INITIALIZER(&dp_offload_thread.queue),
+    .megaflow_to_mark = CMAP_INITIALIZER,
+    .mark_to_flow = CMAP_INITIALIZER,
     .enqueued_item = ATOMIC_VAR_INIT(0),
     .cma = MOV_AVG_CMA_INITIALIZER,
     .ema = MOV_AVG_EMA_INITIALIZER(100),
@@ -2437,16 +2441,7 @@ struct megaflow_to_mark_data {
     uint32_t mark;
 };
 
-struct flow_mark {
-    struct cmap megaflow_to_mark;
-    struct cmap mark_to_flow;
-    struct seq_pool *pool;
-};
-
-static struct flow_mark flow_mark = {
-    .megaflow_to_mark = CMAP_INITIALIZER,
-    .mark_to_flow = CMAP_INITIALIZER,
-};
+static struct seq_pool *flow_mark_pool;
 
 static uint32_t
 flow_mark_alloc(void)
@@ -2457,12 +2452,12 @@ flow_mark_alloc(void)
 
     if (ovsthread_once_start(&pool_init)) {
         /* Haven't initiated yet, do it here */
-        flow_mark.pool = seq_pool_create(netdev_offload_thread_nb(),
+        flow_mark_pool = seq_pool_create(netdev_offload_thread_nb(),
                                          1, MAX_FLOW_MARK);
         ovsthread_once_done(&pool_init);
     }
 
-    if (seq_pool_new_id(flow_mark.pool, tid, &mark)) {
+    if (seq_pool_new_id(flow_mark_pool, tid, &mark)) {
         return mark;
     }
 
@@ -2474,7 +2469,7 @@ flow_mark_free(uint32_t mark)
 {
     unsigned int tid = netdev_offload_thread_id();
 
-    seq_pool_free_id(flow_mark.pool, tid, mark);
+    seq_pool_free_id(flow_mark_pool, tid, mark);
 }
 
 /* associate megaflow with a mark, which is a 1:1 mapping */
@@ -2487,7 +2482,7 @@ megaflow_to_mark_associate(const ovs_u128 *mega_ufid, uint32_t mark)
     data->mega_ufid = *mega_ufid;
     data->mark = mark;
 
-    cmap_insert(&flow_mark.megaflow_to_mark,
+    cmap_insert(&dp_offload_thread.megaflow_to_mark,
                 CONST_CAST(struct cmap_node *, &data->node), hash);
 }
 
@@ -2498,9 +2493,10 @@ megaflow_to_mark_disassociate(const ovs_u128 *mega_ufid)
     size_t hash = dp_netdev_flow_hash(mega_ufid);
     struct megaflow_to_mark_data *data;
 
-    CMAP_FOR_EACH_WITH_HASH (data, node, hash, &flow_mark.megaflow_to_mark) {
+    CMAP_FOR_EACH_WITH_HASH (data, node, hash,
+                             &dp_offload_thread.megaflow_to_mark) {
         if (ovs_u128_equals(*mega_ufid, data->mega_ufid)) {
-            cmap_remove(&flow_mark.megaflow_to_mark,
+            cmap_remove(&dp_offload_thread.megaflow_to_mark,
                         CONST_CAST(struct cmap_node *, &data->node), hash);
             ovsrcu_postpone(free, data);
             return;
@@ -2517,7 +2513,8 @@ megaflow_to_mark_find(const ovs_u128 *mega_ufid)
     size_t hash = dp_netdev_flow_hash(mega_ufid);
     struct megaflow_to_mark_data *data;
 
-    CMAP_FOR_EACH_WITH_HASH (data, node, hash, &flow_mark.megaflow_to_mark) {
+    CMAP_FOR_EACH_WITH_HASH (data, node, hash,
+                             &dp_offload_thread.megaflow_to_mark) {
         if (ovs_u128_equals(*mega_ufid, data->mega_ufid)) {
             return data->mark;
         }
@@ -2534,7 +2531,7 @@ mark_to_flow_associate(const uint32_t mark, struct dp_netdev_flow *flow)
 {
     dp_netdev_flow_ref(flow);
 
-    cmap_insert(&flow_mark.mark_to_flow,
+    cmap_insert(&dp_offload_thread.mark_to_flow,
                 CONST_CAST(struct cmap_node *, &flow->mark_node),
                 hash_int(mark, 0));
     flow->mark = mark;
@@ -2549,7 +2546,7 @@ flow_mark_has_no_ref(uint32_t mark)
     struct dp_netdev_flow *flow;
 
     CMAP_FOR_EACH_WITH_HASH (flow, mark_node, hash_int(mark, 0),
-                             &flow_mark.mark_to_flow) {
+                             &dp_offload_thread.mark_to_flow) {
         if (flow->mark == mark) {
             return false;
         }
@@ -2574,7 +2571,7 @@ mark_to_flow_disassociate(struct dp_netdev_pmd_thread *pmd,
         return EINVAL;
     }
 
-    cmap_remove(&flow_mark.mark_to_flow, mark_node, hash_int(mark, 0));
+    cmap_remove(&dp_offload_thread.mark_to_flow, mark_node, hash_int(mark, 0));
     flow->mark = INVALID_FLOW_MARK;
 
     /*
@@ -2611,7 +2608,7 @@ flow_mark_flush(struct dp_netdev_pmd_thread *pmd)
 {
     struct dp_netdev_flow *flow;
 
-    CMAP_FOR_EACH (flow, mark_node, &flow_mark.mark_to_flow) {
+    CMAP_FOR_EACH (flow, mark_node, &dp_offload_thread.mark_to_flow) {
         if (flow->pmd_id == pmd->core_id) {
             queue_netdev_flow_del(pmd, flow);
         }
@@ -2625,7 +2622,7 @@ mark_to_flow_find(const struct dp_netdev_pmd_thread *pmd,
     struct dp_netdev_flow *flow;
 
     CMAP_FOR_EACH_WITH_HASH (flow, mark_node, hash_int(mark, 0),
-                             &flow_mark.mark_to_flow) {
+                             &dp_offload_thread.mark_to_flow) {
         if (flow->mark == mark && flow->pmd_id == pmd->core_id &&
             flow->dead == false) {
             return flow;
-- 
2.31.1



More information about the dev mailing list