diff options
author | Eric Dumazet <edumazet@google.com> | 2024-04-26 09:42:22 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2024-05-30 10:49:17 +0300 |
commit | 4574ba1b31b3bd7a69bee9ee6b7348877a831cfb (patch) | |
tree | 53bc2db287841058335328ffee77773ec37227bf /net | |
parent | 2fcffaaf529d5fe3fdc6c0ee65a6f266b74de782 (diff) | |
download | linux-4574ba1b31b3bd7a69bee9ee6b7348877a831cfb.tar.xz |
net: give more chances to rcu in netdev_wait_allrefs_any()
[ Upstream commit cd42ba1c8ac9deb9032add6adf491110e7442040 ]
This came while reviewing commit c4e86b4363ac ("net: add two more
call_rcu_hurry()").
Paolo asked if adding one synchronize_rcu() would help.
While synchronize_rcu() does not help, making sure to call
rcu_barrier() before msleep(wait) is definitely helping
to make sure lazy call_rcu() are completed.
Instead of waiting ~100 seconds in my tests, the ref_tracker
splats occurs one time only, and netdev_wait_allrefs_any()
latency is reduced to the strict minimum.
Ideally we should audit our call_rcu() users to make sure
no refcount (or cascading call_rcu()) is held too long,
because rcu_barrier() is quite expensive.
Fixes: 0e4be9e57e8c ("net: use exponential backoff in netdev_wait_allrefs")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Link: https://lore.kernel.org/all/28bbf698-befb-42f6-b561-851c67f464aa@kernel.org/T/#m76d73ed6b03cd930778ac4d20a777f22a08d6824
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'net')
-rw-r--r-- | net/core/dev.c | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index c365aa06f886..a32811aebde5 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -10455,8 +10455,9 @@ static struct net_device *netdev_wait_allrefs_any(struct list_head *list) rebroadcast_time = jiffies; } + rcu_barrier(); + if (!wait) { - rcu_barrier(); wait = WAIT_REFS_MIN_MSECS; } else { msleep(wait); |