Skip to content

Commit df542f6

Browse files
Furong XuPaolo Abeni
authored andcommitted
net: stmmac: Switch to zero-copy in non-XDP RX path
Avoid memcpy in non-XDP RX path by marking all allocated SKBs to be recycled in the upper network stack. This patch brings ~11.5% driver performance improvement in a TCP RX throughput test with iPerf tool on a single isolated Cortex-A65 CPU core, from 2.18 Gbits/sec increased to 2.43 Gbits/sec. Signed-off-by: Furong Xu <[email protected]> Reviewed-by: Alexander Lobakin <[email protected]> Reviewed-by: Larysa Zaremba <[email protected]> Reviewed-by: Yanteng Si <[email protected]> Signed-off-by: Paolo Abeni <[email protected]>
1 parent 0b21051 commit df542f6

File tree

2 files changed

+18
-9
lines changed

2 files changed

+18
-9
lines changed

drivers/net/ethernet/stmicro/stmmac/stmmac.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ struct stmmac_rx_queue {
126126
unsigned int cur_rx;
127127
unsigned int dirty_rx;
128128
unsigned int buf_alloc_num;
129+
unsigned int napi_skb_frag_size;
129130
dma_addr_t dma_rx_phy;
130131
u32 rx_tail_addr;
131132
unsigned int state_saved;

drivers/net/ethernet/stmicro/stmmac/stmmac_main.c

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1341,7 +1341,7 @@ static unsigned int stmmac_rx_offset(struct stmmac_priv *priv)
13411341
if (stmmac_xdp_is_enabled(priv))
13421342
return XDP_PACKET_HEADROOM;
13431343

1344-
return 0;
1344+
return NET_SKB_PAD;
13451345
}
13461346

13471347
static int stmmac_set_bfsize(int mtu, int bufsize)
@@ -2040,17 +2040,21 @@ static int __alloc_dma_rx_desc_resources(struct stmmac_priv *priv,
20402040
struct stmmac_channel *ch = &priv->channel[queue];
20412041
bool xdp_prog = stmmac_xdp_is_enabled(priv);
20422042
struct page_pool_params pp_params = { 0 };
2043-
unsigned int num_pages;
2043+
unsigned int dma_buf_sz_pad, num_pages;
20442044
unsigned int napi_id;
20452045
int ret;
20462046

2047+
dma_buf_sz_pad = stmmac_rx_offset(priv) + dma_conf->dma_buf_sz +
2048+
SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
2049+
num_pages = DIV_ROUND_UP(dma_buf_sz_pad, PAGE_SIZE);
2050+
20472051
rx_q->queue_index = queue;
20482052
rx_q->priv_data = priv;
2053+
rx_q->napi_skb_frag_size = num_pages * PAGE_SIZE;
20492054

20502055
pp_params.flags = PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV;
20512056
pp_params.pool_size = dma_conf->dma_rx_size;
2052-
num_pages = DIV_ROUND_UP(dma_conf->dma_buf_sz, PAGE_SIZE);
2053-
pp_params.order = ilog2(num_pages);
2057+
pp_params.order = order_base_2(num_pages);
20542058
pp_params.nid = dev_to_node(priv->device);
20552059
pp_params.dev = priv->device;
20562060
pp_params.dma_dir = xdp_prog ? DMA_BIDIRECTIONAL : DMA_FROM_DEVICE;
@@ -5582,22 +5586,26 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
55825586
}
55835587

55845588
if (!skb) {
5589+
unsigned int head_pad_len;
5590+
55855591
/* XDP program may expand or reduce tail */
55865592
buf1_len = ctx.xdp.data_end - ctx.xdp.data;
55875593

5588-
skb = napi_alloc_skb(&ch->rx_napi, buf1_len);
5594+
skb = napi_build_skb(page_address(buf->page),
5595+
rx_q->napi_skb_frag_size);
55895596
if (!skb) {
5597+
page_pool_recycle_direct(rx_q->page_pool,
5598+
buf->page);
55905599
rx_dropped++;
55915600
count++;
55925601
goto drain_data;
55935602
}
55945603

55955604
/* XDP program may adjust header */
5596-
skb_copy_to_linear_data(skb, ctx.xdp.data, buf1_len);
5605+
head_pad_len = ctx.xdp.data - ctx.xdp.data_hard_start;
5606+
skb_reserve(skb, head_pad_len);
55975607
skb_put(skb, buf1_len);
5598-
5599-
/* Data payload copied into SKB, page ready for recycle */
5600-
page_pool_recycle_direct(rx_q->page_pool, buf->page);
5608+
skb_mark_for_recycle(skb);
56015609
buf->page = NULL;
56025610
} else if (buf1_len) {
56035611
dma_sync_single_for_cpu(priv->device, buf->addr,

0 commit comments

Comments
 (0)