From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
To: netdev@vger.kernel.org
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Subject: [PATCH 03/10] ftgmac100: Use a scratch buffer for failed RX allocations
Date: Thu, 6 Apr 2017 11:02:45 +1000 [thread overview]
Message-ID: <20170406010252.29208-4-benh@kernel.crashing.org> (raw)
In-Reply-To: <20170406010252.29208-1-benh@kernel.crashing.org>
We can occasionally fail to allocate new RX buffers at
runtime or when starting the driver. At the moment the
latter just fails to open which is fine but the former
leaves stale DMA pointers in the ring.
Instead, use a scratch page and have all RX ring descriptors
point to it by default unless a proper buffer can be allocated.
It will help later on when re-initializing the whole ring
at runtime on link changes since there is no clean failure
path there unlike open().
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
drivers/net/ethernet/faraday/ftgmac100.c | 42 +++++++++++++++++++++++++++++---
1 file changed, 38 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/faraday/ftgmac100.c b/drivers/net/ethernet/faraday/ftgmac100.c
index ee73a57..a03cc03 100644
--- a/drivers/net/ethernet/faraday/ftgmac100.c
+++ b/drivers/net/ethernet/faraday/ftgmac100.c
@@ -69,6 +69,10 @@ struct ftgmac100 {
u32 txdes0_edotr_mask;
spinlock_t tx_lock;
+ /* Scratch page to use when rx skb alloc fails */
+ void *rx_scratch;
+ dma_addr_t rx_scratch_dma;
+
/* Component structures */
struct net_device *netdev;
struct device *dev;
@@ -402,12 +406,14 @@ static int ftgmac100_alloc_rx_page(struct ftgmac100 *priv,
struct net_device *netdev = priv->netdev;
struct page *page;
dma_addr_t map;
+ int err;
page = alloc_page(gfp);
if (!page) {
if (net_ratelimit())
netdev_err(netdev, "failed to allocate rx page\n");
- return -ENOMEM;
+ err = -ENOMEM;
+ map = priv->rx_scratch_dma;
}
map = dma_map_page(priv->dev, page, 0, RX_BUF_SIZE, DMA_FROM_DEVICE);
@@ -415,7 +421,9 @@ static int ftgmac100_alloc_rx_page(struct ftgmac100 *priv,
if (net_ratelimit())
netdev_err(netdev, "failed to map rx page\n");
__free_page(page);
- return -ENOMEM;
+ err = -ENOMEM;
+ map = priv->rx_scratch_dma;
+ page = NULL;
}
ftgmac100_rxdes_set_page(priv, rxdes, page);
@@ -549,6 +557,16 @@ static bool ftgmac100_rx_packet(struct ftgmac100 *priv, int *processed)
return true;
}
+ /* If the packet had no buffer (failed to allocate earlier)
+ * then try to allocate one and skip
+ */
+ page = ftgmac100_rxdes_get_page(priv, rxdes);
+ if (!page) {
+ ftgmac100_alloc_rx_page(priv, rxdes, GFP_ATOMIC);
+ ftgmac100_rx_pointer_advance(priv);
+ return true;
+ }
+
/* start processing */
skb = netdev_alloc_skb_ip_align(netdev, 128);
if (unlikely(!skb)) {
@@ -852,6 +870,11 @@ static void ftgmac100_free_rings(struct ftgmac100 *priv)
if (priv->descs)
dma_free_coherent(priv->dev, sizeof(struct ftgmac100_descs),
priv->descs, priv->descs_dma_addr);
+
+ /* Free scratch packet buffer */
+ if (priv->rx_scratch)
+ dma_free_coherent(priv->dev, RX_BUF_SIZE,
+ priv->rx_scratch, priv->rx_scratch_dma);
}
static int ftgmac100_alloc_rings(struct ftgmac100 *priv)
@@ -863,6 +886,14 @@ static int ftgmac100_alloc_rings(struct ftgmac100 *priv)
if (!priv->descs)
return -ENOMEM;
+ /* Allocate scratch packet buffer */
+ priv->rx_scratch = dma_alloc_coherent(priv->dev,
+ RX_BUF_SIZE,
+ &priv->rx_scratch_dma,
+ GFP_KERNEL);
+ if (!priv->rx_scratch)
+ return -ENOMEM;
+
return 0;
}
@@ -871,8 +902,11 @@ static void ftgmac100_init_rings(struct ftgmac100 *priv)
int i;
/* Initialize RX ring */
- for (i = 0; i < RX_QUEUE_ENTRIES; i++)
- priv->descs->rxdes[i].rxdes0 = 0;
+ for (i = 0; i < RX_QUEUE_ENTRIES; i++) {
+ struct ftgmac100_rxdes *rxdes = &priv->descs->rxdes[i];
+ ftgmac100_rxdes_set_dma_addr(rxdes, priv->rx_scratch_dma);
+ rxdes->rxdes0 = 0;
+ }
ftgmac100_rxdes_set_end_of_ring(priv, &priv->descs->rxdes[i - 1]);
/* Initialize TX ring */
--
2.9.3
next prev parent reply other threads:[~2017-04-06 1:03 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-04-06 1:02 [PATCH 00/10] ftgmac: Rework batch 2 - RX path Benjamin Herrenschmidt
2017-04-06 1:02 ` [PATCH 01/10] ftgmac100: Move ftgmac100_alloc_rx_page() before its users Benjamin Herrenschmidt
2017-04-06 1:02 ` [PATCH 02/10] ftgmac100: Drop support for fragmented receive Benjamin Herrenschmidt
2017-04-06 1:02 ` Benjamin Herrenschmidt [this message]
2017-04-06 1:02 ` [PATCH 04/10] ftgmac100: Cleanup rx checksum handling Benjamin Herrenschmidt
2017-04-06 1:02 ` [PATCH 05/10] ftgmac100: Simplify rx packets error handling Benjamin Herrenschmidt
2017-04-06 1:02 ` [PATCH 06/10] ftgmac100: Simplify rx pointer handling in the rx path Benjamin Herrenschmidt
2017-04-06 1:02 ` [PATCH 07/10] ftgmac100: Directly receive into sk_buffs Benjamin Herrenschmidt
2017-04-06 1:02 ` [PATCH 08/10] ftgmac100: Add missing barrier in ftgmac100_rx_packet() Benjamin Herrenschmidt
2017-04-06 1:02 ` [PATCH 09/10] ftgmac100: Remove rx descriptor accessors Benjamin Herrenschmidt
2017-04-06 1:02 ` [PATCH 10/10] ftgmac100: Work around HW bug in runt frame detection Benjamin Herrenschmidt
2017-04-06 22:40 ` [PATCH 00/10] ftgmac: Rework batch 2 - RX path 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=20170406010252.29208-4-benh@kernel.crashing.org \
--to=benh@kernel.crashing.org \
--cc=netdev@vger.kernel.org \
/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).