diff options
| author | Martin KaFai Lau <martin.lau@kernel.org> | 2025-09-23 13:35:13 -0700 |
|---|---|---|
| committer | Martin KaFai Lau <martin.lau@kernel.org> | 2025-09-23 15:21:41 -0700 |
| commit | 5000380e3204fa19a049c6ad5549ff3412124abd (patch) | |
| tree | 55c7a5032dc4336896636bbbffb8cfd9545420e0 /net/bpf/test_run.c | |
| parent | 54728bd535fb3899ad51489dc1e05eb5bb53cb95 (diff) | |
| parent | efec2e55bdefb889639a6e7fe1f1f2431cdddc6a (diff) | |
Merge branch 'add-kfunc-bpf_xdp_pull_data'
Amery Hung says:
====================
Add kfunc bpf_xdp_pull_data
v7 -> v6
patch 5 (new patch)
- Rename variables in bpf_prog_test_run_xdp()
patch 6
- Fix bugs (Martin)
v6 -> v5
patch 6
- v5 selftest failed on S390 when changing how tailroom occupied by
skb_shared_info is calculated. Revert selftest to v4, where we get
SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) by running an XDP
program
Link: https://lore.kernel.org/bpf/20250919230952.3628709-1-ameryhung@gmail.com/
v5 -> v4
patch 1
- Add a new patch clearing pfmemalloc bit in xdp->frags when all frags
are freed in bpf_xdp_adjust_tail() (Maciej)
patch 2
- Refactor bpf_xdp_shrink_data() (Maciej)
patch 3
- Clear pfmemalloc when all frags are freed in bpf_xdp_pull_data()
(Maciej)
patch 6
- Use BTF to get sizes of skb_shared_info and xdp_frame (Maciej)
Link: https://lore.kernel.org/bpf/20250919182100.1925352-1-ameryhung@gmail.com/
v3 -> v4
patch 2
- Improve comments (Jakub)
- Drop new_end and len_free to simplify code (Jakub)
patch 4
- Instead of adding is_xdp to bpf_test_init, move lower-bound check
of user_size to callers (Martin)
- Simplify linear data size calculation (Martin)
patch 5
- Add static function identifier (Martin)
- Free calloc-ed buf (Martin)
Link: https://lore.kernel.org/bpf/20250917225513.3388199-1-ameryhung@gmail.com/
v2 -> v3
Separate mlx5 fixes from the patchset
patch 2
- Use headroom for pulling data by shifting metadata and data down
(Jakub)
- Drop the flags argument (Martin)
patch 4
- Support empty linear xdp data for BPF_PROG_TEST_RUN
Link: https://lore.kernel.org/bpf/20250915224801.2961360-1-ameryhung@gmail.com/
v1 -> v2
Rebase onto bpf-next
Try to build on top of the mlx5 patchset that avoids copying payload
to linear part by Christoph but got a kernel panic. Will rebase on
that patchset if it got merged first, or separate the mlx5 fix
from this set.
patch 1
- Remove the unnecessary head frag search (Dragos)
- Rewind the end frag pointer to simplify the change (Dragos)
- Rewind the end frag pointer and recalculate truesize only when the
number of frags changed (Dragos)
patch 3
- Fix len == zero behavior. To mirror bpf_skb_pull_data() correctly,
the kfunc should do nothing (Stanislav)
- Fix a pointer wrap around bug (Jakub)
- Use memmove() when moving sinfo->frags (Jakub)
Link: https://lore.kernel.org/bpf/20250905173352.3759457-1-ameryhung@gmail.com/
====================
Link: https://patch.msgid.link/20250922233356.3356453-1-ameryhung@gmail.com
Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
Diffstat (limited to 'net/bpf/test_run.c')
| -rw-r--r-- | net/bpf/test_run.c | 37 |
1 files changed, 23 insertions, 14 deletions
diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c index 9728dbd4c66c..3df3fe46beb3 100644 --- a/net/bpf/test_run.c +++ b/net/bpf/test_run.c @@ -665,7 +665,7 @@ static void *bpf_test_init(const union bpf_attr *kattr, u32 user_size, void __user *data_in = u64_to_user_ptr(kattr->test.data_in); void *data; - if (user_size < ETH_HLEN || user_size > PAGE_SIZE - headroom - tailroom) + if (user_size > PAGE_SIZE - headroom - tailroom) return ERR_PTR(-EINVAL); size = SKB_DATA_ALIGN(size); @@ -1001,6 +1001,9 @@ int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr, kattr->test.cpu || kattr->test.batch_size) return -EINVAL; + if (size < ETH_HLEN) + return -EINVAL; + data = bpf_test_init(kattr, kattr->test.data_size_in, size, NET_SKB_PAD + NET_IP_ALIGN, SKB_DATA_ALIGN(sizeof(struct skb_shared_info))); @@ -1207,9 +1210,9 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, { bool do_live = (kattr->test.flags & BPF_F_TEST_XDP_LIVE_FRAMES); u32 tailroom = SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); + u32 retval = 0, meta_sz = 0, duration, max_linear_sz, size; + u32 linear_sz = kattr->test.data_size_in; u32 batch_size = kattr->test.batch_size; - u32 retval = 0, duration, max_data_sz; - u32 size = kattr->test.data_size_in; u32 headroom = XDP_PACKET_HEADROOM; u32 repeat = kattr->test.repeat; struct netdev_rx_queue *rxqueue; @@ -1246,39 +1249,45 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, if (ctx) { /* There can't be user provided data before the meta data */ - if (ctx->data_meta || ctx->data_end != size || + if (ctx->data_meta || ctx->data_end > kattr->test.data_size_in || ctx->data > ctx->data_end || unlikely(xdp_metalen_invalid(ctx->data)) || (do_live && (kattr->test.data_out || kattr->test.ctx_out))) goto free_ctx; /* Meta data is allocated from the headroom */ headroom -= ctx->data; - } - max_data_sz = PAGE_SIZE - headroom - tailroom; - if (size > max_data_sz) { - /* disallow live data mode for jumbo frames */ - if (do_live) - goto free_ctx; - size = max_data_sz; + meta_sz = ctx->data; + linear_sz = ctx->data_end; } - data = bpf_test_init(kattr, size, max_data_sz, headroom, tailroom); + max_linear_sz = PAGE_SIZE - headroom - tailroom; + linear_sz = min_t(u32, linear_sz, max_linear_sz); + + /* disallow live data mode for jumbo frames */ + if (do_live && kattr->test.data_size_in > linear_sz) + goto free_ctx; + + if (kattr->test.data_size_in - meta_sz < ETH_HLEN) + return -EINVAL; + + data = bpf_test_init(kattr, linear_sz, max_linear_sz, headroom, tailroom); if (IS_ERR(data)) { ret = PTR_ERR(data); goto free_ctx; } rxqueue = __netif_get_rx_queue(current->nsproxy->net_ns->loopback_dev, 0); - rxqueue->xdp_rxq.frag_size = headroom + max_data_sz + tailroom; + rxqueue->xdp_rxq.frag_size = PAGE_SIZE; xdp_init_buff(&xdp, rxqueue->xdp_rxq.frag_size, &rxqueue->xdp_rxq); - xdp_prepare_buff(&xdp, data, headroom, size, true); + xdp_prepare_buff(&xdp, data, headroom, linear_sz, true); sinfo = xdp_get_shared_info_from_buff(&xdp); ret = xdp_convert_md_to_buff(ctx, &xdp); if (ret) goto free_data; + size = linear_sz; if (unlikely(kattr->test.data_size_in > size)) { void __user *data_in = u64_to_user_ptr(kattr->test.data_in); |