[12/22] Cyclades PC300 driver: locking improvements

From: Andrea Shepard
Date: Sun Jan 29 2012 - 21:54:18 EST


Avoid redundant do/while in CPC_LOCK/CPC_UNLOCK macros; hold the lock during
DMA buffer writes in cpc_queue_xmit() to avert a potential race condition.

Signed-off-by: Andrea Shepard <andrea@xxxxxxxxxxxxxxxxxxx>

diff --git a/drivers/net/wan/pc300_drv.c b/drivers/net/wan/pc300_drv.c
index 36cf3b0..14500eb 100644
--- a/drivers/net/wan/pc300_drv.c
+++ b/drivers/net/wan/pc300_drv.c
@@ -243,15 +243,15 @@ static char rcsid[] =

#include "pc300.h"

-#define CPC_LOCK(card,flags) \
- do { \
- spin_lock_irqsave(&card->card_lock, flags); \
- } while (0)
+#define CPC_LOCK(card, flags) \
+ { \
+ spin_lock_irqsave(&((card)->card_lock), (flags)); \
+ }

-#define CPC_UNLOCK(card,flags) \
- do { \
- spin_unlock_irqrestore(&card->card_lock, flags); \
- } while (0)
+#define CPC_UNLOCK(card, flags) \
+ { \
+ spin_unlock_irqrestore(&((card)->card_lock), (flags)); \
+ }

#undef PC300_DEBUG_PCI
#undef PC300_DEBUG_INTR
@@ -1971,8 +1971,10 @@ static int cpc_queue_xmit(struct sk_buff *skb, struct net_device *dev)
return 0;
}

+ CPC_LOCK(card, flags);
/* Write buffer to DMA buffers */
if (dma_buf_write(card, ch, (u8 *) skb->data, skb->len) != 0) {
+ CPC_UNLOCK(card, flags);
printk(KERN_ERR "%s: write error. Dropping TX packet.\n",
dev->name);
#ifdef PC300_DEBUG_QUEUE
@@ -1985,7 +1987,8 @@ static int cpc_queue_xmit(struct sk_buff *skb, struct net_device *dev)
stats->tx_errors++;
stats->tx_dropped++;
return 0;
- }
+ } else
+ CPC_UNLOCK(card, flags);
#ifdef PC300_DEBUG_TX
printk("%s T:", dev->name);
for (i = 0; i < skb->len; i++)
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/