Message ID | 20131125234058.GA12566@electric-eye.fr.zoreil.com |
---|---|
State | Accepted, archived |
Delegated to: | David Miller |
Headers | show |
From: Francois Romieu <romieu@fr.zoreil.com> Date: Tue, 26 Nov 2013 00:40:58 +0100 > 2fdac010bdcf10a30711b6924612dfc40daf19b8 ("via-velocity.c: update napi > implementation") overlooked an irq disabling spinlock when the Rx part > of the NAPI poll handler was converted from netif_rx to netif_receive_skb. > > NAPI Rx processing can be taken out of the locked section with a pair of > napi_{disable / enable} since it only races with the MTU change function. > > An heavier rework of the NAPI locking would be able to perform NAPI Tx > before Rx where I simply removed one of velocity_tx_srv calls. > > References: https://bugzilla.redhat.com/show_bug.cgi?id=1022733 > Fixes: 2fdac010bdcf (via-velocity.c: update napi implementation) > Signed-off-by: Francois Romieu <romieu@fr.zoreil.com> > Tested-by: Alex A. Schmidt <aaschmidt1@gmail.com> Applied and queued up for -stable, thanks. Just a note that we usually recommend to people to do TX processing before RX in NAPI, because the TX work can liberate packets and make them available to RX reclaim. But that would be quite hard with the approach you took to fix this bug simply. -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/net/ethernet/via/via-velocity.c b/drivers/net/ethernet/via/via-velocity.c index d022bf9..ad61d26 100644 --- a/drivers/net/ethernet/via/via-velocity.c +++ b/drivers/net/ethernet/via/via-velocity.c @@ -2172,16 +2172,13 @@ static int velocity_poll(struct napi_struct *napi, int budget) unsigned int rx_done; unsigned long flags; - spin_lock_irqsave(&vptr->lock, flags); /* * Do rx and tx twice for performance (taken from the VIA * out-of-tree driver). */ - rx_done = velocity_rx_srv(vptr, budget / 2); - velocity_tx_srv(vptr); - rx_done += velocity_rx_srv(vptr, budget - rx_done); + rx_done = velocity_rx_srv(vptr, budget); + spin_lock_irqsave(&vptr->lock, flags); velocity_tx_srv(vptr); - /* If budget not fully consumed, exit the polling mode */ if (rx_done < budget) { napi_complete(napi); @@ -2342,6 +2339,8 @@ static int velocity_change_mtu(struct net_device *dev, int new_mtu) if (ret < 0) goto out_free_tmp_vptr_1; + napi_disable(&vptr->napi); + spin_lock_irqsave(&vptr->lock, flags); netif_stop_queue(dev); @@ -2362,6 +2361,8 @@ static int velocity_change_mtu(struct net_device *dev, int new_mtu) velocity_give_many_rx_descs(vptr); + napi_enable(&vptr->napi); + mac_enable_int(vptr->mac_regs); netif_start_queue(dev);