Commit 29c36d50 authored by George Anzinger's avatar George Anzinger Committed by Linus Torvalds

[PATCH] too much timer simplification...

Noted by David Mosberger:

 "If someone happens to arm a periodic timer at exactly 256 jiffies (as
  ohci happens to do on platforms with HZ=1024), then you end up getting
  an endless loop of timer activations, causing a machine hang.

  The problem is that __run_timers updates base->timer_jiffies _before_
  running the callback routines.  If a callback re-arms the timer at
  exactly 256 jiffies, add_timers() will reinsert the timer into the list
  that we're currently processing, which of course will cause the timer to
  expire immediately again, etc., etc., ad naseum... "

The answer here is to move the whole expired list to a local header and
to not look back.
parent 7b55ea65
......@@ -397,7 +397,8 @@ static inline void __run_timers(tvec_base_t *base)
spin_lock_irq(&base->lock);
while (time_after_eq(jiffies, base->timer_jiffies)) {
struct list_head *head;
struct list_head work_list = LIST_HEAD_INIT(work_list);
struct list_head *head = &work_list;
int index = base->timer_jiffies & TVR_MASK;
/*
......@@ -409,8 +410,8 @@ static inline void __run_timers(tvec_base_t *base)
!cascade(base, &base->tv4, INDEX(2)))
cascade(base, &base->tv5, INDEX(3));
++base->timer_jiffies;
list_splice_init(base->tv1.vec + index, &work_list);
repeat:
head = base->tv1.vec + index;
if (!list_empty(head)) {
void (*fn)(unsigned long);
unsigned long data;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment