]> www.infradead.org Git - users/hch/configfs.git/commitdiff
profiling: remove profile=sleep support
authorTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Sun, 4 Aug 2024 09:48:10 +0000 (18:48 +0900)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 4 Aug 2024 20:36:28 +0000 (13:36 -0700)
The kernel sleep profile is no longer working due to a recursive locking
bug introduced by commit 42a20f86dc19 ("sched: Add wrapper for get_wchan()
to keep task blocked")

Booting with the 'profile=sleep' kernel command line option added or
executing

  # echo -n sleep > /sys/kernel/profiling

after boot causes the system to lock up.

Lockdep reports

  kthreadd/3 is trying to acquire lock:
  ffff93ac82e08d58 (&p->pi_lock){....}-{2:2}, at: get_wchan+0x32/0x70

  but task is already holding lock:
  ffff93ac82e08d58 (&p->pi_lock){....}-{2:2}, at: try_to_wake_up+0x53/0x370

with the call trace being

   lock_acquire+0xc8/0x2f0
   get_wchan+0x32/0x70
   __update_stats_enqueue_sleeper+0x151/0x430
   enqueue_entity+0x4b0/0x520
   enqueue_task_fair+0x92/0x6b0
   ttwu_do_activate+0x73/0x140
   try_to_wake_up+0x213/0x370
   swake_up_locked+0x20/0x50
   complete+0x2f/0x40
   kthread+0xfb/0x180

However, since nobody noticed this regression for more than two years,
let's remove 'profile=sleep' support based on the assumption that nobody
needs this functionality.

Fixes: 42a20f86dc19 ("sched: Add wrapper for get_wchan() to keep task blocked")
Cc: stable@vger.kernel.org # v5.16+
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Documentation/admin-guide/kernel-parameters.txt
include/linux/profile.h
kernel/profile.c
kernel/sched/stats.c

index f1384c7b59c9282fc6fb40569a92f6c13861bbb9..09126bb8cc9ffb140280c56895754a0e2c602f25 100644 (file)
 
        profile=        [KNL] Enable kernel profiling via /proc/profile
                        Format: [<profiletype>,]<number>
-                       Param: <profiletype>: "schedule", "sleep", or "kvm"
+                       Param: <profiletype>: "schedule" or "kvm"
                                [defaults to kernel profiling]
                        Param: "schedule" - profile schedule points.
-                       Param: "sleep" - profile D-state sleeping (millisecs).
-                               Requires CONFIG_SCHEDSTATS
                        Param: "kvm" - profile VM exits.
                        Param: <number> - step/bucket size as a power of 2 for
                                statistical time based profiling.
index 2fb487f61d12abf8e8a881467cf598e646995fa0..3f53cdb0c27c1a2be13d63199f2949a2033f174c 100644 (file)
@@ -10,7 +10,6 @@
 
 #define CPU_PROFILING  1
 #define SCHED_PROFILING        2
-#define SLEEP_PROFILING        3
 #define KVM_PROFILING  4
 
 struct proc_dir_entry;
index ff68d3816182aff6c901023c47a7f81291cf17ad..1fcf1adcf4eb033ef0a5e2960c63404700b94519 100644 (file)
@@ -50,20 +50,11 @@ EXPORT_SYMBOL_GPL(prof_on);
 int profile_setup(char *str)
 {
        static const char schedstr[] = "schedule";
-       static const char sleepstr[] = "sleep";
        static const char kvmstr[] = "kvm";
        const char *select = NULL;
        int par;
 
-       if (!strncmp(str, sleepstr, strlen(sleepstr))) {
-#ifdef CONFIG_SCHEDSTATS
-               force_schedstat_enabled();
-               prof_on = SLEEP_PROFILING;
-               select = sleepstr;
-#else
-               pr_warn("kernel sleep profiling requires CONFIG_SCHEDSTATS\n");
-#endif /* CONFIG_SCHEDSTATS */
-       } else if (!strncmp(str, schedstr, strlen(schedstr))) {
+       if (!strncmp(str, schedstr, strlen(schedstr))) {
                prof_on = SCHED_PROFILING;
                select = schedstr;
        } else if (!strncmp(str, kvmstr, strlen(kvmstr))) {
index 78e48f5426ee1f8157e32381d32b79cfd5990373..eb0cdcd4d9212e3a5ce1696f4257f93c66dacfb2 100644 (file)
@@ -92,16 +92,6 @@ void __update_stats_enqueue_sleeper(struct rq *rq, struct task_struct *p,
 
                        trace_sched_stat_blocked(p, delta);
 
-                       /*
-                        * Blocking time is in units of nanosecs, so shift by
-                        * 20 to get a milliseconds-range estimation of the
-                        * amount of time that the task spent sleeping:
-                        */
-                       if (unlikely(prof_on == SLEEP_PROFILING)) {
-                               profile_hits(SLEEP_PROFILING,
-                                            (void *)get_wchan(p),
-                                            delta >> 20);
-                       }
                        account_scheduler_latency(p, delta >> 10, 0);
                }
        }