From patchwork Mon Jan 7 16:27:54 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Petazzoni X-Patchwork-Id: 1941601 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork2.kernel.org (Postfix) with ESMTP id F2769DF230 for ; Mon, 7 Jan 2013 16:30:49 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1TsFYd-0002Un-AY; Mon, 07 Jan 2013 16:28:15 +0000 Received: from mail.free-electrons.com ([94.23.32.191]) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1TsFYW-0002Sc-S7 for linux-arm-kernel@lists.infradead.org; Mon, 07 Jan 2013 16:28:10 +0000 Received: by mail.free-electrons.com (Postfix, from userid 106) id 442BD161; Mon, 7 Jan 2013 17:28:08 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on mail.free-electrons.com X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED,SHORTCIRCUIT shortcircuit=ham autolearn=disabled version=3.3.2 Received: from localhost (col31-4-88-188-83-94.fbx.proxad.net [88.188.83.94]) by mail.free-electrons.com (Postfix) with ESMTPSA id B887311B; Mon, 7 Jan 2013 17:28:07 +0100 (CET) From: Thomas Petazzoni To: "David S. Miller" Subject: [PATCH 3.8-rc] net: mvneta: fix driver operation in SMP context Date: Mon, 7 Jan 2013 17:27:54 +0100 Message-Id: <1357576074-24245-1-git-send-email-thomas.petazzoni@free-electrons.com> X-Mailer: git-send-email 1.7.9.5 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130107_112810_150854_2B8A2ED9 X-CRM114-Status: GOOD ( 16.11 ) X-Spam-Score: -2.6 (--) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-2.6 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record -0.7 RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: Lior Amsalem , Andrew Lunn , Jason Cooper , netdev@vger.kernel.org, Maen Suleiman , Gregory Clement , Dmitri Epshtein , linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org From: Dmitri Epshtein 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 Signed-off-by: Thomas Petazzoni Acked-by: Jason Cooper Tested-by: Gregory CLEMENT Acked-by: Gregory CLEMENT --- This is 3.8-rc material. --- drivers/net/ethernet/marvell/mvneta.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c index b6025c3..af2c421 100644 --- 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 mvneta_port *pp, struct sk_buff *skb) 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, 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); @@ -2550,6 +2562,7 @@ static const struct net_device_ops mvneta_netdev_ops = { .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 = {