Skip to content

Commit

Permalink
net: Convert netpoll blocking api in bonding driver to be a counter
Browse files Browse the repository at this point in the history
A while back I made some changes to enable netpoll in the bonding driver.  Among
them was a per-cpu flag that indicated we were in a path that held locks which
could cause the netpoll path to block in during tx, and as such the tx path
should queue the frame for later use.  This appears to have given rise to a
regression.  If one of those paths on which we hold the per-cpu flag yields the
cpu, its possible for us to come back on a different cpu, leading to us clearing
a different flag than we set.  This results in odd netpoll drops, and BUG
backtraces appearing in the log, as we check to make sure that we only clear set
bits, and only set clear bits.  I had though briefly about changing the
offending paths so that they wouldn't sleep, but looking at my origional work
more closely, it doesn't appear that a per-cpu flag is warranted.  We alrady
gate the checking of this flag on IFF_IN_NETPOLL, so we don't hit this in the
normal tx case anyway.  And practically speaking, the normal use case for
netpoll is to only have one client anyway, so we're not going to erroneously
queue netpoll frames when its actually safe to do so.  As such, lets just
convert that per-cpu flag to an atomic counter.  It fixes the rescheduling bugs,
is equivalent from a performance perspective and actually eliminates some code
in the process.

Tested by the reporter and myself, successfully

Reported-by: Liang Zheng <[email protected]>
CC: Jay Vosburgh <[email protected]>
CC: Andy Gospodarek <[email protected]>
CC: David S. Miller <[email protected]>
Signed-off-by: Neil Horman <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
nhorman authored and davem330 committed Dec 10, 2010
1 parent 4e085e7 commit fb4fa76
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 20 deletions.
17 changes: 5 additions & 12 deletions drivers/net/bonding/bond_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ MODULE_PARM_DESC(resend_igmp, "Number of IGMP membership reports to send on link
/*----------------------------- Global variables ----------------------------*/

#ifdef CONFIG_NET_POLL_CONTROLLER
cpumask_var_t netpoll_block_tx;
atomic_t netpoll_block_tx = ATOMIC_INIT(0);
#endif

static const char * const version =
Expand Down Expand Up @@ -5299,13 +5299,6 @@ static int __init bonding_init(void)
if (res)
goto out;

#ifdef CONFIG_NET_POLL_CONTROLLER
if (!alloc_cpumask_var(&netpoll_block_tx, GFP_KERNEL)) {
res = -ENOMEM;
goto out;
}
#endif

res = register_pernet_subsys(&bond_net_ops);
if (res)
goto out;
Expand Down Expand Up @@ -5334,9 +5327,6 @@ static int __init bonding_init(void)
rtnl_link_unregister(&bond_link_ops);
err_link:
unregister_pernet_subsys(&bond_net_ops);
#ifdef CONFIG_NET_POLL_CONTROLLER
free_cpumask_var(netpoll_block_tx);
#endif
goto out;

}
Expand All @@ -5353,7 +5343,10 @@ static void __exit bonding_exit(void)
unregister_pernet_subsys(&bond_net_ops);

#ifdef CONFIG_NET_POLL_CONTROLLER
free_cpumask_var(netpoll_block_tx);
/*
* Make sure we don't have an imbalance on our netpoll blocking
*/
WARN_ON(atomic_read(&netpoll_block_tx));
#endif
}

Expand Down
12 changes: 4 additions & 8 deletions drivers/net/bonding/bonding.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,26 +119,22 @@


#ifdef CONFIG_NET_POLL_CONTROLLER
extern cpumask_var_t netpoll_block_tx;
extern atomic_t netpoll_block_tx;

static inline void block_netpoll_tx(void)
{
preempt_disable();
BUG_ON(cpumask_test_and_set_cpu(smp_processor_id(),
netpoll_block_tx));
atomic_inc(&netpoll_block_tx);
}

static inline void unblock_netpoll_tx(void)
{
BUG_ON(!cpumask_test_and_clear_cpu(smp_processor_id(),
netpoll_block_tx));
preempt_enable();
atomic_dec(&netpoll_block_tx);
}

static inline int is_netpoll_tx_blocked(struct net_device *dev)
{
if (unlikely(dev->priv_flags & IFF_IN_NETPOLL))
return cpumask_test_cpu(smp_processor_id(), netpoll_block_tx);
return atomic_read(&netpoll_block_tx);
return 0;
}
#else
Expand Down

0 comments on commit fb4fa76

Please sign in to comment.