RE: [PATCH bpf v3 1/9] xdp: use modulo operation to calculate XDP frag tailroom
From: Loktionov, Aleksandr
Date: Tue Feb 17 2026 - 10:11:19 EST
> -----Original Message-----
> From: Zaremba, Larysa <larysa.zaremba@xxxxxxxxx>
> Sent: Tuesday, February 17, 2026 2:25 PM
> To: bpf@xxxxxxxxxxxxxxx
> Cc: Zaremba, Larysa <larysa.zaremba@xxxxxxxxx>; Claudiu Manoil
> <claudiu.manoil@xxxxxxx>; Vladimir Oltean <vladimir.oltean@xxxxxxx>;
> Wei Fang <wei.fang@xxxxxxx>; Clark Wang <xiaoning.wang@xxxxxxx>;
> Andrew Lunn <andrew+netdev@xxxxxxx>; David S. Miller
> <davem@xxxxxxxxxxxxx>; Eric Dumazet <edumazet@xxxxxxxxxx>; Jakub
> Kicinski <kuba@xxxxxxxxxx>; Paolo Abeni <pabeni@xxxxxxxxxx>; Nguyen,
> Anthony L <anthony.l.nguyen@xxxxxxxxx>; Kitszel, Przemyslaw
> <przemyslaw.kitszel@xxxxxxxxx>; Alexei Starovoitov <ast@xxxxxxxxxx>;
> Daniel Borkmann <daniel@xxxxxxxxxxxxx>; Jesper Dangaard Brouer
> <hawk@xxxxxxxxxx>; John Fastabend <john.fastabend@xxxxxxxxx>;
> Stanislav Fomichev <sdf@xxxxxxxxxxx>; Andrii Nakryiko
> <andrii@xxxxxxxxxx>; Martin KaFai Lau <martin.lau@xxxxxxxxx>; Eduard
> Zingerman <eddyz87@xxxxxxxxx>; Song Liu <song@xxxxxxxxxx>; Yonghong
> Song <yonghong.song@xxxxxxxxx>; KP Singh <kpsingh@xxxxxxxxxx>; Hao Luo
> <haoluo@xxxxxxxxxx>; Jiri Olsa <jolsa@xxxxxxxxxx>; Simon Horman
> <horms@xxxxxxxxxx>; Shuah Khan <shuah@xxxxxxxxxx>; Lobakin, Aleksander
> <aleksander.lobakin@xxxxxxxxx>; Fijalkowski, Maciej
> <maciej.fijalkowski@xxxxxxxxx>; Bastien Curutchet (eBPF Foundation)
> <bastien.curutchet@xxxxxxxxxxx>; Vyavahare, Tushar
> <tushar.vyavahare@xxxxxxxxx>; Jason Xing <kernelxing@xxxxxxxxxxx>;
> Ricardo B. Marlière <rbm@xxxxxxxx>; Eelco Chaudron
> <echaudro@xxxxxxxxxx>; Lorenzo Bianconi <lorenzo@xxxxxxxxxx>; Toke
> Hoiland-Jorgensen <toke@xxxxxxxxxx>; imx@xxxxxxxxxxxxxxx;
> netdev@xxxxxxxxxxxxxxx; linux-kernel@xxxxxxxxxxxxxxx; intel-wired-
> lan@xxxxxxxxxxxxxxxx; linux-kselftest@xxxxxxxxxxxxxxx; Loktionov,
> Aleksandr <aleksandr.loktionov@xxxxxxxxx>; Dragos Tatulea
> <dtatulea@xxxxxxxxxx>
> Subject: [PATCH bpf v3 1/9] xdp: use modulo operation to calculate XDP
> frag tailroom
>
> The current formula for calculating XDP tailroom in mbuf packets works
> only if each frag has its own page (if rxq->frag_size is PAGE_SIZE),
> this defeats the purpose of the parameter overall and without any
> indication leads to negative calculated tailroom on at least half of
> frags, if shared pages are used.
>
> There are not many drivers that set rxq->frag_size. Among them:
> * i40e and enetc always split page uniformly between frags, use shared
> pages
> * ice uses page_pool frags via libeth, those are power-of-2 and
> uniformly
> distributed across page
> * idpf has variable frag_size with XDP on, so current API is not
> applicable
> * mlx5, mtk and mvneta use PAGE_SIZE or 0 as frag_size for page_pool
>
> As for AF_XDP ZC, only ice, i40e and idpf declare frag_size for it.
> Modulo operation yields good results for aligned chunks, they are all
> power-of-2, between 2K and PAGE_SIZE. Formula without modulo fails
> when chunk_size is 2K. Buffers in unaligned mode are not distributed
> uniformly, so modulo operation would not work.
>
> To accommodate unaligned buffers, we could define frag_size as data +
> tailroom, and hence do not subtract offset when calculating tailroom,
> but this would necessitate more changes in the drivers.
>
> Define rxq->frag_size as an even portion of a page that fully belongs
> to a single frag. When calculating tailroom, locate the data start
> within such portion by performing a modulo operation on page offset.
>
> Fixes: bf25146a5595 ("bpf: add frags support to the
> bpf_xdp_adjust_tail() API")
> Acked-by: Jakub Kicinski <kuba@xxxxxxxxxx>
> Signed-off-by: Larysa Zaremba <larysa.zaremba@xxxxxxxxx>
> ---
> net/core/filter.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/net/core/filter.c b/net/core/filter.c index
> ba019ded773d..5f5489665c58 100644
> --- a/net/core/filter.c
> +++ b/net/core/filter.c
> @@ -4156,7 +4156,8 @@ static int bpf_xdp_frags_increase_tail(struct
> xdp_buff *xdp, int offset)
> if (!rxq->frag_size || rxq->frag_size > xdp->frame_sz)
> return -EOPNOTSUPP;
>
> - tailroom = rxq->frag_size - skb_frag_size(frag) -
> skb_frag_off(frag);
> + tailroom = rxq->frag_size - skb_frag_size(frag) -
> + skb_frag_off(frag) % rxq->frag_size;
> if (unlikely(offset > tailroom))
> return -EINVAL;
>
> --
> 2.52.0
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@xxxxxxxxx>