diff mbox series

[ovs-dev,1/2] dpif-netdev: Add check mark to avoid ovs-vswitchd crash.

Message ID 20200523122828.54627-1-xiangxia.m.yue@gmail.com
State Superseded
Headers show
Series [ovs-dev,1/2] dpif-netdev: Add check mark to avoid ovs-vswitchd crash. | expand

Commit Message

Tonghao Zhang May 23, 2020, 12:28 p.m. UTC
From: Tonghao Zhang <xiangxia.m.yue@gmail.com>

When changing the pmd interfaces attribute, ovs-vswitchd will
reload pmd and flush offload flows. reload_affected_pmds may
be invoked twice or more. In that case, the flows may been
queued to "dp_netdev_flow_offload" thread again.

For example:
$ ovs-vsctl -- set interface <Interface> options:dpdk-lsc-interrupt=true

ovs-vswitchd main       flow-offload thread
append F to queue       ...
...
append F to queue
...                     del F
...                     del F (crash [1])

[1]:
ovs_assert_failure          lib/cmap.c:922
cmap_replace                lib/cmap.c:921
cmap_remove                 lib/cmap.h:295
mark_to_flow_disassociate   lib/dpif-netdev.c:2269
dp_netdev_flow_offload_del  lib/dpif-netdev.c:2369
dp_netdev_flow_offload_main lib/dpif-netdev.c:2492

Cc: Yuanhan Liu <yliu@fridaylinux.org>
Cc: Ian Stokes <i.maximets@ovn.org>
Cc: Ben Pfaff <blp@ovn.org>
Cc: William Tu <u9012063@gmail.com>
Signed-off-by: Tonghao Zhang <xiangxia.m.yue@gmail.com>
---
 lib/dpif-netdev.c | 7 +++++++
 1 file changed, 7 insertions(+)
diff mbox series

Patch

diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index 46eb1e3d97c9..25c4b960857a 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -2265,6 +2265,13 @@  mark_to_flow_disassociate(struct dp_netdev_pmd_thread *pmd,
     uint32_t mark = flow->mark;
     struct cmap_node *mark_node = CONST_CAST(struct cmap_node *,
                                              &flow->mark_node);
+    /* Check the mark if avoidable, INVALID_FLOW_MARK may
+     * mean that the flow has been disassociated or never
+     * associated.
+     */
+    if (OVS_UNLIKELY(mark == INVALID_FLOW_MARK)) {
+        return -1;
+    }
 
     cmap_remove(&flow_mark.mark_to_flow, mark_node, hash_int(mark, 0));
     flow->mark = INVALID_FLOW_MARK;