Merge "sched: warn/panic upon excessive scheduling latency"

This commit is contained in:
Linux Build Service Account 2015-03-09 22:53:49 -07:00 committed by Gerrit - the friendly Code Review server
commit aee63baa3f
4 changed files with 68 additions and 2 deletions

View File

@ -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

View File

@ -140,6 +140,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,

View File

@ -29,6 +29,7 @@
#include <linux/mempolicy.h>
#include <linux/migrate.h>
#include <linux/task_work.h>
#include <linux/ratelimit.h>
#include <trace/events/sched.h>
@ -121,6 +122,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 */
/*
* Increase the granularity value when there are more CPUs,
* because with more CPUs the 'effective latency' as visible
@ -751,6 +757,31 @@ static void update_stats_enqueue(struct cfs_rq *cfs_rq, struct sched_entity *se,
update_stats_wait_start(cfs_rq, se, migrating);
}
#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_sched(fmt, p->comm, p->pid, latency_us);
}
}
#else
static inline void check_for_high_latency(struct task_struct *p, u64 latency)
{
}
#endif
static void
update_stats_wait_end(struct cfs_rq *cfs_rq, struct sched_entity *se,
bool migrating)
@ -768,8 +799,13 @@ update_stats_wait_end(struct cfs_rq *cfs_rq, struct sched_entity *se,
rq_of(cfs_rq)->clock - se->statistics.wait_start);
#ifdef CONFIG_SCHEDSTATS
if (entity_is_task(se)) {
trace_sched_stat_wait(task_of(se),
rq_of(cfs_rq)->clock - se->statistics.wait_start);
u64 delta;
delta = rq_of(cfs_rq)->clock - se->statistics.wait_start;
trace_sched_stat_wait(task_of(se), delta);
delta = delta >> 10;
check_for_high_latency(task_of(se), delta);
}
#endif
schedstat_set(se->statistics.wait_start, 0);

View File

@ -603,6 +603,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",