Skip to content

Commit 4a54387

Browse files
Tetsuo Handaintel-lab-lkp
authored andcommitted
profiling: remove profile=sleep support
The kernel sleep profile is no longer working due to a recursive locking bug introduced by commit 42a20f8 ("sched: Add wrapper for get_wchan() to keep task blocked"); either booting with profile=sleep kernel command line option added or executing # echo -n sleep > /sys/kernel/profiling after boot causes the system to lock up. ============================================ WARNING: possible recursive locking detected 5.15.0-rc4+ torvalds#104 Not tainted -------------------------------------------- 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 other info that might help us debug this: Possible unsafe locking scenario: CPU0 ---- lock(&p->pi_lock); lock(&p->pi_lock); *** DEADLOCK *** May be due to missing lock nesting notation 3 locks held by kthreadd/3: #0: ffffae5ac2833d68 (&x->wait){....}-{2:2}, at: complete+0x18/0x40 #1: ffff93ac82e08d58 (&p->pi_lock){....}-{2:2}, at: try_to_wake_up+0x53/0x370 #2: ffff93ad29fe9458 (&rq->__lock){-...}-{2:2}, at: try_to_wake_up+0x19f/0x370 stack backtrace: CPU: 0 PID: 3 Comm: kthreadd Not tainted 5.15.0-rc4+ torvalds#104 Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 11/12/2020 Call Trace: dump_stack_lvl+0x57/0x72 validate_chain.cold+0x122/0x127 __lock_acquire+0x4d2/0x930 lock_acquire+0xc8/0x2f0 ? get_wchan+0x32/0x70 ? rcu_read_lock_sched_held+0x3f/0x80 _raw_spin_lock_irq+0x47/0x90 ? get_wchan+0x32/0x70 get_wchan+0x32/0x70 __update_stats_enqueue_sleeper+0x151/0x430 enqueue_entity+0x4b0/0x520 enqueue_task_fair+0x92/0x6b0 ? lock_is_held_type+0xa7/0x120 ttwu_do_activate+0x73/0x140 try_to_wake_up+0x213/0x370 swake_up_locked+0x20/0x50 complete+0x2f/0x40 ? __cancel_work_timer+0x1b0/0x1b0 kthread+0xfb/0x180 ? set_kthread_struct+0x40/0x40 ret_from_fork+0x22/0x30 However, since nobody noticed this regression for more than 2 years, let's remove profile=sleep support based on an assumption that nobody needs this functionality. Fixes: 42a20f8 ("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>
1 parent cea5a34 commit 4a54387

File tree

4 files changed

+2
-24
lines changed

4 files changed

+2
-24
lines changed

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4798,11 +4798,9 @@
47984798

47994799
profile= [KNL] Enable kernel profiling via /proc/profile
48004800
Format: [<profiletype>,]<number>
4801-
Param: <profiletype>: "schedule", "sleep", or "kvm"
4801+
Param: <profiletype>: "schedule" or "kvm"
48024802
[defaults to kernel profiling]
48034803
Param: "schedule" - profile schedule points.
4804-
Param: "sleep" - profile D-state sleeping (millisecs).
4805-
Requires CONFIG_SCHEDSTATS
48064804
Param: "kvm" - profile VM exits.
48074805
Param: <number> - step/bucket size as a power of 2 for
48084806
statistical time based profiling.

include/linux/profile.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010

1111
#define CPU_PROFILING 1
1212
#define SCHED_PROFILING 2
13-
#define SLEEP_PROFILING 3
1413
#define KVM_PROFILING 4
1514

1615
struct proc_dir_entry;

kernel/profile.c

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -57,20 +57,11 @@ static DEFINE_MUTEX(profile_flip_mutex);
5757
int profile_setup(char *str)
5858
{
5959
static const char schedstr[] = "schedule";
60-
static const char sleepstr[] = "sleep";
6160
static const char kvmstr[] = "kvm";
6261
const char *select = NULL;
6362
int par;
6463

65-
if (!strncmp(str, sleepstr, strlen(sleepstr))) {
66-
#ifdef CONFIG_SCHEDSTATS
67-
force_schedstat_enabled();
68-
prof_on = SLEEP_PROFILING;
69-
select = sleepstr;
70-
#else
71-
pr_warn("kernel sleep profiling requires CONFIG_SCHEDSTATS\n");
72-
#endif /* CONFIG_SCHEDSTATS */
73-
} else if (!strncmp(str, schedstr, strlen(schedstr))) {
64+
if (!strncmp(str, schedstr, strlen(schedstr))) {
7465
prof_on = SCHED_PROFILING;
7566
select = schedstr;
7667
} else if (!strncmp(str, kvmstr, strlen(kvmstr))) {

kernel/sched/stats.c

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -92,16 +92,6 @@ void __update_stats_enqueue_sleeper(struct rq *rq, struct task_struct *p,
9292

9393
trace_sched_stat_blocked(p, delta);
9494

95-
/*
96-
* Blocking time is in units of nanosecs, so shift by
97-
* 20 to get a milliseconds-range estimation of the
98-
* amount of time that the task spent sleeping:
99-
*/
100-
if (unlikely(prof_on == SLEEP_PROFILING)) {
101-
profile_hits(SLEEP_PROFILING,
102-
(void *)get_wchan(p),
103-
delta >> 20);
104-
}
10595
account_scheduler_latency(p, delta >> 10, 0);
10696
}
10797
}

0 commit comments

Comments
 (0)