From 51d5712982694f1cf1b033c232ba9688ee296188 Mon Sep 17 00:00:00 2001 From: Joachim Foerster Date: Wed, 29 Jun 2022 11:56:22 +0200 Subject: [PATCH] modules/mqnic: Introduce proper error path on failing to allocate RX buffers This basically allows the "refilling" of RX buffers to fail. A fail to allocate RX buffers can occur on bringing a network device up or when changing the number of RX channels at run-time through `ethtool -L rx `. Signed-off-by: Joachim Foerster --- modules/mqnic/mqnic.h | 2 +- modules/mqnic/mqnic_rx.c | 23 ++++++++++++++++++----- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/modules/mqnic/mqnic.h b/modules/mqnic/mqnic.h index 41661d8cd..e3fdb003e 100644 --- a/modules/mqnic/mqnic.h +++ b/modules/mqnic/mqnic.h @@ -624,7 +624,7 @@ void mqnic_rx_write_head_ptr(struct mqnic_ring *ring); void mqnic_free_rx_desc(struct mqnic_ring *ring, int index); int mqnic_free_rx_buf(struct mqnic_ring *ring); int mqnic_prepare_rx_desc(struct mqnic_ring *ring, int index); -void mqnic_refill_rx_buffers(struct mqnic_ring *ring); +int mqnic_refill_rx_buffers(struct mqnic_ring *ring); int mqnic_process_rx_cq(struct mqnic_cq *cq, int napi_budget); void mqnic_rx_irq(struct mqnic_cq *cq); int mqnic_poll_rx_cq(struct napi_struct *napi, int budget); diff --git a/modules/mqnic/mqnic_rx.c b/modules/mqnic/mqnic_rx.c index d5504bbc3..d3cd4569b 100644 --- a/modules/mqnic/mqnic_rx.c +++ b/modules/mqnic/mqnic_rx.c @@ -96,7 +96,16 @@ int mqnic_open_rx_ring(struct mqnic_ring *ring, struct mqnic_priv *priv, iowrite32(ilog2(ring->size) | (ring->log_desc_block_size << 8), ring->hw_addr + MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG); - mqnic_refill_rx_buffers(ring); + ret = mqnic_refill_rx_buffers(ring); + if (ret) { + netdev_err(priv->ndev, "failed to allocate RX buffer for RX queue index %d (of %u total) entry index %u (of %u total)", + ring->index, priv->rxq_count, ring->head_ptr, ring->size); + if (ret == -ENOMEM) + netdev_err(priv->ndev, "machine might not have enough DMA-capable RAM; try to decrease number of RX channels (currently %u) and/or RX ring parameters (entries; currently %u) and/or module parameter \"num_rxq_entries\" (currently %u)", + priv->rxq_count, ring->size, mqnic_num_rxq_entries); + + goto fail; + } return 0; @@ -229,7 +238,7 @@ int mqnic_prepare_rx_desc(struct mqnic_ring *ring, int index) if (unlikely(!page)) { dev_err(ring->dev, "%s: failed to allocate memory on interface %d", __func__, ring->interface->index); - return -1; + return -ENOMEM; } // map page @@ -256,15 +265,17 @@ int mqnic_prepare_rx_desc(struct mqnic_ring *ring, int index) return 0; } -void mqnic_refill_rx_buffers(struct mqnic_ring *ring) +int mqnic_refill_rx_buffers(struct mqnic_ring *ring) { u32 missing = ring->size - (ring->head_ptr - ring->tail_ptr); + int ret = 0; if (missing < 8) - return; + return 0; for (; missing-- > 0;) { - if (mqnic_prepare_rx_desc(ring, ring->head_ptr & ring->size_mask)) + ret = mqnic_prepare_rx_desc(ring, ring->head_ptr & ring->size_mask); + if (ret) break; ring->head_ptr++; } @@ -272,6 +283,8 @@ void mqnic_refill_rx_buffers(struct mqnic_ring *ring) // enqueue on NIC dma_wmb(); mqnic_rx_write_head_ptr(ring); + + return ret; } int mqnic_process_rx_cq(struct mqnic_cq *cq, int napi_budget)