aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCorey Minyard <minyard@acm.org>2005-09-06 18:18:38 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-07 19:57:47 -0400
commit75b0768a396f2a25901b7b1edc87b95cdb3af4ef (patch)
treea35e7a9b5b92e03410f695d32f1a1cf3bafa335a
parentc14979b993021377228958498937bcdd9539cbce (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>
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c36
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
62static inline void add_usec_to_timer(struct timer_list *t, long v) 62static 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