On Fri, 2017-12-08 at 10:54 +0800, Jason Wang wrote:
Private destructor could be called when register_netdev() fail withHi Jason, thank you for the following up.
rtnl lock held. This will lead deadlock in tun_free_netdev() who
tries
to hold rtnl_lock. Fixing this by switching to use spinlock to
synchronize.
Fixes: 96f84061620c ("tun: add eBPF based queue selection method")
Reported-by: Eric Dumazet <eric.dumazet@xxxxxxxxx>
Cc: Eric Dumazet <eric.dumazet@xxxxxxxxx>
Cc: Willem de Bruijn <willemb@xxxxxxxxxx>
Signed-off-by: Jason Wang <jasowang@xxxxxxxxxx>
---
Âdrivers/net/tun.c | 7 ++++---
Â1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 787cc35..f7ccd79 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -2050,8 +2050,11 @@ static int __tun_set_steering_ebpf(struct
tun_struct *tun,
 new->prog = prog;
 }
- old = rtnl_dereference(tun->steering_prog);
+ spin_lock(&tun->lock);
+ old = rcu_dereference_protected(tun->steering_prog,
+ lock_is_held(&tun->lock));
 rcu_assign_pointer(tun->steering_prog, new);
+ spin_unlock(&tun->lock);
Have you tested this code path with lockdep enabled ?
My gut feeling is that you need spin_lock_bh() here.
Thanks