From nobody Fri Dec 19 21:17:23 2025 Received: from mail-pg1-f202.google.com (mail-pg1-f202.google.com [209.85.215.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E7E6A3148B8 for ; Thu, 4 Dec 2025 02:50:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764816638; cv=none; b=FftqEyaPIdqogIh5xmbi2o3DaRiz3OvFrivjOrMBXJljlWkleIMjqP/C2n0znHYglHYN7YYVDxTWwMeu0SgjlsI4oAusyBNl8RABBMphhKP8FsINfdOPvme/Jhc1Tl/tMCOYhfaXQxAGXj5PTURGxiApOiTWCKWfsDwCYGGaqlA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764816638; c=relaxed/simple; bh=QCDqMS2iL6NJvwlOUAHOfCZ1wJXr07eE1QzpvwzI2kI=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=WKkb23Ty5dg0Mx5orVrcxVK3WePqp40OuWQrhmDom20tieJqIQxEoAwwkwbRtHnWWcycu1Dz8F+NxxnVFrUw3vMVbm4CbQw7OesWimks4u81Y7oM9YZYdPF0OFvqxMsFcA51RJbcG1kq9/nS0Et1gmXYqDrerKi9PP71reNAml0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--wusamuel.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=bnSJ4n+B; arc=none smtp.client-ip=209.85.215.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--wusamuel.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="bnSJ4n+B" Received: by mail-pg1-f202.google.com with SMTP id 41be03b00d2f7-bb27b422cf2so665993a12.1 for ; Wed, 03 Dec 2025 18:50:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1764816631; x=1765421431; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=3ojdYWQIWL/SNwbxa/IEirZwm3RCurubO9Kbb4a3348=; b=bnSJ4n+Buhvxweu8ey2pvCqDrfyzoP2+Oa8sg9E8tg0pYUxmjs1dXp71W4jLbmbv8F DeoOBwK7UM7eQq7K69/dzzD59LEkb7RUmtKrmnBS4FG9jXvXoqX29JR6ik7bFsIRu73Q fYQg1X65bBN5WWWMXteBqFRF4lpd301wpABf+iilN2MiuRKrZxP7ILrFKt04QkREL5lk XytzKL+Lg0n9/PLIYOAdZUkbPnOOytGfEph1gedwCNAL5+qkOc+s5z3ry4PZ2PjMaoUm o8k8V4JZOfjv5eRndEmKT0FZ/qeSjcK5oNXB2J3JIRM54Jwk0owufM4tTwmsjOwqNAUC anuw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1764816631; x=1765421431; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=3ojdYWQIWL/SNwbxa/IEirZwm3RCurubO9Kbb4a3348=; b=RsBaFNur3faGKHuJjIP4mVXlqCcKvGYbFmUutpBtP0rhDoGMssodCHQe9+DwwgdAUc k2Uqr20Gx9xJZHDyQl2bItObKkeHGk23XT/g2bNv7CvVbAfvGpfOG0kJyPwar0umzHSm 4zT3AX184CTQrr1gfPZd8Z66BxCoAfcA01twTb2xtNYWUK8NrQd+NoNn9sdRC6z3REnE pDQkCV2luJS5ePmB+hb+WVpYO01L8wd3L7871AzRXs2C9KXlJqvJJW6LFRgb4Sz54BzX 7clRULTsC1IZlsA9X8Ryc4vpqYrOFCnj+HVjHDg1FDXGtrhLrodiBAThElzsahpI/qqP LJrg== X-Forwarded-Encrypted: i=1; AJvYcCVb9mdIsc7U+DVRiagCJr7BRoEAmzzsdRYWH7GrHsvFJp7VmCPsMEmzITSRlLW5QETMLnpV5P1Z2OIlvtw=@vger.kernel.org X-Gm-Message-State: AOJu0YzBJVGHPSB0GdnZZLhgVdvHzYn4XUjcgYMKBhsYTA/vh+T12DYT srH5/1VOFvjPK0PPqWiCZPeOgeckb30zrN9qD0voykWyFRcuvLen/az2zVe+dcTxEZpRQyXGeXG jOL/1DCo5TljkPA== X-Google-Smtp-Source: AGHT+IE1IL3Y10G3B/sbvEiw46evUWtOH5VTTCB2roL1OD61dgKPHCl58pJNgzJKYfsG+Vq6sx889nyqCyW1Bg== X-Received: from dycsd11.prod.google.com ([2002:a05:693c:310b:b0:2a4:5ebc:ca00]) (user=wusamuel job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7300:640d:b0:2a4:3593:9689 with SMTP id 5a478bee46e88-2ab92d39d41mr3811313eec.6.1764816631033; Wed, 03 Dec 2025 18:50:31 -0800 (PST) Date: Wed, 3 Dec 2025 18:50:01 -0800 In-Reply-To: <20251204025003.3162056-1-wusamuel@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251204025003.3162056-1-wusamuel@google.com> X-Mailer: git-send-email 2.52.0.177.g9f829587af-goog Message-ID: <20251204025003.3162056-5-wusamuel@google.com> Subject: [PATCH v1 4/4] selftests/bpf: Open coded BPF wakeup_sources test From: Samuel Wu To: Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Martin KaFai Lau , Eduard Zingerman , Song Liu , Yonghong Song , John Fastabend , KP Singh , Stanislav Fomichev , Hao Luo , Jiri Olsa , Shuah Khan Cc: rafael.j.wysocki@intel.com, Samuel Wu , kernel-team@android.com, linux-kernel@vger.kernel.org, bpf@vger.kernel.org, linux-kselftest@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" This commit introduces a new selftest for the BPF wakeup_source iterator to verify the functionality of open-coded iteration. The test adds: - A new BPF map `test_ws_hash` to track iterated wakeup source names. - A BPF program `iter_ws_for_each` that iterates over wakeup sources and updates the `test_ws_hash` map with the names of found sources. - A new subtest `subtest_ws_iter_check_open_coded` to trigger the BPF program and assert that the expected wakeup sources are marked in the map. Signed-off-by: Samuel Wu --- .../testing/selftests/bpf/bpf_experimental.h | 5 ++ .../bpf/prog_tests/wakeup_source_iter.c | 42 +++++++++++++++++ .../selftests/bpf/progs/wakeup_source_iter.c | 47 +++++++++++++++++++ 3 files changed, 94 insertions(+) diff --git a/tools/testing/selftests/bpf/bpf_experimental.h b/tools/testing= /selftests/bpf/bpf_experimental.h index 2cd9165c7348..e532999b91ca 100644 --- a/tools/testing/selftests/bpf/bpf_experimental.h +++ b/tools/testing/selftests/bpf/bpf_experimental.h @@ -598,6 +598,11 @@ extern void bpf_iter_dmabuf_destroy(struct bpf_iter_dm= abuf *it) __weak __ksym; =20 extern int bpf_cgroup_read_xattr(struct cgroup *cgroup, const char *name__= str, struct bpf_dynptr *value_p) __weak __ksym; +struct bpf_iter_wakeup_source; +extern int bpf_iter_wakeup_source_new(struct bpf_iter_wakeup_source *it) _= _weak __ksym; +extern struct wakeup_source *bpf_iter_wakeup_source_next( + struct bpf_iter_wakeup_source *it) __weak __ksym; +extern void bpf_iter_wakeup_source_destroy(struct bpf_iter_wakeup_source *= it) __weak __ksym; =20 #define PREEMPT_BITS 8 #define SOFTIRQ_BITS 8 diff --git a/tools/testing/selftests/bpf/prog_tests/wakeup_source_iter.c b/= tools/testing/selftests/bpf/prog_tests/wakeup_source_iter.c index 5cea4d4458f3..b2eaba38cc68 100644 --- a/tools/testing/selftests/bpf/prog_tests/wakeup_source_iter.c +++ b/tools/testing/selftests/bpf/prog_tests/wakeup_source_iter.c @@ -241,9 +241,37 @@ static void subtest_ws_iter_check_no_infinite_reads( close(iter_fd); } =20 +static void subtest_ws_iter_check_open_coded(struct wakeup_source_iter *sk= el, + int map_fd) +{ + LIBBPF_OPTS(bpf_test_run_opts, topts); + char key[WAKEUP_SOURCE_NAME_LEN] =3D {0}; + int err, fd; + bool found =3D false; + + fd =3D bpf_program__fd(skel->progs.iter_ws_for_each); + + err =3D bpf_prog_test_run_opts(fd, &topts); + if (!ASSERT_OK(err, "test_run_opts err")) + return; + if (!ASSERT_OK(topts.retval, "test_run_opts retval")) + return; + + strncpy(key, test_ws_name, WAKEUP_SOURCE_NAME_LEN - 1); + + if (!ASSERT_OK(bpf_map_lookup_elem(map_fd, key, &found), + "lookup test_ws_name")) + return; + + ASSERT_TRUE(found, "found test ws via bpf_for_each"); +} + void test_wakeup_source_iter(void) { struct wakeup_source_iter *skel =3D NULL; + int map_fd; + const bool found_val =3D false; + char key[WAKEUP_SOURCE_NAME_LEN] =3D {0}; =20 if (geteuid() !=3D 0) { fprintf(stderr, @@ -256,6 +284,17 @@ void test_wakeup_source_iter(void) if (!ASSERT_OK_PTR(skel, "wakeup_source_iter__open_and_load")) return; =20 + map_fd =3D bpf_map__fd(skel->maps.test_ws_hash); + if (!ASSERT_OK_FD(map_fd, "map_fd")) + goto destroy_skel; + + /* Copy test name to key buffer, ensuring it's zero-padded */ + strncpy(key, test_ws_name, WAKEUP_SOURCE_NAME_LEN - 1); + + if (!ASSERT_OK(bpf_map_update_elem(map_fd, key, &found_val, BPF_ANY), + "insert test_ws_name")) + goto destroy_skel; + if (!ASSERT_OK(setup_test_ws(), "setup_test_ws")) goto destroy; =20 @@ -274,8 +313,11 @@ void test_wakeup_source_iter(void) subtest_ws_iter_check_sleep_times(skel); if (test__start_subtest("no_infinite_reads")) subtest_ws_iter_check_no_infinite_reads(skel); + if (test__start_subtest("open_coded")) + subtest_ws_iter_check_open_coded(skel, map_fd); =20 destroy: teardown_test_ws(); +destroy_skel: wakeup_source_iter__destroy(skel); } diff --git a/tools/testing/selftests/bpf/progs/wakeup_source_iter.c b/tools= /testing/selftests/bpf/progs/wakeup_source_iter.c index 8c1470f06740..7812e773aa0c 100644 --- a/tools/testing/selftests/bpf/progs/wakeup_source_iter.c +++ b/tools/testing/selftests/bpf/progs/wakeup_source_iter.c @@ -9,6 +9,13 @@ =20 char _license[] SEC("license") =3D "GPL"; =20 +struct { + __uint(type, BPF_MAP_TYPE_HASH); + __uint(key_size, WAKEUP_SOURCE_NAME_LEN); + __type(value, bool); + __uint(max_entries, 5); +} test_ws_hash SEC(".maps"); + SEC("iter/wakeup_source") int wakeup_source_collector(struct bpf_iter__wakeup_source *ctx) { @@ -68,3 +75,43 @@ int wakeup_source_collector(struct bpf_iter__wakeup_sour= ce *ctx) wakeup_count); return 0; } + +SEC("syscall") +int iter_ws_for_each(const void *ctx) +{ + struct wakeup_source *ws; + + bpf_for_each(wakeup_source, ws) { + char name[WAKEUP_SOURCE_NAME_LEN]; + const char *pname; + bool *found; + long len; + int i; + + if (bpf_core_read(&pname, sizeof(pname), &ws->name)) + return 1; + + if (!pname) + continue; + + len =3D bpf_probe_read_kernel_str(name, sizeof(name), pname); + if (len < 0) + return 1; + + /* + * Clear the remainder of the buffer to ensure a stable key for + * the map lookup. + */ + bpf_for(i, len, WAKEUP_SOURCE_NAME_LEN) + name[i] =3D 0; + + found =3D bpf_map_lookup_elem(&test_ws_hash, name); + if (found) { + bool t =3D true; + + bpf_map_update_elem(&test_ws_hash, name, &t, BPF_EXIST); + } + } + + return 0; +} --=20 2.52.0.177.g9f829587af-goog