* [PATCH bpf-next 1/2] bpf: add bpf_dynptr_memset() kfunc @ 2025-06-18 22:33 Ihor Solodrai 2025-06-18 22:33 ` [PATCH bpf-next 2/2] selftests/bpf: add test cases for bpf_dynptr_memset() Ihor Solodrai 2025-06-18 23:44 ` [PATCH bpf-next 1/2] bpf: add bpf_dynptr_memset() kfunc Mykyta Yatsenko 0 siblings, 2 replies; 14+ messages in thread From: Ihor Solodrai @ 2025-06-18 22:33 UTC (permalink / raw) To: andrii; +Cc: bpf, ast, daniel, eddyz87, mykolal, kernel-team Currently there is no straightforward way to fill dynptr memory with a value (most commonly zero). One can do it with bpf_dynptr_write(), but a temporary buffer is necessary for that. Implement bpf_dynptr_memset() - an analogue of memset() from libc. Signed-off-by: Ihor Solodrai <isolodrai@meta.com> --- kernel/bpf/helpers.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c index b71e428ad936..dfd04628a522 100644 --- a/kernel/bpf/helpers.c +++ b/kernel/bpf/helpers.c @@ -2906,6 +2906,33 @@ __bpf_kfunc int bpf_dynptr_copy(struct bpf_dynptr *dst_ptr, u32 dst_off, return 0; } +/** + * bpf_dynptr_memset() - Fill dynptr memory with a constant byte. + * @ptr: Destination dynptr - where data will be filled + * @val: Constant byte to fill the memory with + * @n: Number of bytes to fill + * + * Fills the first n bytes of the memory area pointed to by ptr + * with the constant byte val. + * Returns 0 on success; negative error, otherwise. + */ + __bpf_kfunc int bpf_dynptr_memset(struct bpf_dynptr *ptr, u8 val, u32 n) + { + struct bpf_dynptr_kern *p = (struct bpf_dynptr_kern *)ptr; + int err; + + if (__bpf_dynptr_is_rdonly(p)) + return -EINVAL; + + err = bpf_dynptr_check_off_len(p, 0, n); + if (err) + return err; + + memset(p->data + p->offset, val, n); + + return 0; +} + __bpf_kfunc void *bpf_cast_to_kern_ctx(void *obj) { return obj; @@ -3364,6 +3391,7 @@ BTF_ID_FLAGS(func, bpf_dynptr_is_rdonly) BTF_ID_FLAGS(func, bpf_dynptr_size) BTF_ID_FLAGS(func, bpf_dynptr_clone) BTF_ID_FLAGS(func, bpf_dynptr_copy) +BTF_ID_FLAGS(func, bpf_dynptr_memset) #ifdef CONFIG_NET BTF_ID_FLAGS(func, bpf_modify_return_test_tp) #endif -- 2.47.1 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH bpf-next 2/2] selftests/bpf: add test cases for bpf_dynptr_memset() 2025-06-18 22:33 [PATCH bpf-next 1/2] bpf: add bpf_dynptr_memset() kfunc Ihor Solodrai @ 2025-06-18 22:33 ` Ihor Solodrai 2025-06-18 23:44 ` [PATCH bpf-next 1/2] bpf: add bpf_dynptr_memset() kfunc Mykyta Yatsenko 1 sibling, 0 replies; 14+ messages in thread From: Ihor Solodrai @ 2025-06-18 22:33 UTC (permalink / raw) To: andrii; +Cc: bpf, ast, daniel, eddyz87, mykolal, kernel-team Add tests to verify the behavior of bpf_dynptr_memset(): * normal memset 0 * memset in dynptr that was adjusted * error: size overflow * error: readonly dynptr Signed-off-by: Ihor Solodrai <isolodrai@meta.com> --- .../testing/selftests/bpf/prog_tests/dynptr.c | 4 ++ .../selftests/bpf/progs/dynptr_success.c | 66 +++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/tools/testing/selftests/bpf/prog_tests/dynptr.c b/tools/testing/selftests/bpf/prog_tests/dynptr.c index 62e7ec775f24..423e95755aa0 100644 --- a/tools/testing/selftests/bpf/prog_tests/dynptr.c +++ b/tools/testing/selftests/bpf/prog_tests/dynptr.c @@ -21,6 +21,10 @@ static struct { {"test_dynptr_data", SETUP_SYSCALL_SLEEP}, {"test_dynptr_copy", SETUP_SYSCALL_SLEEP}, {"test_dynptr_copy_xdp", SETUP_XDP_PROG}, + {"test_dynptr_memset_zero", SETUP_SYSCALL_SLEEP}, + {"test_dynptr_memset_zero_offset", SETUP_SYSCALL_SLEEP}, + {"test_dynptr_memset_overflow", SETUP_SYSCALL_SLEEP}, + {"test_dynptr_memset_readonly", SETUP_SKB_PROG}, {"test_ringbuf", SETUP_SYSCALL_SLEEP}, {"test_skb_readonly", SETUP_SKB_PROG}, {"test_dynptr_skb_data", SETUP_SKB_PROG}, diff --git a/tools/testing/selftests/bpf/progs/dynptr_success.c b/tools/testing/selftests/bpf/progs/dynptr_success.c index a0391f9da2d4..204e02816947 100644 --- a/tools/testing/selftests/bpf/progs/dynptr_success.c +++ b/tools/testing/selftests/bpf/progs/dynptr_success.c @@ -681,6 +681,72 @@ int test_dynptr_copy_xdp(struct xdp_md *xdp) return XDP_DROP; } +char memset_zero_data[] = "data to be zeroed"; + +SEC("?tp/syscalls/sys_enter_nanosleep") +int test_dynptr_memset_zero(void *ctx) +{ + __u32 data_sz = sizeof(memset_zero_data); + char zeroes[32] = {'\0'}; + struct bpf_dynptr ptr; + + err = bpf_dynptr_from_mem(memset_zero_data, data_sz, 0, &ptr); + err = err ?: bpf_dynptr_memset(&ptr, 0, data_sz); + err = err ?: bpf_memcmp(zeroes, memset_zero_data, data_sz); + + return 0; +} + +char memset_zero_offset_data[] = "data to be zeroed partially"; + +SEC("?tp/syscalls/sys_enter_nanosleep") +int test_dynptr_memset_zero_offset(void *ctx) +{ + char expected[] = "data\0\0\0\0be zeroed partially"; + __u32 data_sz = sizeof(memset_zero_offset_data); + struct bpf_dynptr ptr; + + err = bpf_dynptr_from_mem(memset_zero_offset_data, data_sz, 0, &ptr); + err = err ?: bpf_dynptr_adjust(&ptr, 4, 8); + err = err ?: bpf_dynptr_memset(&ptr, 0, bpf_dynptr_size(&ptr)); + err = err ?: bpf_memcmp(expected, memset_zero_offset_data, data_sz); + + return 0; +} + +char memset_overflow_data[] = "memset overflow data"; + +SEC("?tp/syscalls/sys_enter_nanosleep") +int test_dynptr_memset_overflow(void *ctx) +{ + __u32 data_sz = sizeof(memset_overflow_data); + struct bpf_dynptr ptr; + int ret; + + err = bpf_dynptr_from_mem(memset_overflow_data, data_sz, 0, &ptr); + ret = bpf_dynptr_memset(&ptr, 0, data_sz + 1); + if (ret != -E2BIG) + err = 1; + + return 0; +} + +SEC("?cgroup_skb/egress") +int test_dynptr_memset_readonly(struct __sk_buff *skb) +{ + struct bpf_dynptr ptr; + int ret; + + err = bpf_dynptr_from_skb(skb, 0, &ptr); + + /* cgroup skbs are read only, memset should fail */ + ret = bpf_dynptr_memset(&ptr, 0, bpf_dynptr_size(&ptr)); + if (ret != -EINVAL) + err = 1; + + return 0; +} + void *user_ptr; /* Contains the copy of the data pointed by user_ptr. * Size 384 to make it not fit into a single kernel chunk when copying -- 2.47.1 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH bpf-next 1/2] bpf: add bpf_dynptr_memset() kfunc 2025-06-18 22:33 [PATCH bpf-next 1/2] bpf: add bpf_dynptr_memset() kfunc Ihor Solodrai 2025-06-18 22:33 ` [PATCH bpf-next 2/2] selftests/bpf: add test cases for bpf_dynptr_memset() Ihor Solodrai @ 2025-06-18 23:44 ` Mykyta Yatsenko 2025-06-19 17:09 ` Ihor Solodrai 1 sibling, 1 reply; 14+ messages in thread From: Mykyta Yatsenko @ 2025-06-18 23:44 UTC (permalink / raw) To: ihor.solodrai, andrii; +Cc: bpf, ast, daniel, eddyz87, mykolal, kernel-team On 6/18/25 23:33, Ihor Solodrai wrote: > Currently there is no straightforward way to fill dynptr memory with a > value (most commonly zero). One can do it with bpf_dynptr_write(), but > a temporary buffer is necessary for that. > > Implement bpf_dynptr_memset() - an analogue of memset() from libc. > > Signed-off-by: Ihor Solodrai <isolodrai@meta.com> > --- > kernel/bpf/helpers.c | 28 ++++++++++++++++++++++++++++ > 1 file changed, 28 insertions(+) > > diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c > index b71e428ad936..dfd04628a522 100644 > --- a/kernel/bpf/helpers.c > +++ b/kernel/bpf/helpers.c > @@ -2906,6 +2906,33 @@ __bpf_kfunc int bpf_dynptr_copy(struct bpf_dynptr *dst_ptr, u32 dst_off, > return 0; > } > > +/** > + * bpf_dynptr_memset() - Fill dynptr memory with a constant byte. > + * @ptr: Destination dynptr - where data will be filled > + * @val: Constant byte to fill the memory with > + * @n: Number of bytes to fill > + * > + * Fills the first n bytes of the memory area pointed to by ptr > + * with the constant byte val. > + * Returns 0 on success; negative error, otherwise. > + */ > + __bpf_kfunc int bpf_dynptr_memset(struct bpf_dynptr *ptr, u8 val, u32 n) > + { > + struct bpf_dynptr_kern *p = (struct bpf_dynptr_kern *)ptr; > + int err; > + > + if (__bpf_dynptr_is_rdonly(p)) > + return -EINVAL; > + > + err = bpf_dynptr_check_off_len(p, 0, n); > + if (err) > + return err; > + > + memset(p->data + p->offset, val, n); Do we need to handle non-contiguous buffers, similarly to bpf_dynptr_write (BPF_DYNPTR_TYPE_XDP case)? > + > + return 0; > +} > + > __bpf_kfunc void *bpf_cast_to_kern_ctx(void *obj) > { > return obj; > @@ -3364,6 +3391,7 @@ BTF_ID_FLAGS(func, bpf_dynptr_is_rdonly) > BTF_ID_FLAGS(func, bpf_dynptr_size) > BTF_ID_FLAGS(func, bpf_dynptr_clone) > BTF_ID_FLAGS(func, bpf_dynptr_copy) > +BTF_ID_FLAGS(func, bpf_dynptr_memset) > #ifdef CONFIG_NET > BTF_ID_FLAGS(func, bpf_modify_return_test_tp) > #endif ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH bpf-next 1/2] bpf: add bpf_dynptr_memset() kfunc 2025-06-18 23:44 ` [PATCH bpf-next 1/2] bpf: add bpf_dynptr_memset() kfunc Mykyta Yatsenko @ 2025-06-19 17:09 ` Ihor Solodrai 2025-06-19 17:19 ` Eduard Zingerman 0 siblings, 1 reply; 14+ messages in thread From: Ihor Solodrai @ 2025-06-19 17:09 UTC (permalink / raw) To: Mykyta Yatsenko, andrii; +Cc: bpf, ast, daniel, eddyz87, mykolal, kernel-team On 6/18/25 4:44 PM, Mykyta Yatsenko wrote: > On 6/18/25 23:33, Ihor Solodrai wrote: >> Currently there is no straightforward way to fill dynptr memory with a >> value (most commonly zero). One can do it with bpf_dynptr_write(), but >> a temporary buffer is necessary for that. >> >> Implement bpf_dynptr_memset() - an analogue of memset() from libc. >> >> Signed-off-by: Ihor Solodrai <isolodrai@meta.com> >> --- >> kernel/bpf/helpers.c | 28 ++++++++++++++++++++++++++++ >> 1 file changed, 28 insertions(+) >> >> diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c >> index b71e428ad936..dfd04628a522 100644 >> --- a/kernel/bpf/helpers.c >> +++ b/kernel/bpf/helpers.c >> @@ -2906,6 +2906,33 @@ __bpf_kfunc int bpf_dynptr_copy(struct >> bpf_dynptr *dst_ptr, u32 dst_off, >> return 0; >> } >> +/** >> + * bpf_dynptr_memset() - Fill dynptr memory with a constant byte. >> + * @ptr: Destination dynptr - where data will be filled >> + * @val: Constant byte to fill the memory with >> + * @n: Number of bytes to fill >> + * >> + * Fills the first n bytes of the memory area pointed to by ptr >> + * with the constant byte val. >> + * Returns 0 on success; negative error, otherwise. >> + */ >> + __bpf_kfunc int bpf_dynptr_memset(struct bpf_dynptr *ptr, u8 val, >> u32 n) >> + { >> + struct bpf_dynptr_kern *p = (struct bpf_dynptr_kern *)ptr; >> + int err; >> + >> + if (__bpf_dynptr_is_rdonly(p)) >> + return -EINVAL; >> + >> + err = bpf_dynptr_check_off_len(p, 0, n); >> + if (err) >> + return err; >> + >> + memset(p->data + p->offset, val, n); > Do we need to handle non-contiguous buffers, similarly to > bpf_dynptr_write (BPF_DYNPTR_TYPE_XDP case)? It appears so, yes. I am a little lost on how exactly to do it though. Looking at bpf_xdp_store_bytes [1]: BPF_CALL_4(bpf_xdp_store_bytes, struct xdp_buff *, xdp, u32, offset, void *, buf, u32, len) { void *ptr; ptr = bpf_xdp_pointer(xdp, offset, len); if (IS_ERR(ptr)) return PTR_ERR(ptr); if (!ptr) bpf_xdp_copy_buf(xdp, offset, buf, len, true); else memcpy(ptr, buf, len); return 0; } ... int __bpf_xdp_store_bytes(struct xdp_buff *xdp, u32 offset, void *buf, u32 len) { return ____bpf_xdp_store_bytes(xdp, offset, buf, len); } It looks like I'd need to implement similar logic for memset. But then, does memset even make sense for xdp/skb buffers? Maybe -ENOTSUPP is more appropriate? I'd appreciate any hints. [1] https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git/tree/net/core/filter.c#n4084 >> + >> + return 0; >> +} >> + >> __bpf_kfunc void *bpf_cast_to_kern_ctx(void *obj) >> { >> return obj; >> @@ -3364,6 +3391,7 @@ BTF_ID_FLAGS(func, bpf_dynptr_is_rdonly) >> BTF_ID_FLAGS(func, bpf_dynptr_size) >> BTF_ID_FLAGS(func, bpf_dynptr_clone) >> BTF_ID_FLAGS(func, bpf_dynptr_copy) >> +BTF_ID_FLAGS(func, bpf_dynptr_memset) >> #ifdef CONFIG_NET >> BTF_ID_FLAGS(func, bpf_modify_return_test_tp) >> #endif > ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH bpf-next 1/2] bpf: add bpf_dynptr_memset() kfunc 2025-06-19 17:09 ` Ihor Solodrai @ 2025-06-19 17:19 ` Eduard Zingerman 2025-06-19 17:55 ` Ihor Solodrai 2025-06-20 15:09 ` Mykyta Yatsenko 0 siblings, 2 replies; 14+ messages in thread From: Eduard Zingerman @ 2025-06-19 17:19 UTC (permalink / raw) To: Ihor Solodrai, Mykyta Yatsenko, andrii Cc: bpf, ast, daniel, mykolal, kernel-team On Thu, 2025-06-19 at 10:09 -0700, Ihor Solodrai wrote: [...] > But then, does memset even make sense for xdp/skb buffers? Why not? > Maybe -ENOTSUPP is more appropriate? > > I'd appreciate any hints. I think Mykyta has kernel/trace/bpf_trace.c:__bpf_dynptr_copy_str() in mind. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH bpf-next 1/2] bpf: add bpf_dynptr_memset() kfunc 2025-06-19 17:19 ` Eduard Zingerman @ 2025-06-19 17:55 ` Ihor Solodrai 2025-06-19 17:57 ` Eduard Zingerman 2025-06-20 15:09 ` Mykyta Yatsenko 1 sibling, 1 reply; 14+ messages in thread From: Ihor Solodrai @ 2025-06-19 17:55 UTC (permalink / raw) To: Eduard Zingerman, Mykyta Yatsenko, andrii Cc: bpf, ast, daniel, mykolal, kernel-team On 6/19/25 10:19 AM, Eduard Zingerman wrote: > On Thu, 2025-06-19 at 10:09 -0700, Ihor Solodrai wrote: > > [...] > >> But then, does memset even make sense for xdp/skb buffers? > > Why not? I was thinking that in a BPF program you'd usually be reading xdp/skb and not writing to it, especially not via memset. But never mind, I am likely wrong. > >> Maybe -ENOTSUPP is more appropriate? >> >> I'd appreciate any hints. > > I think Mykyta has kernel/trace/bpf_trace.c:__bpf_dynptr_copy_str() in mind. Thanks for the pointer. So it looks like memset can use bpf_dynptr_slice_rdwr() to handle xdp/skb cases. Something like: void *ptr = bpf_dynptr_slice_rdwr(&dynptr, 0, buffer, sizeof(buffer)); if (!ptr) return -EINVAL; memset(ptr, val, n); if (ptr == buffer) bpf_dynptr_write(&dynptr, 0, buffer, sizeof(buffer), 0); > ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH bpf-next 1/2] bpf: add bpf_dynptr_memset() kfunc 2025-06-19 17:55 ` Ihor Solodrai @ 2025-06-19 17:57 ` Eduard Zingerman 2025-06-19 18:04 ` Ihor Solodrai 0 siblings, 1 reply; 14+ messages in thread From: Eduard Zingerman @ 2025-06-19 17:57 UTC (permalink / raw) To: Ihor Solodrai, Mykyta Yatsenko, andrii Cc: bpf, ast, daniel, mykolal, kernel-team On Thu, 2025-06-19 at 10:55 -0700, Ihor Solodrai wrote: [...] > > I think Mykyta has kernel/trace/bpf_trace.c:__bpf_dynptr_copy_str() in mind. > > Thanks for the pointer. So it looks like memset can use > bpf_dynptr_slice_rdwr() to handle xdp/skb cases. Something like: > > void *ptr = bpf_dynptr_slice_rdwr(&dynptr, 0, buffer, sizeof(buffer)); > if (!ptr) > return -EINVAL; > > memset(ptr, val, n); > > if (ptr == buffer) > bpf_dynptr_write(&dynptr, 0, buffer, sizeof(buffer), 0); > > I think so. In a loop. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH bpf-next 1/2] bpf: add bpf_dynptr_memset() kfunc 2025-06-19 17:57 ` Eduard Zingerman @ 2025-06-19 18:04 ` Ihor Solodrai 2025-06-19 18:13 ` Eduard Zingerman 0 siblings, 1 reply; 14+ messages in thread From: Ihor Solodrai @ 2025-06-19 18:04 UTC (permalink / raw) To: Eduard Zingerman, Mykyta Yatsenko, andrii Cc: bpf, ast, daniel, mykolal, kernel-team On 6/19/25 10:57 AM, Eduard Zingerman wrote: > On Thu, 2025-06-19 at 10:55 -0700, Ihor Solodrai wrote: > > [...] > >>> I think Mykyta has kernel/trace/bpf_trace.c:__bpf_dynptr_copy_str() in mind. >> >> Thanks for the pointer. So it looks like memset can use >> bpf_dynptr_slice_rdwr() to handle xdp/skb cases. Something like: >> >> void *ptr = bpf_dynptr_slice_rdwr(&dynptr, 0, buffer, sizeof(buffer)); >> if (!ptr) >> return -EINVAL; >> >> memset(ptr, val, n); >> >> if (ptr == buffer) >> bpf_dynptr_write(&dynptr, 0, buffer, sizeof(buffer), 0); >> >> > > I think so. In a loop. But allocating and copying buffers for memset... It should be possible to walk through fragments like net/core/filter.c:bpf_xdp_copy_buf does. Any reasons it's a bad idea? > ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH bpf-next 1/2] bpf: add bpf_dynptr_memset() kfunc 2025-06-19 18:04 ` Ihor Solodrai @ 2025-06-19 18:13 ` Eduard Zingerman 2025-06-19 18:17 ` Eduard Zingerman 0 siblings, 1 reply; 14+ messages in thread From: Eduard Zingerman @ 2025-06-19 18:13 UTC (permalink / raw) To: Ihor Solodrai, Mykyta Yatsenko, andrii Cc: bpf, ast, daniel, mykolal, kernel-team On Thu, 2025-06-19 at 11:04 -0700, Ihor Solodrai wrote: [...] > It should be possible to walk through fragments like > net/core/filter.c:bpf_xdp_copy_buf does. > > Any reasons it's a bad idea? > You can do that as well. Also, what's the plan if you'd like to memset only a fragment of the memory pointed-to by dynptr? ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH bpf-next 1/2] bpf: add bpf_dynptr_memset() kfunc 2025-06-19 18:13 ` Eduard Zingerman @ 2025-06-19 18:17 ` Eduard Zingerman 2025-06-23 21:38 ` Andrii Nakryiko 0 siblings, 1 reply; 14+ messages in thread From: Eduard Zingerman @ 2025-06-19 18:17 UTC (permalink / raw) To: Ihor Solodrai, Mykyta Yatsenko, andrii Cc: bpf, ast, daniel, mykolal, kernel-team On Thu, 2025-06-19 at 11:13 -0700, Eduard Zingerman wrote: [...] > Also, what's the plan if you'd like to memset only a fragment of the > memory pointed-to by dynptr? Oh, I see, there is bpf_dynptr_adjust(), sorry for the noise. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH bpf-next 1/2] bpf: add bpf_dynptr_memset() kfunc 2025-06-19 18:17 ` Eduard Zingerman @ 2025-06-23 21:38 ` Andrii Nakryiko 2025-06-23 21:45 ` Eduard Zingerman 0 siblings, 1 reply; 14+ messages in thread From: Andrii Nakryiko @ 2025-06-23 21:38 UTC (permalink / raw) To: Eduard Zingerman Cc: Ihor Solodrai, Mykyta Yatsenko, andrii, bpf, ast, daniel, mykolal, kernel-team On Thu, Jun 19, 2025 at 11:17 AM Eduard Zingerman <eddyz87@gmail.com> wrote: > > On Thu, 2025-06-19 at 11:13 -0700, Eduard Zingerman wrote: > > [...] > > > Also, what's the plan if you'd like to memset only a fragment of the > > memory pointed-to by dynptr? > > Oh, I see, there is bpf_dynptr_adjust(), sorry for the noise. > Even though we do have bpf_dynptr_adjust() for maximum generality and flexibility, for most dynptr-based APIs we try to pass also additional offset into dynptr to avoid unnecessary overhead. So it's not a bad idea to add this to bpf_memset(), IMO. bpf_memset(struct bpf_dynptr *dptr, u32 off, u8 val, u32 n) ? a bit unfortunate that we have 3 integers that you need to be careful to not swap accidentally, but even with just val and n you'd have to be careful. For other APIs we normally have offset to follow dynptr pointer, so hopefully this arrangement won't that surprising. Thoughts? ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH bpf-next 1/2] bpf: add bpf_dynptr_memset() kfunc 2025-06-23 21:38 ` Andrii Nakryiko @ 2025-06-23 21:45 ` Eduard Zingerman 2025-06-23 22:12 ` Andrii Nakryiko 0 siblings, 1 reply; 14+ messages in thread From: Eduard Zingerman @ 2025-06-23 21:45 UTC (permalink / raw) To: Andrii Nakryiko Cc: Ihor Solodrai, Mykyta Yatsenko, andrii, bpf, ast, daniel, mykolal, kernel-team On Mon, 2025-06-23 at 14:38 -0700, Andrii Nakryiko wrote: > On Thu, Jun 19, 2025 at 11:17 AM Eduard Zingerman <eddyz87@gmail.com> wrote: > > > > On Thu, 2025-06-19 at 11:13 -0700, Eduard Zingerman wrote: > > > > [...] > > > > > Also, what's the plan if you'd like to memset only a fragment of the > > > memory pointed-to by dynptr? > > > > Oh, I see, there is bpf_dynptr_adjust(), sorry for the noise. > > > > Even though we do have bpf_dynptr_adjust() for maximum generality and > flexibility, for most dynptr-based APIs we try to pass also additional > offset into dynptr to avoid unnecessary overhead. So it's not a bad > idea to add this to bpf_memset(), IMO. > > bpf_memset(struct bpf_dynptr *dptr, u32 off, u8 val, u32 n) ? > > a bit unfortunate that we have 3 integers that you need to be careful > to not swap accidentally, but even with just val and n you'd have to > be careful. For other APIs we normally have offset to follow dynptr > pointer, so hopefully this arrangement won't that surprising. > > Thoughts? Unfortunate indeed. The off and n being separated looks weird, tbh. For dynptr funcs we actually have "dptr, off, size" everywhere, maybe do the same here? ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH bpf-next 1/2] bpf: add bpf_dynptr_memset() kfunc 2025-06-23 21:45 ` Eduard Zingerman @ 2025-06-23 22:12 ` Andrii Nakryiko 0 siblings, 0 replies; 14+ messages in thread From: Andrii Nakryiko @ 2025-06-23 22:12 UTC (permalink / raw) To: Eduard Zingerman Cc: Ihor Solodrai, Mykyta Yatsenko, andrii, bpf, ast, daniel, mykolal, kernel-team On Mon, Jun 23, 2025 at 2:45 PM Eduard Zingerman <eddyz87@gmail.com> wrote: > > On Mon, 2025-06-23 at 14:38 -0700, Andrii Nakryiko wrote: > > On Thu, Jun 19, 2025 at 11:17 AM Eduard Zingerman <eddyz87@gmail.com> wrote: > > > > > > On Thu, 2025-06-19 at 11:13 -0700, Eduard Zingerman wrote: > > > > > > [...] > > > > > > > Also, what's the plan if you'd like to memset only a fragment of the > > > > memory pointed-to by dynptr? > > > > > > Oh, I see, there is bpf_dynptr_adjust(), sorry for the noise. > > > > > > > Even though we do have bpf_dynptr_adjust() for maximum generality and > > flexibility, for most dynptr-based APIs we try to pass also additional > > offset into dynptr to avoid unnecessary overhead. So it's not a bad > > idea to add this to bpf_memset(), IMO. > > > > bpf_memset(struct bpf_dynptr *dptr, u32 off, u8 val, u32 n) ? > > > > a bit unfortunate that we have 3 integers that you need to be careful > > to not swap accidentally, but even with just val and n you'd have to > > be careful. For other APIs we normally have offset to follow dynptr > > pointer, so hopefully this arrangement won't that surprising. > > > > Thoughts? > > Unfortunate indeed. > The off and n being separated looks weird, tbh. > For dynptr funcs we actually have "dptr, off, size" everywhere, maybe > do the same here? yep, fine by me. I never liked libc's memset() order anyways :) ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH bpf-next 1/2] bpf: add bpf_dynptr_memset() kfunc 2025-06-19 17:19 ` Eduard Zingerman 2025-06-19 17:55 ` Ihor Solodrai @ 2025-06-20 15:09 ` Mykyta Yatsenko 1 sibling, 0 replies; 14+ messages in thread From: Mykyta Yatsenko @ 2025-06-20 15:09 UTC (permalink / raw) To: Eduard Zingerman, Ihor Solodrai, andrii Cc: bpf, ast, daniel, mykolal, kernel-team On 6/19/25 18:19, Eduard Zingerman wrote: > On Thu, 2025-06-19 at 10:09 -0700, Ihor Solodrai wrote: > > [...] > >> But then, does memset even make sense for xdp/skb buffers? > Why not? > >> Maybe -ENOTSUPP is more appropriate? >> >> I'd appreciate any hints. > I think Mykyta has kernel/trace/bpf_trace.c:__bpf_dynptr_copy_str() in mind. > Right, similarly to `__bpf_dynptr_copy` from bpf_trace.c: fast path if destination has enough contiguous memory, just call memset. Slow path - use temp buffer, that you can memset once and then __bpf_dynptr_write it in a loop. __bpf_dynptr_write handles the trickiness of the non-contiguous buffers. ^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2025-06-23 22:12 UTC | newest] Thread overview: 14+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-06-18 22:33 [PATCH bpf-next 1/2] bpf: add bpf_dynptr_memset() kfunc Ihor Solodrai 2025-06-18 22:33 ` [PATCH bpf-next 2/2] selftests/bpf: add test cases for bpf_dynptr_memset() Ihor Solodrai 2025-06-18 23:44 ` [PATCH bpf-next 1/2] bpf: add bpf_dynptr_memset() kfunc Mykyta Yatsenko 2025-06-19 17:09 ` Ihor Solodrai 2025-06-19 17:19 ` Eduard Zingerman 2025-06-19 17:55 ` Ihor Solodrai 2025-06-19 17:57 ` Eduard Zingerman 2025-06-19 18:04 ` Ihor Solodrai 2025-06-19 18:13 ` Eduard Zingerman 2025-06-19 18:17 ` Eduard Zingerman 2025-06-23 21:38 ` Andrii Nakryiko 2025-06-23 21:45 ` Eduard Zingerman 2025-06-23 22:12 ` Andrii Nakryiko 2025-06-20 15:09 ` Mykyta Yatsenko
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).