| From 854b37b81b47443208c75ba7c3775fd49d335344 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Mon, 28 Jun 2021 17:18:15 +0800 |
| Subject: bpf, samples: Fix xdpsock with '-M' parameter missing unload process |
| |
| From: Wang Hai <wanghai38@huawei.com> |
| |
| [ Upstream commit 2620e92ae6ed83260eb46d214554cd308ee35d92 ] |
| |
| Execute the following command and exit, then execute it again, the following |
| error will be reported: |
| |
| $ sudo ./samples/bpf/xdpsock -i ens4f2 -M |
| ^C |
| $ sudo ./samples/bpf/xdpsock -i ens4f2 -M |
| libbpf: elf: skipping unrecognized data section(16) .eh_frame |
| libbpf: elf: skipping relo section(17) .rel.eh_frame for section(16) .eh_frame |
| libbpf: Kernel error message: XDP program already attached |
| ERROR: link set xdp fd failed |
| |
| Commit c9d27c9e8dc7 ("samples: bpf: Do not unload prog within xdpsock") removed |
| the unloading prog code because of the presence of bpf_link. This is fine if |
| XDP_SHARED_UMEM is disabled, but if it is enabled, unloading the prog is still |
| needed. |
| |
| Fixes: c9d27c9e8dc7 ("samples: bpf: Do not unload prog within xdpsock") |
| Signed-off-by: Wang Hai <wanghai38@huawei.com> |
| Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> |
| Acked-by: Magnus Karlsson <magnus.karlsson@intel.com> |
| Cc: Maciej Fijalkowski <maciej.fijalkowski@intel.com> |
| Link: https://lore.kernel.org/bpf/20210628091815.2373487-1-wanghai38@huawei.com |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| samples/bpf/xdpsock_user.c | 28 ++++++++++++++++++++++++++++ |
| 1 file changed, 28 insertions(+) |
| |
| diff --git a/samples/bpf/xdpsock_user.c b/samples/bpf/xdpsock_user.c |
| index 53e300f860bb..33d0bdebbed8 100644 |
| --- a/samples/bpf/xdpsock_user.c |
| +++ b/samples/bpf/xdpsock_user.c |
| @@ -96,6 +96,7 @@ static int opt_xsk_frame_size = XSK_UMEM__DEFAULT_FRAME_SIZE; |
| static int opt_timeout = 1000; |
| static bool opt_need_wakeup = true; |
| static u32 opt_num_xsks = 1; |
| +static u32 prog_id; |
| static bool opt_busy_poll; |
| static bool opt_reduced_cap; |
| |
| @@ -461,6 +462,23 @@ static void *poller(void *arg) |
| return NULL; |
| } |
| |
| +static void remove_xdp_program(void) |
| +{ |
| + u32 curr_prog_id = 0; |
| + |
| + if (bpf_get_link_xdp_id(opt_ifindex, &curr_prog_id, opt_xdp_flags)) { |
| + printf("bpf_get_link_xdp_id failed\n"); |
| + exit(EXIT_FAILURE); |
| + } |
| + |
| + if (prog_id == curr_prog_id) |
| + bpf_set_link_xdp_fd(opt_ifindex, -1, opt_xdp_flags); |
| + else if (!curr_prog_id) |
| + printf("couldn't find a prog id on a given interface\n"); |
| + else |
| + printf("program on interface changed, not removing\n"); |
| +} |
| + |
| static void int_exit(int sig) |
| { |
| benchmark_done = true; |
| @@ -471,6 +489,9 @@ static void __exit_with_error(int error, const char *file, const char *func, |
| { |
| fprintf(stderr, "%s:%s:%i: errno: %d/\"%s\"\n", file, func, |
| line, error, strerror(error)); |
| + |
| + if (opt_num_xsks > 1) |
| + remove_xdp_program(); |
| exit(EXIT_FAILURE); |
| } |
| |
| @@ -490,6 +511,9 @@ static void xdpsock_cleanup(void) |
| if (write(sock, &cmd, sizeof(int)) < 0) |
| exit_with_error(errno); |
| } |
| + |
| + if (opt_num_xsks > 1) |
| + remove_xdp_program(); |
| } |
| |
| static void swap_mac_addresses(void *data) |
| @@ -857,6 +881,10 @@ static struct xsk_socket_info *xsk_configure_socket(struct xsk_umem_info *umem, |
| if (ret) |
| exit_with_error(-ret); |
| |
| + ret = bpf_get_link_xdp_id(opt_ifindex, &prog_id, opt_xdp_flags); |
| + if (ret) |
| + exit_with_error(-ret); |
| + |
| xsk->app_stats.rx_empty_polls = 0; |
| xsk->app_stats.fill_fail_polls = 0; |
| xsk->app_stats.copy_tx_sendtos = 0; |
| -- |
| 2.30.2 |
| |