diff options
Diffstat (limited to 'kernel/timer.c')
-rw-r--r-- | kernel/timer.c | 31 |
1 files changed, 27 insertions, 4 deletions
diff --git a/kernel/timer.c b/kernel/timer.c index 5c1e84beaf4a..3424dfd11d50 100644 --- a/kernel/timer.c +++ b/kernel/timer.c | |||
@@ -604,7 +604,8 @@ static struct tvec_base *lock_timer_base(struct timer_list *timer, | |||
604 | } | 604 | } |
605 | 605 | ||
606 | static inline int | 606 | static inline int |
607 | __mod_timer(struct timer_list *timer, unsigned long expires, bool pending_only) | 607 | __mod_timer(struct timer_list *timer, unsigned long expires, |
608 | bool pending_only, int pinned) | ||
608 | { | 609 | { |
609 | struct tvec_base *base, *new_base; | 610 | struct tvec_base *base, *new_base; |
610 | unsigned long flags; | 611 | unsigned long flags; |
@@ -668,7 +669,7 @@ out_unlock: | |||
668 | */ | 669 | */ |
669 | int mod_timer_pending(struct timer_list *timer, unsigned long expires) | 670 | int mod_timer_pending(struct timer_list *timer, unsigned long expires) |
670 | { | 671 | { |
671 | return __mod_timer(timer, expires, true); | 672 | return __mod_timer(timer, expires, true, TIMER_NOT_PINNED); |
672 | } | 673 | } |
673 | EXPORT_SYMBOL(mod_timer_pending); | 674 | EXPORT_SYMBOL(mod_timer_pending); |
674 | 675 | ||
@@ -702,11 +703,33 @@ int mod_timer(struct timer_list *timer, unsigned long expires) | |||
702 | if (timer->expires == expires && timer_pending(timer)) | 703 | if (timer->expires == expires && timer_pending(timer)) |
703 | return 1; | 704 | return 1; |
704 | 705 | ||
705 | return __mod_timer(timer, expires, false); | 706 | return __mod_timer(timer, expires, false, TIMER_NOT_PINNED); |
706 | } | 707 | } |
707 | EXPORT_SYMBOL(mod_timer); | 708 | EXPORT_SYMBOL(mod_timer); |
708 | 709 | ||
709 | /** | 710 | /** |
711 | * mod_timer_pinned - modify a timer's timeout | ||
712 | * @timer: the timer to be modified | ||
713 | * @expires: new timeout in jiffies | ||
714 | * | ||
715 | * mod_timer_pinned() is a way to update the expire field of an | ||
716 | * active timer (if the timer is inactive it will be activated) | ||
717 | * and not allow the timer to be migrated to a different CPU. | ||
718 | * | ||
719 | * mod_timer_pinned(timer, expires) is equivalent to: | ||
720 | * | ||
721 | * del_timer(timer); timer->expires = expires; add_timer(timer); | ||
722 | */ | ||
723 | int mod_timer_pinned(struct timer_list *timer, unsigned long expires) | ||
724 | { | ||
725 | if (timer->expires == expires && timer_pending(timer)) | ||
726 | return 1; | ||
727 | |||
728 | return __mod_timer(timer, expires, false, TIMER_PINNED); | ||
729 | } | ||
730 | EXPORT_SYMBOL(mod_timer_pinned); | ||
731 | |||
732 | /** | ||
710 | * add_timer - start a timer | 733 | * add_timer - start a timer |
711 | * @timer: the timer to be added | 734 | * @timer: the timer to be added |
712 | * | 735 | * |
@@ -1356,7 +1379,7 @@ signed long __sched schedule_timeout(signed long timeout) | |||
1356 | expire = timeout + jiffies; | 1379 | expire = timeout + jiffies; |
1357 | 1380 | ||
1358 | setup_timer_on_stack(&timer, process_timeout, (unsigned long)current); | 1381 | setup_timer_on_stack(&timer, process_timeout, (unsigned long)current); |
1359 | __mod_timer(&timer, expire, false); | 1382 | __mod_timer(&timer, expire, false, TIMER_NOT_PINNED); |
1360 | schedule(); | 1383 | schedule(); |
1361 | del_singleshot_timer_sync(&timer); | 1384 | del_singleshot_timer_sync(&timer); |
1362 | 1385 | ||