diff options
author | Bjoern Brandenburg <bbb@mpi-sws.org> | 2016-03-18 13:07:39 -0400 |
---|---|---|
committer | Bjoern Brandenburg <bbb@mpi-sws.org> | 2017-05-26 17:12:38 -0400 |
commit | 13113c878cbcfdedcf339a20d85c473011937dff (patch) | |
tree | 48d4a076a66edac6034d416b65e4f59dd667c220 | |
parent | 81129a9d240efb1030e3e68784480dbbd95e5fff (diff) |
Hook into hrtimer to report large latencies
-rw-r--r-- | include/linux/hrtimer.h | 3 | ||||
-rw-r--r-- | kernel/time/hrtimer.c | 29 |
2 files changed, 32 insertions, 0 deletions
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 5e00f80b1535..720063df0ac0 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h | |||
@@ -109,6 +109,9 @@ struct hrtimer { | |||
109 | void *start_site; | 109 | void *start_site; |
110 | char start_comm[16]; | 110 | char start_comm[16]; |
111 | #endif | 111 | #endif |
112 | #ifdef CONFIG_REPORT_TIMER_LATENCY | ||
113 | ktime_t when_added; | ||
114 | #endif | ||
112 | }; | 115 | }; |
113 | 116 | ||
114 | /** | 117 | /** |
diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c index a78e3558d0b6..b4824e1dbc6d 100644 --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c | |||
@@ -990,6 +990,10 @@ void hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim, | |||
990 | 990 | ||
991 | tim = hrtimer_update_lowres(timer, tim, mode); | 991 | tim = hrtimer_update_lowres(timer, tim, mode); |
992 | 992 | ||
993 | #ifdef CONFIG_REPORT_TIMER_LATENCY | ||
994 | timer->when_added = base->get_time(); | ||
995 | #endif | ||
996 | |||
993 | hrtimer_set_expires_range_ns(timer, tim, delta_ns); | 997 | hrtimer_set_expires_range_ns(timer, tim, delta_ns); |
994 | 998 | ||
995 | /* Switch the timer base, if necessary: */ | 999 | /* Switch the timer base, if necessary: */ |
@@ -1274,6 +1278,9 @@ static void __hrtimer_run_queues(struct hrtimer_cpu_base *cpu_base, ktime_t now) | |||
1274 | { | 1278 | { |
1275 | struct hrtimer_clock_base *base = cpu_base->clock_base; | 1279 | struct hrtimer_clock_base *base = cpu_base->clock_base; |
1276 | unsigned int active = cpu_base->active_bases; | 1280 | unsigned int active = cpu_base->active_bases; |
1281 | #ifdef CONFIG_REPORT_TIMER_LATENCY | ||
1282 | ktime_t was_exp_nxt = cpu_base->expires_next; | ||
1283 | #endif | ||
1277 | 1284 | ||
1278 | for (; active; base++, active >>= 1) { | 1285 | for (; active; base++, active >>= 1) { |
1279 | struct timerqueue_node *node; | 1286 | struct timerqueue_node *node; |
@@ -1304,6 +1311,28 @@ static void __hrtimer_run_queues(struct hrtimer_cpu_base *cpu_base, ktime_t now) | |||
1304 | if (basenow.tv64 < hrtimer_get_softexpires_tv64(timer)) | 1311 | if (basenow.tv64 < hrtimer_get_softexpires_tv64(timer)) |
1305 | break; | 1312 | break; |
1306 | 1313 | ||
1314 | #ifdef CONFIG_REPORT_TIMER_LATENCY | ||
1315 | if (cpu_base->hres_active && | ||
1316 | (basenow.tv64 >= | ||
1317 | hrtimer_get_expires_tv64(timer) + | ||
1318 | ((s64) CONFIG_REPORT_TIMER_LATENCY_THRESHOLD))) { | ||
1319 | printk_ratelimited(KERN_WARNING | ||
1320 | "WARNING: P%d timer latency:%lld now:%lld " | ||
1321 | "basenow:%lld exp:%lld soft-exp:%lld " | ||
1322 | "nxt:%lld added:%lld " | ||
1323 | "timer:%p fn:%p" | ||
1324 | "\n", | ||
1325 | smp_processor_id(), | ||
1326 | basenow.tv64 - hrtimer_get_expires_tv64(timer), | ||
1327 | now.tv64, basenow.tv64, | ||
1328 | hrtimer_get_expires_tv64(timer), | ||
1329 | hrtimer_get_softexpires_tv64(timer), | ||
1330 | was_exp_nxt.tv64, | ||
1331 | timer->when_added.tv64, | ||
1332 | timer, timer->function); | ||
1333 | } | ||
1334 | #endif | ||
1335 | |||
1307 | __run_hrtimer(cpu_base, base, timer, &basenow); | 1336 | __run_hrtimer(cpu_base, base, timer, &basenow); |
1308 | } | 1337 | } |
1309 | } | 1338 | } |