summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/qlogic/qede/qede_fp.c
diff options
context:
space:
mode:
authorMintz, Yuval <Yuval.Mintz@cavium.com>2017-01-01 14:57:04 +0300
committerDavid S. Miller <davem@davemloft.net>2017-01-02 05:02:14 +0300
commite3eef7ee0201dbe5f4fc011b58d26228b57736ce (patch)
tree6d4c2f2cc6cab6bd563ffc3a3f10d4f5827b82c2 /drivers/net/ethernet/qlogic/qede/qede_fp.c
parente1d32acbcbd35af5264acc70ff03bf8da9e447a8 (diff)
downloadlinux-e3eef7ee0201dbe5f4fc011b58d26228b57736ce.tar.xz
qede: Postpone reallocation until NAPI end
During Rx flow driver allocates a replacement buffer each time it consumes an Rx buffer. Failing to do so, it would consume the currently processed buffer and re-post it on the ring. As a result, the Rx ring is always completely full [from driver POV]. We now allow the Rx ring to shorten by doing the re-allocations at the end of the NAPI run. The only limitation is that we still want to make sure each time we reallocate that we'd still have sufficient elements in the Rx ring to guarantee that FW would be able to post additional data and trigger an interrupt. Signed-off-by: Yuval Mintz <Yuval.Mintz@cavium.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/qlogic/qede/qede_fp.c')
-rw-r--r--drivers/net/ethernet/qlogic/qede/qede_fp.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/drivers/net/ethernet/qlogic/qede/qede_fp.c b/drivers/net/ethernet/qlogic/qede/qede_fp.c
index 1614eed2d65d..a06acab48086 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_fp.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_fp.c
@@ -46,13 +46,22 @@
* Content also used by slowpath *
*********************************/
-int qede_alloc_rx_buffer(struct qede_rx_queue *rxq)
+int qede_alloc_rx_buffer(struct qede_rx_queue *rxq, bool allow_lazy)
{
struct sw_rx_data *sw_rx_data;
struct eth_rx_bd *rx_bd;
dma_addr_t mapping;
struct page *data;
+ /* In case lazy-allocation is allowed, postpone allocation until the
+ * end of the NAPI run. We'd still need to make sure the Rx ring has
+ * sufficient buffers to guarantee an additional Rx interrupt.
+ */
+ if (allow_lazy && likely(rxq->filled_buffers > 12)) {
+ rxq->filled_buffers--;
+ return 0;
+ }
+
data = alloc_pages(GFP_ATOMIC, 0);
if (unlikely(!data))
return -ENOMEM;
@@ -79,6 +88,7 @@ int qede_alloc_rx_buffer(struct qede_rx_queue *rxq)
rx_bd->addr.lo = cpu_to_le32(lower_32_bits(mapping));
rxq->sw_rx_prod++;
+ rxq->filled_buffers++;
return 0;
}
@@ -523,7 +533,7 @@ static inline int qede_realloc_rx_buffer(struct qede_rx_queue *rxq,
curr_cons->page_offset += rxq->rx_buf_seg_size;
if (curr_cons->page_offset == PAGE_SIZE) {
- if (unlikely(qede_alloc_rx_buffer(rxq))) {
+ if (unlikely(qede_alloc_rx_buffer(rxq, true))) {
/* Since we failed to allocate new buffer
* current buffer can be used again.
*/
@@ -1002,7 +1012,7 @@ static bool qede_rx_xdp(struct qede_dev *edev,
switch (act) {
case XDP_TX:
/* We need the replacement buffer before transmit. */
- if (qede_alloc_rx_buffer(rxq)) {
+ if (qede_alloc_rx_buffer(rxq, true)) {
qede_recycle_rx_bd_ring(rxq, 1);
return false;
}
@@ -1116,7 +1126,7 @@ static int qede_rx_build_jumbo(struct qede_dev *edev,
}
/* We need a replacement buffer for each BD */
- if (unlikely(qede_alloc_rx_buffer(rxq)))
+ if (unlikely(qede_alloc_rx_buffer(rxq, true)))
goto out;
/* Now that we've allocated the replacement buffer,
@@ -1293,6 +1303,11 @@ static int qede_rx_int(struct qede_fastpath *fp, int budget)
work_done++;
}
+ /* Allocate replacement buffers */
+ while (rxq->num_rx_buffers - rxq->filled_buffers)
+ if (qede_alloc_rx_buffer(rxq, false))
+ break;
+
/* Update producers */
qede_update_rx_prod(edev, rxq);