mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH bpf-next v3 0/3] Add wakeup_source iterators
@ 2026-01-24  1:21 Samuel Wu
  2026-01-24  1:21 ` [PATCH bpf-next v3 1/3] PM: wakeup: Handle empty list in wakeup_sources_walk Samuel Wu
                   ` (2 more replies)
  0 siblings, 3 replies; 11+ messages in thread
From: Samuel Wu @ 2026-01-24  1:21 UTC (permalink / raw)
  To: Rafael J. Wysocki, Len Brown, Pavel Machek, Greg Kroah-Hartman,
	Danilo Krummrich, 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: Samuel Wu, kernel-team, linux-kernel, linux-pm, bpf, linux-kselftest

This patch series introduces BPF iterators for wakeup_source, enabling
BPF programs to efficiently traverse a device's wakeup sources.

Currently, inspecting wakeup sources typically involves reading interfaces
like /sys/class/wakeup/* or debugfs. The repeated syscalls to query the
sysfs nodes is inefficient, as there can be hundreds of wakeup_sources, and
each wakeup source have multiple stats, with one sysfs node per stat.
debugfs is unstable and insecure.

The iterators utilize pre-existing wakeup_sources_walk_* functions to
traverse over the SRCU that backs the list of wakeup_sources.

Changes in v3:
 - Update wakeup_sources_walk_start() to handle an empty list per bpf-ci
 - Simplify read of a struct's field in BPF program selftest per Andrii
 - Drop open coded iterators for wakeup_sources
 - Fix condition from !get_ws_iter_stream to get_ws_iter_stream in selftest
 - Read event_count instead of wakeup_count in selftest
 - v2 link: https://lore.kernel.org/all/20260108225523.3268383-1-wusamuel@google.com/

Changes in v2:
 - Guard BPF Makefile with CONFIG_PM_SLEEP to fix build errors
 - Update copyright from 2025 to 2026
 - v1 link: https://lore.kernel.org/all/20251204025003.3162056-1-wusamuel@google.com/

Samuel Wu (3):
  PM: wakeup: Handle empty list in wakeup_sources_walk
  bpf: Add wakeup_source iterator
  selftests/bpf: Add tests for wakeup_sources

 drivers/base/power/wakeup.c                   |   4 +-
 kernel/bpf/Makefile                           |   3 +
 kernel/bpf/wakeup_source_iter.c               | 103 +++++++
 tools/testing/selftests/bpf/config            |   1 +
 .../bpf/prog_tests/wakeup_source_iter.c       | 281 ++++++++++++++++++
 .../selftests/bpf/progs/wakeup_source_iter.c  |  60 ++++
 6 files changed, 449 insertions(+), 3 deletions(-)
 create mode 100644 kernel/bpf/wakeup_source_iter.c
 create mode 100644 tools/testing/selftests/bpf/prog_tests/wakeup_source_iter.c
 create mode 100644 tools/testing/selftests/bpf/progs/wakeup_source_iter.c

-- 
2.52.0.457.g6b5491de43-goog


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH bpf-next v3 1/3] PM: wakeup: Handle empty list in wakeup_sources_walk
  2026-01-24  1:21 [PATCH bpf-next v3 0/3] Add wakeup_source iterators Samuel Wu
@ 2026-01-24  1:21 ` Samuel Wu
  2026-01-27 16:15   ` Rafael J. Wysocki
  2026-01-24  1:21 ` [PATCH bpf-next v3 2/3] bpf: Add wakeup_source iterator Samuel Wu
  2026-01-24  1:21 ` [PATCH bpf-next v3 3/3] selftests/bpf: Add tests for wakeup_sources Samuel Wu
  2 siblings, 1 reply; 11+ messages in thread
From: Samuel Wu @ 2026-01-24  1:21 UTC (permalink / raw)
  To: Rafael J. Wysocki, Len Brown, Pavel Machek, Greg Kroah-Hartman,
	Danilo Krummrich, 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: Samuel Wu, kernel-team, linux-kernel, linux-pm, bpf, linux-kselftest

In the case of an empty wakeup_sources list, wakeup_sources_walk_start()
will return an invalid but non-NULL address. This also affects wrappers
of the aforementioned function, like for_each_wakeup_source().

This patch updates wakeup_sources_walk_start() to return NULL in case of
an empty list.

Signed-off-by: Samuel Wu <wusamuel@google.com>
---
 drivers/base/power/wakeup.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c
index 1e1a0e7eeac5..e69033d16fba 100644
--- a/drivers/base/power/wakeup.c
+++ b/drivers/base/power/wakeup.c
@@ -275,9 +275,7 @@ EXPORT_SYMBOL_GPL(wakeup_sources_read_unlock);
  */
 struct wakeup_source *wakeup_sources_walk_start(void)
 {
-	struct list_head *ws_head = &wakeup_sources;
-
-	return list_entry_rcu(ws_head->next, struct wakeup_source, entry);
+	return list_first_or_null_rcu(&wakeup_sources, struct wakeup_source, entry);
 }
 EXPORT_SYMBOL_GPL(wakeup_sources_walk_start);
 
-- 
2.52.0.457.g6b5491de43-goog


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH bpf-next v3 2/3] bpf: Add wakeup_source iterator
  2026-01-24  1:21 [PATCH bpf-next v3 0/3] Add wakeup_source iterators Samuel Wu
  2026-01-24  1:21 ` [PATCH bpf-next v3 1/3] PM: wakeup: Handle empty list in wakeup_sources_walk Samuel Wu
@ 2026-01-24  1:21 ` Samuel Wu
  2026-01-24  1:50   ` bot+bpf-ci
  2026-01-24  1:21 ` [PATCH bpf-next v3 3/3] selftests/bpf: Add tests for wakeup_sources Samuel Wu
  2 siblings, 1 reply; 11+ messages in thread
From: Samuel Wu @ 2026-01-24  1:21 UTC (permalink / raw)
  To: Rafael J. Wysocki, Len Brown, Pavel Machek, Greg Kroah-Hartman,
	Danilo Krummrich, 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: Samuel Wu, kernel-team, linux-kernel, linux-pm, bpf, linux-kselftest

Add a BPF iterator for traversing through wakeup_sources.

Setup iterators to traverse through a SRCUs of wakeup_sources. This is a
more elegant and efficient traversal than going through the options
today, such as at /sys/class/wakeup, or through debugfs.

Signed-off-by: Samuel Wu <wusamuel@google.com>
---
 kernel/bpf/Makefile             |   3 +
 kernel/bpf/wakeup_source_iter.c | 103 ++++++++++++++++++++++++++++++++
 2 files changed, 106 insertions(+)
 create mode 100644 kernel/bpf/wakeup_source_iter.c

diff --git a/kernel/bpf/Makefile b/kernel/bpf/Makefile
index 79cf22860a99..1259373298e1 100644
--- a/kernel/bpf/Makefile
+++ b/kernel/bpf/Makefile
@@ -66,6 +66,9 @@ obj-$(CONFIG_BPF_SYSCALL) += kmem_cache_iter.o
 ifeq ($(CONFIG_DMA_SHARED_BUFFER),y)
 obj-$(CONFIG_BPF_SYSCALL) += dmabuf_iter.o
 endif
+ifeq ($(CONFIG_PM_SLEEP),y)
+obj-$(CONFIG_BPF_SYSCALL) += wakeup_source_iter.o
+endif
 
 CFLAGS_REMOVE_percpu_freelist.o = $(CC_FLAGS_FTRACE)
 CFLAGS_REMOVE_bpf_lru_list.o = $(CC_FLAGS_FTRACE)
diff --git a/kernel/bpf/wakeup_source_iter.c b/kernel/bpf/wakeup_source_iter.c
new file mode 100644
index 000000000000..ab83d212a1f9
--- /dev/null
+++ b/kernel/bpf/wakeup_source_iter.c
@@ -0,0 +1,103 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (c) 2026 Google LLC */
+#include <linux/bpf.h>
+#include <linux/btf_ids.h>
+#include <linux/kernel.h>
+#include <linux/pm_wakeup.h>
+#include <linux/seq_file.h>
+
+struct bpf_iter__wakeup_source {
+	__bpf_md_ptr(struct bpf_iter_meta *, meta);
+	__bpf_md_ptr(struct wakeup_source *, wakeup_source);
+};
+
+static void *wakeup_source_iter_seq_start(struct seq_file *seq, loff_t *pos)
+{
+	int *srcuidx = seq->private;
+	struct wakeup_source *ws;
+	loff_t i;
+
+	*srcuidx = wakeup_sources_read_lock();
+
+	ws = wakeup_sources_walk_start();
+	for (i = 0; ws && i < *pos; i++)
+		ws = wakeup_sources_walk_next(ws);
+
+	return ws;
+}
+
+static void *wakeup_source_iter_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+	struct wakeup_source *ws = v;
+
+	++*pos;
+
+	return wakeup_sources_walk_next(ws);
+}
+
+static void wakeup_source_iter_seq_stop(struct seq_file *seq, void *v)
+{
+	int *srcuidx = seq->private;
+
+	if (*srcuidx >= 0)
+		wakeup_sources_read_unlock(*srcuidx);
+	*srcuidx = -1;
+}
+
+static int __wakeup_source_seq_show(struct seq_file *seq, void *v, bool in_stop)
+{
+	struct bpf_iter_meta meta = {
+		.seq = seq,
+	};
+	struct bpf_iter__wakeup_source ctx = {
+		.meta = &meta,
+		.wakeup_source = v,
+	};
+	struct bpf_prog *prog = bpf_iter_get_info(&meta, in_stop);
+
+	if (prog)
+		return bpf_iter_run_prog(prog, &ctx);
+
+	return 0;
+}
+
+static int wakeup_source_iter_seq_show(struct seq_file *seq, void *v)
+{
+	return __wakeup_source_seq_show(seq, v, false);
+}
+
+static const struct seq_operations wakeup_source_iter_seq_ops = {
+	.start	= wakeup_source_iter_seq_start,
+	.next	= wakeup_source_iter_seq_next,
+	.stop	= wakeup_source_iter_seq_stop,
+	.show	= wakeup_source_iter_seq_show,
+};
+
+static const struct bpf_iter_seq_info wakeup_source_iter_seq_info = {
+	.seq_ops		= &wakeup_source_iter_seq_ops,
+	.seq_priv_size		= sizeof(int),
+};
+
+static struct bpf_iter_reg bpf_wakeup_source_reg_info = {
+	.target			= "wakeup_source",
+	.ctx_arg_info_size	= 1,
+	.ctx_arg_info		= {
+		{
+			offsetof(struct bpf_iter__wakeup_source, wakeup_source),
+			PTR_TO_BTF_ID_OR_NULL
+		},
+	},
+	.seq_info		= &wakeup_source_iter_seq_info,
+};
+
+DEFINE_BPF_ITER_FUNC(wakeup_source, struct bpf_iter_meta *meta,
+		     struct wakeup_source *wakeup_source)
+BTF_ID_LIST_SINGLE(bpf_wakeup_source_btf_id, struct, wakeup_source)
+
+static int __init wakeup_source_iter_init(void)
+{
+	bpf_wakeup_source_reg_info.ctx_arg_info[0].btf_id = bpf_wakeup_source_btf_id[0];
+	return bpf_iter_reg_target(&bpf_wakeup_source_reg_info);
+}
+
+late_initcall(wakeup_source_iter_init);
-- 
2.52.0.457.g6b5491de43-goog


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH bpf-next v3 3/3] selftests/bpf: Add tests for wakeup_sources
  2026-01-24  1:21 [PATCH bpf-next v3 0/3] Add wakeup_source iterators Samuel Wu
  2026-01-24  1:21 ` [PATCH bpf-next v3 1/3] PM: wakeup: Handle empty list in wakeup_sources_walk Samuel Wu
  2026-01-24  1:21 ` [PATCH bpf-next v3 2/3] bpf: Add wakeup_source iterator Samuel Wu
@ 2026-01-24  1:21 ` Samuel Wu
  2026-01-24  1:50   ` bot+bpf-ci
  2 siblings, 1 reply; 11+ messages in thread
From: Samuel Wu @ 2026-01-24  1:21 UTC (permalink / raw)
  To: Rafael J. Wysocki, Len Brown, Pavel Machek, Greg Kroah-Hartman,
	Danilo Krummrich, 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: Samuel Wu, kernel-team, linux-kernel, linux-pm, bpf, linux-kselftest

Sets up the framework to test wakeup_sources iterators using BPF, and
adds a few basic tests.

Adds several helper functions that for grabbing and releasing a
wakelock, abstracting out key functions to setup a framework for testing
wakeup_sources.

Additionally, adds 3 tests:
1. check_active_count: Checks that stats related to active_count are
   properly set after several lock/unlock cycles
2. check_sleep_times: Checks that time accounting related to sleep are
   properly calculated
3. check_no_infinite_reads: Checks that the iterator traversal returns
   NULL at the end

Signed-off-by: Samuel Wu <wusamuel@google.com>
---
 tools/testing/selftests/bpf/config            |   1 +
 .../bpf/prog_tests/wakeup_source_iter.c       | 281 ++++++++++++++++++
 .../selftests/bpf/progs/wakeup_source_iter.c  |  60 ++++
 3 files changed, 342 insertions(+)
 create mode 100644 tools/testing/selftests/bpf/prog_tests/wakeup_source_iter.c
 create mode 100644 tools/testing/selftests/bpf/progs/wakeup_source_iter.c

diff --git a/tools/testing/selftests/bpf/config b/tools/testing/selftests/bpf/config
index 558839e3c185..c12c5e04b81f 100644
--- a/tools/testing/selftests/bpf/config
+++ b/tools/testing/selftests/bpf/config
@@ -111,6 +111,7 @@ CONFIG_IP6_NF_IPTABLES=y
 CONFIG_IP6_NF_FILTER=y
 CONFIG_NF_NAT=y
 CONFIG_PACKET=y
+CONFIG_PM_WAKELOCKS=y
 CONFIG_RC_CORE=y
 CONFIG_SAMPLES=y
 CONFIG_SAMPLE_LIVEPATCH=m
diff --git a/tools/testing/selftests/bpf/prog_tests/wakeup_source_iter.c b/tools/testing/selftests/bpf/prog_tests/wakeup_source_iter.c
new file mode 100644
index 000000000000..c8a38717e284
--- /dev/null
+++ b/tools/testing/selftests/bpf/prog_tests/wakeup_source_iter.c
@@ -0,0 +1,281 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2026 Google LLC */
+
+#include <test_progs.h>
+#include <bpf/libbpf.h>
+#include "wakeup_source_iter.skel.h"
+
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+
+/* Sleep for 10ms to ensure active time is > 0 after converting ns to ms*/
+#define TEST_SLEEP_US 10000
+#define TEST_SLEEP_MS (TEST_SLEEP_US / 1000)
+#define WAKEUP_SOURCE_NAME_LEN 32
+
+static const char test_ws_name[] = "bpf_selftest_ws";
+static bool test_ws_created;
+
+/*
+ * Creates a new wakeup source by writing to /sys/power/wake_lock.
+ * This lock persists until explicitly unlocked.
+ */
+static int lock_ws(const char *name)
+{
+	int fd;
+	ssize_t bytes;
+
+	fd = open("/sys/power/wake_lock", O_WRONLY);
+	if (!ASSERT_OK_FD(fd, "open /sys/power/wake_lock"))
+		return -1;
+
+	bytes = write(fd, name, strlen(name));
+	close(fd);
+	if (!ASSERT_EQ(bytes, strlen(name), "write to wake_lock"))
+		return -1;
+
+	return 0;
+}
+
+/*
+ * Destroys the ws by writing the same name to /sys/power/wake_unlock.
+ */
+static void unlock_ws(const char *name)
+{
+	int fd;
+
+	fd = open("/sys/power/wake_unlock", O_WRONLY);
+	if (!ASSERT_OK_FD(fd, "open /sys/power/wake_unlock"))
+		goto cleanup;
+
+	write(fd, name, strlen(name));
+
+cleanup:
+	if (fd)
+		close(fd);
+}
+
+/*
+ * Setups for testing ws iterators. Will run once prior to suite of tests.
+ */
+static int setup_test_ws(void)
+{
+	if (lock_ws(test_ws_name))
+		return -1;
+	test_ws_created = true;
+
+	return 0;
+}
+
+/*
+ * Tears down and cleanups testing ws iterators. WIll run once after the suite
+ * of tests.
+ */
+static void teardown_test_ws(void)
+{
+	if (!test_ws_created)
+		return;
+	unlock_ws(test_ws_name);
+	test_ws_created = false;
+}
+
+struct WakeupSourceInfo {
+	char name[WAKEUP_SOURCE_NAME_LEN];
+	unsigned long active_count;
+	long active_time_ms;
+	unsigned long event_count;
+	unsigned long expire_count;
+	long last_change_ms;
+	long max_time_ms;
+	long prevent_sleep_time_ms;
+	long total_time_ms;
+	unsigned long wakeup_count;
+};
+
+/*
+ * Reads and parses one wakeup_source record from the iterator file.
+ * A record is a single space-delimited line.
+ * Returns true on success, false on EOF. Asserts internally on errors.
+ */
+static bool read_ws_info(FILE *iter_file, struct WakeupSourceInfo *ws_info,
+			 char **line)
+{
+	size_t linesize;
+	int items;
+
+	if (getline(line, &linesize, iter_file) == -1)
+		return false;
+
+	(*line)[strcspn(*line, "\n")] = 0;
+
+	items = sscanf(*line, "%s %lu %ld %lu %lu %ld %ld %ld %ld %lu",
+		       ws_info->name, &ws_info->active_count,
+		       &ws_info->active_time_ms, &ws_info->event_count,
+		       &ws_info->expire_count, &ws_info->last_change_ms,
+		       &ws_info->max_time_ms, &ws_info->prevent_sleep_time_ms,
+		       &ws_info->total_time_ms, &ws_info->wakeup_count);
+
+	if (!ASSERT_EQ(items, 10, "read wakeup source info"))
+		return false;
+
+	if (!ASSERT_LT(strlen(ws_info->name), WAKEUP_SOURCE_NAME_LEN,
+		       "name length"))
+		return false;
+
+	return true;
+}
+
+static int get_ws_iter_stream(struct wakeup_source_iter *skel, int *iter_fd,
+			      FILE **iter_file)
+{
+	*iter_fd = bpf_iter_create(
+			bpf_link__fd(skel->links.wakeup_source_collector));
+	if (!ASSERT_OK_FD(*iter_fd, "iter_create"))
+		return -1;
+
+	*iter_file = fdopen(*iter_fd, "r");
+	if (!ASSERT_OK_PTR(*iter_file, "fdopen"))
+		return -1;
+
+	return 0;
+}
+
+static void subtest_ws_iter_check_active_count(struct wakeup_source_iter *skel)
+{
+	static const char subtest_ws_name[] = "bpf_selftest_ws_active_count";
+	const int lock_unlock_cycles = 5;
+	struct WakeupSourceInfo ws_info;
+	char *line = NULL;
+	bool found_ws = false;
+	FILE *iter_file = NULL;
+	int iter_fd = -1;
+	int i;
+
+	for (i = 0; i < lock_unlock_cycles; i++) {
+		if (!ASSERT_OK(lock_ws(subtest_ws_name), "lock_ws"))
+			goto cleanup;
+		unlock_ws(subtest_ws_name);
+	}
+
+	if (get_ws_iter_stream(skel, &iter_fd, &iter_file))
+		goto cleanup;
+
+	while (read_ws_info(iter_file, &ws_info, &line)) {
+		if (strcmp(ws_info.name, subtest_ws_name) == 0) {
+			found_ws = true;
+			ASSERT_EQ(ws_info.active_count, lock_unlock_cycles,
+				  "active_count check");
+			ASSERT_EQ(ws_info.event_count, lock_unlock_cycles,
+				  "event_count check");
+			break;
+		}
+	}
+
+	ASSERT_TRUE(found_ws, "found active_count test ws");
+
+	free(line);
+cleanup:
+	if (iter_file)
+		fclose(iter_file);
+	else if (iter_fd >= 0)
+		close(iter_fd);
+}
+
+static void subtest_ws_iter_check_sleep_times(struct wakeup_source_iter *skel)
+{
+	bool found_test_ws = false;
+	struct WakeupSourceInfo ws_info;
+	char *line = NULL;
+	FILE *iter_file;
+	int iter_fd;
+
+	if (get_ws_iter_stream(skel, &iter_fd, &iter_file))
+		goto cleanup;
+
+	while (read_ws_info(iter_file, &ws_info, &line)) {
+		if (strcmp(ws_info.name, test_ws_name) == 0) {
+			found_test_ws = true;
+			ASSERT_GT(ws_info.last_change_ms, 0,
+				  "Expected non-zero last change");
+			ASSERT_GE(ws_info.active_time_ms, TEST_SLEEP_MS,
+				  "Expected active time >= TEST_SLEEP_MS");
+			ASSERT_GE(ws_info.max_time_ms, TEST_SLEEP_MS,
+				  "Expected max time >= TEST_SLEEP_MS");
+			ASSERT_GE(ws_info.total_time_ms, TEST_SLEEP_MS,
+				  "Expected total time >= TEST_SLEEP_MS");
+			break;
+		}
+	}
+
+	ASSERT_TRUE(found_test_ws, "found_test_ws");
+
+	free(line);
+cleanup:
+	if (iter_file)
+		fclose(iter_file);
+	else if (iter_fd >= 0)
+		close(iter_fd);
+}
+
+static void subtest_ws_iter_check_no_infinite_reads(
+		struct wakeup_source_iter *skel)
+{
+	int iter_fd;
+	char buf[256];
+
+	iter_fd = bpf_iter_create(bpf_link__fd(skel->links.wakeup_source_collector));
+	if (!ASSERT_OK_FD(iter_fd, "iter_create"))
+		return;
+
+	while (read(iter_fd, buf, sizeof(buf)) > 0)
+		;
+
+	/* Final read should return 0 */
+	ASSERT_EQ(read(iter_fd, buf, sizeof(buf)), 0, "read");
+
+	close(iter_fd);
+}
+
+void test_wakeup_source_iter(void)
+{
+	struct wakeup_source_iter *skel = NULL;
+
+	if (geteuid() != 0) {
+		fprintf(stderr,
+			"Skipping wakeup_source_iter test, requires root\n");
+		test__skip();
+		return;
+	}
+
+	skel = wakeup_source_iter__open_and_load();
+	if (!ASSERT_OK_PTR(skel, "wakeup_source_iter__open_and_load"))
+		return;
+
+	if (!ASSERT_OK(setup_test_ws(), "setup_test_ws"))
+		goto destroy;
+
+	if (!ASSERT_OK(wakeup_source_iter__attach(skel), "skel_attach"))
+		goto destroy;
+
+	/*
+	 * Sleep on O(ms) to ensure that time stats' resolution isn't lost when
+	 * converting from ns to ms
+	 */
+	usleep(TEST_SLEEP_US);
+
+	if (test__start_subtest("active_count"))
+		subtest_ws_iter_check_active_count(skel);
+	if (test__start_subtest("sleep_times"))
+		subtest_ws_iter_check_sleep_times(skel);
+	if (test__start_subtest("no_infinite_reads"))
+		subtest_ws_iter_check_no_infinite_reads(skel);
+
+destroy:
+	teardown_test_ws();
+	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
new file mode 100644
index 000000000000..eb19569e4424
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/wakeup_source_iter.c
@@ -0,0 +1,60 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2026 Google LLC */
+#include <vmlinux.h>
+#include <bpf/bpf_core_read.h>
+#include <bpf/bpf_helpers.h>
+
+#define NSEC_PER_MS 1000000UL
+#define WAKEUP_SOURCE_NAME_LEN 32
+
+char _license[] SEC("license") = "GPL";
+
+SEC("iter/wakeup_source")
+int wakeup_source_collector(struct bpf_iter__wakeup_source *ctx)
+{
+	const struct wakeup_source *ws = ctx->wakeup_source;
+	struct seq_file *seq = ctx->meta->seq;
+	char name[WAKEUP_SOURCE_NAME_LEN] = {'\0'};
+	const char *pname;
+	bool active, autosleep_enable;
+	s64 active_time, curr_time, max_time, prevent_sleep_time, total_time;
+
+	if (!ws)
+		return 0;
+
+	active = BPF_CORE_READ_BITFIELD_PROBED(ws, active);
+	autosleep_enable = BPF_CORE_READ_BITFIELD_PROBED(ws, autosleep_enabled);
+	if (bpf_core_read(&pname, sizeof(pname), &ws->name) ||
+	    bpf_probe_read_kernel_str(name, sizeof(name), pname) < 0)
+		return 0;
+
+	active_time = 0;
+	curr_time = bpf_ktime_get_ns();
+	max_time = ws->max_time;
+	prevent_sleep_time = ws->prevent_sleep_time;
+	total_time = ws->total_time;
+
+	if (active) {
+		active_time = curr_time - ws->last_time;
+		total_time += active_time;
+		if (active_time > max_time)
+			max_time = active_time;
+		if (autosleep_enable)
+			prevent_sleep_time +=
+				curr_time - ws->start_prevent_time;
+	}
+
+	BPF_SEQ_PRINTF(seq,
+		       "%s %lu %ld %lu %lu %ld %ld %ld %ld %lu\n",
+		       name,
+		       ws->active_count,
+		       active_time / NSEC_PER_MS,
+		       ws->event_count,
+		       ws->expire_count,
+		       ws->last_time / NSEC_PER_MS,
+		       max_time / NSEC_PER_MS,
+		       prevent_sleep_time / NSEC_PER_MS,
+		       total_time / NSEC_PER_MS,
+		       ws->wakeup_count);
+	return 0;
+}
-- 
2.52.0.457.g6b5491de43-goog


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH bpf-next v3 3/3] selftests/bpf: Add tests for wakeup_sources
  2026-01-24  1:21 ` [PATCH bpf-next v3 3/3] selftests/bpf: Add tests for wakeup_sources Samuel Wu
@ 2026-01-24  1:50   ` bot+bpf-ci
  2026-02-02 20:27     ` Samuel Wu
  0 siblings, 1 reply; 11+ messages in thread
From: bot+bpf-ci @ 2026-01-24  1:50 UTC (permalink / raw)
  To: wusamuel, rafael, lenb, pavel, gregkh, dakr, ast, daniel, andrii,
	martin.lau, eddyz87, song, yonghong.song, john.fastabend,
	kpsingh, sdf, haoluo, jolsa, shuah
  Cc: wusamuel, kernel-team, linux-kernel, linux-pm, bpf,
	linux-kselftest, ast, andrii, daniel, martin.lau, eddyz87,
	yonghong.song, clm, ihor.solodrai

[-- Attachment #1: Type: text/plain, Size: 2071 bytes --]

> diff --git a/tools/testing/selftests/bpf/prog_tests/wakeup_source_iter.c b/tools/testing/selftests/bpf/prog_tests/wakeup_source_iter.c
> new file mode 100644
> index 000000000000..c8a38717e284
> --- /dev/null
> +++ b/tools/testing/selftests/bpf/prog_tests/wakeup_source_iter.c

[ ... ]

> +static int get_ws_iter_stream(struct wakeup_source_iter *skel, int *iter_fd,
> +			      FILE **iter_file)
> +{
> +	*iter_fd = bpf_iter_create(
> +			bpf_link__fd(skel->links.wakeup_source_collector));
> +	if (!ASSERT_OK_FD(*iter_fd, "iter_create"))
> +		return -1;
> +
> +	*iter_file = fdopen(*iter_fd, "r");
> +	if (!ASSERT_OK_PTR(*iter_file, "fdopen"))
> +		return -1;
> +
> +	return 0;
> +}

If bpf_iter_create() fails above, get_ws_iter_stream() returns -1 without
writing to *iter_file.

> +static void subtest_ws_iter_check_active_count(struct wakeup_source_iter *skel)
> +{

[ ... ]

> +	char *line = NULL;
> +	bool found_ws = false;
> +	FILE *iter_file = NULL;
> +	int iter_fd = -1;

This function correctly initializes iter_file and iter_fd before calling
get_ws_iter_stream().

[ ... ]

> +}
> +
> +static void subtest_ws_iter_check_sleep_times(struct wakeup_source_iter *skel)
> +{
> +	bool found_test_ws = false;
> +	struct WakeupSourceInfo ws_info;
> +	char *line = NULL;
> +	FILE *iter_file;
> +	int iter_fd;

In contrast to subtest_ws_iter_check_active_count(), iter_file and iter_fd
are not initialized here.

> +
> +	if (get_ws_iter_stream(skel, &iter_fd, &iter_file))
> +		goto cleanup;

[ ... ]

> +cleanup:
> +	if (iter_file)
> +		fclose(iter_file);
> +	else if (iter_fd >= 0)
> +		close(iter_fd);
> +}

If get_ws_iter_stream() fails at bpf_iter_create(), can this access
uninitialized iter_file and iter_fd? The cleanup code would then evaluate
garbage values, potentially calling fclose() with an invalid pointer.


---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md

CI run summary: https://github.com/kernel-patches/bpf/actions/runs/21306880863

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH bpf-next v3 2/3] bpf: Add wakeup_source iterator
  2026-01-24  1:21 ` [PATCH bpf-next v3 2/3] bpf: Add wakeup_source iterator Samuel Wu
@ 2026-01-24  1:50   ` bot+bpf-ci
  2026-02-02 20:33     ` Samuel Wu
  0 siblings, 1 reply; 11+ messages in thread
From: bot+bpf-ci @ 2026-01-24  1:50 UTC (permalink / raw)
  To: wusamuel, rafael, lenb, pavel, gregkh, dakr, ast, daniel, andrii,
	martin.lau, eddyz87, song, yonghong.song, john.fastabend,
	kpsingh, sdf, haoluo, jolsa, shuah
  Cc: wusamuel, kernel-team, linux-kernel, linux-pm, bpf,
	linux-kselftest, ast, andrii, daniel, martin.lau, eddyz87,
	yonghong.song, clm, ihor.solodrai

[-- Attachment #1: Type: text/plain, Size: 1548 bytes --]

> diff --git a/kernel/bpf/wakeup_source_iter.c b/kernel/bpf/wakeup_source_iter.c
> new file mode 100644
> index 000000000000..ab83d212a1f9
> --- /dev/null
> +++ b/kernel/bpf/wakeup_source_iter.c

[ ... ]

> +static void wakeup_source_iter_seq_stop(struct seq_file *seq, void *v)
> +{
> +	int *srcuidx = seq->private;
> +
> +	if (*srcuidx >= 0)
> +		wakeup_sources_read_unlock(*srcuidx);
> +	*srcuidx = -1;
> +}

Should this function call __wakeup_source_seq_show(seq, v, true) when v is
NULL to notify the BPF program that iteration has completed?

Looking at other BPF iterators like map_iter, prog_iter, link_iter,
task_iter, and kmem_cache_iter, they all invoke the BPF program with
in_stop=true when the stop callback receives a NULL pointer. For example,
map_iter does:

    static void bpf_map_seq_stop(struct seq_file *seq, void *v)
    {
        if (!v)
            (void)__bpf_map_seq_show(seq, v, true);
        ...
    }

The bpf_seq_read() function in kernel/bpf/bpf_iter.c has this comment at
the stop label: "/* bpf program called if !p */", which suggests this
callback is expected.

The __wakeup_source_seq_show() function already accepts an in_stop
parameter but is never called with true. Without this callback, BPF
programs using this iterator cannot detect when iteration has finished.


---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md

CI run summary: https://github.com/kernel-patches/bpf/actions/runs/21306880863

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH bpf-next v3 1/3] PM: wakeup: Handle empty list in wakeup_sources_walk
  2026-01-24  1:21 ` [PATCH bpf-next v3 1/3] PM: wakeup: Handle empty list in wakeup_sources_walk Samuel Wu
@ 2026-01-27 16:15   ` Rafael J. Wysocki
  2026-02-02 20:23     ` Samuel Wu
  0 siblings, 1 reply; 11+ messages in thread
From: Rafael J. Wysocki @ 2026-01-27 16:15 UTC (permalink / raw)
  To: Samuel Wu
  Cc: Rafael J. Wysocki, Len Brown, Pavel Machek, Greg Kroah-Hartman,
	Danilo Krummrich, 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, kernel-team, linux-kernel,
	linux-pm, bpf, linux-kselftest

On Sat, Jan 24, 2026 at 2:22 AM Samuel Wu <wusamuel@google.com> wrote:
>
> In the case of an empty wakeup_sources list, wakeup_sources_walk_start()
> will return an invalid but non-NULL address. This also affects wrappers
> of the aforementioned function, like for_each_wakeup_source().
>
> This patch updates wakeup_sources_walk_start() to return NULL in case of
> an empty list.
>
> Signed-off-by: Samuel Wu <wusamuel@google.com>
> ---
>  drivers/base/power/wakeup.c | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
>
> diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c
> index 1e1a0e7eeac5..e69033d16fba 100644
> --- a/drivers/base/power/wakeup.c
> +++ b/drivers/base/power/wakeup.c
> @@ -275,9 +275,7 @@ EXPORT_SYMBOL_GPL(wakeup_sources_read_unlock);
>   */
>  struct wakeup_source *wakeup_sources_walk_start(void)
>  {
> -       struct list_head *ws_head = &wakeup_sources;
> -
> -       return list_entry_rcu(ws_head->next, struct wakeup_source, entry);
> +       return list_first_or_null_rcu(&wakeup_sources, struct wakeup_source, entry);
>  }
>  EXPORT_SYMBOL_GPL(wakeup_sources_walk_start);
>
> --

This looks like a fix for the for_each_wakeup_source() users.

I can apply it without the next two patches.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH bpf-next v3 1/3] PM: wakeup: Handle empty list in wakeup_sources_walk
  2026-01-27 16:15   ` Rafael J. Wysocki
@ 2026-02-02 20:23     ` Samuel Wu
  2026-02-02 20:40       ` Rafael J. Wysocki
  0 siblings, 1 reply; 11+ messages in thread
From: Samuel Wu @ 2026-02-02 20:23 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Len Brown, Pavel Machek, Greg Kroah-Hartman, Danilo Krummrich,
	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, kernel-team, linux-kernel, linux-pm, bpf,
	linux-kselftest

On Tue, Jan 27, 2026 at 8:15 AM Rafael J. Wysocki <rafael@kernel.org> wrote:
>
> On Sat, Jan 24, 2026 at 2:22 AM Samuel Wu <wusamuel@google.com> wrote:
> >
> > In the case of an empty wakeup_sources list, wakeup_sources_walk_start()
> > will return an invalid but non-NULL address. This also affects wrappers
> > of the aforementioned function, like for_each_wakeup_source().
> >
> > This patch updates wakeup_sources_walk_start() to return NULL in case of
> > an empty list.
> >
> > Signed-off-by: Samuel Wu <wusamuel@google.com>
> > ---
> >  drivers/base/power/wakeup.c | 4 +---
> >  1 file changed, 1 insertion(+), 3 deletions(-)
> >
> > diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c
> > index 1e1a0e7eeac5..e69033d16fba 100644
> > --- a/drivers/base/power/wakeup.c
> > +++ b/drivers/base/power/wakeup.c
> > @@ -275,9 +275,7 @@ EXPORT_SYMBOL_GPL(wakeup_sources_read_unlock);
> >   */
> >  struct wakeup_source *wakeup_sources_walk_start(void)
> >  {
> > -       struct list_head *ws_head = &wakeup_sources;
> > -
> > -       return list_entry_rcu(ws_head->next, struct wakeup_source, entry);
> > +       return list_first_or_null_rcu(&wakeup_sources, struct wakeup_source, entry);
> >  }
> >  EXPORT_SYMBOL_GPL(wakeup_sources_walk_start);
> >
> > --
>
> This looks like a fix for the for_each_wakeup_source() users.
>
> I can apply it without the next two patches.

Yes please. Feel free to apply this patch independently, as it can
exist as a standalone fix independent of the subsequent two patches in
the series.

Thanks!

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH bpf-next v3 3/3] selftests/bpf: Add tests for wakeup_sources
  2026-01-24  1:50   ` bot+bpf-ci
@ 2026-02-02 20:27     ` Samuel Wu
  0 siblings, 0 replies; 11+ messages in thread
From: Samuel Wu @ 2026-02-02 20:27 UTC (permalink / raw)
  To: bot+bpf-ci
  Cc: rafael, lenb, pavel, gregkh, dakr, ast, daniel, andrii,
	martin.lau, eddyz87, song, yonghong.song, john.fastabend,
	kpsingh, sdf, haoluo, jolsa, shuah, kernel-team, linux-kernel,
	linux-pm, bpf, linux-kselftest, martin.lau, clm, ihor.solodrai

On Fri, Jan 23, 2026 at 5:50 PM <bot+bpf-ci@kernel.org> wrote:
>
> > diff --git a/tools/testing/selftests/bpf/prog_tests/wakeup_source_iter.c b/tools/testing/selftests/bpf/prog_tests/wakeup_source_iter.c
> > new file mode 100644
> > index 000000000000..c8a38717e284
> > --- /dev/null
> > +++ b/tools/testing/selftests/bpf/prog_tests/wakeup_source_iter.c
>
> [ ... ]
>
> > +static int get_ws_iter_stream(struct wakeup_source_iter *skel, int *iter_fd,
> > +                           FILE **iter_file)
> > +{
> > +     *iter_fd = bpf_iter_create(
> > +                     bpf_link__fd(skel->links.wakeup_source_collector));
> > +     if (!ASSERT_OK_FD(*iter_fd, "iter_create"))
> > +             return -1;
> > +
> > +     *iter_file = fdopen(*iter_fd, "r");
> > +     if (!ASSERT_OK_PTR(*iter_file, "fdopen"))
> > +             return -1;
> > +
> > +     return 0;
> > +}
>
> If bpf_iter_create() fails above, get_ws_iter_stream() returns -1 without
> writing to *iter_file.
>

This should be fine, if the BPF iter file isn't created, we will not
write to that file.

> > +static void subtest_ws_iter_check_active_count(struct wakeup_source_iter *skel)
> > +{
>
> [ ... ]
>
> > +     char *line = NULL;
> > +     bool found_ws = false;
> > +     FILE *iter_file = NULL;
> > +     int iter_fd = -1;
>
> This function correctly initializes iter_file and iter_fd before calling
> get_ws_iter_stream().
>
> [ ... ]
>
> > +}
> > +
> > +static void subtest_ws_iter_check_sleep_times(struct wakeup_source_iter *skel)
> > +{
> > +     bool found_test_ws = false;
> > +     struct WakeupSourceInfo ws_info;
> > +     char *line = NULL;
> > +     FILE *iter_file;
> > +     int iter_fd;
>
> In contrast to subtest_ws_iter_check_active_count(), iter_file and iter_fd
> are not initialized here.
>

Ack, this is important and I can address it in the v4 of the patch.

> > +
> > +     if (get_ws_iter_stream(skel, &iter_fd, &iter_file))
> > +             goto cleanup;
>
> [ ... ]
>
> > +cleanup:
> > +     if (iter_file)
> > +             fclose(iter_file);
> > +     else if (iter_fd >= 0)
> > +             close(iter_fd);
> > +}
>
> If get_ws_iter_stream() fails at bpf_iter_create(), can this access
> uninitialized iter_file and iter_fd? The cleanup code would then evaluate
> garbage values, potentially calling fclose() with an invalid pointer.
>

Correct, and this issue will be fixed when the variables are
initialized as pointed out in the previous comment.

>
> ---
> AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
> See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
>
> CI run summary: https://github.com/kernel-patches/bpf/actions/runs/21306880863

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH bpf-next v3 2/3] bpf: Add wakeup_source iterator
  2026-01-24  1:50   ` bot+bpf-ci
@ 2026-02-02 20:33     ` Samuel Wu
  0 siblings, 0 replies; 11+ messages in thread
From: Samuel Wu @ 2026-02-02 20:33 UTC (permalink / raw)
  To: bot+bpf-ci
  Cc: rafael, lenb, pavel, gregkh, dakr, ast, daniel, andrii,
	martin.lau, eddyz87, song, yonghong.song, john.fastabend,
	kpsingh, sdf, haoluo, jolsa, shuah, kernel-team, linux-kernel,
	linux-pm, bpf, linux-kselftest, martin.lau, clm, ihor.solodrai

On Fri, Jan 23, 2026 at 5:50 PM <bot+bpf-ci@kernel.org> wrote:
>
> > diff --git a/kernel/bpf/wakeup_source_iter.c b/kernel/bpf/wakeup_source_iter.c
> > new file mode 100644
> > index 000000000000..ab83d212a1f9
> > --- /dev/null
> > +++ b/kernel/bpf/wakeup_source_iter.c
>
> [ ... ]
>
> > +static void wakeup_source_iter_seq_stop(struct seq_file *seq, void *v)
> > +{
> > +     int *srcuidx = seq->private;
> > +
> > +     if (*srcuidx >= 0)
> > +             wakeup_sources_read_unlock(*srcuidx);
> > +     *srcuidx = -1;
> > +}
>
> Should this function call __wakeup_source_seq_show(seq, v, true) when v is
> NULL to notify the BPF program that iteration has completed?

My understanding is that above code is invoked as a N+1 case after
iterating through a list of size N. If desired behavior is to do
additional cleanup not already covered by _seq_stop() (e.g. printing
closing footers), then v == NULL should be handled. However, there is
no such need for wakeup_source_iter at the moment.

>
> Looking at other BPF iterators like map_iter, prog_iter, link_iter,
> task_iter, and kmem_cache_iter, they all invoke the BPF program with
> in_stop=true when the stop callback receives a NULL pointer. For example,
> map_iter does:
>
>     static void bpf_map_seq_stop(struct seq_file *seq, void *v)
>     {
>         if (!v)
>             (void)__bpf_map_seq_show(seq, v, true);
>         ...
>     }
>
> The bpf_seq_read() function in kernel/bpf/bpf_iter.c has this comment at
> the stop label: "/* bpf program called if !p */", which suggests this
> callback is expected.
>
> The __wakeup_source_seq_show() function already accepts an in_stop
> parameter but is never called with true. Without this callback, BPF
> programs using this iterator cannot detect when iteration has finished.
>

If I understand correctly, this is not mandatory. For a
straightforward iterator like this one, I'd like to keep it simple and
not unnecessarily handle this case.

>
> ---
> AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
> See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
>
> CI run summary: https://github.com/kernel-patches/bpf/actions/runs/21306880863

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH bpf-next v3 1/3] PM: wakeup: Handle empty list in wakeup_sources_walk
  2026-02-02 20:23     ` Samuel Wu
@ 2026-02-02 20:40       ` Rafael J. Wysocki
  0 siblings, 0 replies; 11+ messages in thread
From: Rafael J. Wysocki @ 2026-02-02 20:40 UTC (permalink / raw)
  To: Samuel Wu
  Cc: Rafael J. Wysocki, Len Brown, Pavel Machek, Greg Kroah-Hartman,
	Danilo Krummrich, 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, kernel-team, linux-kernel,
	linux-pm, bpf, linux-kselftest

On Mon, Feb 2, 2026 at 9:23 PM Samuel Wu <wusamuel@google.com> wrote:
>
> On Tue, Jan 27, 2026 at 8:15 AM Rafael J. Wysocki <rafael@kernel.org> wrote:
> >
> > On Sat, Jan 24, 2026 at 2:22 AM Samuel Wu <wusamuel@google.com> wrote:
> > >
> > > In the case of an empty wakeup_sources list, wakeup_sources_walk_start()
> > > will return an invalid but non-NULL address. This also affects wrappers
> > > of the aforementioned function, like for_each_wakeup_source().
> > >
> > > This patch updates wakeup_sources_walk_start() to return NULL in case of
> > > an empty list.
> > >
> > > Signed-off-by: Samuel Wu <wusamuel@google.com>
> > > ---
> > >  drivers/base/power/wakeup.c | 4 +---
> > >  1 file changed, 1 insertion(+), 3 deletions(-)
> > >
> > > diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c
> > > index 1e1a0e7eeac5..e69033d16fba 100644
> > > --- a/drivers/base/power/wakeup.c
> > > +++ b/drivers/base/power/wakeup.c
> > > @@ -275,9 +275,7 @@ EXPORT_SYMBOL_GPL(wakeup_sources_read_unlock);
> > >   */
> > >  struct wakeup_source *wakeup_sources_walk_start(void)
> > >  {
> > > -       struct list_head *ws_head = &wakeup_sources;
> > > -
> > > -       return list_entry_rcu(ws_head->next, struct wakeup_source, entry);
> > > +       return list_first_or_null_rcu(&wakeup_sources, struct wakeup_source, entry);
> > >  }
> > >  EXPORT_SYMBOL_GPL(wakeup_sources_walk_start);
> > >
> > > --
> >
> > This looks like a fix for the for_each_wakeup_source() users.
> >
> > I can apply it without the next two patches.
>
> Yes please. Feel free to apply this patch independently, as it can
> exist as a standalone fix independent of the subsequent two patches in
> the series.

OK, applied as 6.20/7.0 material, thanks!

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2026-02-02 20:40 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-01-24  1:21 [PATCH bpf-next v3 0/3] Add wakeup_source iterators Samuel Wu
2026-01-24  1:21 ` [PATCH bpf-next v3 1/3] PM: wakeup: Handle empty list in wakeup_sources_walk Samuel Wu
2026-01-27 16:15   ` Rafael J. Wysocki
2026-02-02 20:23     ` Samuel Wu
2026-02-02 20:40       ` Rafael J. Wysocki
2026-01-24  1:21 ` [PATCH bpf-next v3 2/3] bpf: Add wakeup_source iterator Samuel Wu
2026-01-24  1:50   ` bot+bpf-ci
2026-02-02 20:33     ` Samuel Wu
2026-01-24  1:21 ` [PATCH bpf-next v3 3/3] selftests/bpf: Add tests for wakeup_sources Samuel Wu
2026-01-24  1:50   ` bot+bpf-ci
2026-02-02 20:27     ` Samuel Wu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®