Commit c7cd9014 authored by Dale Farnsworth's avatar Dale Farnsworth Committed by Jeff Garzik

[PATCH] mv643xx_eth: Fix spinlock recursion bug

This patch eliminates a spinlock recursion bug introduced recently.
Since eth_port_send() is always called with the lock held, we simply
remove the locking inside the function itself.
Signed-off-by: default avatarDale Farnsworth <dale@farnsworth.org>
Signed-off-by: default avatarJeff Garzik <jgarzik@pobox.com>
parent efd51b5c
...@@ -2617,7 +2617,6 @@ static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp, ...@@ -2617,7 +2617,6 @@ static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp,
struct eth_tx_desc *current_descriptor; struct eth_tx_desc *current_descriptor;
struct eth_tx_desc *first_descriptor; struct eth_tx_desc *first_descriptor;
u32 command; u32 command;
unsigned long flags;
/* Do not process Tx ring in case of Tx ring resource error */ /* Do not process Tx ring in case of Tx ring resource error */
if (mp->tx_resource_err) if (mp->tx_resource_err)
...@@ -2634,8 +2633,6 @@ static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp, ...@@ -2634,8 +2633,6 @@ static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp,
return ETH_ERROR; return ETH_ERROR;
} }
spin_lock_irqsave(&mp->lock, flags);
mp->tx_ring_skbs++; mp->tx_ring_skbs++;
BUG_ON(mp->tx_ring_skbs > mp->tx_ring_size); BUG_ON(mp->tx_ring_skbs > mp->tx_ring_size);
...@@ -2685,15 +2682,11 @@ static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp, ...@@ -2685,15 +2682,11 @@ static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp,
mp->tx_resource_err = 1; mp->tx_resource_err = 1;
mp->tx_curr_desc_q = tx_first_desc; mp->tx_curr_desc_q = tx_first_desc;
spin_unlock_irqrestore(&mp->lock, flags);
return ETH_QUEUE_LAST_RESOURCE; return ETH_QUEUE_LAST_RESOURCE;
} }
mp->tx_curr_desc_q = tx_next_desc; mp->tx_curr_desc_q = tx_next_desc;
spin_unlock_irqrestore(&mp->lock, flags);
return ETH_OK; return ETH_OK;
} }
#else #else
...@@ -2704,14 +2697,11 @@ static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp, ...@@ -2704,14 +2697,11 @@ static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp,
int tx_desc_used; int tx_desc_used;
struct eth_tx_desc *current_descriptor; struct eth_tx_desc *current_descriptor;
unsigned int command_status; unsigned int command_status;
unsigned long flags;
/* Do not process Tx ring in case of Tx ring resource error */ /* Do not process Tx ring in case of Tx ring resource error */
if (mp->tx_resource_err) if (mp->tx_resource_err)
return ETH_QUEUE_FULL; return ETH_QUEUE_FULL;
spin_lock_irqsave(&mp->lock, flags);
mp->tx_ring_skbs++; mp->tx_ring_skbs++;
BUG_ON(mp->tx_ring_skbs > mp->tx_ring_size); BUG_ON(mp->tx_ring_skbs > mp->tx_ring_size);
...@@ -2742,12 +2732,9 @@ static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp, ...@@ -2742,12 +2732,9 @@ static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp,
/* Check for ring index overlap in the Tx desc ring */ /* Check for ring index overlap in the Tx desc ring */
if (tx_desc_curr == tx_desc_used) { if (tx_desc_curr == tx_desc_used) {
mp->tx_resource_err = 1; mp->tx_resource_err = 1;
spin_unlock_irqrestore(&mp->lock, flags);
return ETH_QUEUE_LAST_RESOURCE; return ETH_QUEUE_LAST_RESOURCE;
} }
spin_unlock_irqrestore(&mp->lock, flags);
return ETH_OK; return ETH_OK;
} }
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment