diff options
Diffstat (limited to 'kernel/hrtimer.c')
| -rw-r--r-- | kernel/hrtimer.c | 50 |
1 files changed, 26 insertions, 24 deletions
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index 0237a556eb1f..d2a7296c8251 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c | |||
| @@ -501,6 +501,7 @@ int hrtimer_cancel(struct hrtimer *timer) | |||
| 501 | 501 | ||
| 502 | if (ret >= 0) | 502 | if (ret >= 0) |
| 503 | return ret; | 503 | return ret; |
| 504 | cpu_relax(); | ||
| 504 | } | 505 | } |
| 505 | } | 506 | } |
| 506 | 507 | ||
| @@ -606,6 +607,9 @@ static inline void run_hrtimer_queue(struct hrtimer_base *base) | |||
| 606 | { | 607 | { |
| 607 | struct rb_node *node; | 608 | struct rb_node *node; |
| 608 | 609 | ||
| 610 | if (!base->first) | ||
| 611 | return; | ||
| 612 | |||
| 609 | if (base->get_softirq_time) | 613 | if (base->get_softirq_time) |
| 610 | base->softirq_time = base->get_softirq_time(); | 614 | base->softirq_time = base->get_softirq_time(); |
| 611 | 615 | ||
| @@ -655,29 +659,28 @@ void hrtimer_run_queues(void) | |||
| 655 | /* | 659 | /* |
| 656 | * Sleep related functions: | 660 | * Sleep related functions: |
| 657 | */ | 661 | */ |
| 658 | 662 | static int hrtimer_wakeup(struct hrtimer *timer) | |
| 659 | struct sleep_hrtimer { | ||
| 660 | struct hrtimer timer; | ||
| 661 | struct task_struct *task; | ||
| 662 | int expired; | ||
| 663 | }; | ||
| 664 | |||
| 665 | static int nanosleep_wakeup(struct hrtimer *timer) | ||
| 666 | { | 663 | { |
| 667 | struct sleep_hrtimer *t = | 664 | struct hrtimer_sleeper *t = |
| 668 | container_of(timer, struct sleep_hrtimer, timer); | 665 | container_of(timer, struct hrtimer_sleeper, timer); |
| 666 | struct task_struct *task = t->task; | ||
| 669 | 667 | ||
| 670 | t->expired = 1; | 668 | t->task = NULL; |
| 671 | wake_up_process(t->task); | 669 | if (task) |
| 670 | wake_up_process(task); | ||
| 672 | 671 | ||
| 673 | return HRTIMER_NORESTART; | 672 | return HRTIMER_NORESTART; |
| 674 | } | 673 | } |
| 675 | 674 | ||
| 676 | static int __sched do_nanosleep(struct sleep_hrtimer *t, enum hrtimer_mode mode) | 675 | void hrtimer_init_sleeper(struct hrtimer_sleeper *sl, task_t *task) |
| 677 | { | 676 | { |
| 678 | t->timer.function = nanosleep_wakeup; | 677 | sl->timer.function = hrtimer_wakeup; |
| 679 | t->task = current; | 678 | sl->task = task; |
| 680 | t->expired = 0; | 679 | } |
| 680 | |||
| 681 | static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mode) | ||
| 682 | { | ||
| 683 | hrtimer_init_sleeper(t, current); | ||
| 681 | 684 | ||
| 682 | do { | 685 | do { |
| 683 | set_current_state(TASK_INTERRUPTIBLE); | 686 | set_current_state(TASK_INTERRUPTIBLE); |
| @@ -685,18 +688,17 @@ static int __sched do_nanosleep(struct sleep_hrtimer *t, enum hrtimer_mode mode) | |||
| 685 | 688 | ||
| 686 | schedule(); | 689 | schedule(); |
| 687 | 690 | ||
| 688 | if (unlikely(!t->expired)) { | 691 | hrtimer_cancel(&t->timer); |
| 689 | hrtimer_cancel(&t->timer); | 692 | mode = HRTIMER_ABS; |
| 690 | mode = HRTIMER_ABS; | 693 | |
| 691 | } | 694 | } while (t->task && !signal_pending(current)); |
| 692 | } while (!t->expired && !signal_pending(current)); | ||
| 693 | 695 | ||
| 694 | return t->expired; | 696 | return t->task == NULL; |
| 695 | } | 697 | } |
| 696 | 698 | ||
| 697 | static long __sched nanosleep_restart(struct restart_block *restart) | 699 | static long __sched nanosleep_restart(struct restart_block *restart) |
| 698 | { | 700 | { |
| 699 | struct sleep_hrtimer t; | 701 | struct hrtimer_sleeper t; |
| 700 | struct timespec __user *rmtp; | 702 | struct timespec __user *rmtp; |
| 701 | struct timespec tu; | 703 | struct timespec tu; |
| 702 | ktime_t time; | 704 | ktime_t time; |
| @@ -729,7 +731,7 @@ long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp, | |||
| 729 | const enum hrtimer_mode mode, const clockid_t clockid) | 731 | const enum hrtimer_mode mode, const clockid_t clockid) |
| 730 | { | 732 | { |
| 731 | struct restart_block *restart; | 733 | struct restart_block *restart; |
| 732 | struct sleep_hrtimer t; | 734 | struct hrtimer_sleeper t; |
| 733 | struct timespec tu; | 735 | struct timespec tu; |
| 734 | ktime_t rem; | 736 | ktime_t rem; |
| 735 | 737 | ||
