diff options
Diffstat (limited to 'kernel/timer.c')
| -rw-r--r-- | kernel/timer.c | 68 |
1 files changed, 57 insertions, 11 deletions
diff --git a/kernel/timer.c b/kernel/timer.c index 13dd64fe143d..ef1c385bc572 100644 --- a/kernel/timer.c +++ b/kernel/timer.c | |||
| @@ -491,14 +491,18 @@ static inline void debug_timer_free(struct timer_list *timer) | |||
| 491 | debug_object_free(timer, &timer_debug_descr); | 491 | debug_object_free(timer, &timer_debug_descr); |
| 492 | } | 492 | } |
| 493 | 493 | ||
| 494 | static void __init_timer(struct timer_list *timer); | 494 | static void __init_timer(struct timer_list *timer, |
| 495 | const char *name, | ||
| 496 | struct lock_class_key *key); | ||
| 495 | 497 | ||
| 496 | void init_timer_on_stack(struct timer_list *timer) | 498 | void init_timer_on_stack_key(struct timer_list *timer, |
| 499 | const char *name, | ||
| 500 | struct lock_class_key *key) | ||
| 497 | { | 501 | { |
| 498 | debug_object_init_on_stack(timer, &timer_debug_descr); | 502 | debug_object_init_on_stack(timer, &timer_debug_descr); |
| 499 | __init_timer(timer); | 503 | __init_timer(timer, name, key); |
| 500 | } | 504 | } |
| 501 | EXPORT_SYMBOL_GPL(init_timer_on_stack); | 505 | EXPORT_SYMBOL_GPL(init_timer_on_stack_key); |
| 502 | 506 | ||
| 503 | void destroy_timer_on_stack(struct timer_list *timer) | 507 | void destroy_timer_on_stack(struct timer_list *timer) |
| 504 | { | 508 | { |
| @@ -512,7 +516,9 @@ static inline void debug_timer_activate(struct timer_list *timer) { } | |||
| 512 | static inline void debug_timer_deactivate(struct timer_list *timer) { } | 516 | static inline void debug_timer_deactivate(struct timer_list *timer) { } |
| 513 | #endif | 517 | #endif |
| 514 | 518 | ||
| 515 | static void __init_timer(struct timer_list *timer) | 519 | static void __init_timer(struct timer_list *timer, |
| 520 | const char *name, | ||
| 521 | struct lock_class_key *key) | ||
| 516 | { | 522 | { |
| 517 | timer->entry.next = NULL; | 523 | timer->entry.next = NULL; |
| 518 | timer->base = __raw_get_cpu_var(tvec_bases); | 524 | timer->base = __raw_get_cpu_var(tvec_bases); |
| @@ -521,6 +527,7 @@ static void __init_timer(struct timer_list *timer) | |||
| 521 | timer->start_pid = -1; | 527 | timer->start_pid = -1; |
| 522 | memset(timer->start_comm, 0, TASK_COMM_LEN); | 528 | memset(timer->start_comm, 0, TASK_COMM_LEN); |
| 523 | #endif | 529 | #endif |
| 530 | lockdep_init_map(&timer->lockdep_map, name, key, 0); | ||
| 524 | } | 531 | } |
| 525 | 532 | ||
| 526 | /** | 533 | /** |
| @@ -530,19 +537,23 @@ static void __init_timer(struct timer_list *timer) | |||
| 530 | * init_timer() must be done to a timer prior calling *any* of the | 537 | * init_timer() must be done to a timer prior calling *any* of the |
| 531 | * other timer functions. | 538 | * other timer functions. |
| 532 | */ | 539 | */ |
| 533 | void init_timer(struct timer_list *timer) | 540 | void init_timer_key(struct timer_list *timer, |
| 541 | const char *name, | ||
| 542 | struct lock_class_key *key) | ||
| 534 | { | 543 | { |
| 535 | debug_timer_init(timer); | 544 | debug_timer_init(timer); |
| 536 | __init_timer(timer); | 545 | __init_timer(timer, name, key); |
| 537 | } | 546 | } |
| 538 | EXPORT_SYMBOL(init_timer); | 547 | EXPORT_SYMBOL(init_timer_key); |
| 539 | 548 | ||
| 540 | void init_timer_deferrable(struct timer_list *timer) | 549 | void init_timer_deferrable_key(struct timer_list *timer, |
| 550 | const char *name, | ||
| 551 | struct lock_class_key *key) | ||
| 541 | { | 552 | { |
| 542 | init_timer(timer); | 553 | init_timer_key(timer, name, key); |
| 543 | timer_set_deferrable(timer); | 554 | timer_set_deferrable(timer); |
| 544 | } | 555 | } |
| 545 | EXPORT_SYMBOL(init_timer_deferrable); | 556 | EXPORT_SYMBOL(init_timer_deferrable_key); |
| 546 | 557 | ||
| 547 | static inline void detach_timer(struct timer_list *timer, | 558 | static inline void detach_timer(struct timer_list *timer, |
| 548 | int clear_pending) | 559 | int clear_pending) |
| @@ -789,6 +800,15 @@ EXPORT_SYMBOL(try_to_del_timer_sync); | |||
| 789 | */ | 800 | */ |
| 790 | int del_timer_sync(struct timer_list *timer) | 801 | int del_timer_sync(struct timer_list *timer) |
| 791 | { | 802 | { |
| 803 | #ifdef CONFIG_LOCKDEP | ||
| 804 | unsigned long flags; | ||
| 805 | |||
| 806 | local_irq_save(flags); | ||
| 807 | lock_map_acquire(&timer->lockdep_map); | ||
| 808 | lock_map_release(&timer->lockdep_map); | ||
| 809 | local_irq_restore(flags); | ||
| 810 | #endif | ||
| 811 | |||
| 792 | for (;;) { | 812 | for (;;) { |
| 793 | int ret = try_to_del_timer_sync(timer); | 813 | int ret = try_to_del_timer_sync(timer); |
| 794 | if (ret >= 0) | 814 | if (ret >= 0) |
| @@ -861,10 +881,36 @@ static inline void __run_timers(struct tvec_base *base) | |||
| 861 | 881 | ||
| 862 | set_running_timer(base, timer); | 882 | set_running_timer(base, timer); |
| 863 | detach_timer(timer, 1); | 883 | detach_timer(timer, 1); |
| 884 | |||
| 864 | spin_unlock_irq(&base->lock); | 885 | spin_unlock_irq(&base->lock); |
| 865 | { | 886 | { |
| 866 | int preempt_count = preempt_count(); | 887 | int preempt_count = preempt_count(); |
| 888 | |||
| 889 | #ifdef CONFIG_LOCKDEP | ||
| 890 | /* | ||
| 891 | * It is permissible to free the timer from | ||
| 892 | * inside the function that is called from | ||
| 893 | * it, this we need to take into account for | ||
| 894 | * lockdep too. To avoid bogus "held lock | ||
| 895 | * freed" warnings as well as problems when | ||
| 896 | * looking into timer->lockdep_map, make a | ||
| 897 | * copy and use that here. | ||
| 898 | */ | ||
| 899 | struct lockdep_map lockdep_map = | ||
| 900 | timer->lockdep_map; | ||
| 901 | #endif | ||
| 902 | /* | ||
| 903 | * Couple the lock chain with the lock chain at | ||
| 904 | * del_timer_sync() by acquiring the lock_map | ||
| 905 | * around the fn() call here and in | ||
| 906 | * del_timer_sync(). | ||
| 907 | */ | ||
| 908 | lock_map_acquire(&lockdep_map); | ||
| 909 | |||
| 867 | fn(data); | 910 | fn(data); |
| 911 | |||
| 912 | lock_map_release(&lockdep_map); | ||
| 913 | |||
| 868 | if (preempt_count != preempt_count()) { | 914 | if (preempt_count != preempt_count()) { |
| 869 | printk(KERN_ERR "huh, entered %p " | 915 | printk(KERN_ERR "huh, entered %p " |
| 870 | "with preempt_count %08x, exited" | 916 | "with preempt_count %08x, exited" |
