profiling: remove profile=sleep support
commit b88f55389ad27f05ed84af9e1026aa64dbfabc9a upstream. The kernel sleep profile is no longer working due to a recursive locking bug introduced by commit42a20f86dc
("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:42a20f86dc
("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> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
c265240444
commit
2d451ec01e
|
@ -4655,11 +4655,9 @@
|
||||||
|
|
||||||
profile= [KNL] Enable kernel profiling via /proc/profile
|
profile= [KNL] Enable kernel profiling via /proc/profile
|
||||||
Format: [<profiletype>,]<number>
|
Format: [<profiletype>,]<number>
|
||||||
Param: <profiletype>: "schedule", "sleep", or "kvm"
|
Param: <profiletype>: "schedule" or "kvm"
|
||||||
[defaults to kernel profiling]
|
[defaults to kernel profiling]
|
||||||
Param: "schedule" - profile schedule points.
|
Param: "schedule" - profile schedule points.
|
||||||
Param: "sleep" - profile D-state sleeping (millisecs).
|
|
||||||
Requires CONFIG_SCHEDSTATS
|
|
||||||
Param: "kvm" - profile VM exits.
|
Param: "kvm" - profile VM exits.
|
||||||
Param: <number> - step/bucket size as a power of 2 for
|
Param: <number> - step/bucket size as a power of 2 for
|
||||||
statistical time based profiling.
|
statistical time based profiling.
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
|
|
||||||
#define CPU_PROFILING 1
|
#define CPU_PROFILING 1
|
||||||
#define SCHED_PROFILING 2
|
#define SCHED_PROFILING 2
|
||||||
#define SLEEP_PROFILING 3
|
|
||||||
#define KVM_PROFILING 4
|
#define KVM_PROFILING 4
|
||||||
|
|
||||||
struct proc_dir_entry;
|
struct proc_dir_entry;
|
||||||
|
|
|
@ -57,20 +57,11 @@ static DEFINE_MUTEX(profile_flip_mutex);
|
||||||
int profile_setup(char *str)
|
int profile_setup(char *str)
|
||||||
{
|
{
|
||||||
static const char schedstr[] = "schedule";
|
static const char schedstr[] = "schedule";
|
||||||
static const char sleepstr[] = "sleep";
|
|
||||||
static const char kvmstr[] = "kvm";
|
static const char kvmstr[] = "kvm";
|
||||||
const char *select = NULL;
|
const char *select = NULL;
|
||||||
int par;
|
int par;
|
||||||
|
|
||||||
if (!strncmp(str, sleepstr, strlen(sleepstr))) {
|
if (!strncmp(str, schedstr, strlen(schedstr))) {
|
||||||
#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))) {
|
|
||||||
prof_on = SCHED_PROFILING;
|
prof_on = SCHED_PROFILING;
|
||||||
select = schedstr;
|
select = schedstr;
|
||||||
} else if (!strncmp(str, kvmstr, strlen(kvmstr))) {
|
} else if (!strncmp(str, kvmstr, strlen(kvmstr))) {
|
||||||
|
|
|
@ -92,16 +92,6 @@ void __update_stats_enqueue_sleeper(struct rq *rq, struct task_struct *p,
|
||||||
|
|
||||||
trace_sched_stat_blocked(p, delta);
|
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);
|
account_scheduler_latency(p, delta >> 10, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue