summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2026-06-05 11:12:08 -0300
committerArnaldo Carvalho de Melo <acme@redhat.com>2026-06-05 19:17:31 -0300
commitcda5a94ad9181cd60cbf04be11d524201bf489a2 (patch)
treeebdfdf002581e85ce8e456250b8338f46351767e
parent5fb2e6ad8c5d6b3b380f94c7456595511f3731be (diff)
downloadlinux-cda5a94ad9181cd60cbf04be11d524201bf489a2.tar.gz
linux-cda5a94ad9181cd60cbf04be11d524201bf489a2.zip
perf sched: Clean up idle_threads entry on init failure
get_idle_thread() allocates a thread via thread__new() and stores it in idle_threads[cpu], then calls init_idle_thread() to set up the private data. If init_idle_thread() fails (e.g. OOM for the idle_thread_runtime struct), the function returns NULL but leaves the partially initialized thread in idle_threads[cpu]. On subsequent calls for the same CPU, get_idle_thread() finds a non-NULL idle_threads[cpu], skips allocation, and returns thread__get() on a thread that has no priv data. Callers then get a thread whose thread__priv() returns NULL, leading to unexpected behavior. Release the thread and reset the slot to NULL on init failure so the entry doesn't persist in a corrupted state. Fixes: 49394a2a24c7 ("perf sched timehist: Introduce timehist command") Reported-by: sashiko-bot <sashiko-bot@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Namhyung Kim <namhyung@kernel.org> Assisted-by: Claude:claude-opus-4.6 Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r--tools/perf/builtin-sched.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index 21fb820b625b..e4378cc9ab3e 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -2514,8 +2514,11 @@ static struct thread *get_idle_thread(int cpu)
idle_threads[cpu] = thread__new(0, 0);
if (idle_threads[cpu]) {
- if (init_idle_thread(idle_threads[cpu]) < 0)
+ if (init_idle_thread(idle_threads[cpu]) < 0) {
+ /* clean up so next call doesn't find a half-initialized thread */
+ thread__zput(idle_threads[cpu]);
return NULL;
+ }
}
}