* [PATCH 5/5] run_posix_cpu_timers: don't check ->exit_state, use lock_task_sighand()
@ 2010-06-10 23:10 Oleg Nesterov
2010-06-11 18:04 ` [PATCH 6/5] fix the racy usage of thread_group_cputimer() in fastpath_timer_check() Oleg Nesterov
2010-06-18 10:20 ` [tip:sched/core] sched: run_posix_cpu_timers: Don't check ->exit_state, use lock_task_sighand() tip-bot for Oleg Nesterov
0 siblings, 2 replies; 5+ messages in thread
From: Oleg Nesterov @ 2010-06-10 23:10 UTC (permalink / raw)
To: Ingo Molnar
Cc: Peter Zijlstra, Stanislaw Gruszka, Thomas Gleixner, linux-kernel
run_posix_cpu_timers() doesn't work if current has already passed
exit_notify(). This was needed to prevent the races with do_wait().
Since ea6d290c ->signal is always valid and can't go away. We can
remove the "tsk->exit_state == 0" in fastpath_timer_check() and
convert run_posix_cpu_timers() to use lock_task_sighand().
Note: it makes sense to take group_leader's sighand instead, the
sub-thread still uses CPU after release_task(). But we need more
changes to do this.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
---
kernel/posix-cpu-timers.c | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
--- 35-rc2/kernel/posix-cpu-timers.c~5_RUN_PCT_DONT_CK_EXIT_STATE 2010-06-11 01:07:48.000000000 +0200
+++ 35-rc2/kernel/posix-cpu-timers.c 2010-06-11 01:08:03.000000000 +0200
@@ -1272,10 +1272,6 @@ static inline int fastpath_timer_check(s
{
struct signal_struct *sig;
- /* tsk == current, ensure it is safe to use ->signal/sighand */
- if (unlikely(tsk->exit_state))
- return 0;
-
if (!task_cputime_zero(&tsk->cputime_expires)) {
struct task_cputime task_sample = {
.utime = tsk->utime,
@@ -1308,6 +1304,7 @@ void run_posix_cpu_timers(struct task_st
{
LIST_HEAD(firing);
struct k_itimer *timer, *next;
+ unsigned long flags;
BUG_ON(!irqs_disabled());
@@ -1318,7 +1315,8 @@ void run_posix_cpu_timers(struct task_st
if (!fastpath_timer_check(tsk))
return;
- spin_lock(&tsk->sighand->siglock);
+ if (!lock_task_sighand(tsk, &flags))
+ return;
/*
* Here we take off tsk->signal->cpu_timers[N] and
* tsk->cpu_timers[N] all the timers that are firing, and
@@ -1340,7 +1338,7 @@ void run_posix_cpu_timers(struct task_st
* that gets the timer lock before we do will give it up and
* spin until we've taken care of that timer below.
*/
- spin_unlock(&tsk->sighand->siglock);
+ unlock_task_sighand(tsk, &flags);
/*
* Now that all the timers on our list have the firing flag,
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH 6/5] fix the racy usage of thread_group_cputimer() in fastpath_timer_check()
2010-06-10 23:10 [PATCH 5/5] run_posix_cpu_timers: don't check ->exit_state, use lock_task_sighand() Oleg Nesterov
@ 2010-06-11 18:04 ` Oleg Nesterov
2010-06-11 18:06 ` Oleg Nesterov
2010-06-18 10:21 ` [tip:sched/core] sched: Fix " tip-bot for Oleg Nesterov
2010-06-18 10:20 ` [tip:sched/core] sched: run_posix_cpu_timers: Don't check ->exit_state, use lock_task_sighand() tip-bot for Oleg Nesterov
1 sibling, 2 replies; 5+ messages in thread
From: Oleg Nesterov @ 2010-06-11 18:04 UTC (permalink / raw)
To: Ingo Molnar
Cc: Peter Zijlstra, Stanislaw Gruszka, Thomas Gleixner, linux-kernel
fastpath_timer_check()->thread_group_cputimer() is racy and
unneeded.
It is racy because another thread can clear ->running before
thread_group_cputimer() takes cputimer->lock. In this case
thread_group_cputimer() will set ->running = true again and call
thread_group_cputime(). But since we do not hold tasklist or
siglock, we can race with fork/exit and copy the wrong results
into cputimer->cputime.
It is unneeded because if ->running == true we can just use
the numbers in cputimer->cputime we already have.
Change fastpath_timer_check() to copy cputimer->cputime into
the local variable under cputimer->lock. We do not re-check
->running under cputimer->lock, run_posix_cpu_timers() does
this check later.
Note: we can add more optimizations on top of this change.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
---
kernel/posix-cpu-timers.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
--- 35-rc2/kernel/posix-cpu-timers.c~6_FPTC_DONT_SET_RUNNING 2010-06-11 01:08:03.000000000 +0200
+++ 35-rc2/kernel/posix-cpu-timers.c 2010-06-11 19:40:22.000000000 +0200
@@ -1287,7 +1287,10 @@ static inline int fastpath_timer_check(s
if (sig->cputimer.running) {
struct task_cputime group_sample;
- thread_group_cputimer(tsk, &group_sample);
+ spin_lock(&sig->cputimer.lock);
+ group_sample = sig->cputimer.cputime;
+ spin_unlock(&sig->cputimer.lock);
+
if (task_cputime_expired(&group_sample, &sig->cputime_expires))
return 1;
}
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH 6/5] fix the racy usage of thread_group_cputimer() in fastpath_timer_check()
2010-06-11 18:04 ` [PATCH 6/5] fix the racy usage of thread_group_cputimer() in fastpath_timer_check() Oleg Nesterov
@ 2010-06-11 18:06 ` Oleg Nesterov
2010-06-18 10:21 ` [tip:sched/core] sched: Fix " tip-bot for Oleg Nesterov
1 sibling, 0 replies; 5+ messages in thread
From: Oleg Nesterov @ 2010-06-11 18:06 UTC (permalink / raw)
To: Ingo Molnar
Cc: Peter Zijlstra, Stanislaw Gruszka, Thomas Gleixner, linux-kernel
On 06/11, Oleg Nesterov wrote:
>
> fastpath_timer_check()->thread_group_cputimer() is racy and
> unneeded.
Just in case... this fix doesn't depend on other patches I sent.
> It is racy because another thread can clear ->running before
> thread_group_cputimer() takes cputimer->lock. In this case
> thread_group_cputimer() will set ->running = true again and call
> thread_group_cputime(). But since we do not hold tasklist or
> siglock, we can race with fork/exit and copy the wrong results
> into cputimer->cputime.
>
> It is unneeded because if ->running == true we can just use
> the numbers in cputimer->cputime we already have.
>
> Change fastpath_timer_check() to copy cputimer->cputime into
> the local variable under cputimer->lock. We do not re-check
> ->running under cputimer->lock, run_posix_cpu_timers() does
> this check later.
>
> Note: we can add more optimizations on top of this change.
>
> Signed-off-by: Oleg Nesterov <oleg@redhat.com>
> ---
>
> kernel/posix-cpu-timers.c | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
>
> --- 35-rc2/kernel/posix-cpu-timers.c~6_FPTC_DONT_SET_RUNNING 2010-06-11 01:08:03.000000000 +0200
> +++ 35-rc2/kernel/posix-cpu-timers.c 2010-06-11 19:40:22.000000000 +0200
> @@ -1287,7 +1287,10 @@ static inline int fastpath_timer_check(s
> if (sig->cputimer.running) {
> struct task_cputime group_sample;
>
> - thread_group_cputimer(tsk, &group_sample);
> + spin_lock(&sig->cputimer.lock);
> + group_sample = sig->cputimer.cputime;
> + spin_unlock(&sig->cputimer.lock);
> +
> if (task_cputime_expired(&group_sample, &sig->cputime_expires))
> return 1;
> }
^ permalink raw reply [flat|nested] 5+ messages in thread* [tip:sched/core] sched: Fix the racy usage of thread_group_cputimer() in fastpath_timer_check()
2010-06-11 18:04 ` [PATCH 6/5] fix the racy usage of thread_group_cputimer() in fastpath_timer_check() Oleg Nesterov
2010-06-11 18:06 ` Oleg Nesterov
@ 2010-06-18 10:21 ` tip-bot for Oleg Nesterov
1 sibling, 0 replies; 5+ messages in thread
From: tip-bot for Oleg Nesterov @ 2010-06-18 10:21 UTC (permalink / raw)
To: linux-tip-commits
Cc: linux-kernel, hpa, mingo, a.p.zijlstra, oleg, tglx, mingo
Commit-ID: 8d1f431cbec115a780cd551ab1b4955c125f8d31
Gitweb: http://git.kernel.org/tip/8d1f431cbec115a780cd551ab1b4955c125f8d31
Author: Oleg Nesterov <oleg@redhat.com>
AuthorDate: Fri, 11 Jun 2010 20:04:46 +0200
Committer: Ingo Molnar <mingo@elte.hu>
CommitDate: Fri, 18 Jun 2010 10:46:57 +0200
sched: Fix the racy usage of thread_group_cputimer() in fastpath_timer_check()
fastpath_timer_check()->thread_group_cputimer() is racy and
unneeded.
It is racy because another thread can clear ->running before
thread_group_cputimer() takes cputimer->lock. In this case
thread_group_cputimer() will set ->running = true again and call
thread_group_cputime(). But since we do not hold tasklist or
siglock, we can race with fork/exit and copy the wrong results
into cputimer->cputime.
It is unneeded because if ->running == true we can just use
the numbers in cputimer->cputime we already have.
Change fastpath_timer_check() to copy cputimer->cputime into
the local variable under cputimer->lock. We do not re-check
->running under cputimer->lock, run_posix_cpu_timers() does
this check later.
Note: we can add more optimizations on top of this change.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <20100611180446.GA13025@redhat.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
kernel/posix-cpu-timers.c | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c
index d5dbef5..f66bdd3 100644
--- a/kernel/posix-cpu-timers.c
+++ b/kernel/posix-cpu-timers.c
@@ -1287,7 +1287,10 @@ static inline int fastpath_timer_check(struct task_struct *tsk)
if (sig->cputimer.running) {
struct task_cputime group_sample;
- thread_group_cputimer(tsk, &group_sample);
+ spin_lock(&sig->cputimer.lock);
+ group_sample = sig->cputimer.cputime;
+ spin_unlock(&sig->cputimer.lock);
+
if (task_cputime_expired(&group_sample, &sig->cputime_expires))
return 1;
}
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [tip:sched/core] sched: run_posix_cpu_timers: Don't check ->exit_state, use lock_task_sighand()
2010-06-10 23:10 [PATCH 5/5] run_posix_cpu_timers: don't check ->exit_state, use lock_task_sighand() Oleg Nesterov
2010-06-11 18:04 ` [PATCH 6/5] fix the racy usage of thread_group_cputimer() in fastpath_timer_check() Oleg Nesterov
@ 2010-06-18 10:20 ` tip-bot for Oleg Nesterov
1 sibling, 0 replies; 5+ messages in thread
From: tip-bot for Oleg Nesterov @ 2010-06-18 10:20 UTC (permalink / raw)
To: linux-tip-commits
Cc: linux-kernel, hpa, mingo, a.p.zijlstra, oleg, tglx, mingo
Commit-ID: 0bdd2ed4138ec04e09b4f8165981efc99e439f55
Gitweb: http://git.kernel.org/tip/0bdd2ed4138ec04e09b4f8165981efc99e439f55
Author: Oleg Nesterov <oleg@redhat.com>
AuthorDate: Fri, 11 Jun 2010 01:10:18 +0200
Committer: Ingo Molnar <mingo@elte.hu>
CommitDate: Fri, 18 Jun 2010 10:46:57 +0200
sched: run_posix_cpu_timers: Don't check ->exit_state, use lock_task_sighand()
run_posix_cpu_timers() doesn't work if current has already passed
exit_notify(). This was needed to prevent the races with do_wait().
Since ea6d290c ->signal is always valid and can't go away. We can
remove the "tsk->exit_state == 0" in fastpath_timer_check() and
convert run_posix_cpu_timers() to use lock_task_sighand().
Note: it makes sense to take group_leader's sighand instead, the
sub-thread still uses CPU after release_task(). But we need more
changes to do this.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <20100610231018.GA25942@redhat.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
kernel/posix-cpu-timers.c | 10 ++++------
1 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c
index bf2a650..d5dbef5 100644
--- a/kernel/posix-cpu-timers.c
+++ b/kernel/posix-cpu-timers.c
@@ -1272,10 +1272,6 @@ static inline int fastpath_timer_check(struct task_struct *tsk)
{
struct signal_struct *sig;
- /* tsk == current, ensure it is safe to use ->signal/sighand */
- if (unlikely(tsk->exit_state))
- return 0;
-
if (!task_cputime_zero(&tsk->cputime_expires)) {
struct task_cputime task_sample = {
.utime = tsk->utime,
@@ -1308,6 +1304,7 @@ void run_posix_cpu_timers(struct task_struct *tsk)
{
LIST_HEAD(firing);
struct k_itimer *timer, *next;
+ unsigned long flags;
BUG_ON(!irqs_disabled());
@@ -1318,7 +1315,8 @@ void run_posix_cpu_timers(struct task_struct *tsk)
if (!fastpath_timer_check(tsk))
return;
- spin_lock(&tsk->sighand->siglock);
+ if (!lock_task_sighand(tsk, &flags))
+ return;
/*
* Here we take off tsk->signal->cpu_timers[N] and
* tsk->cpu_timers[N] all the timers that are firing, and
@@ -1340,7 +1338,7 @@ void run_posix_cpu_timers(struct task_struct *tsk)
* that gets the timer lock before we do will give it up and
* spin until we've taken care of that timer below.
*/
- spin_unlock(&tsk->sighand->siglock);
+ unlock_task_sighand(tsk, &flags);
/*
* Now that all the timers on our list have the firing flag,
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2010-06-18 10:21 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-06-10 23:10 [PATCH 5/5] run_posix_cpu_timers: don't check ->exit_state, use lock_task_sighand() Oleg Nesterov
2010-06-11 18:04 ` [PATCH 6/5] fix the racy usage of thread_group_cputimer() in fastpath_timer_check() Oleg Nesterov
2010-06-11 18:06 ` Oleg Nesterov
2010-06-18 10:21 ` [tip:sched/core] sched: Fix " tip-bot for Oleg Nesterov
2010-06-18 10:20 ` [tip:sched/core] sched: run_posix_cpu_timers: Don't check ->exit_state, use lock_task_sighand() tip-bot for Oleg Nesterov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox