From patchwork Sun Jul 19 11:00:53 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Guinot X-Patchwork-Id: 6821761 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 65FEDC05AC for ; Sun, 19 Jul 2015 11:03:51 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 552FC204D9 for ; Sun, 19 Jul 2015 11:03:50 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 6775020497 for ; Sun, 19 Jul 2015 11:03:49 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1ZGmLU-00029X-D8; Sun, 19 Jul 2015 11:01:24 +0000 Received: from vm1.sequanux.org ([188.165.36.56]) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1ZGmLQ-00026q-7h for linux-arm-kernel@lists.infradead.org; Sun, 19 Jul 2015 11:01:21 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by vm1.sequanux.org (Postfix) with ESMTP id 6FA6E108206; Sun, 19 Jul 2015 13:00:56 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at vm1.sequanux.org Received: from vm1.sequanux.org ([127.0.0.1]) by localhost (vm1.sequanux.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id zJzm22iJD4IR; Sun, 19 Jul 2015 13:00:54 +0200 (CEST) Received: from localhost (unknown [37.164.102.250]) by vm1.sequanux.org (Postfix) with ESMTPSA id 327E41081C3; Sun, 19 Jul 2015 13:00:54 +0200 (CEST) From: Simon Guinot To: "David S. Miller" , Thomas Petazzoni Subject: [PATCH v2] net: mvneta: fix refilling for Rx DMA buffers Date: Sun, 19 Jul 2015 13:00:53 +0200 Message-Id: <1437303653-2236-1-git-send-email-simon.guinot@sequanux.org> X-Mailer: git-send-email 2.1.4 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150719_040120_590625_A081EE18 X-CRM114-Status: GOOD ( 12.35 ) X-Spam-Score: -3.1 (---) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Andrew Lunn , Jason Cooper , netdev@vger.kernel.org, Vincent Donnefort , stable@vger.kernel.org, Gregory Clement , Yoann Sculo , linux-arm-kernel@lists.infradead.org, Sebastian Hesselbarth MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-5.4 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP With the actual code, if a memory allocation error happens while refilling a Rx descriptor, then the original Rx buffer is both passed to the networking stack (in a SKB) and let in the Rx ring. This leads to various kernel oops and crashes. As a fix, this patch moves Rx descriptor refilling ahead of building SKB with the associated Rx buffer. In case of a memory allocation failure, data is dropped and the original DMA buffer is put back into the Rx ring. Signed-off-by: Simon Guinot Fixes: c5aff18204da ("net: mvneta: driver for Marvell Armada 370/XP network unit") Cc: # v3.8+ Tested-by: Yoann Sculo --- drivers/net/ethernet/marvell/mvneta.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) Changes for v2: - Update commit message. diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c index ce5f7f9cff06..ac3da11e63a0 100644 --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c @@ -1455,7 +1455,7 @@ static int mvneta_rx(struct mvneta_port *pp, int rx_todo, struct mvneta_rx_queue *rxq) { struct net_device *dev = pp->dev; - int rx_done, rx_filled; + int rx_done; u32 rcvd_pkts = 0; u32 rcvd_bytes = 0; @@ -1466,7 +1466,6 @@ static int mvneta_rx(struct mvneta_port *pp, int rx_todo, rx_todo = rx_done; rx_done = 0; - rx_filled = 0; /* Fairness NAPI loop */ while (rx_done < rx_todo) { @@ -1477,7 +1476,6 @@ static int mvneta_rx(struct mvneta_port *pp, int rx_todo, int rx_bytes, err; rx_done++; - rx_filled++; rx_status = rx_desc->status; rx_bytes = rx_desc->data_size - (ETH_FCS_LEN + MVNETA_MH_SIZE); data = (unsigned char *)rx_desc->buf_cookie; @@ -1517,6 +1515,14 @@ static int mvneta_rx(struct mvneta_port *pp, int rx_todo, continue; } + /* Refill processing */ + err = mvneta_rx_refill(pp, rx_desc); + if (err) { + netdev_err(dev, "Linux processing - Can't refill\n"); + rxq->missed++; + goto err_drop_frame; + } + skb = build_skb(data, pp->frag_size > PAGE_SIZE ? 0 : pp->frag_size); if (!skb) goto err_drop_frame; @@ -1536,14 +1542,6 @@ static int mvneta_rx(struct mvneta_port *pp, int rx_todo, mvneta_rx_csum(pp, rx_status, skb); napi_gro_receive(&pp->napi, skb); - - /* Refill processing */ - err = mvneta_rx_refill(pp, rx_desc); - if (err) { - netdev_err(dev, "Linux processing - Can't refill\n"); - rxq->missed++; - rx_filled--; - } } if (rcvd_pkts) { @@ -1556,7 +1554,7 @@ static int mvneta_rx(struct mvneta_port *pp, int rx_todo, } /* Update rxq management counters */ - mvneta_rxq_desc_num_update(pp, rxq, rx_done, rx_filled); + mvneta_rxq_desc_num_update(pp, rxq, rx_done, rx_done); return rx_done; }