sched: warn/panic upon excessive scheduling latency
Add new tunables /proc/sys/kernel/sched_latency_warn_threshold_us and /proc/sys/kernel/sched_latency_panic_threshold_us to warn or panic for the cases that tasks are runnable but not scheduled more than configured time. This helps to find out unacceptably high scheduling latency more easily. Change-Id: If077aba6211062cf26ee289970c5abcd1c218c82 [joonwoop@codeaurora.org: fixed conflict in update_stats_wait_end().] Signed-off-by: Joonwoo Park <joonwoop@codeaurora.org>
This commit is contained in:
parent
fa8dd7068a
commit
8f90803a45
4 changed files with 56 additions and 0 deletions
|
@ -147,6 +147,15 @@ this file correlating for that process to:
|
|||
2) time spent waiting on a runqueue
|
||||
3) # of timeslices run on this cpu
|
||||
|
||||
/proc/sys/kernel/{sched_latency_warn_threshold_us,sched_latency_panic_threshold_us}
|
||||
----------------
|
||||
schedstats provides procfs nodes /proc/sys/kernel/sched_latency_warn_threshold_us
|
||||
and /proc/sys/kernel/sched_latency_panic_threshold_us. These can be configured
|
||||
to detect unreasonably high scheduling latency.
|
||||
Set sched_latency_warn_threshold_us or sched_latency_panic_threshold_us with
|
||||
non-zero threshold to warn or panic system when scheduling latency higher than
|
||||
configured threshold is detected. Default is 0 (disabled) for both.
|
||||
|
||||
A program could be easily written to make use of these extra fields to
|
||||
report on how well a particular process or set of processes is faring
|
||||
under the scheduler's policies. A simple version of such a program is
|
||||
|
|
|
@ -129,6 +129,11 @@ extern unsigned int sysctl_sched_cfs_bandwidth_slice;
|
|||
extern unsigned int sysctl_sched_autogroup_enabled;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SCHEDSTATS
|
||||
extern unsigned int sysctl_sched_latency_panic_threshold;
|
||||
extern unsigned int sysctl_sched_latency_warn_threshold;
|
||||
#endif
|
||||
|
||||
extern int sched_rr_timeslice;
|
||||
|
||||
extern int sched_rr_handler(struct ctl_table *table, int write,
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <linux/mempolicy.h>
|
||||
#include <linux/migrate.h>
|
||||
#include <linux/task_work.h>
|
||||
#include <linux/ratelimit.h>
|
||||
|
||||
#include <trace/events/sched.h>
|
||||
|
||||
|
@ -122,6 +123,11 @@ unsigned int __read_mostly sysctl_sched_shares_window = 10000000UL;
|
|||
unsigned int sysctl_sched_cfs_bandwidth_slice = 5000UL;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SCHEDSTATS
|
||||
unsigned int sysctl_sched_latency_panic_threshold;
|
||||
unsigned int sysctl_sched_latency_warn_threshold;
|
||||
#endif /* CONFIG_SCHEDSTATS */
|
||||
|
||||
static inline void update_load_add(struct load_weight *lw, unsigned long inc)
|
||||
{
|
||||
lw->weight += inc;
|
||||
|
@ -750,6 +756,25 @@ static void update_curr_fair(struct rq *rq)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_SCHEDSTATS
|
||||
static inline void check_for_high_latency(struct task_struct *p, u64 latency_us)
|
||||
{
|
||||
int do_warn, do_panic;
|
||||
const char *fmt = "excessive latency comm=%s pid=%d latency=%llu(us)\n";
|
||||
static DEFINE_RATELIMIT_STATE(rs, DEFAULT_RATELIMIT_INTERVAL,
|
||||
DEFAULT_RATELIMIT_BURST);
|
||||
|
||||
do_warn = (sysctl_sched_latency_warn_threshold &&
|
||||
latency_us > sysctl_sched_latency_warn_threshold);
|
||||
do_panic = (sysctl_sched_latency_panic_threshold &&
|
||||
latency_us > sysctl_sched_latency_panic_threshold);
|
||||
if (unlikely(do_panic || (do_warn && __ratelimit(&rs)))) {
|
||||
if (do_panic)
|
||||
panic(fmt, p->comm, p->pid, latency_us);
|
||||
else
|
||||
printk_deferred(fmt, p->comm, p->pid, latency_us);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
update_stats_wait_start(struct cfs_rq *cfs_rq, struct sched_entity *se)
|
||||
{
|
||||
|
@ -780,6 +805,7 @@ update_stats_wait_end(struct cfs_rq *cfs_rq, struct sched_entity *se)
|
|||
return;
|
||||
}
|
||||
trace_sched_stat_wait(p, delta);
|
||||
check_for_high_latency(p, delta >> 10);
|
||||
}
|
||||
|
||||
se->statistics.wait_max = max(se->statistics.wait_max, delta);
|
||||
|
|
|
@ -593,6 +593,22 @@ static struct ctl_table kern_table[] = {
|
|||
.extra1 = &one,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_SCHEDSTATS
|
||||
{
|
||||
.procname = "sched_latency_panic_threshold_us",
|
||||
.data = &sysctl_sched_latency_panic_threshold,
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_minmax,
|
||||
},
|
||||
{
|
||||
.procname = "sched_latency_warn_threshold_us",
|
||||
.data = &sysctl_sched_latency_warn_threshold,
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_minmax,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_PROVE_LOCKING
|
||||
{
|
||||
.procname = "prove_locking",
|
||||
|
|
Loading…
Add table
Reference in a new issue