]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
perf sched: Clean up idle_threads entry on init failure
authorArnaldo Carvalho de Melo <acme@redhat.com>
Fri, 5 Jun 2026 14:12:08 +0000 (11:12 -0300)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Fri, 5 Jun 2026 22:17:31 +0000 (19:17 -0300)
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>
tools/perf/builtin-sched.c

index 21fb820b625b43e146742a276a2e26830ba5e692..e4378cc9ab3ed48b106bab07c6591036dae61077 100644 (file)
@@ -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;
+                       }
                }
        }