From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754126Ab1JLUvC (ORCPT ); Wed, 12 Oct 2011 16:51:02 -0400 Received: from casper.infradead.org ([85.118.1.10]:33284 "EHLO casper.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752608Ab1JLUvA convert rfc822-to-8bit (ORCPT ); Wed, 12 Oct 2011 16:51:00 -0400 Subject: Re: sig->cputimer.lock/rq->lock lockdep report From: Peter Zijlstra To: Ari Savolainen Cc: Thomas Gleixner , linux-kernel@vger.kernel.org, Dave Jones Date: Wed, 12 Oct 2011 22:50:51 +0200 In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 8BIT X-Mailer: Evolution 3.0.3- Message-ID: <1318452651.14236.9.camel@twins> Mime-Version: 1.0 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wed, 2011-10-12 at 23:13 +0300, Ari Savolainen wrote: > I've got the same problem that Dave reported earlier. I bisected it to > commit d670ec13178d "posix-cpu-timers: Cure SMP wobbles". https://lkml.org/lkml/2011/10/7/282 Does the below work for you? (still not proud of it) --- include/linux/sched.h | 3 +++ kernel/posix-cpu-timers.c | 6 +++++- kernel/sched_stats.h | 4 ++-- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index 41d0237..ad9eafc 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -503,6 +503,7 @@ struct task_cputime { * @running: non-zero when there are timers running and * @cputime receives updates. * @lock: lock for fields in this struct. + * @runtime_lock: lock for cputime.sum_exec_runtime * * This structure contains the version of task_cputime, above, that is * used for thread group CPU timer calculations. @@ -511,6 +512,7 @@ struct thread_group_cputimer { struct task_cputime cputime; int running; spinlock_t lock; + spinlock_t runtime_lock; }; #include @@ -2566,6 +2568,7 @@ void thread_group_cputimer(struct task_struct *tsk, struct task_cputime *times); static inline void thread_group_cputime_init(struct signal_struct *sig) { spin_lock_init(&sig->cputimer.lock); + spin_lock_init(&sig->cputimer.runtime_lock); } /* diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c index c8008dd..fa189a6 100644 --- a/kernel/posix-cpu-timers.c +++ b/kernel/posix-cpu-timers.c @@ -284,9 +284,13 @@ void thread_group_cputimer(struct task_struct *tsk, struct task_cputime *times) * it. */ thread_group_cputime(tsk, &sum); + spin_lock(&cputimer->runtime_lock); update_gt_cputime(&cputimer->cputime, &sum); - } + } else + spin_lock(&cputimer->runtime_lock); + *times = cputimer->cputime; + spin_unlock(&cputimer->runtime_lock); spin_unlock_irqrestore(&cputimer->lock, flags); } diff --git a/kernel/sched_stats.h b/kernel/sched_stats.h index 331e01b..a7e2c1a 100644 --- a/kernel/sched_stats.h +++ b/kernel/sched_stats.h @@ -330,7 +330,7 @@ static inline void account_group_exec_runtime(struct task_struct *tsk, if (!cputimer->running) return; - spin_lock(&cputimer->lock); + spin_lock(&cputimer->runtime_lock); cputimer->cputime.sum_exec_runtime += ns; - spin_unlock(&cputimer->lock); + spin_unlock(&cputimer->runtime_lock); }