diff options
-rw-r--r-- | include/trace/events/timer.h | 21 | ||||
-rw-r--r-- | kernel/time/tick-sched.c | 19 |
2 files changed, 36 insertions, 4 deletions
diff --git a/include/trace/events/timer.h b/include/trace/events/timer.h index 425bcfe56c62..f5eb53eb658f 100644 --- a/include/trace/events/timer.h +++ b/include/trace/events/timer.h | |||
@@ -323,6 +323,27 @@ TRACE_EVENT(itimer_expire, | |||
323 | (int) __entry->pid, (unsigned long long)__entry->now) | 323 | (int) __entry->pid, (unsigned long long)__entry->now) |
324 | ); | 324 | ); |
325 | 325 | ||
326 | #ifdef CONFIG_NO_HZ_FULL | ||
327 | TRACE_EVENT(tick_stop, | ||
328 | |||
329 | TP_PROTO(int success, char *error_msg), | ||
330 | |||
331 | TP_ARGS(success, error_msg), | ||
332 | |||
333 | TP_STRUCT__entry( | ||
334 | __field( int , success ) | ||
335 | __string( msg, error_msg ) | ||
336 | ), | ||
337 | |||
338 | TP_fast_assign( | ||
339 | __entry->success = success; | ||
340 | __assign_str(msg, error_msg); | ||
341 | ), | ||
342 | |||
343 | TP_printk("success=%s msg=%s", __entry->success ? "yes" : "no", __get_str(msg)) | ||
344 | ); | ||
345 | #endif | ||
346 | |||
326 | #endif /* _TRACE_TIMER_H */ | 347 | #endif /* _TRACE_TIMER_H */ |
327 | 348 | ||
328 | /* This part must be outside protection */ | 349 | /* This part must be outside protection */ |
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 12a900dbb819..85e05ab98253 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c | |||
@@ -28,6 +28,8 @@ | |||
28 | 28 | ||
29 | #include "tick-internal.h" | 29 | #include "tick-internal.h" |
30 | 30 | ||
31 | #include <trace/events/timer.h> | ||
32 | |||
31 | /* | 33 | /* |
32 | * Per cpu nohz control structure | 34 | * Per cpu nohz control structure |
33 | */ | 35 | */ |
@@ -153,14 +155,20 @@ static bool can_stop_full_tick(void) | |||
153 | { | 155 | { |
154 | WARN_ON_ONCE(!irqs_disabled()); | 156 | WARN_ON_ONCE(!irqs_disabled()); |
155 | 157 | ||
156 | if (!sched_can_stop_tick()) | 158 | if (!sched_can_stop_tick()) { |
159 | trace_tick_stop(0, "more than 1 task in runqueue\n"); | ||
157 | return false; | 160 | return false; |
161 | } | ||
158 | 162 | ||
159 | if (!posix_cpu_timers_can_stop_tick(current)) | 163 | if (!posix_cpu_timers_can_stop_tick(current)) { |
164 | trace_tick_stop(0, "posix timers running\n"); | ||
160 | return false; | 165 | return false; |
166 | } | ||
161 | 167 | ||
162 | if (!perf_event_can_stop_tick()) | 168 | if (!perf_event_can_stop_tick()) { |
169 | trace_tick_stop(0, "perf events running\n"); | ||
163 | return false; | 170 | return false; |
171 | } | ||
164 | 172 | ||
165 | /* sched_clock_tick() needs us? */ | 173 | /* sched_clock_tick() needs us? */ |
166 | #ifdef CONFIG_HAVE_UNSTABLE_SCHED_CLOCK | 174 | #ifdef CONFIG_HAVE_UNSTABLE_SCHED_CLOCK |
@@ -168,8 +176,10 @@ static bool can_stop_full_tick(void) | |||
168 | * TODO: kick full dynticks CPUs when | 176 | * TODO: kick full dynticks CPUs when |
169 | * sched_clock_stable is set. | 177 | * sched_clock_stable is set. |
170 | */ | 178 | */ |
171 | if (!sched_clock_stable) | 179 | if (!sched_clock_stable) { |
180 | trace_tick_stop(0, "unstable sched clock\n"); | ||
172 | return false; | 181 | return false; |
182 | } | ||
173 | #endif | 183 | #endif |
174 | 184 | ||
175 | return true; | 185 | return true; |
@@ -631,6 +641,7 @@ static ktime_t tick_nohz_stop_sched_tick(struct tick_sched *ts, | |||
631 | 641 | ||
632 | ts->last_tick = hrtimer_get_expires(&ts->sched_timer); | 642 | ts->last_tick = hrtimer_get_expires(&ts->sched_timer); |
633 | ts->tick_stopped = 1; | 643 | ts->tick_stopped = 1; |
644 | trace_tick_stop(1, " "); | ||
634 | } | 645 | } |
635 | 646 | ||
636 | /* | 647 | /* |