diff options
-rw-r--r-- | kernel/posix-cpu-timers.c | 34 |
1 files changed, 16 insertions, 18 deletions
diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c index 79747b7d9420..3b7df8653913 100644 --- a/kernel/posix-cpu-timers.c +++ b/kernel/posix-cpu-timers.c | |||
@@ -788,7 +788,6 @@ static void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec *itp) | |||
788 | { | 788 | { |
789 | unsigned long long now; | 789 | unsigned long long now; |
790 | struct task_struct *p = timer->it.cpu.task; | 790 | struct task_struct *p = timer->it.cpu.task; |
791 | int clear_dead; | ||
792 | 791 | ||
793 | /* | 792 | /* |
794 | * Easy part: convert the reload time. | 793 | * Easy part: convert the reload time. |
@@ -802,6 +801,7 @@ static void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec *itp) | |||
802 | } | 801 | } |
803 | 802 | ||
804 | if (unlikely(p == NULL)) { | 803 | if (unlikely(p == NULL)) { |
804 | WARN_ON_ONCE(CPUCLOCK_PERTHREAD(timer->it_clock)); | ||
805 | /* | 805 | /* |
806 | * This task already died and the timer will never fire. | 806 | * This task already died and the timer will never fire. |
807 | * In this case, expires is actually the dead value. | 807 | * In this case, expires is actually the dead value. |
@@ -817,7 +817,6 @@ static void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec *itp) | |||
817 | */ | 817 | */ |
818 | if (CPUCLOCK_PERTHREAD(timer->it_clock)) { | 818 | if (CPUCLOCK_PERTHREAD(timer->it_clock)) { |
819 | cpu_clock_sample(timer->it_clock, p, &now); | 819 | cpu_clock_sample(timer->it_clock, p, &now); |
820 | clear_dead = p->exit_state; | ||
821 | } else { | 820 | } else { |
822 | read_lock(&tasklist_lock); | 821 | read_lock(&tasklist_lock); |
823 | if (unlikely(p->sighand == NULL)) { | 822 | if (unlikely(p->sighand == NULL)) { |
@@ -833,22 +832,20 @@ static void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec *itp) | |||
833 | goto dead; | 832 | goto dead; |
834 | } else { | 833 | } else { |
835 | cpu_timer_sample_group(timer->it_clock, p, &now); | 834 | cpu_timer_sample_group(timer->it_clock, p, &now); |
836 | clear_dead = (unlikely(p->exit_state) && | 835 | if (unlikely(p->exit_state) && thread_group_empty(p)) { |
837 | thread_group_empty(p)); | 836 | read_unlock(&tasklist_lock); |
837 | /* | ||
838 | * We've noticed that the thread is dead, but | ||
839 | * not yet reaped. Take this opportunity to | ||
840 | * drop our task ref. | ||
841 | */ | ||
842 | clear_dead_task(timer, now); | ||
843 | goto dead; | ||
844 | } | ||
838 | } | 845 | } |
839 | read_unlock(&tasklist_lock); | 846 | read_unlock(&tasklist_lock); |
840 | } | 847 | } |
841 | 848 | ||
842 | if (unlikely(clear_dead)) { | ||
843 | /* | ||
844 | * We've noticed that the thread is dead, but | ||
845 | * not yet reaped. Take this opportunity to | ||
846 | * drop our task ref. | ||
847 | */ | ||
848 | clear_dead_task(timer, now); | ||
849 | goto dead; | ||
850 | } | ||
851 | |||
852 | if (now < timer->it.cpu.expires) { | 849 | if (now < timer->it.cpu.expires) { |
853 | sample_to_timespec(timer->it_clock, | 850 | sample_to_timespec(timer->it_clock, |
854 | timer->it.cpu.expires - now, | 851 | timer->it.cpu.expires - now, |
@@ -1063,11 +1060,13 @@ void posix_cpu_timer_schedule(struct k_itimer *timer) | |||
1063 | struct task_struct *p = timer->it.cpu.task; | 1060 | struct task_struct *p = timer->it.cpu.task; |
1064 | unsigned long long now; | 1061 | unsigned long long now; |
1065 | 1062 | ||
1066 | if (unlikely(p == NULL)) | 1063 | if (unlikely(p == NULL)) { |
1064 | WARN_ON_ONCE(CPUCLOCK_PERTHREAD(timer->it_clock)); | ||
1067 | /* | 1065 | /* |
1068 | * The task was cleaned up already, no future firings. | 1066 | * The task was cleaned up already, no future firings. |
1069 | */ | 1067 | */ |
1070 | goto out; | 1068 | goto out; |
1069 | } | ||
1071 | 1070 | ||
1072 | /* | 1071 | /* |
1073 | * Fetch the current sample and update the timer's expiry time. | 1072 | * Fetch the current sample and update the timer's expiry time. |
@@ -1075,10 +1074,9 @@ void posix_cpu_timer_schedule(struct k_itimer *timer) | |||
1075 | if (CPUCLOCK_PERTHREAD(timer->it_clock)) { | 1074 | if (CPUCLOCK_PERTHREAD(timer->it_clock)) { |
1076 | cpu_clock_sample(timer->it_clock, p, &now); | 1075 | cpu_clock_sample(timer->it_clock, p, &now); |
1077 | bump_cpu_timer(timer, now); | 1076 | bump_cpu_timer(timer, now); |
1078 | if (unlikely(p->exit_state)) { | 1077 | if (unlikely(p->exit_state)) |
1079 | clear_dead_task(timer, now); | ||
1080 | goto out; | 1078 | goto out; |
1081 | } | 1079 | |
1082 | read_lock(&tasklist_lock); /* arm_timer needs it. */ | 1080 | read_lock(&tasklist_lock); /* arm_timer needs it. */ |
1083 | spin_lock(&p->sighand->siglock); | 1081 | spin_lock(&p->sighand->siglock); |
1084 | } else { | 1082 | } else { |