|
|
@@ -1,71 +0,0 @@
|
|
|
-From: Dmitri Epshtein <[email protected]>
|
|
|
-
|
|
|
-In order for the driver to behave properly in a SMP context, the same
|
|
|
-transmit queue should be used by the kernel in dev_queue_xmit() and in
|
|
|
-the driver's mvneta_tx() function. To achieve that, the driver now
|
|
|
-implements the ->ndo_select_txq() operation.
|
|
|
-
|
|
|
-For now, it always returns the same transmit queue, txq_def, until the
|
|
|
-driver is expanded to properly take advantage of the multiqueue
|
|
|
-capabilities of the hardware.
|
|
|
-
|
|
|
-Without this patch, the network driver crashes the kernel almost
|
|
|
-immediately on Armada XP platforms, if the network load is at least a
|
|
|
-little bit parallel (i.e several threads).
|
|
|
-
|
|
|
-[Thomas Petazzoni: reword commit message]
|
|
|
-Signed-off-by: Dmitri Epshtein <[email protected]>
|
|
|
-Signed-off-by: Thomas Petazzoni <[email protected]>
|
|
|
----
|
|
|
-This is 3.8-rc material.
|
|
|
----
|
|
|
- drivers/net/ethernet/marvell/mvneta.c | 17 +++++++++++++++--
|
|
|
- 1 file changed, 15 insertions(+), 2 deletions(-)
|
|
|
-
|
|
|
---- a/drivers/net/ethernet/marvell/mvneta.c
|
|
|
-+++ b/drivers/net/ethernet/marvell/mvneta.c
|
|
|
-@@ -1310,6 +1310,17 @@ static u32 mvneta_skb_tx_csum(struct mvn
|
|
|
- return MVNETA_TX_L4_CSUM_NOT;
|
|
|
- }
|
|
|
-
|
|
|
-+static u16 mvneta_tx_policy(struct mvneta_port *pp, struct sk_buff *skb)
|
|
|
-+{
|
|
|
-+ return (u16)txq_def;
|
|
|
-+}
|
|
|
-+
|
|
|
-+static u16 mvneta_select_txq(struct net_device *dev, struct sk_buff *skb)
|
|
|
-+{
|
|
|
-+ struct mvneta_port *pp = netdev_priv(dev);
|
|
|
-+ return mvneta_tx_policy(pp, skb);
|
|
|
-+}
|
|
|
-+
|
|
|
- /* Returns rx queue pointer (find last set bit) according to causeRxTx
|
|
|
- * value
|
|
|
- */
|
|
|
-@@ -1476,7 +1487,8 @@ error:
|
|
|
- static int mvneta_tx(struct sk_buff *skb, struct net_device *dev)
|
|
|
- {
|
|
|
- struct mvneta_port *pp = netdev_priv(dev);
|
|
|
-- struct mvneta_tx_queue *txq = &pp->txqs[txq_def];
|
|
|
-+ u16 txq_id = mvneta_tx_policy(pp, skb);
|
|
|
-+ struct mvneta_tx_queue *txq = &pp->txqs[txq_id];
|
|
|
- struct mvneta_tx_desc *tx_desc;
|
|
|
- struct netdev_queue *nq;
|
|
|
- int frags = 0;
|
|
|
-@@ -1486,7 +1498,7 @@ static int mvneta_tx(struct sk_buff *skb
|
|
|
- goto out;
|
|
|
-
|
|
|
- frags = skb_shinfo(skb)->nr_frags + 1;
|
|
|
-- nq = netdev_get_tx_queue(dev, txq_def);
|
|
|
-+ nq = netdev_get_tx_queue(dev, txq_id);
|
|
|
-
|
|
|
- /* Get a descriptor for the first part of the packet */
|
|
|
- tx_desc = mvneta_txq_next_desc_get(txq);
|
|
|
-@@ -2550,6 +2562,7 @@ static const struct net_device_ops mvnet
|
|
|
- .ndo_change_mtu = mvneta_change_mtu,
|
|
|
- .ndo_tx_timeout = mvneta_tx_timeout,
|
|
|
- .ndo_get_stats64 = mvneta_get_stats64,
|
|
|
-+ .ndo_select_queue = mvneta_select_txq,
|
|
|
- };
|
|
|
-
|
|
|
- const struct ethtool_ops mvneta_eth_tool_ops = {
|