Merge "sched: warn/panic upon excessive scheduling latency"
This commit is contained in:
commit
aee63baa3f
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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",
|
||||
|
|
Loading…
Reference in New Issue