diff options
author | Eric Dumazet <edumazet@google.com> | 2022-02-04 14:42:37 -0800 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2022-02-05 15:22:45 +0000 |
commit | 4c6c11ea0f7b00a1894803efe980dfaf3b074886 (patch) | |
tree | 7aebfd050e64400172e0ad2c456d149f35898c0e /net/core/link_watch.c | |
parent | 8fd5522f44dcd7f05454ddc4f16d0f821b676cd9 (diff) | |
download | lwn-4c6c11ea0f7b00a1894803efe980dfaf3b074886.tar.gz lwn-4c6c11ea0f7b00a1894803efe980dfaf3b074886.zip |
net: refine dev_put()/dev_hold() debugging
We are still chasing some syzbot reports where we think a rogue dev_put()
is called with no corresponding prior dev_hold().
Unfortunately it eats a reference on dev->dev_refcnt taken by innocent
dev_hold_track(), meaning that the refcount saturation splat comes
too late to be useful.
Make sure that 'not tracked' dev_put() and dev_hold() better use
CONFIG_NET_DEV_REFCNT_TRACKER=y debug infrastructure:
Prior patch in the series allowed ref_tracker_alloc() and ref_tracker_free()
to be called with a NULL @trackerp parameter, and to use a separate refcount
only to detect too many put() even in the following case:
dev_hold_track(dev, tracker_1, GFP_ATOMIC);
dev_hold(dev);
dev_put(dev);
dev_put(dev); // Should complain loudly here.
dev_put_track(dev, tracker_1); // instead of here
Add clarification about netdev_tracker_alloc() role.
v2: I replaced the dev_put() in linkwatch_do_dev()
with __dev_put() because callers called netdev_tracker_free().
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core/link_watch.c')
-rw-r--r-- | net/core/link_watch.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/net/core/link_watch.c b/net/core/link_watch.c index b0f5344d1185..95098d1a49bd 100644 --- a/net/core/link_watch.c +++ b/net/core/link_watch.c @@ -166,10 +166,10 @@ static void linkwatch_do_dev(struct net_device *dev) netdev_state_change(dev); } - /* Note: our callers are responsible for - * calling netdev_tracker_free(). + /* Note: our callers are responsible for calling netdev_tracker_free(). + * This is the reason we use __dev_put() instead of dev_put(). */ - dev_put(dev); + __dev_put(dev); } static void __linkwatch_run_queue(int urgent_only) |