diff options
| author | Steve French <sfrench@us.ibm.com> | 2006-06-25 11:57:32 -0400 |
|---|---|---|
| committer | Steve French <sfrench@us.ibm.com> | 2006-06-25 11:57:32 -0400 |
| commit | bbe5d235ee201705530a7153b57e141cd77d818b (patch) | |
| tree | e98c31b4cb2ced6357a87a02596f9ecdbd6dbb26 /kernel/timer.c | |
| parent | 189acaaef81b1d71aedd0d28810de24160c2e781 (diff) | |
| parent | dfd8317d3340f03bc06eba6b58f0ec0861da4a13 (diff) | |
Merge with /pub/scm/linux/kernel/git/torvalds/linux-2.6.git
Diffstat (limited to 'kernel/timer.c')
| -rw-r--r-- | kernel/timer.c | 30 |
1 files changed, 13 insertions, 17 deletions
diff --git a/kernel/timer.c b/kernel/timer.c index 9e49deed468c..f35b3939e937 100644 --- a/kernel/timer.c +++ b/kernel/timer.c | |||
| @@ -383,23 +383,19 @@ EXPORT_SYMBOL(del_timer_sync); | |||
| 383 | static int cascade(tvec_base_t *base, tvec_t *tv, int index) | 383 | static int cascade(tvec_base_t *base, tvec_t *tv, int index) |
| 384 | { | 384 | { |
| 385 | /* cascade all the timers from tv up one level */ | 385 | /* cascade all the timers from tv up one level */ |
| 386 | struct list_head *head, *curr; | 386 | struct timer_list *timer, *tmp; |
| 387 | struct list_head tv_list; | ||
| 388 | |||
| 389 | list_replace_init(tv->vec + index, &tv_list); | ||
| 387 | 390 | ||
| 388 | head = tv->vec + index; | ||
| 389 | curr = head->next; | ||
| 390 | /* | 391 | /* |
| 391 | * We are removing _all_ timers from the list, so we don't have to | 392 | * We are removing _all_ timers from the list, so we |
| 392 | * detach them individually, just clear the list afterwards. | 393 | * don't have to detach them individually. |
| 393 | */ | 394 | */ |
| 394 | while (curr != head) { | 395 | list_for_each_entry_safe(timer, tmp, &tv_list, entry) { |
| 395 | struct timer_list *tmp; | 396 | BUG_ON(timer->base != base); |
| 396 | 397 | internal_add_timer(base, timer); | |
| 397 | tmp = list_entry(curr, struct timer_list, entry); | ||
| 398 | BUG_ON(tmp->base != base); | ||
| 399 | curr = curr->next; | ||
| 400 | internal_add_timer(base, tmp); | ||
| 401 | } | 398 | } |
| 402 | INIT_LIST_HEAD(head); | ||
| 403 | 399 | ||
| 404 | return index; | 400 | return index; |
| 405 | } | 401 | } |
| @@ -419,10 +415,10 @@ static inline void __run_timers(tvec_base_t *base) | |||
| 419 | 415 | ||
| 420 | spin_lock_irq(&base->lock); | 416 | spin_lock_irq(&base->lock); |
| 421 | while (time_after_eq(jiffies, base->timer_jiffies)) { | 417 | while (time_after_eq(jiffies, base->timer_jiffies)) { |
| 422 | struct list_head work_list = LIST_HEAD_INIT(work_list); | 418 | struct list_head work_list; |
| 423 | struct list_head *head = &work_list; | 419 | struct list_head *head = &work_list; |
| 424 | int index = base->timer_jiffies & TVR_MASK; | 420 | int index = base->timer_jiffies & TVR_MASK; |
| 425 | 421 | ||
| 426 | /* | 422 | /* |
| 427 | * Cascade timers: | 423 | * Cascade timers: |
| 428 | */ | 424 | */ |
| @@ -431,8 +427,8 @@ static inline void __run_timers(tvec_base_t *base) | |||
| 431 | (!cascade(base, &base->tv3, INDEX(1))) && | 427 | (!cascade(base, &base->tv3, INDEX(1))) && |
| 432 | !cascade(base, &base->tv4, INDEX(2))) | 428 | !cascade(base, &base->tv4, INDEX(2))) |
| 433 | cascade(base, &base->tv5, INDEX(3)); | 429 | cascade(base, &base->tv5, INDEX(3)); |
| 434 | ++base->timer_jiffies; | 430 | ++base->timer_jiffies; |
| 435 | list_splice_init(base->tv1.vec + index, &work_list); | 431 | list_replace_init(base->tv1.vec + index, &work_list); |
| 436 | while (!list_empty(head)) { | 432 | while (!list_empty(head)) { |
| 437 | void (*fn)(unsigned long); | 433 | void (*fn)(unsigned long); |
| 438 | unsigned long data; | 434 | unsigned long data; |
