@@ -1794,14 +1794,27 @@ mlx5e_skb_from_cqe_nonlinear(struct mlx5e_rq *rq, struct mlx5e_wqe_frag_info *wi
17941794 }
17951795
17961796 prog = rcu_dereference (rq -> xdp_prog );
1797- if (prog && mlx5e_xdp_handle (rq , prog , mxbuf )) {
1798- if (__test_and_clear_bit (MLX5E_RQ_FLAG_XDP_XMIT , rq -> flags )) {
1799- struct mlx5e_wqe_frag_info * pwi ;
1797+ if (prog ) {
1798+ u8 nr_frags_free , old_nr_frags = sinfo -> nr_frags ;
1799+
1800+ if (mlx5e_xdp_handle (rq , prog , mxbuf )) {
1801+ if (__test_and_clear_bit (MLX5E_RQ_FLAG_XDP_XMIT ,
1802+ rq -> flags )) {
1803+ struct mlx5e_wqe_frag_info * pwi ;
1804+
1805+ wi -= old_nr_frags - sinfo -> nr_frags ;
1806+
1807+ for (pwi = head_wi ; pwi < wi ; pwi ++ )
1808+ pwi -> frag_page -> frags ++ ;
1809+ }
1810+ return NULL ; /* page/packet was consumed by XDP */
1811+ }
18001812
1801- for (pwi = head_wi ; pwi < wi ; pwi ++ )
1802- pwi -> frag_page -> frags ++ ;
1813+ nr_frags_free = old_nr_frags - sinfo -> nr_frags ;
1814+ if (unlikely (nr_frags_free )) {
1815+ wi -= nr_frags_free ;
1816+ truesize -= nr_frags_free * frag_info -> frag_stride ;
18031817 }
1804- return NULL ; /* page/packet was consumed by XDP */
18051818 }
18061819
18071820 skb = mlx5e_build_linear_skb (
@@ -2027,6 +2040,7 @@ mlx5e_skb_from_cqe_mpwrq_nonlinear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *w
20272040 u32 byte_cnt = cqe_bcnt ;
20282041 struct skb_shared_info * sinfo ;
20292042 unsigned int truesize = 0 ;
2043+ u32 pg_consumed_bytes ;
20302044 struct bpf_prog * prog ;
20312045 struct sk_buff * skb ;
20322046 u32 linear_frame_sz ;
@@ -2080,7 +2094,8 @@ mlx5e_skb_from_cqe_mpwrq_nonlinear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *w
20802094
20812095 while (byte_cnt ) {
20822096 /* Non-linear mode, hence non-XSK, which always uses PAGE_SIZE. */
2083- u32 pg_consumed_bytes = min_t (u32 , PAGE_SIZE - frag_offset , byte_cnt );
2097+ pg_consumed_bytes =
2098+ min_t (u32 , PAGE_SIZE - frag_offset , byte_cnt );
20842099
20852100 if (test_bit (MLX5E_RQ_STATE_SHAMPO , & rq -> state ))
20862101 truesize += pg_consumed_bytes ;
@@ -2096,10 +2111,15 @@ mlx5e_skb_from_cqe_mpwrq_nonlinear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *w
20962111 }
20972112
20982113 if (prog ) {
2114+ u8 nr_frags_free , old_nr_frags = sinfo -> nr_frags ;
2115+ u32 len ;
2116+
20992117 if (mlx5e_xdp_handle (rq , prog , mxbuf )) {
21002118 if (__test_and_clear_bit (MLX5E_RQ_FLAG_XDP_XMIT , rq -> flags )) {
21012119 struct mlx5e_frag_page * pfp ;
21022120
2121+ frag_page -= old_nr_frags - sinfo -> nr_frags ;
2122+
21032123 for (pfp = head_page ; pfp < frag_page ; pfp ++ )
21042124 pfp -> frags ++ ;
21052125
@@ -2110,9 +2130,19 @@ mlx5e_skb_from_cqe_mpwrq_nonlinear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *w
21102130 return NULL ; /* page/packet was consumed by XDP */
21112131 }
21122132
2133+ nr_frags_free = old_nr_frags - sinfo -> nr_frags ;
2134+ if (unlikely (nr_frags_free )) {
2135+ frag_page -= nr_frags_free ;
2136+ truesize -= (nr_frags_free - 1 ) * PAGE_SIZE +
2137+ ALIGN (pg_consumed_bytes ,
2138+ BIT (rq -> mpwqe .log_stride_sz ));
2139+ }
2140+
2141+ len = mxbuf -> xdp .data_end - mxbuf -> xdp .data ;
2142+
21132143 skb = mlx5e_build_linear_skb (
21142144 rq , mxbuf -> xdp .data_hard_start , linear_frame_sz ,
2115- mxbuf -> xdp .data - mxbuf -> xdp .data_hard_start , 0 ,
2145+ mxbuf -> xdp .data - mxbuf -> xdp .data_hard_start , len ,
21162146 mxbuf -> xdp .data - mxbuf -> xdp .data_meta );
21172147 if (unlikely (!skb )) {
21182148 mlx5e_page_release_fragmented (rq -> page_pool ,
@@ -2137,8 +2167,11 @@ mlx5e_skb_from_cqe_mpwrq_nonlinear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *w
21372167 do
21382168 pagep -> frags ++ ;
21392169 while (++ pagep < frag_page );
2170+
2171+ headlen = min_t (u16 , MLX5E_RX_MAX_HEAD - len ,
2172+ skb -> data_len );
2173+ __pskb_pull_tail (skb , headlen );
21402174 }
2141- __pskb_pull_tail (skb , headlen );
21422175 } else {
21432176 dma_addr_t addr ;
21442177
0 commit comments