• Jeff Garzik's avatar
    [netdrvr tg3] fix NAPI deadlock · 70a8c581
    Jeff Garzik authored
    * do not hold driver spinlock during RX processing in tg3_poll
      (this is the deadlock fix)
    * create netif_poll_{en,dis}able to synchronize against dev->poll()
    * create __netif_rx_complete to avoid a third irq-save in tg3_poll
    * create tg3_netif_{start,stop} as driver-specific helper functions
      which disable and enable NAPI polling and TX queueing.  Note that
      the TX queueing enable/disable is purely advisory, and is not
      intended to prevent any races.
    * remove tg3_halt call from tg3_set_power_state, as all callers
      have already called tg3_halt, making it redundant.  Removing this
      function call also eliminates some locking complications.
    * use new helper __netif_rx_complete in tg3_poll
    * create tg3_reset_task, as a function that runs in process context
      which resets the NIC.  This is needed because tg3_netif_stop()
      calls schedule() in the process of disabling dev->poll.
    * schedule tg3_reset_task from tg3_tx_timeout
    * schedule tg3_reset_task from tg3_timer
    * wrap several tg3_halt...tg3_init_hw sequences with
      tg3_netif_stop...tg3_netif_start.  In addition to synchronizing
      with dev->poll, this additionally fixes bugs where we were not
      calling netif_wake_queue, when we should have been.
    * move netif_start_queue call to very bottom of tg3_open
    * add missing tg3_netif_{start,stop} to tg3_{suspend,resume},
      further fixing obvious bugs.
    70a8c581
tg3.c 198 KB