From 944629794b0b3845929ad98e89e1fff381add883 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Mon, 10 Nov 2008 15:39:30 +0100 Subject: [PATCH] --- yaml --- r: 118767 b: refs/heads/master c: ad474caca3e2a0550b7ce0706527ad5ab389a4d4 h: refs/heads/master i: 118765: 422f00e198f6a5edd67af428e3f895259a65722d 118763: 0cd7c57dec77b389128a53909382be15ad58b0ef 118759: 742c56a85c0bb20f84708ba246626cf4025900a0 118751: c19cbaca19520ff7f38deb3bbc47bef195d18989 v: v3 --- [refs] | 2 +- trunk/include/linux/sched.h | 1 + trunk/kernel/exit.c | 5 +++++ trunk/kernel/sched.c | 8 ++++++++ 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index d84bac85be38..bc017b9f9bad 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 5ac5c4d604bf894ef672a7971d03fefdc7ea7e49 +refs/heads/master: ad474caca3e2a0550b7ce0706527ad5ab389a4d4 diff --git a/trunk/include/linux/sched.h b/trunk/include/linux/sched.h index 295b7c756ca6..644ffbda17ca 100644 --- a/trunk/include/linux/sched.h +++ b/trunk/include/linux/sched.h @@ -247,6 +247,7 @@ extern void init_idle(struct task_struct *idle, int cpu); extern void init_idle_bootup_task(struct task_struct *idle); extern int runqueue_is_locked(void); +extern void task_rq_unlock_wait(struct task_struct *p); extern cpumask_t nohz_cpu_mask; #if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ) diff --git a/trunk/kernel/exit.c b/trunk/kernel/exit.c index 80137a5d9467..ae2b92be5fae 100644 --- a/trunk/kernel/exit.c +++ b/trunk/kernel/exit.c @@ -141,6 +141,11 @@ static void __exit_signal(struct task_struct *tsk) if (sig) { flush_sigqueue(&sig->shared_pending); taskstats_tgid_free(sig); + /* + * Make sure ->signal can't go away under rq->lock, + * see account_group_exec_runtime(). + */ + task_rq_unlock_wait(tsk); __cleanup_signal(sig); } } diff --git a/trunk/kernel/sched.c b/trunk/kernel/sched.c index f3149244e324..50a21f964679 100644 --- a/trunk/kernel/sched.c +++ b/trunk/kernel/sched.c @@ -969,6 +969,14 @@ static struct rq *task_rq_lock(struct task_struct *p, unsigned long *flags) } } +void task_rq_unlock_wait(struct task_struct *p) +{ + struct rq *rq = task_rq(p); + + smp_mb(); /* spin-unlock-wait is not a full memory barrier */ + spin_unlock_wait(&rq->lock); +} + static void __task_rq_unlock(struct rq *rq) __releases(rq->lock) {