lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Sun, 29 Jan 2012 18:57:24 -0800 From: Andrea Shepard <andrea@...sephoneslair.org> To: linux-kernel@...r.kernel.org, netdev@...r.kernel.org Cc: khc@...waw.pl, davem@...emloft.net, mmarek@...e.cz, jkosina@...e.cz, joe@...ches.com, justinmattock@...il.com, gregkh@...e.de, alan@...ux.intel.com, jdmason@...zu.us Subject: [17/22] Cyclades PC300 driver: queue stop/start fix Change cpc_queue_xmit() to stop and restart the queue while it does things to the DMA buffers and registers. The Cyclades 4.1.0 release doesn't seem to function reliably without this; I suspect it was a race condition bug that was always present. Signed-off-by: Andrea Shepard <andrea@...sephoneslair.org> diff --git a/drivers/net/wan/pc300_drv.c b/drivers/net/wan/pc300_drv.c index c44c26a..4d81507 100644 --- a/drivers/net/wan/pc300_drv.c +++ b/drivers/net/wan/pc300_drv.c @@ -2055,20 +2055,15 @@ static int cpc_queue_xmit(struct sk_buff *skb, struct net_device *dev) if (d->trace_on) { cpc_trace(dev, skb, 'T'); } - dev->trans_start = jiffies; /* Start transmission */ CPC_LOCK(card, flags); - /* verify if it has more than one free descriptor */ - if (card->chan[ch].nfree_tx_bd <= 1) { #ifdef PC300_DEBUG_QUEUE - printk(KERN_DEBUG - "%s: stopping queue for transmission\n", - dev->name); + printk(KERN_DEBUG + "%s: stopping queue for transmission\n", + dev->name); #endif - /* don't have so stop the queue */ - netif_stop_queue(dev); - } + netif_stop_queue(dev); cpc_writel(card->hw.scabase + DTX_REG(EDAL, ch), TX_BD_ADDR(ch, chan->tx_next_bd)); cpc_writeb(card->hw.scabase + M_REG(CMD, ch), CMD_TX_ENA); @@ -2078,12 +2073,22 @@ static int cpc_queue_xmit(struct sk_buff *skb, struct net_device *dev) cpc_readb(card->hw.falcbase + card->hw.cpld_reg2) | (CPLD_REG2_FALC_LED1 << (2 * ch))); } + /* verify if it has more than one free descriptor */ + if (card->chan[ch].nfree_tx_bd > 1) { +#ifdef PC300_DEBUG_QUEUE + printk(KERN_DEBUG + "%s: restarting queue\n", + dev->name); +#endif + netif_wake_queue(dev); + } CPC_UNLOCK(card, flags); dev_kfree_skb(skb); #ifdef PC300_DEBUG_TX - printk(KERN_DEBUG "%s: cpc_queue_xmit returning normally\n", - dev->name); + printk(KERN_DEBUG + "%s: cpc_queue_xmit returning normally\n", + dev->name); #endif return 0; @@ -2221,7 +2226,9 @@ static void sca_tx_intr(pc300dev_t *dev) #ifdef PC300_DEBUG_QUEUE printk(KERN_DEBUG "Waking queue on TX interrupt\n"); #endif - netif_wake_queue(dev->netdev); + if (chan->nfree_tx_bd > 1 && + netif_queue_stopped(dev->netdev)) + netif_wake_queue(dev->netdev); #ifdef CONFIG_PC300_MLPPP } #endif -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@...r.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists