XDP hardware hints discussion mail archive
 help / color / mirror / Atom feed
From: Stanislav Fomichev <sdf@google.com>
To: bpf@vger.kernel.org
Cc: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org,
	martin.lau@linux.dev, song@kernel.org, yhs@fb.com,
	john.fastabend@gmail.com, kpsingh@kernel.org, sdf@google.com,
	haoluo@google.com, jolsa@kernel.org,
	Jakub Kicinski <kuba@kernel.org>,
	Willem de Bruijn <willemb@google.com>,
	Jesper Dangaard Brouer <brouer@redhat.com>,
	Anatoly Burakov <anatoly.burakov@intel.com>,
	Alexander Lobakin <alexandr.lobakin@intel.com>,
	Magnus Karlsson <magnus.karlsson@gmail.com>,
	Maryam Tahhan <mtahhan@redhat.com>,
	xdp-hints@xdp-project.net, netdev@vger.kernel.org
Subject: [xdp-hints] [RFC bpf-next 4/5] selftests/bpf: Convert xskxceiver to use custom program
Date: Thu, 27 Oct 2022 13:00:18 -0700	[thread overview]
Message-ID: <20221027200019.4106375-5-sdf@google.com> (raw)
In-Reply-To: <20221027200019.4106375-1-sdf@google.com>

No functional changes (in theory): convert libxsk-generated
program bytecode to the C code to better illustrate kfunc
metadata (see next patch in the series).

There is also a bunch of unrelated changes, ignore them for the
sake of demo:
- stats.rx_dopped == 2048 vs 2047 ?
- buggy ksft_print_msg calls
- test is limited only to
  TEST_MODE_DRV+TEST_TYPE_RUN_TO_COMPLETION_SINGLE_PKT

Cc: Martin KaFai Lau <martin.lau@linux.dev>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: Willem de Bruijn <willemb@google.com>
Cc: Jesper Dangaard Brouer <brouer@redhat.com>
Cc: Anatoly Burakov <anatoly.burakov@intel.com>
Cc: Alexander Lobakin <alexandr.lobakin@intel.com>
Cc: Magnus Karlsson <magnus.karlsson@gmail.com>
Cc: Maryam Tahhan <mtahhan@redhat.com>
Cc: xdp-hints@xdp-project.net
Cc: netdev@vger.kernel.org
Signed-off-by: Stanislav Fomichev <sdf@google.com>
---
 tools/testing/selftests/bpf/Makefile          |  1 +
 .../testing/selftests/bpf/progs/xskxceiver.c  | 21 ++++
 tools/testing/selftests/bpf/xskxceiver.c      | 98 +++++++++++++++----
 tools/testing/selftests/bpf/xskxceiver.h      |  5 +-
 4 files changed, 105 insertions(+), 20 deletions(-)
 create mode 100644 tools/testing/selftests/bpf/progs/xskxceiver.c

diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index 79edef1dbda4..3cab2e1b0e74 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -378,6 +378,7 @@ linked_maps.skel.h-deps := linked_maps1.bpf.o linked_maps2.bpf.o
 test_subskeleton.skel.h-deps := test_subskeleton_lib2.bpf.o test_subskeleton_lib.bpf.o test_subskeleton.bpf.o
 test_subskeleton_lib.skel.h-deps := test_subskeleton_lib2.bpf.o test_subskeleton_lib.bpf.o
 test_usdt.skel.h-deps := test_usdt.bpf.o test_usdt_multispec.bpf.o
+xskxceiver-deps := xskxceiver.bpf.o
 
 LINKED_BPF_SRCS := $(patsubst %.bpf.o,%.c,$(foreach skel,$(LINKED_SKELS),$($(skel)-deps)))
 
diff --git a/tools/testing/selftests/bpf/progs/xskxceiver.c b/tools/testing/selftests/bpf/progs/xskxceiver.c
new file mode 100644
index 000000000000..b135daddad3a
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/xskxceiver.c
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/bpf.h>
+
+#include <bpf/bpf_helpers.h>
+#include <bpf/bpf_endian.h>
+
+struct {
+	__uint(type, BPF_MAP_TYPE_XSKMAP);
+	__uint(max_entries, 4);
+	__type(key, __u32);
+	__type(value, __u32);
+} xsk SEC(".maps");
+
+SEC("xdp")
+int rx(struct xdp_md *ctx)
+{
+	return bpf_redirect_map(&xsk, ctx->rx_queue_index, XDP_PASS);
+}
+
+char _license[] SEC("license") = "GPL";
diff --git a/tools/testing/selftests/bpf/xskxceiver.c b/tools/testing/selftests/bpf/xskxceiver.c
index 681a5db80dae..066bd691db13 100644
--- a/tools/testing/selftests/bpf/xskxceiver.c
+++ b/tools/testing/selftests/bpf/xskxceiver.c
@@ -399,6 +399,58 @@ static void usage(const char *prog)
 	ksft_print_msg(str, prog);
 }
 
+static void bpf_update_xsk_map(struct ifobject *ifobject, __u32 queue_id)
+{
+	int map_fd;
+	int sock_fd;
+	int ret;
+
+	map_fd = bpf_map__fd(ifobject->bpf_obj->maps.xsk);
+	sock_fd = xsk_socket__fd(ifobject->xsk->xsk);
+
+	(void)bpf_map_delete_elem(map_fd, &queue_id);
+	ret = bpf_map_update_elem(map_fd, &queue_id, &sock_fd, 0);
+	if (ret)
+		exit_with_error(-ret);
+}
+
+static int bpf_attach(struct ifobject *ifobject)
+{
+	__u32 prog_id = 0;
+
+	bpf_xdp_query_id(ifobject->ifindex, ifobject->xdp_flags, &prog_id);
+	if (prog_id)
+		return 0;
+
+	int ret = bpf_xdp_attach(ifobject->ifindex,
+				 bpf_program__fd(ifobject->bpf_obj->progs.rx),
+				 ifobject->xdp_flags, NULL);
+	if (ret < 0) {
+		if (errno != EEXIST && errno != EBUSY) {
+			exit_with_error(errno);
+		}
+	}
+
+	bpf_update_xsk_map(ifobject, 0);
+
+	return 0;
+}
+
+static void bpf_detach(struct ifobject *ifobject)
+{
+	int my_ns = open("/proc/self/ns/net", O_RDONLY);
+
+	/* Make sure we're in the right namespace when detaching.
+	 * Relevant only for TEST_TYPE_BIDI.
+	 */
+	if (ifobject->ns_fd > 0)
+		setns(ifobject->ns_fd, 0);
+
+	bpf_xdp_detach(ifobject->ifindex, ifobject->xdp_flags, NULL);
+
+	setns(my_ns, 0);
+}
+
 static int switch_namespace(const char *nsname)
 {
 	char fqns[26] = "/var/run/netns/";
@@ -1141,9 +1193,10 @@ static int validate_rx_dropped(struct ifobject *ifobject)
 	if (err)
 		return TEST_FAILURE;
 
-	if (stats.rx_dropped == ifobject->pkt_stream->nb_pkts / 2)
+	if (stats.rx_dropped == ifobject->pkt_stream->nb_pkts / 2 - 1)
 		return TEST_PASS;
 
+	printf("%lld != %d\n", stats.rx_dropped, ifobject->pkt_stream->nb_pkts / 2 - 1);
 	return TEST_FAILURE;
 }
 
@@ -1239,7 +1292,6 @@ static void thread_common_ops_tx(struct test_spec *test, struct ifobject *ifobje
 {
 	xsk_configure_socket(test, ifobject, test->ifobj_rx->umem, true);
 	ifobject->xsk = &ifobject->xsk_arr[0];
-	ifobject->xsk_map_fd = test->ifobj_rx->xsk_map_fd;
 	memcpy(ifobject->umem, test->ifobj_rx->umem, sizeof(struct xsk_umem_info));
 }
 
@@ -1284,6 +1336,14 @@ static void thread_common_ops(struct test_spec *test, struct ifobject *ifobject)
 
 	ifobject->ns_fd = switch_namespace(ifobject->nsname);
 
+	ifindex = if_nametoindex(ifobject->ifname);
+	if (!ifindex)
+		exit_with_error(errno);
+
+	ifobject->bpf_obj = xskxceiver__open_and_load();
+	if (libbpf_get_error(ifobject->bpf_obj))
+		exit_with_error(libbpf_get_error(ifobject->bpf_obj));
+
 	if (ifobject->umem->unaligned_mode)
 		mmap_flags |= MAP_HUGETLB;
 
@@ -1307,11 +1367,8 @@ static void thread_common_ops(struct test_spec *test, struct ifobject *ifobject)
 	if (!ifobject->rx_on)
 		return;
 
-	ifindex = if_nametoindex(ifobject->ifname);
-	if (!ifindex)
-		exit_with_error(errno);
-
-	ret = xsk_setup_xdp_prog_xsk(ifobject->xsk->xsk, &ifobject->xsk_map_fd);
+	ifobject->ifindex = ifindex;
+	ret = bpf_attach(ifobject);
 	if (ret)
 		exit_with_error(-ret);
 
@@ -1321,19 +1378,17 @@ static void thread_common_ops(struct test_spec *test, struct ifobject *ifobject)
 
 	if (ifobject->xdp_flags & XDP_FLAGS_SKB_MODE) {
 		if (opts.attach_mode != XDP_ATTACHED_SKB) {
-			ksft_print_msg("ERROR: [%s] XDP prog not in SKB mode\n");
+			ksft_print_msg("ERROR: XDP prog not in SKB mode\n");
 			exit_with_error(-EINVAL);
 		}
 	} else if (ifobject->xdp_flags & XDP_FLAGS_DRV_MODE) {
 		if (opts.attach_mode != XDP_ATTACHED_DRV) {
-			ksft_print_msg("ERROR: [%s] XDP prog not in DRV mode\n");
+			ksft_print_msg("ERROR: XDP prog not in DRV mode\n");
 			exit_with_error(-EINVAL);
 		}
 	}
 
-	ret = xsk_socket__update_xskmap(ifobject->xsk->xsk, ifobject->xsk_map_fd);
-	if (ret)
-		exit_with_error(-ret);
+	bpf_update_xsk_map(ifobject, 0);
 }
 
 static void *worker_testapp_validate_tx(void *arg)
@@ -1372,8 +1427,7 @@ static void *worker_testapp_validate_rx(void *arg)
 	if (test->current_step == 1) {
 		thread_common_ops(test, ifobject);
 	} else {
-		bpf_map_delete_elem(ifobject->xsk_map_fd, &id);
-		xsk_socket__update_xskmap(ifobject->xsk->xsk, ifobject->xsk_map_fd);
+		bpf_update_xsk_map(ifobject, id);
 	}
 
 	fds.fd = xsk_socket__fd(ifobject->xsk->xsk);
@@ -1481,6 +1535,8 @@ static int testapp_validate_traffic(struct test_spec *test)
 	if (test->total_steps == test->current_step || test->fail) {
 		xsk_socket__delete(ifobj_tx->xsk->xsk);
 		xsk_socket__delete(ifobj_rx->xsk->xsk);
+		bpf_detach(ifobj_tx);
+		bpf_detach(ifobj_rx);
 		testapp_clean_xsk_umem(ifobj_rx);
 		if (!ifobj_tx->shared_umem)
 			testapp_clean_xsk_umem(ifobj_tx);
@@ -1531,16 +1587,12 @@ static void testapp_bidi(struct test_spec *test)
 
 static void swap_xsk_resources(struct ifobject *ifobj_tx, struct ifobject *ifobj_rx)
 {
-	int ret;
-
 	xsk_socket__delete(ifobj_tx->xsk->xsk);
 	xsk_socket__delete(ifobj_rx->xsk->xsk);
 	ifobj_tx->xsk = &ifobj_tx->xsk_arr[1];
 	ifobj_rx->xsk = &ifobj_rx->xsk_arr[1];
 
-	ret = xsk_socket__update_xskmap(ifobj_rx->xsk->xsk, ifobj_rx->xsk_map_fd);
-	if (ret)
-		exit_with_error(-ret);
+	bpf_update_xsk_map(ifobj_tx, 0);
 }
 
 static void testapp_bpf_res(struct test_spec *test)
@@ -1635,6 +1687,8 @@ static bool testapp_unaligned(struct test_spec *test)
 {
 	if (!hugepages_present(test->ifobj_tx)) {
 		ksft_test_result_skip("No 2M huge pages present.\n");
+		bpf_detach(test->ifobj_tx);
+		bpf_detach(test->ifobj_rx);
 		return false;
 	}
 
@@ -1947,10 +2001,16 @@ int main(int argc, char **argv)
 
 	for (i = 0; i < modes; i++)
 		for (j = 0; j < TEST_TYPE_MAX; j++) {
+			if (j != TEST_TYPE_RUN_TO_COMPLETION_SINGLE_PKT) continue; // XXX
+			if (i != TEST_MODE_DRV) continue; // XXX
+
 			test_spec_init(&test, ifobj_tx, ifobj_rx, i);
 			run_pkt_test(&test, i, j);
 			usleep(USLEEP_MAX);
 
+			xskxceiver__destroy(ifobj_tx->bpf_obj);
+			xskxceiver__destroy(ifobj_rx->bpf_obj);
+
 			if (test.fail)
 				failed_tests++;
 		}
diff --git a/tools/testing/selftests/bpf/xskxceiver.h b/tools/testing/selftests/bpf/xskxceiver.h
index edb76d2def9f..c27dcbdb030f 100644
--- a/tools/testing/selftests/bpf/xskxceiver.h
+++ b/tools/testing/selftests/bpf/xskxceiver.h
@@ -5,6 +5,8 @@
 #ifndef XSKXCEIVER_H_
 #define XSKXCEIVER_H_
 
+#include "xskxceiver.skel.h"
+
 #ifndef SOL_XDP
 #define SOL_XDP 283
 #endif
@@ -134,6 +136,7 @@ typedef void *(*thread_func_t)(void *arg);
 struct ifobject {
 	char ifname[MAX_INTERFACE_NAME_CHARS];
 	char nsname[MAX_INTERFACES_NAMESPACE_CHARS];
+	struct xskxceiver *bpf_obj;
 	struct xsk_socket_info *xsk;
 	struct xsk_socket_info *xsk_arr;
 	struct xsk_umem_info *umem;
@@ -141,7 +144,7 @@ struct ifobject {
 	validation_func_t validation_func;
 	struct pkt_stream *pkt_stream;
 	int ns_fd;
-	int xsk_map_fd;
+	int ifindex;
 	u32 dst_ip;
 	u32 src_ip;
 	u32 xdp_flags;
-- 
2.38.1.273.g43a17bfeac-goog


  parent reply	other threads:[~2022-10-27 20:00 UTC|newest]

Thread overview: 50+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-10-27 20:00 [xdp-hints] [RFC bpf-next 0/5] xdp: hints via kfuncs Stanislav Fomichev
2022-10-27 20:00 ` [xdp-hints] [RFC bpf-next 1/5] bpf: Support inlined/unrolled kfuncs for xdp metadata Stanislav Fomichev
2022-10-27 20:00 ` [xdp-hints] [RFC bpf-next 2/5] veth: Support rx timestamp metadata for xdp Stanislav Fomichev
2022-10-28  8:40   ` [xdp-hints] " Jesper Dangaard Brouer
2022-10-28 18:46     ` Stanislav Fomichev
2022-10-27 20:00 ` [xdp-hints] [RFC bpf-next 3/5] libbpf: Pass prog_ifindex via bpf_object_open_opts Stanislav Fomichev
2022-10-27 20:05   ` [xdp-hints] " Andrii Nakryiko
2022-10-27 20:10     ` Stanislav Fomichev
2022-10-27 20:00 ` Stanislav Fomichev [this message]
2022-10-27 20:00 ` [xdp-hints] [RFC bpf-next 5/5] selftests/bpf: Test rx_timestamp metadata in xskxceiver Stanislav Fomichev
2022-10-28  6:22   ` [xdp-hints] " Martin KaFai Lau
2022-10-28 10:37     ` Jesper Dangaard Brouer
2022-10-28 18:46       ` Stanislav Fomichev
2022-10-31 14:20         ` Alexander Lobakin
2022-10-31 14:29           ` Alexander Lobakin
2022-10-31 17:00           ` Stanislav Fomichev
2022-11-01 13:18             ` Jesper Dangaard Brouer
2022-11-01 20:12               ` Stanislav Fomichev
2022-11-01 22:23               ` Toke Høiland-Jørgensen
2022-10-28 15:58 ` [xdp-hints] Re: [RFC bpf-next 0/5] xdp: hints via kfuncs John Fastabend
2022-10-28 18:04   ` Jakub Kicinski
2022-10-28 18:46     ` Stanislav Fomichev
2022-10-28 23:16       ` John Fastabend
2022-10-29  1:14         ` Jakub Kicinski
2022-10-31 14:10           ` Bezdeka, Florian
2022-10-31 15:28             ` Toke Høiland-Jørgensen
2022-10-31 17:00               ` Stanislav Fomichev
2022-10-31 22:57                 ` Martin KaFai Lau
2022-11-01  1:59                   ` Stanislav Fomichev
2022-11-01 12:52                     ` Toke Høiland-Jørgensen
2022-11-01 13:43                       ` David Ahern
2022-11-01 14:20                         ` Toke Høiland-Jørgensen
2022-11-01 17:05                     ` Martin KaFai Lau
2022-11-01 20:12                       ` Stanislav Fomichev
2022-11-02 14:06                       ` Jesper Dangaard Brouer
2022-11-02 22:01                         ` Toke Høiland-Jørgensen
2022-11-02 23:10                           ` Stanislav Fomichev
2022-11-03  0:09                             ` Toke Høiland-Jørgensen
2022-11-03 12:01                               ` Jesper Dangaard Brouer
2022-11-03 12:48                                 ` Toke Høiland-Jørgensen
2022-11-03 15:25                                   ` Jesper Dangaard Brouer
2022-10-31 19:36               ` Yonghong Song
2022-10-31 22:09                 ` Stanislav Fomichev
2022-10-31 22:38                   ` Yonghong Song
2022-10-31 22:55                     ` Stanislav Fomichev
2022-11-01 14:23                       ` Jesper Dangaard Brouer
2022-11-01 17:31                   ` Martin KaFai Lau
2022-11-01 20:12                     ` Stanislav Fomichev
2022-11-01 21:17                       ` Martin KaFai Lau
2022-10-31 17:01           ` John Fastabend

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://lists.xdp-project.net/postorius/lists/xdp-hints.xdp-project.net/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20221027200019.4106375-5-sdf@google.com \
    --to=sdf@google.com \
    --cc=alexandr.lobakin@intel.com \
    --cc=anatoly.burakov@intel.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=brouer@redhat.com \
    --cc=daniel@iogearbox.net \
    --cc=haoluo@google.com \
    --cc=john.fastabend@gmail.com \
    --cc=jolsa@kernel.org \
    --cc=kpsingh@kernel.org \
    --cc=kuba@kernel.org \
    --cc=magnus.karlsson@gmail.com \
    --cc=martin.lau@linux.dev \
    --cc=mtahhan@redhat.com \
    --cc=netdev@vger.kernel.org \
    --cc=song@kernel.org \
    --cc=willemb@google.com \
    --cc=xdp-hints@xdp-project.net \
    --cc=yhs@fb.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox