From: Ethan Jackson Date: Sat, 3 Jan 2015 19:39:14 +0000 (-0800) Subject: dpif-netdev: Fix rare flow add race condition. X-Git-Tag: v2.4.0~714 X-Git-Url: http://git.cascardo.eti.br/?a=commitdiff_plain;h=4c75aaabb15389ddc9ec76e23f09d9282648dc13;p=cascardo%2Fovs.git dpif-netdev: Fix rare flow add race condition. Before this patch, dp_netdev_flow_add() inserted newly minted flows in the "flow_table" cmap before inserting them into the per core "dpcls" classifier. Since dpcls_insert() initializes 'flow->cr.mask', there's a brief window where the flow is accessible from the cmap, but has a bogus mask value. In my testing, under rare instances (i.e. once every 20 minutes with a very specific flow table and traffic pattern), revalidators core dump when they call dpif_netdev_flow_dump_next(), which accesses this bogus mask value from dp_netdev_flow_to_dpif_flow(). By inserting into the per core classifier before the cmap, all the values are guaranteed to be initialized during flow dumps. With this patch, I can no longer reproduce the crash. Signed-off-by: Ethan Jackson Acked-by: Jarno Rajahalme --- diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 27a555ecc..54bad0247 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -1742,12 +1742,12 @@ dp_netdev_flow_add(struct dp_netdev_pmd_thread *pmd, ovs_refcount_init(&flow->ref_cnt); ovsrcu_set(&flow->actions, dp_netdev_actions_create(actions, actions_len)); - cmap_insert(&pmd->flow_table, - CONST_CAST(struct cmap_node *, &flow->node), - dp_netdev_flow_hash(&flow->ufid)); netdev_flow_key_init_masked(&flow->cr.flow, &match->flow, &mask); dpcls_insert(&pmd->cls, &flow->cr, &mask); + cmap_insert(&pmd->flow_table, CONST_CAST(struct cmap_node *, &flow->node), + dp_netdev_flow_hash(&flow->ufid)); + if (OVS_UNLIKELY(VLOG_IS_DBG_ENABLED())) { struct match match; struct ds ds = DS_EMPTY_INITIALIZER;