Skip to content

Commit 2976706

Browse files
author
Alexei Starovoitov
committed
Merge branch 'AF_XDP selftests improvements & bpf_link'
Maciej Fijalkowski says: ==================== Changes since v4 (all in patch 6): - do not close potentially invalid bpf_link fd (Toke) - fix misspelling in label (Toke) - mask out XDP_FLAGS_UPDATE_IF_NOEXIST and XDP_FLAGS_REPLACE explicitly when creating bpf_link (Toke) Changes since v3: - do not unload netlink-based XDP prog when updating map elem failed and current socket was not the creator of XDP resources (Toke) - pull out code paths based on prog_id value within __xsk_setup_xdp_prog so that teardown in case of error at any point is more clear Changes since v2: - fix c&p failure in veth's get_channels implementation (Magnus) - provide a backward compatibilty if bpf_link is not supported (Andrii) - check for a link type while looking up existing bpf_links (Andrii) Changes since v1: - selftests improvements and test case for bpf_link persistence itself - do not unload netlink-based prog when --force flag is set (John) - simplify return semantics in xsk_link_lookup (John) v4: https://lore.kernel.org/bpf/20210326230938.49998-1-maciej.fijalkowski@intel.com/ v3: https://lore.kernel.org/bpf/20210322205816.65159-1-maciej.fijalkowski@intel.com/ v2: https://lore.kernel.org/bpf/20210311152910.56760-1-maciej.fijalkowski@intel.com/ v1: https://lore.kernel.org/bpf/20210215154638.4627-1-maciej.fijalkowski@intel.com/ -------------------------------------------------- This set is another approach towards addressing the below issue: // load xdp prog and xskmap and add entry to xskmap at idx 10 $ sudo ./xdpsock -i ens801f0 -t -q 10 // add entry to xskmap at idx 11 $ sudo ./xdpsock -i ens801f0 -t -q 11 terminate one of the processes and another one is unable to work due to the fact that the XDP prog was unloaded from interface. Previous attempt was, to put it mildly, a bit broken, as there was no synchronization between updates to additional map, as Bjorn pointed out. See https://lore.kernel.org/netdev/20190603131907.13395-5-maciej.fijalkowski@intel.com/ In the meantime bpf_link was introduced and it seems that it can address the issue of refcounting the XDP prog on interface. Although the bpf_link is the meat of the set, selftests improvements are a bigger part of it. Overall, we've been able to reduce the complexity of xsk selftests by removing a bunch of synchronization resources and simplifying logic and structs. Last but not least, for multiqueue veth working with AF-XDP, ethtool's get_channels API needs to be implemented, so it's also included in that set. Note also that in order to make it work, a commit from bpf tree: veth: store queue_mapping independently of XDP prog presence https://lore.kernel.org/bpf/20210303152903.11172-1-maciej.fijalkowski@intel.com/ is needed. Thanks, Maciej Björn Töpel (3): selftests: xsk: remove thread attribute selftests: xsk: Remove mutex and condition variable selftests: xsk: Remove unused defines ==================== Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2 parents 05d8170 + ae6b6a1 commit 2976706

File tree

6 files changed

+573
-504
lines changed

6 files changed

+573
-504
lines changed

drivers/net/veth.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,17 @@ static void veth_get_ethtool_stats(struct net_device *dev,
218218
}
219219
}
220220

221+
static void veth_get_channels(struct net_device *dev,
222+
struct ethtool_channels *channels)
223+
{
224+
channels->tx_count = dev->real_num_tx_queues;
225+
channels->rx_count = dev->real_num_rx_queues;
226+
channels->max_tx = dev->real_num_tx_queues;
227+
channels->max_rx = dev->real_num_rx_queues;
228+
channels->combined_count = min(dev->real_num_rx_queues, dev->real_num_tx_queues);
229+
channels->max_combined = min(dev->real_num_rx_queues, dev->real_num_tx_queues);
230+
}
231+
221232
static const struct ethtool_ops veth_ethtool_ops = {
222233
.get_drvinfo = veth_get_drvinfo,
223234
.get_link = ethtool_op_get_link,
@@ -226,6 +237,7 @@ static const struct ethtool_ops veth_ethtool_ops = {
226237
.get_ethtool_stats = veth_get_ethtool_stats,
227238
.get_link_ksettings = veth_get_link_ksettings,
228239
.get_ts_info = ethtool_op_get_ts_info,
240+
.get_channels = veth_get_channels,
229241
};
230242

231243
/* general routines */

samples/bpf/xdpsock_user.c

Lines changed: 14 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,6 @@ static int opt_xsk_frame_size = XSK_UMEM__DEFAULT_FRAME_SIZE;
9696
static int opt_timeout = 1000;
9797
static bool opt_need_wakeup = true;
9898
static u32 opt_num_xsks = 1;
99-
static u32 prog_id;
10099
static bool opt_busy_poll;
101100
static bool opt_reduced_cap;
102101

@@ -462,59 +461,37 @@ static void *poller(void *arg)
462461
return NULL;
463462
}
464463

465-
static void remove_xdp_program(void)
464+
static void int_exit(int sig)
466465
{
467-
u32 curr_prog_id = 0;
468-
int cmd = CLOSE_CONN;
469-
470-
if (bpf_get_link_xdp_id(opt_ifindex, &curr_prog_id, opt_xdp_flags)) {
471-
printf("bpf_get_link_xdp_id failed\n");
472-
exit(EXIT_FAILURE);
473-
}
474-
if (prog_id == curr_prog_id)
475-
bpf_set_link_xdp_fd(opt_ifindex, -1, opt_xdp_flags);
476-
else if (!curr_prog_id)
477-
printf("couldn't find a prog id on a given interface\n");
478-
else
479-
printf("program on interface changed, not removing\n");
480-
481-
if (opt_reduced_cap) {
482-
if (write(sock, &cmd, sizeof(int)) < 0) {
483-
fprintf(stderr, "Error writing into stream socket: %s", strerror(errno));
484-
exit(EXIT_FAILURE);
485-
}
486-
}
466+
benchmark_done = true;
487467
}
488468

489-
static void int_exit(int sig)
469+
static void __exit_with_error(int error, const char *file, const char *func,
470+
int line)
490471
{
491-
benchmark_done = true;
472+
fprintf(stderr, "%s:%s:%i: errno: %d/\"%s\"\n", file, func,
473+
line, error, strerror(error));
474+
exit(EXIT_FAILURE);
492475
}
493476

477+
#define exit_with_error(error) __exit_with_error(error, __FILE__, __func__, __LINE__)
478+
494479
static void xdpsock_cleanup(void)
495480
{
496481
struct xsk_umem *umem = xsks[0]->umem->umem;
497-
int i;
482+
int i, cmd = CLOSE_CONN;
498483

499484
dump_stats();
500485
for (i = 0; i < num_socks; i++)
501486
xsk_socket__delete(xsks[i]->xsk);
502487
(void)xsk_umem__delete(umem);
503-
remove_xdp_program();
504-
}
505488

506-
static void __exit_with_error(int error, const char *file, const char *func,
507-
int line)
508-
{
509-
fprintf(stderr, "%s:%s:%i: errno: %d/\"%s\"\n", file, func,
510-
line, error, strerror(error));
511-
dump_stats();
512-
remove_xdp_program();
513-
exit(EXIT_FAILURE);
489+
if (opt_reduced_cap) {
490+
if (write(sock, &cmd, sizeof(int)) < 0)
491+
exit_with_error(errno);
492+
}
514493
}
515494

516-
#define exit_with_error(error) __exit_with_error(error, __FILE__, __func__, \
517-
__LINE__)
518495
static void swap_mac_addresses(void *data)
519496
{
520497
struct ether_header *eth = (struct ether_header *)data;
@@ -880,10 +857,6 @@ static struct xsk_socket_info *xsk_configure_socket(struct xsk_umem_info *umem,
880857
if (ret)
881858
exit_with_error(-ret);
882859

883-
ret = bpf_get_link_xdp_id(opt_ifindex, &prog_id, opt_xdp_flags);
884-
if (ret)
885-
exit_with_error(-ret);
886-
887860
xsk->app_stats.rx_empty_polls = 0;
888861
xsk->app_stats.fill_fail_polls = 0;
889862
xsk->app_stats.copy_tx_sendtos = 0;

0 commit comments

Comments
 (0)