Merge "trace: Add warning threshold for irqsoff time"

This commit is contained in:
qctecmdr 2020-03-16 22:55:50 -07:00 • committed by Gerrit - the friendly Code Review server
commit fafcdeebed
3 changed files with 60 additions and 3 deletions

View file

@ -82,6 +82,9 @@ extern unsigned int sysctl_preemptoff_tracing_threshold_ns;
#endif
#if defined(CONFIG_PREEMPTIRQ_EVENTS) && defined(CONFIG_IRQSOFF_TRACER)
extern unsigned int sysctl_irqsoff_tracing_threshold_ns;
extern unsigned int sysctl_irqsoff_dmesg_output_enabled;
extern unsigned int sysctl_irqsoff_crash_sentinel_value;
extern unsigned int sysctl_irqsoff_crash_threshold_ns;
#endif
enum sched_tunable_scaling {

View file

@ -141,6 +141,9 @@ static int ten_thousand = 10000;
#ifdef CONFIG_PERF_EVENTS
static int six_hundred_forty_kb = 640 * 1024;
#endif
static unsigned int __maybe_unused half_million = 500000;
static unsigned int __maybe_unused one_hundred_million = 100000000;
static unsigned int __maybe_unused one_million = 1000000;
#ifdef CONFIG_SCHED_WALT
static int neg_three = -3;
static int three = 3;
@ -355,8 +358,33 @@ static struct ctl_table kern_table[] = {
.data = &sysctl_irqsoff_tracing_threshold_ns,
.maxlen = sizeof(unsigned int),
.mode = 0644,
.proc_handler = proc_douintvec_minmax,
.extra1 = &half_million,
.extra2 = &one_hundred_million,
},
{
.procname = "irqsoff_dmesg_output_enabled",
.data = &sysctl_irqsoff_dmesg_output_enabled,
.maxlen = sizeof(unsigned int),
.mode = 0644,
.proc_handler = proc_dointvec,
},
{
.procname = "irqsoff_crash_sentinel_value",
.data = &sysctl_irqsoff_crash_sentinel_value,
.maxlen = sizeof(unsigned int),
.mode = 0644,
.proc_handler = proc_dointvec,
},
{
.procname = "irqsoff_crash_threshold_ns",
.data = &sysctl_irqsoff_crash_threshold_ns,
.maxlen = sizeof(unsigned int),
.mode = 0644,
.proc_handler = proc_douintvec_minmax,
.extra1 = &one_million,
.extra2 = &one_hundred_million,
},
#endif
#ifdef CONFIG_SCHED_WALT
{

View file

@ -608,11 +608,24 @@ static void irqsoff_tracer_stop(struct trace_array *tr)
#ifdef CONFIG_IRQSOFF_TRACER
#ifdef CONFIG_PREEMPTIRQ_EVENTS
#define IRQSOFF_SENTINEL 0x0fffDEAD
/*
* irqsoff stack tracing threshold in ns.
* default: 1ms
* default: 5ms
*/
unsigned int sysctl_irqsoff_tracing_threshold_ns = 1000000UL;
unsigned int sysctl_irqsoff_tracing_threshold_ns = 5000000UL;
/*
* Enable irqsoff tracing to dmesg
*/
unsigned int sysctl_irqsoff_dmesg_output_enabled;
/*
* Sentinel value to prevent unnecessary irqsoff crash
*/
unsigned int sysctl_irqsoff_crash_sentinel_value;
/*
* Irqsoff warning threshold to trigger crash
*/
unsigned int sysctl_irqsoff_crash_threshold_ns = 10000000UL;
struct irqsoff_store {
u64 ts;
@ -637,9 +650,22 @@ void tracer_hardirqs_on(unsigned long a0, unsigned long a1)
delta = sched_clock() - is->ts;
if (!is_idle_task(current) &&
delta > sysctl_irqsoff_tracing_threshold_ns)
delta > sysctl_irqsoff_tracing_threshold_ns) {
trace_irqs_disable(delta, is->caddr[0], is->caddr[1],
is->caddr[2], is->caddr[3]);
if (sysctl_irqsoff_dmesg_output_enabled == IRQSOFF_SENTINEL)
printk_deferred(KERN_ERR "D=%llu C:(%ps<-%ps<-%ps<-%ps)\n",
delta, is->caddr[0], is->caddr[1],
is->caddr[2], is->caddr[3]);
if (sysctl_irqsoff_crash_sentinel_value == IRQSOFF_SENTINEL &&
delta > sysctl_irqsoff_crash_threshold_ns) {
printk_deferred(KERN_ERR
"delta=%llu(ns) > crash_threshold=%llu(ns) Task=%s\n",
delta, sysctl_irqsoff_crash_threshold_ns,
current->comm);
BUG_ON(1);
}
}
is->ts = 0;
lockdep_on();
#endif /* CONFIG_PREEMPTIRQ_EVENTS */