diff mbox series

[ovs-dev,RFC,22/26] dpif-netdev: Make megaflow and mark mappings thread objects

Message ID f1e8ba16bb7e301b6eb87eb8901b42f61289497d.1607177117.git.grive@u256.net
State RFC
Headers show
Series [ovs-dev,RFC,01/26] netdev: Add flow API de-init function | expand

Commit Message

Gaetan Rivet Dec. 5, 2020, 2:22 p.m. UTC
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@u256.net>
---
 lib/dpif-netdev.c | 41 +++++++++++++++++++----------------------
 1 file changed, 19 insertions(+), 22 deletions(-)
diff mbox series

Patch

diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index d0cdb33db..aeadb0790 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -439,6 +439,8 @@  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_ema ema;
 };
 
@@ -446,6 +448,8 @@  struct dp_offload_thread {
 
 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),
     .ema = MOV_AVG_EMA_INITIALIZER(DP_NETDEV_OFFLOAD_EMA_N),
 };
@@ -2409,16 +2413,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)
@@ -2429,12 +2424,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;
     }
 
@@ -2446,7 +2441,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 */
@@ -2459,7 +2454,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);
 }
 
@@ -2470,9 +2465,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;
@@ -2489,7 +2485,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;
         }
@@ -2506,7 +2503,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;
@@ -2521,7 +2518,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;
         }
@@ -2546,7 +2543,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;
 
     /*
@@ -2583,7 +2580,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);
         }
@@ -2597,7 +2594,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;