Messages in this thread Patch in this message | | | From | Daniel Phillips <> | Subject | Re: [RFC] New Improved Stronger Whiter Timers (was: Kernel Janitor) | Date | Tue, 30 Jan 2001 22:22:01 +0100 |
| |
On Tue, 30 Jan 2001, Manfred Spraul wrote: > This one is an UP and SMP race: > > spin_unlock_irq(&timerlist_lock); > + if (timer->event) > + { > + if ((requeue = timer->event(data))) > + { > + timer->expires += requeue; > + internal_add_timer(timer); > + } > + } > + else > + timer->function(data); /* bad old way */ > spin_lock_irq(&timerlist_lock); > > internal_add_timer assumes that the timerlist_lock is acquired.
Yes, oops, here is the fix.
--- ../2.4.1.clean/include/linux/timer.h Tue Jan 30 08:24:55 2001 +++ ./include/linux/timer.h Tue Jan 30 21:52:58 2001 @@ -22,6 +22,7 @@ unsigned long expires; unsigned long data; void (*function)(unsigned long); + unsigned long (*event)(unsigned long data); }; extern void add_timer(struct timer_list * timer); @@ -49,6 +50,9 @@ static inline void init_timer(struct timer_list * timer) { timer->list.next = timer->list.prev = NULL; + timer->function = NULL; + timer->event = NULL; + timer->data = 0; } static inline int timer_pending (const struct timer_list * timer) --- ../2.4.1.clean/kernel/timer.c Sun Dec 10 18:53:19 2000 +++ ./kernel/timer.c Tue Jan 30 22:09:09 2001 @@ -301,19 +301,30 @@ curr = head->next; if (curr != head) { struct timer_list *timer; - void (*fn)(unsigned long); - unsigned long data; + unsigned long data, requeue; timer = list_entry(curr, struct timer_list, list); - fn = timer->function; data= timer->data; detach_timer(timer); timer->list.next = timer->list.prev = NULL; timer_enter(timer); spin_unlock_irq(&timerlist_lock); - fn(data); - spin_lock_irq(&timerlist_lock); + if (timer->event) + { + requeue = timer->event(data); + spin_lock_irq(&timerlist_lock); + if (requeue) + { + timer->expires += requeue; + internal_add_timer(timer); + } + } + else + { + timer->function(data); /* bad old way */ + spin_lock_irq(&timerlist_lock); + } timer_exit(); goto repeat; } -- Daniel - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/
| |