rcu.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Hou Tao <hotforest@gmail.com>
To: bpf@vger.kernel.org, rcu@vger.kernel.org
Cc: linux-kernel@vger.kernel.org, Alexei Starovoitov <ast@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>,
	Andrii Nakryiko <andrii@kernel.org>,
	Martin KaFai Lau <martin.lau@linux.dev>,
	Eduard Zingerman <eddyz87@gmail.com>, Song Liu <song@kernel.org>,
	Yonghong Song <yonghong.song@linux.dev>,
	John Fastabend <john.fastabend@gmail.com>,
	KP Singh <kpsingh@kernel.org>,
	Stanislav Fomichev <sdf@fomichev.me>, Hao Luo <haoluo@google.com>,
	Jiri Olsa <jolsa@kernel.org>,
	"Paul E . McKenney" <paulmck@kernel.org>,
	houtao1@huawei.com, hotforest@gmail.com
Subject: [PATCH bpf-next 3/3] selftests/bpf: Add test case for atomic htab update
Date: Tue,  4 Feb 2025 16:28:48 +0800	[thread overview]
Message-ID: <20250204082848.13471-4-hotforest@gmail.com> (raw)
In-Reply-To: <20250204082848.13471-1-hotforest@gmail.com>

Add a test case to verify the atomic update of existing element in hash
map. The test proceeds in three steps:
1) fill the map with keys in the range [0, 63]
2) create 8 threads to lookup these keys concurrently
3) create 2 threads to overwrite these keys concurrently

Without atomic update support, the lookup operation may return -ENOENT
error and the test will fail. After the atomic-update change, the lookup
operation will always return 0 and the test will succeed.

Signed-off-by: Hou Tao <hotforest@gmail.com>
---
 .../selftests/bpf/prog_tests/htab_lookup.c    | 130 ++++++++++++++++++
 .../testing/selftests/bpf/progs/htab_lookup.c |  13 ++
 2 files changed, 143 insertions(+)
 create mode 100644 tools/testing/selftests/bpf/prog_tests/htab_lookup.c
 create mode 100644 tools/testing/selftests/bpf/progs/htab_lookup.c

diff --git a/tools/testing/selftests/bpf/prog_tests/htab_lookup.c b/tools/testing/selftests/bpf/prog_tests/htab_lookup.c
new file mode 100644
index 000000000000..ef9036827439
--- /dev/null
+++ b/tools/testing/selftests/bpf/prog_tests/htab_lookup.c
@@ -0,0 +1,130 @@
+// SPDX-License-Identifier: GPL-2.0
+#define _GNU_SOURCE
+#include <stdbool.h>
+#include <test_progs.h>
+#include "htab_lookup.skel.h"
+
+struct htab_op_ctx {
+	int fd;
+	int loop;
+	unsigned int entries;
+	bool stop;
+};
+
+static void *htab_lookup_fn(void *arg)
+{
+	struct htab_op_ctx *ctx = arg;
+	int i = 0;
+
+	while (i++ < ctx->loop && !ctx->stop) {
+		unsigned int j;
+
+		for (j = 0; j < ctx->entries; j++) {
+			unsigned long key = j, value;
+			int err;
+
+			err = bpf_map_lookup_elem(ctx->fd, &key, &value);
+			if (err) {
+				ctx->stop = true;
+				return (void *)(long)err;
+			}
+		}
+	}
+
+	return NULL;
+}
+
+static void *htab_update_fn(void *arg)
+{
+	struct htab_op_ctx *ctx = arg;
+	int i = 0;
+
+	while (i++ < ctx->loop && !ctx->stop) {
+		unsigned int j;
+
+		for (j = 0; j < ctx->entries; j++) {
+			unsigned long key = j, value = j;
+			int err;
+
+			err = bpf_map_update_elem(ctx->fd, &key, &value, BPF_EXIST);
+			if (err) {
+				if (err == -ENOMEM)
+					continue;
+				ctx->stop = true;
+				return (void *)(long)err;
+			}
+		}
+	}
+
+	return NULL;
+}
+
+static int setup_htab(int fd, unsigned int entries)
+{
+	unsigned int i;
+
+	for (i = 0; i < entries; i++) {
+		unsigned long key = i, value = i;
+		int err;
+
+		err = bpf_map_update_elem(fd, &key, &value, 0);
+		if (!ASSERT_OK(err, "init update"))
+			return -1;
+	}
+
+	return 0;
+}
+
+void test_htab_lookup(void)
+{
+	unsigned int i, wr_nr = 2, rd_nr = 8;
+	pthread_t tids[wr_nr + rd_nr];
+	struct htab_lookup *skel;
+	struct htab_op_ctx ctx;
+	int err;
+
+	skel = htab_lookup__open_and_load();
+	if (!ASSERT_OK_PTR(skel, "htab_lookup__open_and_load"))
+		return;
+
+	ctx.fd = bpf_map__fd(skel->maps.htab);
+	ctx.loop = 50;
+	ctx.stop = false;
+	ctx.entries = 64;
+
+	err = setup_htab(ctx.fd, ctx.entries);
+	if (err)
+		goto destroy;
+
+	memset(tids, 0, sizeof(tids));
+	for (i = 0; i < wr_nr; i++) {
+		err = pthread_create(&tids[i], NULL, htab_update_fn, &ctx);
+		if (!ASSERT_OK(err, "pthread_create")) {
+			ctx.stop = true;
+			goto reap;
+		}
+	}
+	for (i = 0; i < rd_nr; i++) {
+		err = pthread_create(&tids[i + wr_nr], NULL, htab_lookup_fn, &ctx);
+		if (!ASSERT_OK(err, "pthread_create")) {
+			ctx.stop = true;
+			goto reap;
+		}
+	}
+
+reap:
+	for (i = 0; i < wr_nr + rd_nr; i++) {
+		void *ret = NULL;
+		char desc[32];
+
+		if (!tids[i])
+			continue;
+
+		snprintf(desc, sizeof(desc), "thread %u", i + 1);
+		err = pthread_join(tids[i], &ret);
+		ASSERT_OK(err, desc);
+		ASSERT_EQ(ret, NULL, desc);
+	}
+destroy:
+	htab_lookup__destroy(skel);
+}
diff --git a/tools/testing/selftests/bpf/progs/htab_lookup.c b/tools/testing/selftests/bpf/progs/htab_lookup.c
new file mode 100644
index 000000000000..baa30fa5b84f
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/htab_lookup.c
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/bpf.h>
+#include <bpf/bpf_helpers.h>
+
+char _license[] SEC("license") = "GPL";
+
+struct {
+	__uint(type, BPF_MAP_TYPE_HASH);
+	__uint(max_entries, 64);
+	__type(key, unsigned long);
+	__type(value, unsigned long);
+	__uint(map_flags, BPF_F_NO_PREALLOC);
+} htab SEC(".maps");
-- 
2.48.1


      parent reply	other threads:[~2025-02-04  8:29 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-02-04  8:28 [PATCH bpf-next 0/3] bpf: Overwrite the htab element atomically Hou Tao
2025-02-04  8:28 ` [PATCH bpf-next 1/3] rculist: add hlist_nulls_replace_rcu() helper Hou Tao
2025-02-04  8:28 ` [PATCH bpf-next 2/3] bpf: Overwrite the element in hash map atomically Hou Tao
2025-02-05  1:38   ` [RESEND] " Hou Tao
2025-02-06 15:05     ` Toke Høiland-Jørgensen
2025-02-08 10:16       ` Hou Tao
2025-02-26  3:24         ` Alexei Starovoitov
2025-02-26  4:05           ` Hou Tao
2025-02-26  5:42             ` Alexei Starovoitov
2025-02-26 23:17               ` Zvi Effron
2025-02-27  1:48                 ` Hou Tao
2025-02-27  1:59                   ` Alexei Starovoitov
2025-02-27  2:43                     ` Hou Tao
2025-02-27  3:17                       ` Alexei Starovoitov
2025-02-27  4:08                         ` Hou Tao
2025-03-06 10:22                         ` Nick Zavaritsky
2025-02-04  8:28 ` Hou Tao [this message]

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

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

  git send-email \
    --in-reply-to=20250204082848.13471-4-hotforest@gmail.com \
    --to=hotforest@gmail.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=eddyz87@gmail.com \
    --cc=haoluo@google.com \
    --cc=houtao1@huawei.com \
    --cc=john.fastabend@gmail.com \
    --cc=jolsa@kernel.org \
    --cc=kpsingh@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=martin.lau@linux.dev \
    --cc=paulmck@kernel.org \
    --cc=rcu@vger.kernel.org \
    --cc=sdf@fomichev.me \
    --cc=song@kernel.org \
    --cc=yonghong.song@linux.dev \
    /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;
as well as URLs for NNTP newsgroup(s).