• H
    [NET]: Prevent transmission after dev_deactivate · d4828d85
    Herbert Xu 提交于
    The dev_deactivate function has bit-rotted since the introduction of
    lockless drivers.  In particular, the spin_unlock_wait call at the end
    has no effect on the xmit routine of lockless drivers.
    
    With a little bit of work, we can make it much more useful by providing
    the guarantee that when it returns, no more calls to the xmit routine
    of the underlying driver will be made.
    
    The idea is simple.  There are two entry points in to the xmit routine.
    The first comes from dev_queue_xmit.  That one is easily stopped by
    using synchronize_rcu.  This works because we set the qdisc to noop_qdisc
    before the synchronize_rcu call.  That in turn causes all subsequent
    packets sent to dev_queue_xmit to be dropped.  The synchronize_rcu call
    also ensures all outstanding calls leave their critical section.
    
    The other entry point is from qdisc_run.  Since we now have a bit that
    indicates whether it's running, all we have to do is to wait until the
    bit is off.
    
    I've removed the loop to wait for __LINK_STATE_SCHED to clear.  This is
    useless because netif_wake_queue can cause it to be set again.  It is
    also harmless because we've disarmed qdisc_run.
    
    I've also removed the spin_unlock_wait on xmit_lock because its only
    purpose of making sure that all outstanding xmit_lock holders have
    exited is also given by dev_watchdog_down.
    Signed-off-by: NHerbert Xu <herbert@gondor.apana.org.au>
    Signed-off-by: NDavid S. Miller <davem@davemloft.net>
    d4828d85
sch_generic.c 15.1 KB