diff options
Diffstat (limited to 'kernel/timer.c')
| -rw-r--r-- | kernel/timer.c | 75 |
1 files changed, 62 insertions, 13 deletions
diff --git a/kernel/timer.c b/kernel/timer.c index 9b77fc9a9ac8..cffffad01c31 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,28 +527,36 @@ 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 | /** |
| 527 | * init_timer - initialize a timer. | 534 | * init_timer_key - initialize a timer |
| 528 | * @timer: the timer to be initialized | 535 | * @timer: the timer to be initialized |
| 536 | * @name: name of the timer | ||
| 537 | * @key: lockdep class key of the fake lock used for tracking timer | ||
| 538 | * sync lock dependencies | ||
| 529 | * | 539 | * |
| 530 | * init_timer() must be done to a timer prior calling *any* of the | 540 | * init_timer_key() must be done to a timer prior calling *any* of the |
| 531 | * other timer functions. | 541 | * other timer functions. |
| 532 | */ | 542 | */ |
| 533 | void init_timer(struct timer_list *timer) | 543 | void init_timer_key(struct timer_list *timer, |
| 544 | const char *name, | ||
| 545 | struct lock_class_key *key) | ||
| 534 | { | 546 | { |
| 535 | debug_timer_init(timer); | 547 | debug_timer_init(timer); |
| 536 | __init_timer(timer); | 548 | __init_timer(timer, name, key); |
| 537 | } | 549 | } |
| 538 | EXPORT_SYMBOL(init_timer); | 550 | EXPORT_SYMBOL(init_timer_key); |
| 539 | 551 | ||
| 540 | void init_timer_deferrable(struct timer_list *timer) | 552 | void init_timer_deferrable_key(struct timer_list *timer, |
| 553 | const char *name, | ||
| 554 | struct lock_class_key *key) | ||
| 541 | { | 555 | { |
| 542 | init_timer(timer); | 556 | init_timer_key(timer, name, key); |
| 543 | timer_set_deferrable(timer); | 557 | timer_set_deferrable(timer); |
| 544 | } | 558 | } |
| 545 | EXPORT_SYMBOL(init_timer_deferrable); | 559 | EXPORT_SYMBOL(init_timer_deferrable_key); |
| 546 | 560 | ||
| 547 | static inline void detach_timer(struct timer_list *timer, | 561 | static inline void detach_timer(struct timer_list *timer, |
| 548 | int clear_pending) | 562 | int clear_pending) |
| @@ -826,6 +840,15 @@ EXPORT_SYMBOL(try_to_del_timer_sync); | |||
| 826 | */ | 840 | */ |
| 827 | int del_timer_sync(struct timer_list *timer) | 841 | int del_timer_sync(struct timer_list *timer) |
| 828 | { | 842 | { |
| 843 | #ifdef CONFIG_LOCKDEP | ||
| 844 | unsigned long flags; | ||
| 845 | |||
| 846 | local_irq_save(flags); | ||
| 847 | lock_map_acquire(&timer->lockdep_map); | ||
| 848 | lock_map_release(&timer->lockdep_map); | ||
| 849 | local_irq_restore(flags); | ||
| 850 | #endif | ||
| 851 | |||
| 829 | for (;;) { | 852 | for (;;) { |
| 830 | int ret = try_to_del_timer_sync(timer); | 853 | int ret = try_to_del_timer_sync(timer); |
| 831 | if (ret >= 0) | 854 | if (ret >= 0) |
| @@ -897,10 +920,36 @@ static inline void __run_timers(struct tvec_base *base) | |||
| 897 | 920 | ||
| 898 | set_running_timer(base, timer); | 921 | set_running_timer(base, timer); |
| 899 | detach_timer(timer, 1); | 922 | detach_timer(timer, 1); |
| 923 | |||
| 900 | spin_unlock_irq(&base->lock); | 924 | spin_unlock_irq(&base->lock); |
| 901 | { | 925 | { |
| 902 | int preempt_count = preempt_count(); | 926 | int preempt_count = preempt_count(); |
| 927 | |||
| 928 | #ifdef CONFIG_LOCKDEP | ||
| 929 | /* | ||
| 930 | * It is permissible to free the timer from | ||
| 931 | * inside the function that is called from | ||
| 932 | * it, this we need to take into account for | ||
| 933 | * lockdep too. To avoid bogus "held lock | ||
| 934 | * freed" warnings as well as problems when | ||
| 935 | * looking into timer->lockdep_map, make a | ||
| 936 | * copy and use that here. | ||
| 937 | */ | ||
| 938 | struct lockdep_map lockdep_map = | ||
| 939 | timer->lockdep_map; | ||
| 940 | #endif | ||
| 941 | /* | ||
| 942 | * Couple the lock chain with the lock chain at | ||
| 943 | * del_timer_sync() by acquiring the lock_map | ||
| 944 | * around the fn() call here and in | ||
| 945 | * del_timer_sync(). | ||
| 946 | */ | ||
| 947 | lock_map_acquire(&lockdep_map); | ||
| 948 | |||
| 903 | fn(data); | 949 | fn(data); |
| 950 | |||
| 951 | lock_map_release(&lockdep_map); | ||
| 952 | |||
| 904 | if (preempt_count != preempt_count()) { | 953 | if (preempt_count != preempt_count()) { |
| 905 | printk(KERN_ERR "huh, entered %p " | 954 | printk(KERN_ERR "huh, entered %p " |
| 906 | "with preempt_count %08x, exited" | 955 | "with preempt_count %08x, exited" |
