diff options
author | Corey Minyard <minyard@acm.org> | 2005-09-06 18:18:38 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-09-07 19:57:47 -0400 |
commit | 75b0768a396f2a25901b7b1edc87b95cdb3af4ef (patch) | |
tree | a35e7a9b5b92e03410f695d32f1a1cf3bafa335a /drivers/char | |
parent | c14979b993021377228958498937bcdd9539cbce (diff) |
[PATCH] ipmi: high-res timer support fixes
Fix some problems with the high-res timer support.
Signed-off-by: Corey Minyard <minyard@acm.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/ipmi/ipmi_si_intf.c | 36 |
1 files changed, 21 insertions, 15 deletions
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 51ce508b2f51..60f2f968b689 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
@@ -61,11 +61,11 @@ | |||
61 | # endif | 61 | # endif |
62 | static inline void add_usec_to_timer(struct timer_list *t, long v) | 62 | static inline void add_usec_to_timer(struct timer_list *t, long v) |
63 | { | 63 | { |
64 | t->sub_expires += nsec_to_arch_cycle(v * 1000); | 64 | t->arch_cycle_expires += nsec_to_arch_cycle(v * 1000); |
65 | while (t->sub_expires >= arch_cycles_per_jiffy) | 65 | while (t->arch_cycle_expires >= arch_cycles_per_jiffy) |
66 | { | 66 | { |
67 | t->expires++; | 67 | t->expires++; |
68 | t->sub_expires -= arch_cycles_per_jiffy; | 68 | t->arch_cycle_expires -= arch_cycles_per_jiffy; |
69 | } | 69 | } |
70 | } | 70 | } |
71 | #endif | 71 | #endif |
@@ -762,18 +762,20 @@ static void si_restart_short_timer(struct smi_info *smi_info) | |||
762 | #if defined(CONFIG_HIGH_RES_TIMERS) | 762 | #if defined(CONFIG_HIGH_RES_TIMERS) |
763 | unsigned long flags; | 763 | unsigned long flags; |
764 | unsigned long jiffies_now; | 764 | unsigned long jiffies_now; |
765 | unsigned long seq; | ||
765 | 766 | ||
766 | if (del_timer(&(smi_info->si_timer))) { | 767 | if (del_timer(&(smi_info->si_timer))) { |
767 | /* If we don't delete the timer, then it will go off | 768 | /* If we don't delete the timer, then it will go off |
768 | immediately, anyway. So we only process if we | 769 | immediately, anyway. So we only process if we |
769 | actually delete the timer. */ | 770 | actually delete the timer. */ |
770 | 771 | ||
771 | /* We already have irqsave on, so no need for it | 772 | do { |
772 | here. */ | 773 | seq = read_seqbegin_irqsave(&xtime_lock, flags); |
773 | read_lock(&xtime_lock); | 774 | jiffies_now = jiffies; |
774 | jiffies_now = jiffies; | 775 | smi_info->si_timer.expires = jiffies_now; |
775 | smi_info->si_timer.expires = jiffies_now; | 776 | smi_info->si_timer.arch_cycle_expires |
776 | smi_info->si_timer.sub_expires = get_arch_cycles(jiffies_now); | 777 | = get_arch_cycles(jiffies_now); |
778 | } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); | ||
777 | 779 | ||
778 | add_usec_to_timer(&smi_info->si_timer, SI_SHORT_TIMEOUT_USEC); | 780 | add_usec_to_timer(&smi_info->si_timer, SI_SHORT_TIMEOUT_USEC); |
779 | 781 | ||
@@ -827,15 +829,19 @@ static void smi_timeout(unsigned long data) | |||
827 | /* If the state machine asks for a short delay, then shorten | 829 | /* If the state machine asks for a short delay, then shorten |
828 | the timer timeout. */ | 830 | the timer timeout. */ |
829 | if (smi_result == SI_SM_CALL_WITH_DELAY) { | 831 | if (smi_result == SI_SM_CALL_WITH_DELAY) { |
832 | #if defined(CONFIG_HIGH_RES_TIMERS) | ||
833 | unsigned long seq; | ||
834 | #endif | ||
830 | spin_lock_irqsave(&smi_info->count_lock, flags); | 835 | spin_lock_irqsave(&smi_info->count_lock, flags); |
831 | smi_info->short_timeouts++; | 836 | smi_info->short_timeouts++; |
832 | spin_unlock_irqrestore(&smi_info->count_lock, flags); | 837 | spin_unlock_irqrestore(&smi_info->count_lock, flags); |
833 | #if defined(CONFIG_HIGH_RES_TIMERS) | 838 | #if defined(CONFIG_HIGH_RES_TIMERS) |
834 | read_lock(&xtime_lock); | 839 | do { |
835 | smi_info->si_timer.expires = jiffies; | 840 | seq = read_seqbegin_irqsave(&xtime_lock, flags); |
836 | smi_info->si_timer.sub_expires | 841 | smi_info->si_timer.expires = jiffies; |
837 | = get_arch_cycles(smi_info->si_timer.expires); | 842 | smi_info->si_timer.arch_cycle_expires |
838 | read_unlock(&xtime_lock); | 843 | = get_arch_cycles(smi_info->si_timer.expires); |
844 | } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); | ||
839 | add_usec_to_timer(&smi_info->si_timer, SI_SHORT_TIMEOUT_USEC); | 845 | add_usec_to_timer(&smi_info->si_timer, SI_SHORT_TIMEOUT_USEC); |
840 | #else | 846 | #else |
841 | smi_info->si_timer.expires = jiffies + 1; | 847 | smi_info->si_timer.expires = jiffies + 1; |
@@ -846,7 +852,7 @@ static void smi_timeout(unsigned long data) | |||
846 | spin_unlock_irqrestore(&smi_info->count_lock, flags); | 852 | spin_unlock_irqrestore(&smi_info->count_lock, flags); |
847 | smi_info->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES; | 853 | smi_info->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES; |
848 | #if defined(CONFIG_HIGH_RES_TIMERS) | 854 | #if defined(CONFIG_HIGH_RES_TIMERS) |
849 | smi_info->si_timer.sub_expires = 0; | 855 | smi_info->si_timer.arch_cycle_expires = 0; |
850 | #endif | 856 | #endif |
851 | } | 857 | } |
852 | 858 | ||