Skip to content

Commit

Permalink
[NET]: Use local_irq_{save,restore}() in napi_complete().
Browse files Browse the repository at this point in the history
Based upon a lockdep report.

Since ->poll() can be invoked from netpoll with interrupts
disabled, we must not unconditionally enable interrupts
in napi_complete().

Instead we must use local_irq_{save,restore}().

Noticed by Peter Zijlstra:

<irqs disabled>

  netpoll_poll()
    poll_napi()
      spin_trylock(&napi->poll_lock)
      poll_one_napi()
        napi->poll() := sky2_poll()
          napi_complete()
            local_irq_disable()
            local_irq_enable() <--- *BUG*

  <irq>
    irq_exit()
      do_softirq()
        net_rx_action()
          spin_lock(&napi->poll_lock) <--- Deadlock!

Because we still hold the lock....

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Mar 28, 2008
1 parent 8eeee8b commit 50fd440
Showing 1 changed file with 4 additions and 2 deletions.
6 changes: 4 additions & 2 deletions include/linux/netdevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -383,9 +383,11 @@ static inline void __napi_complete(struct napi_struct *n)

static inline void napi_complete(struct napi_struct *n)
{
local_irq_disable();
unsigned long flags;

local_irq_save(flags);
__napi_complete(n);
local_irq_enable();
local_irq_restore(flags);
}

/**
Expand Down

0 comments on commit 50fd440

Please sign in to comment.