From patchwork Mon Apr 15 06:35:37 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Willy Tarreau X-Patchwork-Id: 236500 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 5A03F2C007A for ; Mon, 15 Apr 2013 16:40:51 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752521Ab3DOGkr (ORCPT ); Mon, 15 Apr 2013 02:40:47 -0400 Received: from 1wt.eu ([62.212.114.60]:33031 "EHLO 1wt.eu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752480Ab3DOGkq (ORCPT ); Mon, 15 Apr 2013 02:40:46 -0400 Received: (from willy@localhost) by mail.home.local (8.14.4/8.14.4/Submit) id r3F6Zb7l026525; Mon, 15 Apr 2013 08:35:37 +0200 Date: Mon, 15 Apr 2013 08:35:37 +0200 From: Willy Tarreau To: "David S. Miller" Cc: netdev@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Dmitri Epshtein , Thomas Petazzoni , Gregory CLEMENT , Ben Hutchings , Jason Cooper , Andrew Lunn , Lior Amsalem , Maen Suleiman Subject: net: mvneta: fix improper tx queue usage in mvneta_tx() Message-ID: <20130415063537.GA26507@1wt.eu> Mime-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.4.2.3i Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From 4f2069c92a27790e6071dc2a80f92c166e0b0ca4 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Thu, 11 Apr 2013 23:00:37 +0200 Subject: net: mvneta: fix improper tx queue usage in mvneta_tx() 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 Cc: Dmitri Epshtein Cc: Thomas Petazzoni Cc: Gregory CLEMENT Cc: Ben Hutchings Tested-by: Gregory CLEMENT --- drivers/net/ethernet/marvell/mvneta.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c index 1e628ce..a47a097 100644 --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c @@ -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" @@ -1475,7 +1474,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 = 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; @@ -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); @@ -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; @@ -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);