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