Messages in this thread Patch in this message | | | Subject | Re: sig->cputimer.lock/rq->lock lockdep report | From | Peter Zijlstra <> | Date | Wed, 12 Oct 2011 22:50:51 +0200 |
| |
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 <linux/rwsem.h> @@ -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); }
| |