diff mbox series

[bpf-next] xsk: fix destination buffer address when copying with metadata

Message ID 20221104032311.1606050-1-sdf@google.com (mailing list archive)
State RFC
Delegated to: BPF
Headers show
Series [bpf-next] xsk: fix destination buffer address when copying with metadata | expand

Checks

Context Check Description
netdev/tree_selection success Clearly marked for bpf-next
netdev/fixes_present success Fixes tag not required for -next series
netdev/subject_prefix success Link
netdev/cover_letter success Single patches do not need cover letters
netdev/patch_count success Link
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 2 this patch: 2
netdev/cc_maintainers warning 6 maintainers not CCed: hawk@kernel.org pabeni@redhat.com davem@davemloft.net edumazet@google.com kuba@kernel.org netdev@vger.kernel.org
netdev/build_clang success Errors and warnings before: 5 this patch: 5
netdev/module_param success Was 0 now: 0
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 2 this patch: 2
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 8 lines checked
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
bpf/vmtest-bpf-next-VM_Test-8 success Logs for test_maps on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-9 success Logs for test_maps on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-12 success Logs for test_progs on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-13 success Logs for test_progs_no_alu32 on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-14 success Logs for test_progs_no_alu32 on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-15 success Logs for test_progs_no_alu32 on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-17 success Logs for test_progs_no_alu32_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-18 success Logs for test_progs_no_alu32_parallel on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-20 success Logs for test_progs_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-21 success Logs for test_progs_parallel on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-22 success Logs for test_verifier on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-23 success Logs for test_verifier on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-24 success Logs for test_verifier on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-10 success Logs for test_progs on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-11 success Logs for test_progs on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-16 success Logs for test_progs_no_alu32_parallel on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-19 success Logs for test_progs_parallel on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-2 success Logs for llvm-toolchain
bpf/vmtest-bpf-next-PR fail PR summary
bpf/vmtest-bpf-next-VM_Test-1 pending Logs for ${{ matrix.test }} on ${{ matrix.arch }} with ${{ matrix.toolchain }}
bpf/vmtest-bpf-next-VM_Test-3 fail Logs for build for s390x with gcc
bpf/vmtest-bpf-next-VM_Test-4 success Logs for build for x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-5 success Logs for build for x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-6 success Logs for llvm-toolchain
bpf/vmtest-bpf-next-VM_Test-7 success Logs for set-matrix

Commit Message

Stanislav Fomichev Nov. 4, 2022, 3:23 a.m. UTC
While working on a simplified test for [0] it occurred to me that
the following looks fishy:

	data = xsk_umem__get_data(xsk->umem_area, rx_desc->addr);
	data_meta = data - sizeof(my metadata);

Since the data points to umem frame at addr X, data_mem points to
the end of umem frame X-1.

I don't think it's by design?

0: https://lore.kernel.org/bpf/20221028181431.05173968@kernel.org/T/#t

Cc: Björn Töpel <bjorn@kernel.org>
Cc: Magnus Karlsson <magnus.karlsson@intel.com>
Cc: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
Cc: Jonathan Lemon <jonathan.lemon@gmail.com>
Signed-off-by: Stanislav Fomichev <sdf@google.com>
---
 net/xdp/xsk.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Comments

Björn Töpel Nov. 4, 2022, 8:22 a.m. UTC | #1
Stanislav Fomichev <sdf@google.com> writes:

> While working on a simplified test for [0] it occurred to me that
> the following looks fishy:
>
> 	data = xsk_umem__get_data(xsk->umem_area, rx_desc->addr);
> 	data_meta = data - sizeof(my metadata);
>
> Since the data points to umem frame at addr X, data_mem points to
> the end of umem frame X-1.
>
> I don't think it's by design?

It is by design. :-)

> diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c
> index 9f0561b67c12..0547fe37ba7e 100644
> --- a/net/xdp/xsk.c
> +++ b/net/xdp/xsk.c
> @@ -163,7 +163,7 @@ static void xsk_copy_xdp(struct xdp_buff *to, struct xdp_buff *from, u32 len)
>  	} else {
>  		from_buf = from->data_meta;
>  		metalen = from->data - from->data_meta;
> -		to_buf = to->data - metalen;

This is to include the XDP meta data in the receive buffer. Note that
AF_XDP descriptor that you get back on the RX ring points to the *data*
not the metadata.

For the unaligned mode you can pass any address (umem offset) into the
fill ring, and the kernel will simply mask it and setup headroom
accordingly.

The buffer allocator guarantees that there's XDP_PACKET_HEADROOM
available.

IOW your example userland code above is correct.


Björn
Stanislav Fomichev Nov. 4, 2022, 6:21 p.m. UTC | #2
On Fri, Nov 4, 2022 at 1:22 AM Björn Töpel <bjorn@kernel.org> wrote:
>
> Stanislav Fomichev <sdf@google.com> writes:
>
> > While working on a simplified test for [0] it occurred to me that
> > the following looks fishy:
> >
> >       data = xsk_umem__get_data(xsk->umem_area, rx_desc->addr);
> >       data_meta = data - sizeof(my metadata);
> >
> > Since the data points to umem frame at addr X, data_mem points to
> > the end of umem frame X-1.
> >
> > I don't think it's by design?
>
> It is by design. :-)

Noted, thanks for clarifying!

> > diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c
> > index 9f0561b67c12..0547fe37ba7e 100644
> > --- a/net/xdp/xsk.c
> > +++ b/net/xdp/xsk.c
> > @@ -163,7 +163,7 @@ static void xsk_copy_xdp(struct xdp_buff *to, struct xdp_buff *from, u32 len)
> >       } else {
> >               from_buf = from->data_meta;
> >               metalen = from->data - from->data_meta;
> > -             to_buf = to->data - metalen;
>
> This is to include the XDP meta data in the receive buffer. Note that
> AF_XDP descriptor that you get back on the RX ring points to the *data*
> not the metadata.
>
> For the unaligned mode you can pass any address (umem offset) into the
> fill ring, and the kernel will simply mask it and setup headroom
> accordingly.

Thanks for the details! And what happens in the aligned case?

Looking purely from the user side:

tx_desc = xsk_ring_prod__tx_desc(&xsk->tx, idx);
tx_desc->addr = idx * UMEM_FRAME_SIZE; /* this has to be aligned to
the frame size? */
data = xsk_umem__get_data(xsk->umem_area, tx_desc->addr);

data here is basically = umem_area + idx * UMEM_FRAM_SIZE, right? How
do I make sure metadata is placed in the same umem chunk? Will passing
umem headroom do the trick?




> The buffer allocator guarantees that there's XDP_PACKET_HEADROOM
> available.
>
> IOW your example userland code above is correct.
>
>
> Björn
>
>
Stanislav Fomichev Nov. 4, 2022, 9:47 p.m. UTC | #3
On Fri, Nov 4, 2022 at 11:21 AM Stanislav Fomichev <sdf@google.com> wrote:
>
> On Fri, Nov 4, 2022 at 1:22 AM Björn Töpel <bjorn@kernel.org> wrote:
> >
> > Stanislav Fomichev <sdf@google.com> writes:
> >
> > > While working on a simplified test for [0] it occurred to me that
> > > the following looks fishy:
> > >
> > >       data = xsk_umem__get_data(xsk->umem_area, rx_desc->addr);
> > >       data_meta = data - sizeof(my metadata);
> > >
> > > Since the data points to umem frame at addr X, data_mem points to
> > > the end of umem frame X-1.
> > >
> > > I don't think it's by design?
> >
> > It is by design. :-)
>
> Noted, thanks for clarifying!
>
> > > diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c
> > > index 9f0561b67c12..0547fe37ba7e 100644
> > > --- a/net/xdp/xsk.c
> > > +++ b/net/xdp/xsk.c
> > > @@ -163,7 +163,7 @@ static void xsk_copy_xdp(struct xdp_buff *to, struct xdp_buff *from, u32 len)
> > >       } else {
> > >               from_buf = from->data_meta;
> > >               metalen = from->data - from->data_meta;
> > > -             to_buf = to->data - metalen;
> >
> > This is to include the XDP meta data in the receive buffer. Note that
> > AF_XDP descriptor that you get back on the RX ring points to the *data*
> > not the metadata.
> >
> > For the unaligned mode you can pass any address (umem offset) into the
> > fill ring, and the kernel will simply mask it and setup headroom
> > accordingly.
>
> Thanks for the details! And what happens in the aligned case?
>
> Looking purely from the user side:
>
> tx_desc = xsk_ring_prod__tx_desc(&xsk->tx, idx);
> tx_desc->addr = idx * UMEM_FRAME_SIZE; /* this has to be aligned to
> the frame size? */
> data = xsk_umem__get_data(xsk->umem_area, tx_desc->addr);
>
> data here is basically = umem_area + idx * UMEM_FRAM_SIZE, right? How
> do I make sure metadata is placed in the same umem chunk? Will passing
> umem headroom do the trick?

Ignore me. I do see now that there is always XDP_PACKET_HEADROOM bytes
of headroom in rx_desc.



>
> > The buffer allocator guarantees that there's XDP_PACKET_HEADROOM
> > available.
> >
> > IOW your example userland code above is correct.
> >
> >
> > Björn
> >
> >
diff mbox series

Patch

diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c
index 9f0561b67c12..0547fe37ba7e 100644
--- a/net/xdp/xsk.c
+++ b/net/xdp/xsk.c
@@ -163,7 +163,7 @@  static void xsk_copy_xdp(struct xdp_buff *to, struct xdp_buff *from, u32 len)
 	} else {
 		from_buf = from->data_meta;
 		metalen = from->data - from->data_meta;
-		to_buf = to->data - metalen;
+		to_buf = to->data;
 	}
 
 	memcpy(to_buf, from_buf, len + metalen);