From: Simon Guinot <simon.guinot@sequanux.org>
To: "David S. Miller" <davem@davemloft.net>,
Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Cc: Jason Cooper <jason@lakedaemon.net>, Andrew Lunn <andrew@lunn.ch>,
Gregory Clement <gregory.clement@free-electrons.com>,
Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>,
netdev@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
Vincent Donnefort <vdonnefort@gmail.com>,
Yoann Sculo <yoann@sculo.fr>, <stable@vger.kernel.org>
Subject: [PATCH v2] net: mvneta: fix refilling for Rx DMA buffers
Date: Sun, 19 Jul 2015 13:00:53 +0200 [thread overview]
Message-ID: <1437303653-2236-1-git-send-email-simon.guinot@sequanux.org> (raw)
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 <simon.guinot@sequanux.org>
Fixes: c5aff18204da ("net: mvneta: driver for Marvell Armada 370/XP network unit")
Cc: <stable@vger.kernel.org> # v3.8+
Tested-by: Yoann Sculo <yoann@sculo.fr>
---
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;
}
--
2.1.4
next reply other threads:[~2015-07-19 11:00 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-07-19 11:00 Simon Guinot [this message]
2015-07-21 7:30 ` [PATCH v2] net: mvneta: fix refilling for Rx DMA buffers David Miller
[not found] ` <CAA-51jPPDHfE1uT2NuJ53wWTvEgh7DcW0K0-xZgQdjAD2CC04w@mail.gmail.com>
2015-09-14 22:13 ` Simon Guinot
2015-09-14 22:16 ` Oren Laskin
2015-09-14 22:46 ` Simon Guinot
2015-09-15 9:09 ` Vincent Donnefort
2015-09-15 20:36 ` Simon Guinot
2015-09-15 20:41 ` [PATCH] net: mvneta: fix DMA buffer unmapping in mvneta_rx() Simon Guinot
2015-09-15 21:19 ` Oren Laskin
2015-09-15 21:55 ` David Miller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1437303653-2236-1-git-send-email-simon.guinot@sequanux.org \
--to=simon.guinot@sequanux.org \
--cc=andrew@lunn.ch \
--cc=davem@davemloft.net \
--cc=gregory.clement@free-electrons.com \
--cc=jason@lakedaemon.net \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=netdev@vger.kernel.org \
--cc=sebastian.hesselbarth@gmail.com \
--cc=stable@vger.kernel.org \
--cc=thomas.petazzoni@free-electrons.com \
--cc=vdonnefort@gmail.com \
--cc=yoann@sculo.fr \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).