Skip to content

Commit

Permalink
net: mvneta: fix improper tx queue usage in mvneta_tx()
Browse files Browse the repository at this point in the history
mvneta_tx() was using a static tx queue number causing crashes as
soon as a little bit of traffic was sent via the interface, because
it is normally expected that the same queue should be used as in
dev_queue_xmit().

As suggested by Ben Hutchings, let's use skb_get_queue_mapping() to
get the proper Tx queue number, and use alloc_etherdev_mqs() instead
of alloc_etherdev_mq() to create the queues.

Both my Mirabox and my OpenBlocks AX3 used to crash without this patch
and don't anymore with it. The issue appeared in 3.8 but became more
visible after the fix allowing GSO to be enabled.

Original work was done by Dmitri Epshtein and Thomas Petazzoni. I
just adapted it to take care of Ben's comments.

Signed-off-by: Willy Tarreau <w@1wt.eu>
Cc: Dmitri Epshtein <dima@marvell.com>
Cc: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Cc: Gregory CLEMENT <gregory.clement@free-electrons.com>
Cc: Ben Hutchings <bhutchings@solarflare.com>
Tested-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Willy Tarreau authored and David S. Miller committed Apr 15, 2013
1 parent 06848c1 commit ee40a11
Showing 1 changed file with 4 additions and 5 deletions.
9 changes: 4 additions & 5 deletions drivers/net/ethernet/marvell/mvneta.c
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,6 @@ static int rxq_number = 8;
static int txq_number = 8;

static int rxq_def;
static int txq_def;

#define MVNETA_DRIVER_NAME "mvneta"
#define MVNETA_DRIVER_VERSION "1.0"
Expand Down Expand Up @@ -1475,7 +1474,8 @@ static int mvneta_tx_frag_process(struct mvneta_port *pp, struct sk_buff *skb,
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 = skb_get_queue_mapping(skb);
struct mvneta_tx_queue *txq = &pp->txqs[txq_id];
struct mvneta_tx_desc *tx_desc;
struct netdev_queue *nq;
int frags = 0;
Expand All @@ -1485,7 +1485,7 @@ static int mvneta_tx(struct sk_buff *skb, struct net_device *dev)
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);
Expand Down Expand Up @@ -2689,7 +2689,7 @@ static int mvneta_probe(struct platform_device *pdev)
return -EINVAL;
}

dev = alloc_etherdev_mq(sizeof(struct mvneta_port), 8);
dev = alloc_etherdev_mqs(sizeof(struct mvneta_port), txq_number, rxq_number);
if (!dev)
return -ENOMEM;

Expand Down Expand Up @@ -2844,4 +2844,3 @@ module_param(rxq_number, int, S_IRUGO);
module_param(txq_number, int, S_IRUGO);

module_param(rxq_def, int, S_IRUGO);
module_param(txq_def, int, S_IRUGO);

0 comments on commit ee40a11

Please sign in to comment.