Skip to content

Commit b736e34

Browse files
committed
Merge branch 'net-mlx5-avoid-payload-in-skb-s-linear-part-for-better-gro-processing'
Tariq Toukan says: ==================== net/mlx5: Avoid payload in skb's linear part for better GRO-processing This is V7 of a series originally submitted by Christoph. When LRO is enabled on the MLX, mlx5e_skb_from_cqe_mpwrq_nonlinear copies parts of the payload to the linear part of the skb. This triggers suboptimal processing in GRO, causing slow throughput. This patch series addresses this by using eth_get_headlen to compute the size of the protocol headers and only copy those bits. This results in a significant throughput improvement (detailed results in the specific patch). ==================== Link: https://patch.msgid.link/20260601061522.398044-1-tariqt@nvidia.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2 parents cbadf60 + 399f030 commit b736e34

1 file changed

Lines changed: 22 additions & 11 deletions

File tree

  • drivers/net/ethernet/mellanox/mlx5/core

drivers/net/ethernet/mellanox/mlx5/core/en_rx.c

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1912,7 +1912,6 @@ mlx5e_skb_from_cqe_mpwrq_nonlinear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *w
19121912
u32 page_idx)
19131913
{
19141914
struct mlx5e_frag_page *frag_page = &wi->alloc_units.frag_pages[page_idx];
1915-
u16 headlen = min_t(u16, MLX5E_RX_MAX_HEAD, cqe_bcnt);
19161915
struct mlx5e_frag_page *head_page = frag_page;
19171916
struct mlx5e_frag_page *linear_page = NULL;
19181917
struct mlx5e_xdp_buff *mxbuf = &rq->mxbuf;
@@ -1923,11 +1922,12 @@ mlx5e_skb_from_cqe_mpwrq_nonlinear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *w
19231922
unsigned int truesize = 0;
19241923
u32 pg_consumed_bytes;
19251924
struct bpf_prog *prog;
1925+
void *va, *head_addr;
19261926
struct sk_buff *skb;
19271927
u32 linear_frame_sz;
19281928
u16 linear_data_len;
19291929
u16 linear_hr;
1930-
void *va;
1930+
u16 headlen;
19311931

19321932
if (unlikely(cqe_bcnt > rq->hw_mtu)) {
19331933
u8 lro_num_seg = get_cqe_lro_num_seg(cqe);
@@ -1940,9 +1940,11 @@ mlx5e_skb_from_cqe_mpwrq_nonlinear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *w
19401940

19411941
prog = rcu_dereference(rq->xdp_prog);
19421942

1943+
head_addr = netmem_address(head_page->netmem) + head_offset;
1944+
19431945
if (prog) {
19441946
/* area for bpf_xdp_[store|load]_bytes */
1945-
net_prefetchw(netmem_address(frag_page->netmem) + frag_offset);
1947+
net_prefetchw(head_addr);
19461948

19471949
va = mlx5e_mpwqe_get_linear_page_frag(rq);
19481950
if (!va) {
@@ -1956,6 +1958,8 @@ mlx5e_skb_from_cqe_mpwrq_nonlinear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *w
19561958
linear_frame_sz = MLX5_SKB_FRAG_SZ(linear_hr + MLX5E_RX_MAX_HEAD);
19571959
linear_page = &rq->mpwqe.linear_info->frag_page;
19581960
} else {
1961+
dma_addr_t addr;
1962+
19591963
skb = napi_alloc_skb(rq->cq.napi,
19601964
ALIGN(MLX5E_RX_MAX_HEAD, sizeof(long)));
19611965
if (unlikely(!skb)) {
@@ -1967,6 +1971,14 @@ mlx5e_skb_from_cqe_mpwrq_nonlinear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *w
19671971
net_prefetchw(va); /* xdp_frame data area */
19681972
net_prefetchw(skb->data);
19691973

1974+
headlen = min(MLX5E_RX_MAX_HEAD, cqe_bcnt);
1975+
addr = page_pool_get_dma_addr_netmem(head_page->netmem);
1976+
dma_sync_single_for_cpu(rq->pdev, addr + head_offset,
1977+
ALIGN(headlen, sizeof(long)),
1978+
rq->buff.map_dir);
1979+
1980+
headlen = eth_get_headlen(rq->netdev, head_addr, headlen);
1981+
19701982
frag_offset += headlen;
19711983
byte_cnt -= headlen;
19721984
linear_hr = skb_headroom(skb);
@@ -2051,13 +2063,11 @@ mlx5e_skb_from_cqe_mpwrq_nonlinear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *w
20512063
pagep->frags++;
20522064
while (++pagep < frag_page);
20532065

2054-
headlen = min_t(u16, MLX5E_RX_MAX_HEAD - len,
2055-
skb->data_len);
2056-
__pskb_pull_tail(skb, headlen);
2066+
if (len < ETH_HLEN)
2067+
__pskb_pull_tail(skb, min(ETH_HLEN - len,
2068+
skb->data_len));
20572069
}
20582070
} else {
2059-
dma_addr_t addr;
2060-
20612071
if (xdp_buff_has_frags(&mxbuf->xdp)) {
20622072
struct mlx5e_frag_page *pagep;
20632073

@@ -2071,10 +2081,11 @@ mlx5e_skb_from_cqe_mpwrq_nonlinear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *w
20712081
pagep->frags++;
20722082
while (++pagep < frag_page);
20732083
}
2084+
20742085
/* copy header */
2075-
addr = page_pool_get_dma_addr_netmem(head_page->netmem);
2076-
mlx5e_copy_skb_header(rq, skb, head_page->netmem, addr,
2077-
head_offset, head_offset, headlen);
2086+
skb_copy_to_linear_data(skb, head_addr,
2087+
ALIGN(headlen, sizeof(long)));
2088+
20782089
/* skb linear part was allocated with headlen and aligned to long */
20792090
skb->tail += headlen;
20802091
skb->len += headlen;

0 commit comments

Comments
 (0)