net: sched: Do not assume RTNL is held in tunnel key action helpers
authorIdo Schimmel <idosch@mellanox.com>
Thu, 19 Mar 2020 11:33:10 +0000 (13:33 +0200)
committerDavid S. Miller <davem@davemloft.net>
Fri, 20 Mar 2020 03:25:52 +0000 (20:25 -0700)
The cited commit removed RTNL from tc_setup_flow_action(), but the
function calls two tunnel key action helpers that use rtnl_dereference()
to fetch the action's parameters. This leads to "suspicious RCU usage"
warnings [1][2].

Change the helpers to use rcu_dereference_protected() while requiring
the action's lock to be held. This is safe because the two helpers are
only called from tc_setup_flow_action() which acquires the lock.

[1]
[  156.950855] =============================
[  156.955463] WARNING: suspicious RCU usage
[  156.960085] 5.6.0-rc5-custom-47426-gdfe43878d573 #2409 Not tainted
[  156.967116] -----------------------------
[  156.971728] include/net/tc_act/tc_tunnel_key.h:31 suspicious rcu_dereference_protected() usage!
[  156.981583]
[  156.981583] other info that might help us debug this:
[  156.981583]
[  156.990675]
[  156.990675] rcu_scheduler_active = 2, debug_locks = 1
[  156.998205] 1 lock held by tc/877:
[  157.002187]  #0: ffff8881cbf7bea0 (&(&p->tcfa_lock)->rlock){+...}, at: tc_setup_flow_action+0xbe/0x4f78
[  157.012866]
[  157.012866] stack backtrace:
[  157.017886] CPU: 2 PID: 877 Comm: tc Not tainted 5.6.0-rc5-custom-47426-gdfe43878d573 #2409
[  157.027253] Hardware name: Mellanox Technologies Ltd. MSN2100-CB2FO/SA001017, BIOS 5.6.5 06/07/2016
[  157.037389] Call Trace:
[  157.040170]  dump_stack+0xfd/0x178
[  157.044034]  lockdep_rcu_suspicious+0x14a/0x153
[  157.049157]  tc_setup_flow_action+0x89f/0x4f78
[  157.054227]  fl_hw_replace_filter+0x375/0x640
[  157.064348]  fl_change+0x28ec/0x4f6b
[  157.088843]  tc_new_tfilter+0x15e2/0x2260
[  157.176801]  rtnetlink_rcv_msg+0x8d6/0xb60
[  157.190915]  netlink_rcv_skb+0x177/0x460
[  157.208884]  rtnetlink_rcv+0x21/0x30
[  157.212925]  netlink_unicast+0x5d0/0x7f0
[  157.227728]  netlink_sendmsg+0x981/0xe90
[  157.245416]  ____sys_sendmsg+0x76d/0x8f0
[  157.255348]  ___sys_sendmsg+0x10f/0x190
[  157.320308]  __sys_sendmsg+0x115/0x1f0
[  157.342553]  __x64_sys_sendmsg+0x7d/0xc0
[  157.346987]  do_syscall_64+0xc1/0x600
[  157.351142]  entry_SYSCALL_64_after_hwframe+0x49/0xbe

[2]
[  157.432346] =============================
[  157.436937] WARNING: suspicious RCU usage
[  157.441537] 5.6.0-rc5-custom-47426-gdfe43878d573 #2409 Not tainted
[  157.448559] -----------------------------
[  157.453204] include/net/tc_act/tc_tunnel_key.h:43 suspicious rcu_dereference_protected() usage!
[  157.463042]
[  157.463042] other info that might help us debug this:
[  157.463042]
[  157.472112]
[  157.472112] rcu_scheduler_active = 2, debug_locks = 1
[  157.479529] 1 lock held by tc/877:
[  157.483442]  #0: ffff8881cbf7bea0 (&(&p->tcfa_lock)->rlock){+...}, at: tc_setup_flow_action+0xbe/0x4f78
[  157.494119]
[  157.494119] stack backtrace:
[  157.499114] CPU: 2 PID: 877 Comm: tc Not tainted 5.6.0-rc5-custom-47426-gdfe43878d573 #2409
[  157.508485] Hardware name: Mellanox Technologies Ltd. MSN2100-CB2FO/SA001017, BIOS 5.6.5 06/07/2016
[  157.518628] Call Trace:
[  157.521416]  dump_stack+0xfd/0x178
[  157.525293]  lockdep_rcu_suspicious+0x14a/0x153
[  157.530425]  tc_setup_flow_action+0x993/0x4f78
[  157.535505]  fl_hw_replace_filter+0x375/0x640
[  157.545650]  fl_change+0x28ec/0x4f6b
[  157.570204]  tc_new_tfilter+0x15e2/0x2260
[  157.658199]  rtnetlink_rcv_msg+0x8d6/0xb60
[  157.672315]  netlink_rcv_skb+0x177/0x460
[  157.690278]  rtnetlink_rcv+0x21/0x30
[  157.694320]  netlink_unicast+0x5d0/0x7f0
[  157.709129]  netlink_sendmsg+0x981/0xe90
[  157.726813]  ____sys_sendmsg+0x76d/0x8f0
[  157.736725]  ___sys_sendmsg+0x10f/0x190
[  157.801721]  __sys_sendmsg+0x115/0x1f0
[  157.823967]  __x64_sys_sendmsg+0x7d/0xc0
[  157.828403]  do_syscall_64+0xc1/0x600
[  157.832558]  entry_SYSCALL_64_after_hwframe+0x49/0xbe

Fixes: b15e7a6e8d31 ("net: sched: don't take rtnl lock during flow_action setup")
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
Reviewed-by: Vlad Buslov <vladbu@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/tc_act/tc_tunnel_key.h

index 2b3df07..e1057b2 100644 (file)
@@ -28,8 +28,10 @@ static inline bool is_tcf_tunnel_set(const struct tc_action *a)
 {
 #ifdef CONFIG_NET_CLS_ACT
        struct tcf_tunnel_key *t = to_tunnel_key(a);
-       struct tcf_tunnel_key_params *params = rtnl_dereference(t->params);
+       struct tcf_tunnel_key_params *params;
 
+       params = rcu_dereference_protected(t->params,
+                                          lockdep_is_held(&a->tcfa_lock));
        if (a->ops && a->ops->id == TCA_ID_TUNNEL_KEY)
                return params->tcft_action == TCA_TUNNEL_KEY_ACT_SET;
 #endif
@@ -40,8 +42,10 @@ static inline bool is_tcf_tunnel_release(const struct tc_action *a)
 {
 #ifdef CONFIG_NET_CLS_ACT
        struct tcf_tunnel_key *t = to_tunnel_key(a);
-       struct tcf_tunnel_key_params *params = rtnl_dereference(t->params);
+       struct tcf_tunnel_key_params *params;
 
+       params = rcu_dereference_protected(t->params,
+                                          lockdep_is_held(&a->tcfa_lock));
        if (a->ops && a->ops->id == TCA_ID_TUNNEL_KEY)
                return params->tcft_action == TCA_TUNNEL_KEY_ACT_RELEASE;
 #endif