Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

[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
Loading
Loading
Loading
Loading
+0 −13
Original line number Diff line number Diff line
@@ -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 *first_descriptor;
	u32 command;
	unsigned long flags;

	/* Do not process Tx ring in case of Tx ring resource error */
	if (mp->tx_resource_err)
@@ -2634,8 +2633,6 @@ static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp,
		return ETH_ERROR;
	}

	spin_lock_irqsave(&mp->lock, flags);

	mp->tx_ring_skbs++;
	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,
		mp->tx_resource_err = 1;
		mp->tx_curr_desc_q = tx_first_desc;

		spin_unlock_irqrestore(&mp->lock, flags);

		return ETH_QUEUE_LAST_RESOURCE;
	}

	mp->tx_curr_desc_q = tx_next_desc;

	spin_unlock_irqrestore(&mp->lock, flags);

	return ETH_OK;
}
#else
@@ -2704,14 +2697,11 @@ static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp,
	int tx_desc_used;
	struct eth_tx_desc *current_descriptor;
	unsigned int command_status;
	unsigned long flags;

	/* Do not process Tx ring in case of Tx ring resource error */
	if (mp->tx_resource_err)
		return ETH_QUEUE_FULL;

	spin_lock_irqsave(&mp->lock, flags);

	mp->tx_ring_skbs++;
	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,
	/* Check for ring index overlap in the Tx desc ring */
	if (tx_desc_curr == tx_desc_used) {
		mp->tx_resource_err = 1;

		spin_unlock_irqrestore(&mp->lock, flags);
		return ETH_QUEUE_LAST_RESOURCE;
	}

	spin_unlock_irqrestore(&mp->lock, flags);
	return ETH_OK;
}
#endif