aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/posix-cpu-timers.c70
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.