This fixes a problem introduced by:
commit 2cde6acd49da ("netpoll: Fix __netpoll_rcu_free so that it can hold the 
rtnl lock")

When using netconsole on a bond, __netpoll_cleanup can asynchronously
recurse multiple times, each __netpoll_free_async call can result in
more __netpoll_free_async's. This means there is now a race between
cleanup_work queues on multiple netpoll_info's on multiple devices and
the configuration of a new netpoll. For example if a netconsole is set
to enable 0, reconfigured, and enable 1 immediately, this netconsole
will likely not work.

Given the reason for __netpoll_free_async is it can be called when rtnl
is not locked, if it is locked, we should be able to execute
synchronously.

CC: Neil Horman <nhor...@tuxdriver.com>
CC: "David S. Miller" <da...@davemloft.net>
Signed-off-by: Debabrata Banerjee <dbane...@akamai.com>
---
 net/core/netpoll.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index de1d1ba92f2d..b899cbfbe639 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -826,7 +826,10 @@ static void netpoll_async_cleanup(struct work_struct *work)
 
 void __netpoll_free_async(struct netpoll *np)
 {
-       schedule_work(&np->cleanup_work);
+       if (rtnl_is_locked())
+               __netpoll_cleanup(np);
+       else
+               schedule_work(&np->cleanup_work);
 }
 EXPORT_SYMBOL_GPL(__netpoll_free_async);
 
-- 
2.19.1

Reply via email to