On 2017年12月08日 11:11, Eric Dumazet wrote:
On Fri, 2017-12-08 at 10:54 +0800, Jason Wang wrote:
Private destructor could be called when register_netdev() fail with
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.duma...@gmail.com>
Cc: Eric Dumazet <eric.duma...@gmail.com>
Cc: Willem de Bruijn <will...@google.com>
Signed-off-by: Jason Wang <jasow...@redhat.com>
---
  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);

Hi Jason, thank you for the following up.

Have you tested this code path with lockdep enabled ?

No I test without it.


My gut feeling is that you need spin_lock_bh() here.

Thanks


Yes, I miss the fact this the lock is used by e.g flow caches too. Will post V2.

Thanks

Reply via email to