diff options
Diffstat (limited to 'kernel/timer.c')
-rw-r--r-- | kernel/timer.c | 153 |
1 files changed, 145 insertions, 8 deletions
diff --git a/kernel/timer.c b/kernel/timer.c index f3d35d4ea42e..ceacc6626572 100644 --- a/kernel/timer.c +++ b/kernel/timer.c | |||
@@ -320,14 +320,130 @@ static void timer_stats_account_timer(struct timer_list *timer) | |||
320 | static void timer_stats_account_timer(struct timer_list *timer) {} | 320 | static void timer_stats_account_timer(struct timer_list *timer) {} |
321 | #endif | 321 | #endif |
322 | 322 | ||
323 | /** | 323 | #ifdef CONFIG_DEBUG_OBJECTS_TIMERS |
324 | * init_timer - initialize a timer. | 324 | |
325 | * @timer: the timer to be initialized | 325 | static struct debug_obj_descr timer_debug_descr; |
326 | * | 326 | |
327 | * init_timer() must be done to a timer prior calling *any* of the | 327 | /* |
328 | * other timer functions. | 328 | * fixup_init is called when: |
329 | * - an active object is initialized | ||
329 | */ | 330 | */ |
330 | void init_timer(struct timer_list *timer) | 331 | static int timer_fixup_init(void *addr, enum debug_obj_state state) |
332 | { | ||
333 | struct timer_list *timer = addr; | ||
334 | |||
335 | switch (state) { | ||
336 | case ODEBUG_STATE_ACTIVE: | ||
337 | del_timer_sync(timer); | ||
338 | debug_object_init(timer, &timer_debug_descr); | ||
339 | return 1; | ||
340 | default: | ||
341 | return 0; | ||
342 | } | ||
343 | } | ||
344 | |||
345 | /* | ||
346 | * fixup_activate is called when: | ||
347 | * - an active object is activated | ||
348 | * - an unknown object is activated (might be a statically initialized object) | ||
349 | */ | ||
350 | static int timer_fixup_activate(void *addr, enum debug_obj_state state) | ||
351 | { | ||
352 | struct timer_list *timer = addr; | ||
353 | |||
354 | switch (state) { | ||
355 | |||
356 | case ODEBUG_STATE_NOTAVAILABLE: | ||
357 | /* | ||
358 | * This is not really a fixup. The timer was | ||
359 | * statically initialized. We just make sure that it | ||
360 | * is tracked in the object tracker. | ||
361 | */ | ||
362 | if (timer->entry.next == NULL && | ||
363 | timer->entry.prev == TIMER_ENTRY_STATIC) { | ||
364 | debug_object_init(timer, &timer_debug_descr); | ||
365 | debug_object_activate(timer, &timer_debug_descr); | ||
366 | return 0; | ||
367 | } else { | ||
368 | WARN_ON_ONCE(1); | ||
369 | } | ||
370 | return 0; | ||
371 | |||
372 | case ODEBUG_STATE_ACTIVE: | ||
373 | WARN_ON(1); | ||
374 | |||
375 | default: | ||
376 | return 0; | ||
377 | } | ||
378 | } | ||
379 | |||
380 | /* | ||
381 | * fixup_free is called when: | ||
382 | * - an active object is freed | ||
383 | */ | ||
384 | static int timer_fixup_free(void *addr, enum debug_obj_state state) | ||
385 | { | ||
386 | struct timer_list *timer = addr; | ||
387 | |||
388 | switch (state) { | ||
389 | case ODEBUG_STATE_ACTIVE: | ||
390 | del_timer_sync(timer); | ||
391 | debug_object_free(timer, &timer_debug_descr); | ||
392 | return 1; | ||
393 | default: | ||
394 | return 0; | ||
395 | } | ||
396 | } | ||
397 | |||
398 | static struct debug_obj_descr timer_debug_descr = { | ||
399 | .name = "timer_list", | ||
400 | .fixup_init = timer_fixup_init, | ||
401 | .fixup_activate = timer_fixup_activate, | ||
402 | .fixup_free = timer_fixup_free, | ||
403 | }; | ||
404 | |||
405 | static inline void debug_timer_init(struct timer_list *timer) | ||
406 | { | ||
407 | debug_object_init(timer, &timer_debug_descr); | ||
408 | } | ||
409 | |||
410 | static inline void debug_timer_activate(struct timer_list *timer) | ||
411 | { | ||
412 | debug_object_activate(timer, &timer_debug_descr); | ||
413 | } | ||
414 | |||
415 | static inline void debug_timer_deactivate(struct timer_list *timer) | ||
416 | { | ||
417 | debug_object_deactivate(timer, &timer_debug_descr); | ||
418 | } | ||
419 | |||
420 | static inline void debug_timer_free(struct timer_list *timer) | ||
421 | { | ||
422 | debug_object_free(timer, &timer_debug_descr); | ||
423 | } | ||
424 | |||
425 | static void __init_timer(struct timer_list *timer); | ||
426 | |||
427 | void init_timer_on_stack(struct timer_list *timer) | ||
428 | { | ||
429 | debug_object_init_on_stack(timer, &timer_debug_descr); | ||
430 | __init_timer(timer); | ||
431 | } | ||
432 | EXPORT_SYMBOL_GPL(init_timer_on_stack); | ||
433 | |||
434 | void destroy_timer_on_stack(struct timer_list *timer) | ||
435 | { | ||
436 | debug_object_free(timer, &timer_debug_descr); | ||
437 | } | ||
438 | EXPORT_SYMBOL_GPL(destroy_timer_on_stack); | ||
439 | |||
440 | #else | ||
441 | static inline void debug_timer_init(struct timer_list *timer) { } | ||
442 | static inline void debug_timer_activate(struct timer_list *timer) { } | ||
443 | static inline void debug_timer_deactivate(struct timer_list *timer) { } | ||
444 | #endif | ||
445 | |||
446 | static void __init_timer(struct timer_list *timer) | ||
331 | { | 447 | { |
332 | timer->entry.next = NULL; | 448 | timer->entry.next = NULL; |
333 | timer->base = __raw_get_cpu_var(tvec_bases); | 449 | timer->base = __raw_get_cpu_var(tvec_bases); |
@@ -337,6 +453,19 @@ void init_timer(struct timer_list *timer) | |||
337 | memset(timer->start_comm, 0, TASK_COMM_LEN); | 453 | memset(timer->start_comm, 0, TASK_COMM_LEN); |
338 | #endif | 454 | #endif |
339 | } | 455 | } |
456 | |||
457 | /** | ||
458 | * init_timer - initialize a timer. | ||
459 | * @timer: the timer to be initialized | ||
460 | * | ||
461 | * init_timer() must be done to a timer prior calling *any* of the | ||
462 | * other timer functions. | ||
463 | */ | ||
464 | void init_timer(struct timer_list *timer) | ||
465 | { | ||
466 | debug_timer_init(timer); | ||
467 | __init_timer(timer); | ||
468 | } | ||
340 | EXPORT_SYMBOL(init_timer); | 469 | EXPORT_SYMBOL(init_timer); |
341 | 470 | ||
342 | void init_timer_deferrable(struct timer_list *timer) | 471 | void init_timer_deferrable(struct timer_list *timer) |
@@ -351,6 +480,8 @@ static inline void detach_timer(struct timer_list *timer, | |||
351 | { | 480 | { |
352 | struct list_head *entry = &timer->entry; | 481 | struct list_head *entry = &timer->entry; |
353 | 482 | ||
483 | debug_timer_deactivate(timer); | ||
484 | |||
354 | __list_del(entry->prev, entry->next); | 485 | __list_del(entry->prev, entry->next); |
355 | if (clear_pending) | 486 | if (clear_pending) |
356 | entry->next = NULL; | 487 | entry->next = NULL; |
@@ -405,6 +536,8 @@ int __mod_timer(struct timer_list *timer, unsigned long expires) | |||
405 | ret = 1; | 536 | ret = 1; |
406 | } | 537 | } |
407 | 538 | ||
539 | debug_timer_activate(timer); | ||
540 | |||
408 | new_base = __get_cpu_var(tvec_bases); | 541 | new_base = __get_cpu_var(tvec_bases); |
409 | 542 | ||
410 | if (base != new_base) { | 543 | if (base != new_base) { |
@@ -450,6 +583,7 @@ void add_timer_on(struct timer_list *timer, int cpu) | |||
450 | BUG_ON(timer_pending(timer) || !timer->function); | 583 | BUG_ON(timer_pending(timer) || !timer->function); |
451 | spin_lock_irqsave(&base->lock, flags); | 584 | spin_lock_irqsave(&base->lock, flags); |
452 | timer_set_base(timer, base); | 585 | timer_set_base(timer, base); |
586 | debug_timer_activate(timer); | ||
453 | internal_add_timer(base, timer); | 587 | internal_add_timer(base, timer); |
454 | /* | 588 | /* |
455 | * Check whether the other CPU is idle and needs to be | 589 | * Check whether the other CPU is idle and needs to be |
@@ -1086,11 +1220,14 @@ signed long __sched schedule_timeout(signed long timeout) | |||
1086 | 1220 | ||
1087 | expire = timeout + jiffies; | 1221 | expire = timeout + jiffies; |
1088 | 1222 | ||
1089 | setup_timer(&timer, process_timeout, (unsigned long)current); | 1223 | setup_timer_on_stack(&timer, process_timeout, (unsigned long)current); |
1090 | __mod_timer(&timer, expire); | 1224 | __mod_timer(&timer, expire); |
1091 | schedule(); | 1225 | schedule(); |
1092 | del_singleshot_timer_sync(&timer); | 1226 | del_singleshot_timer_sync(&timer); |
1093 | 1227 | ||
1228 | /* Remove the timer from the object tracker */ | ||
1229 | destroy_timer_on_stack(&timer); | ||
1230 | |||
1094 | timeout = expire - jiffies; | 1231 | timeout = expire - jiffies; |
1095 | 1232 | ||
1096 | out: | 1233 | out: |