Loading kernel/sched/core.c +19 −6 Original line number Diff line number Diff line Loading @@ -3322,10 +3322,24 @@ struct preempt_store { u64 ts; unsigned long caddr[4]; bool irqs_disabled; bool is_idle_task; }; DEFINE_PER_CPU(struct preempt_store, the_ps); /* * This is only called from __schedule() upon context switch. * * schedule() calls __schedule() with preemption disabled. * if we had entered idle and exiting idle now, reset the preemption * tracking otherwise we may think preemption is disabled the whole time * when the non idle task re-enables the preemption in schedule(). */ static inline void preempt_latency_reset(void) { if (is_idle_task(this_rq()->curr)) this_cpu_ptr(&the_ps)->ts = 0; } /* * If the value passed in is equal to the current preempt count * then we just disabled preemption. Start timing the latency. Loading @@ -3333,7 +3347,6 @@ DEFINE_PER_CPU(struct preempt_store, the_ps); static inline void preempt_latency_start(int val) { int cpu = raw_smp_processor_id(); struct rq *rq = cpu_rq(cpu); struct preempt_store *ps = &per_cpu(the_ps, cpu); if (preempt_count() == val) { Loading @@ -3347,7 +3360,6 @@ static inline void preempt_latency_start(int val) ps->caddr[2] = CALLER_ADDR2; ps->caddr[3] = CALLER_ADDR3; ps->irqs_disabled = irqs_disabled(); ps->is_idle_task = (rq->curr == rq->idle); trace_preempt_off(CALLER_ADDR0, ip); } Loading Loading @@ -3384,14 +3396,13 @@ static inline void preempt_latency_stop(int val) if (preempt_count() == val) { struct preempt_store *ps = &per_cpu(the_ps, raw_smp_processor_id()); u64 delta = sched_clock() - ps->ts; u64 delta = ps->ts ? (sched_clock() - ps->ts) : 0; /* * Trace preempt disable stack if preemption * is disabled for more than the threshold. */ if (!ps->is_idle_task && delta > sysctl_preemptoff_tracing_threshold_ns) if (delta > sysctl_preemptoff_tracing_threshold_ns) trace_sched_preempt_disable(delta, ps->irqs_disabled, ps->caddr[0], ps->caddr[1], ps->caddr[2], ps->caddr[3]); Loading Loading @@ -3424,6 +3435,7 @@ NOKPROBE_SYMBOL(preempt_count_sub); #else static inline void preempt_latency_start(int val) { } static inline void preempt_latency_stop(int val) { } static inline void preempt_latency_reset(void) { } #endif static inline unsigned long get_preempt_disable_ip(struct task_struct *p) Loading Loading @@ -3647,6 +3659,7 @@ static void __sched notrace __schedule(bool preempt) if (!prev->on_rq) prev->last_sleep_ts = wallclock; preempt_latency_reset(); update_task_ravg(prev, rq, PUT_PREV_TASK, wallclock, 0); update_task_ravg(next, rq, PICK_NEXT_TASK, wallclock, 0); rq->nr_switches++; Loading Loading
kernel/sched/core.c +19 −6 Original line number Diff line number Diff line Loading @@ -3322,10 +3322,24 @@ struct preempt_store { u64 ts; unsigned long caddr[4]; bool irqs_disabled; bool is_idle_task; }; DEFINE_PER_CPU(struct preempt_store, the_ps); /* * This is only called from __schedule() upon context switch. * * schedule() calls __schedule() with preemption disabled. * if we had entered idle and exiting idle now, reset the preemption * tracking otherwise we may think preemption is disabled the whole time * when the non idle task re-enables the preemption in schedule(). */ static inline void preempt_latency_reset(void) { if (is_idle_task(this_rq()->curr)) this_cpu_ptr(&the_ps)->ts = 0; } /* * If the value passed in is equal to the current preempt count * then we just disabled preemption. Start timing the latency. Loading @@ -3333,7 +3347,6 @@ DEFINE_PER_CPU(struct preempt_store, the_ps); static inline void preempt_latency_start(int val) { int cpu = raw_smp_processor_id(); struct rq *rq = cpu_rq(cpu); struct preempt_store *ps = &per_cpu(the_ps, cpu); if (preempt_count() == val) { Loading @@ -3347,7 +3360,6 @@ static inline void preempt_latency_start(int val) ps->caddr[2] = CALLER_ADDR2; ps->caddr[3] = CALLER_ADDR3; ps->irqs_disabled = irqs_disabled(); ps->is_idle_task = (rq->curr == rq->idle); trace_preempt_off(CALLER_ADDR0, ip); } Loading Loading @@ -3384,14 +3396,13 @@ static inline void preempt_latency_stop(int val) if (preempt_count() == val) { struct preempt_store *ps = &per_cpu(the_ps, raw_smp_processor_id()); u64 delta = sched_clock() - ps->ts; u64 delta = ps->ts ? (sched_clock() - ps->ts) : 0; /* * Trace preempt disable stack if preemption * is disabled for more than the threshold. */ if (!ps->is_idle_task && delta > sysctl_preemptoff_tracing_threshold_ns) if (delta > sysctl_preemptoff_tracing_threshold_ns) trace_sched_preempt_disable(delta, ps->irqs_disabled, ps->caddr[0], ps->caddr[1], ps->caddr[2], ps->caddr[3]); Loading Loading @@ -3424,6 +3435,7 @@ NOKPROBE_SYMBOL(preempt_count_sub); #else static inline void preempt_latency_start(int val) { } static inline void preempt_latency_stop(int val) { } static inline void preempt_latency_reset(void) { } #endif static inline unsigned long get_preempt_disable_ip(struct task_struct *p) Loading Loading @@ -3647,6 +3659,7 @@ static void __sched notrace __schedule(bool preempt) if (!prev->on_rq) prev->last_sleep_ts = wallclock; preempt_latency_reset(); update_task_ravg(prev, rq, PUT_PREV_TASK, wallclock, 0); update_task_ravg(next, rq, PICK_NEXT_TASK, wallclock, 0); rq->nr_switches++; Loading