eth: fbnic: Reuse RX mailbox pages

Currently, the RX mailbox frees and reallocates a page for each received
message. Since FW Rx messages are processed synchronously, and nothing
hold these pages (unlike skbs which we hand over to the stack), reuse
the pages and put them back on the Rx ring. Now that we ensure the ring
is always fully populated we don't have to worry about filling it up
after partial population during init, either. Update
fbnic_mbx_process_rx_msgs() to recycle pages after message processing.

Signed-off-by: Mohsin Bashir <mohsin.bashr@gmail.com>
Link: https://patch.msgid.link/20260115003353.4150771-4-mohsin.bashr@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Mohsin Bashir 2026-01-14 16:33:51 -08:00 committed by Jakub Kicinski
parent 0c86b52b1a
commit 301ae0d539

View File

@ -1592,7 +1592,7 @@ static const struct fbnic_tlv_parser fbnic_fw_tlv_parser[] = {
static void fbnic_mbx_process_rx_msgs(struct fbnic_dev *fbd)
{
struct fbnic_fw_mbx *rx_mbx = &fbd->mbx[FBNIC_IPC_MBX_RX_IDX];
u8 head = rx_mbx->head;
u8 head = rx_mbx->head, tail = rx_mbx->tail;
u64 desc, length;
while (head != rx_mbx->tail) {
@ -1603,8 +1603,8 @@ static void fbnic_mbx_process_rx_msgs(struct fbnic_dev *fbd)
if (!(desc & FBNIC_IPC_MBX_DESC_FW_CMPL))
break;
dma_unmap_single(fbd->dev, rx_mbx->buf_info[head].addr,
PAGE_SIZE, DMA_FROM_DEVICE);
dma_sync_single_for_cpu(fbd->dev, rx_mbx->buf_info[head].addr,
FBNIC_RX_PAGE_SIZE, DMA_FROM_DEVICE);
msg = rx_mbx->buf_info[head].msg;
@ -1637,19 +1637,26 @@ static void fbnic_mbx_process_rx_msgs(struct fbnic_dev *fbd)
dev_dbg(fbd->dev, "Parsed msg type %d\n", msg->hdr.type);
next_page:
fw_wr32(fbd, FBNIC_IPC_MBX(FBNIC_IPC_MBX_RX_IDX, head), 0);
free_page((unsigned long)rx_mbx->buf_info[head].msg);
rx_mbx->buf_info[tail] = rx_mbx->buf_info[head];
rx_mbx->buf_info[head].msg = NULL;
rx_mbx->buf_info[head].addr = 0;
head++;
head %= FBNIC_IPC_MBX_DESC_LEN;
__fbnic_mbx_wr_desc(fbd, FBNIC_IPC_MBX_RX_IDX, tail,
FIELD_PREP(FBNIC_IPC_MBX_DESC_LEN_MASK,
FBNIC_RX_PAGE_SIZE) |
(rx_mbx->buf_info[tail].addr &
FBNIC_IPC_MBX_DESC_ADDR_MASK) |
FBNIC_IPC_MBX_DESC_HOST_CMPL);
head = (head + 1) & (FBNIC_IPC_MBX_DESC_LEN - 1);
tail = (tail + 1) & (FBNIC_IPC_MBX_DESC_LEN - 1);
}
/* Record head for next interrupt */
rx_mbx->head = head;
/* Make sure we have at least one page for the FW to write to */
fbnic_mbx_alloc_rx_msgs(fbd);
rx_mbx->tail = tail;
}
void fbnic_mbx_poll(struct fbnic_dev *fbd)