Commit 39e940d4 authored by Maciej Fijalkowski's avatar Maciej Fijalkowski Committed by Daniel Borkmann

selftests/xsk: Destroy BPF resources only when ctx refcount drops to 0

Currently, xsk_socket__delete frees BPF resources regardless of ctx
refcount. Xdpxceiver has a test to verify whether underlying BPF
resources would not be wiped out after closing XSK socket that was
bound to interface with other active sockets. From library's xsk part
perspective it also means that the internal xsk context is shared and
its refcount is bumped accordingly.

After a switch to loading XDP prog based on previously opened XSK
socket, mentioned xdpxceiver test fails with:

  not ok 16 [xdpxceiver.c:swap_xsk_resources:1334]: ERROR: 9/"Bad file descriptor

which means that in swap_xsk_resources(), xsk_socket__delete() released
xskmap which in turn caused a failure of xsk_socket__update_xskmap().

To fix this, when deleting socket, decrement ctx refcount before
releasing BPF resources and do so only when refcount dropped to 0 which
means there are no more active sockets for this ctx so BPF resources can
be freed safely.

Fixes: 2f6324a3 ("libbpf: Support shared umems between queues and devices")
Signed-off-by: default avatarMaciej Fijalkowski <maciej.fijalkowski@intel.com>
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
Acked-by: default avatarMagnus Karlsson <magnus.karlsson@intel.com>
Link: https://lore.kernel.org/bpf/20220629143458.934337-5-maciej.fijalkowski@intel.com
parent 6d4c767c
...@@ -1156,8 +1156,6 @@ int xsk_socket__create_shared(struct xsk_socket **xsk_ptr, ...@@ -1156,8 +1156,6 @@ int xsk_socket__create_shared(struct xsk_socket **xsk_ptr,
goto out_mmap_tx; goto out_mmap_tx;
} }
ctx->prog_fd = -1;
if (!(xsk->config.libbpf_flags & XSK_LIBBPF_FLAGS__INHIBIT_PROG_LOAD)) { if (!(xsk->config.libbpf_flags & XSK_LIBBPF_FLAGS__INHIBIT_PROG_LOAD)) {
err = __xsk_setup_xdp_prog(xsk, NULL); err = __xsk_setup_xdp_prog(xsk, NULL);
if (err) if (err)
...@@ -1238,7 +1236,10 @@ void xsk_socket__delete(struct xsk_socket *xsk) ...@@ -1238,7 +1236,10 @@ void xsk_socket__delete(struct xsk_socket *xsk)
ctx = xsk->ctx; ctx = xsk->ctx;
umem = ctx->umem; umem = ctx->umem;
if (ctx->prog_fd != -1) {
xsk_put_ctx(ctx, true);
if (!ctx->refcount) {
xsk_delete_bpf_maps(xsk); xsk_delete_bpf_maps(xsk);
close(ctx->prog_fd); close(ctx->prog_fd);
if (ctx->has_bpf_link) if (ctx->has_bpf_link)
...@@ -1257,8 +1258,6 @@ void xsk_socket__delete(struct xsk_socket *xsk) ...@@ -1257,8 +1258,6 @@ void xsk_socket__delete(struct xsk_socket *xsk)
} }
} }
xsk_put_ctx(ctx, true);
umem->refcount--; umem->refcount--;
/* Do not close an fd that also has an associated umem connected /* Do not close an fd that also has an associated umem connected
* to it. * to it.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment