diff options
-rw-r--r-- | kernel/posix-cpu-timers.c | 70 |
1 files changed, 25 insertions, 45 deletions
diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c index dc4355b967db..ab9911b54faf 100644 --- a/kernel/posix-cpu-timers.c +++ b/kernel/posix-cpu-timers.c | |||
@@ -374,27 +374,27 @@ static int posix_cpu_timer_del(struct k_itimer *timer) | |||
374 | struct task_struct *p = timer->it.cpu.task; | 374 | struct task_struct *p = timer->it.cpu.task; |
375 | int ret = 0; | 375 | int ret = 0; |
376 | 376 | ||
377 | if (likely(p != NULL)) { | 377 | WARN_ON_ONCE(p == NULL); |
378 | read_lock(&tasklist_lock); | ||
379 | if (unlikely(p->sighand == NULL)) { | ||
380 | /* | ||
381 | * We raced with the reaping of the task. | ||
382 | * The deletion should have cleared us off the list. | ||
383 | */ | ||
384 | BUG_ON(!list_empty(&timer->it.cpu.entry)); | ||
385 | } else { | ||
386 | spin_lock(&p->sighand->siglock); | ||
387 | if (timer->it.cpu.firing) | ||
388 | ret = TIMER_RETRY; | ||
389 | else | ||
390 | list_del(&timer->it.cpu.entry); | ||
391 | spin_unlock(&p->sighand->siglock); | ||
392 | } | ||
393 | read_unlock(&tasklist_lock); | ||
394 | 378 | ||
395 | if (!ret) | 379 | read_lock(&tasklist_lock); |
396 | put_task_struct(p); | 380 | if (unlikely(p->sighand == NULL)) { |
381 | /* | ||
382 | * We raced with the reaping of the task. | ||
383 | * The deletion should have cleared us off the list. | ||
384 | */ | ||
385 | BUG_ON(!list_empty(&timer->it.cpu.entry)); | ||
386 | } else { | ||
387 | spin_lock(&p->sighand->siglock); | ||
388 | if (timer->it.cpu.firing) | ||
389 | ret = TIMER_RETRY; | ||
390 | else | ||
391 | list_del(&timer->it.cpu.entry); | ||
392 | spin_unlock(&p->sighand->siglock); | ||
397 | } | 393 | } |
394 | read_unlock(&tasklist_lock); | ||
395 | |||
396 | if (!ret) | ||
397 | put_task_struct(p); | ||
398 | 398 | ||
399 | return ret; | 399 | return ret; |
400 | } | 400 | } |
@@ -622,12 +622,7 @@ static int posix_cpu_timer_set(struct k_itimer *timer, int flags, | |||
622 | unsigned long long old_expires, new_expires, old_incr, val; | 622 | unsigned long long old_expires, new_expires, old_incr, val; |
623 | int ret; | 623 | int ret; |
624 | 624 | ||
625 | if (unlikely(p == NULL)) { | 625 | WARN_ON_ONCE(p == NULL); |
626 | /* | ||
627 | * Timer refers to a dead task's clock. | ||
628 | */ | ||
629 | return -ESRCH; | ||
630 | } | ||
631 | 626 | ||
632 | new_expires = timespec_to_sample(timer->it_clock, &new->it_value); | 627 | new_expires = timespec_to_sample(timer->it_clock, &new->it_value); |
633 | 628 | ||
@@ -770,6 +765,8 @@ static void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec *itp) | |||
770 | unsigned long long now; | 765 | unsigned long long now; |
771 | struct task_struct *p = timer->it.cpu.task; | 766 | struct task_struct *p = timer->it.cpu.task; |
772 | 767 | ||
768 | WARN_ON_ONCE(p == NULL); | ||
769 | |||
773 | /* | 770 | /* |
774 | * Easy part: convert the reload time. | 771 | * Easy part: convert the reload time. |
775 | */ | 772 | */ |
@@ -781,18 +778,6 @@ static void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec *itp) | |||
781 | return; | 778 | return; |
782 | } | 779 | } |
783 | 780 | ||
784 | if (unlikely(p == NULL)) { | ||
785 | WARN_ON_ONCE(CPUCLOCK_PERTHREAD(timer->it_clock)); | ||
786 | /* | ||
787 | * This task already died and the timer will never fire. | ||
788 | * In this case, expires is actually the dead value. | ||
789 | */ | ||
790 | dead: | ||
791 | sample_to_timespec(timer->it_clock, timer->it.cpu.expires, | ||
792 | &itp->it_value); | ||
793 | return; | ||
794 | } | ||
795 | |||
796 | /* | 781 | /* |
797 | * Sample the clock to take the difference with the expiry time. | 782 | * Sample the clock to take the difference with the expiry time. |
798 | */ | 783 | */ |
@@ -807,8 +792,9 @@ static void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec *itp) | |||
807 | * Call the timer disarmed, nothing else to do. | 792 | * Call the timer disarmed, nothing else to do. |
808 | */ | 793 | */ |
809 | timer->it.cpu.expires = 0; | 794 | timer->it.cpu.expires = 0; |
795 | sample_to_timespec(timer->it_clock, timer->it.cpu.expires, | ||
796 | &itp->it_value); | ||
810 | read_unlock(&tasklist_lock); | 797 | read_unlock(&tasklist_lock); |
811 | goto dead; | ||
812 | } else { | 798 | } else { |
813 | cpu_timer_sample_group(timer->it_clock, p, &now); | 799 | cpu_timer_sample_group(timer->it_clock, p, &now); |
814 | } | 800 | } |
@@ -1029,13 +1015,7 @@ void posix_cpu_timer_schedule(struct k_itimer *timer) | |||
1029 | struct task_struct *p = timer->it.cpu.task; | 1015 | struct task_struct *p = timer->it.cpu.task; |
1030 | unsigned long long now; | 1016 | unsigned long long now; |
1031 | 1017 | ||
1032 | if (unlikely(p == NULL)) { | 1018 | WARN_ON_ONCE(p == NULL); |
1033 | WARN_ON_ONCE(CPUCLOCK_PERTHREAD(timer->it_clock)); | ||
1034 | /* | ||
1035 | * The task was cleaned up already, no future firings. | ||
1036 | */ | ||
1037 | goto out; | ||
1038 | } | ||
1039 | 1019 | ||
1040 | /* | 1020 | /* |
1041 | * Fetch the current sample and update the timer's expiry time. | 1021 | * Fetch the current sample and update the timer's expiry time. |