diff options
| author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-01-24 10:42:31 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-01-24 10:42:31 -0500 |
| commit | 6e35c24b9f5b2f68732910d2138bc0eb1b477ab1 (patch) | |
| tree | 350c60fc080ec1f6dee8c1eb4c37aee7ee0cfce9 /drivers | |
| parent | d0f29485686d9d1c4f31240953a742d5dd4fdb72 (diff) | |
| parent | e47b207a5bcb73bb097f94d9fe364f50737b0eb2 (diff) | |
Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6
* 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6:
mv643xx_eth: Fix race condition in mv643xx_eth_free_tx_descs
s2io bogus memset
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/net/mv643xx_eth.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index c41ae4286eea..b3bf86422734 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c | |||
| @@ -314,6 +314,13 @@ int mv643xx_eth_free_tx_descs(struct net_device *dev, int force) | |||
| 314 | 314 | ||
| 315 | while (mp->tx_desc_count > 0) { | 315 | while (mp->tx_desc_count > 0) { |
| 316 | spin_lock_irqsave(&mp->lock, flags); | 316 | spin_lock_irqsave(&mp->lock, flags); |
| 317 | |||
| 318 | /* tx_desc_count might have changed before acquiring the lock */ | ||
| 319 | if (mp->tx_desc_count <= 0) { | ||
| 320 | spin_unlock_irqrestore(&mp->lock, flags); | ||
| 321 | return released; | ||
| 322 | } | ||
| 323 | |||
| 317 | tx_index = mp->tx_used_desc_q; | 324 | tx_index = mp->tx_used_desc_q; |
| 318 | desc = &mp->p_tx_desc_area[tx_index]; | 325 | desc = &mp->p_tx_desc_area[tx_index]; |
| 319 | cmd_sts = desc->cmd_sts; | 326 | cmd_sts = desc->cmd_sts; |
| @@ -332,13 +339,13 @@ int mv643xx_eth_free_tx_descs(struct net_device *dev, int force) | |||
| 332 | if (skb) | 339 | if (skb) |
| 333 | mp->tx_skb[tx_index] = NULL; | 340 | mp->tx_skb[tx_index] = NULL; |
| 334 | 341 | ||
| 335 | spin_unlock_irqrestore(&mp->lock, flags); | ||
| 336 | |||
| 337 | if (cmd_sts & ETH_ERROR_SUMMARY) { | 342 | if (cmd_sts & ETH_ERROR_SUMMARY) { |
| 338 | printk("%s: Error in TX\n", dev->name); | 343 | printk("%s: Error in TX\n", dev->name); |
| 339 | mp->stats.tx_errors++; | 344 | mp->stats.tx_errors++; |
| 340 | } | 345 | } |
| 341 | 346 | ||
| 347 | spin_unlock_irqrestore(&mp->lock, flags); | ||
| 348 | |||
| 342 | if (cmd_sts & ETH_TX_FIRST_DESC) | 349 | if (cmd_sts & ETH_TX_FIRST_DESC) |
| 343 | dma_unmap_single(NULL, addr, count, DMA_TO_DEVICE); | 350 | dma_unmap_single(NULL, addr, count, DMA_TO_DEVICE); |
| 344 | else | 351 | else |
