Re: kernel timer races

From: Andrey Savochkin (saw@saw.sw.com.sg)
Date: Fri May 26 2000 - 07:33:50 EST


Hello,

On Thu, May 25, 2000 at 01:40:45PM +0100, Alan Cox wrote:
> There is a really dumb fix perhaps ?
>
> wait_on_timers();
>
> That would map to a bh wait on 2.2 and the saner timer wait on 2.3.x

Andrew, there are a lot of possible timer races, but most of them can be very
easy solved by the timer user. For example, setting some flag before
del_timer call so that the handler will not reinsert the timer solves several
kinds of the races. BTW, this flag seems to be necessary with del_timer_sync
anyway.

I like the Alan's proposal.
Actually, with wait_on_timers() and reinsert protection flag we do not need
del_timer_sync for most drivers. wait_on_timers() has larger overhead
because it waits for all timers, but, I think, it's acceptable for device
close call.

Best regards
                Andrey

--- ./kernel/timer.c.timer Fri May 26 17:55:54 2000
+++ ./kernel/timer.c Fri May 26 20:20:40 2000
@@ -270,9 +270,12 @@
         tv->index = (tv->index + 1) & TVN_MASK;
 }
 
+static volatile int walking_timer_list;
+
 static inline void run_timer_list(void)
 {
         spin_lock_irq(&timerlist_lock);
+ walking_timer_list = 1;
         while ((long)(jiffies - timer_jiffies) >= 0) {
                 struct list_head *head, *curr;
                 if (!tv1.index) {
@@ -304,7 +307,20 @@
                 ++timer_jiffies;
                 tv1.index = (tv1.index + 1) & TVR_MASK;
         }
+ walking_timer_list = 0;
         spin_unlock_irq(&timerlist_lock);
+}
+
+/*
+ * This function ensures that timers running at the moment of the call on other
+ * CPUs (if any) have finished. It doesn't guarantee that upon the exit the
+ * next round of timers hasn't begun.
+ */
+void wait_on_timers(void)
+{
+ do {
+ rmb();
+ } while (walking_timer_list);
 }
 
 

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Wed May 31 2000 - 21:00:15 EST