diff options
author | Peter Zijlstra <peterz@infradead.org> | 2013-07-12 05:08:33 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-07-25 17:07:43 -0400 |
commit | 65e303d786e20460c3d67d362f989f59944fb744 (patch) | |
tree | 2061b341fb44af50077dcc291e831ef1a1863e4e /kernel | |
parent | b2412679ab3e923437e2ee109560c151c9b0cedc (diff) |
perf: Fix perf_lock_task_context() vs RCU
commit 058ebd0eba3aff16b144eabf4510ed9510e1416e upstream.
Jiri managed to trigger this warning:
[] ======================================================
[] [ INFO: possible circular locking dependency detected ]
[] 3.10.0+ #228 Tainted: G W
[] -------------------------------------------------------
[] p/6613 is trying to acquire lock:
[] (rcu_node_0){..-...}, at: [<ffffffff810ca797>] rcu_read_unlock_special+0xa7/0x250
[]
[] but task is already holding lock:
[] (&ctx->lock){-.-...}, at: [<ffffffff810f2879>] perf_lock_task_context+0xd9/0x2c0
[]
[] which lock already depends on the new lock.
[]
[] the existing dependency chain (in reverse order) is:
[]
[] -> #4 (&ctx->lock){-.-...}:
[] -> #3 (&rq->lock){-.-.-.}:
[] -> #2 (&p->pi_lock){-.-.-.}:
[] -> #1 (&rnp->nocb_gp_wq[1]){......}:
[] -> #0 (rcu_node_0){..-...}:
Paul was quick to explain that due to preemptible RCU we cannot call
rcu_read_unlock() while holding scheduler (or nested) locks when part
of the read side critical section was preemptible.
Therefore solve it by making the entire RCU read side non-preemptible.
Also pull out the retry from under the non-preempt to play nice with RT.
Reported-by: Jiri Olsa <jolsa@redhat.com>
Helped-out-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/events/core.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/kernel/events/core.c b/kernel/events/core.c index cb8744a1b120..e76e4959908c 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c | |||
@@ -761,8 +761,18 @@ perf_lock_task_context(struct task_struct *task, int ctxn, unsigned long *flags) | |||
761 | { | 761 | { |
762 | struct perf_event_context *ctx; | 762 | struct perf_event_context *ctx; |
763 | 763 | ||
764 | rcu_read_lock(); | ||
765 | retry: | 764 | retry: |
765 | /* | ||
766 | * One of the few rules of preemptible RCU is that one cannot do | ||
767 | * rcu_read_unlock() while holding a scheduler (or nested) lock when | ||
768 | * part of the read side critical section was preemptible -- see | ||
769 | * rcu_read_unlock_special(). | ||
770 | * | ||
771 | * Since ctx->lock nests under rq->lock we must ensure the entire read | ||
772 | * side critical section is non-preemptible. | ||
773 | */ | ||
774 | preempt_disable(); | ||
775 | rcu_read_lock(); | ||
766 | ctx = rcu_dereference(task->perf_event_ctxp[ctxn]); | 776 | ctx = rcu_dereference(task->perf_event_ctxp[ctxn]); |
767 | if (ctx) { | 777 | if (ctx) { |
768 | /* | 778 | /* |
@@ -778,6 +788,8 @@ retry: | |||
778 | raw_spin_lock_irqsave(&ctx->lock, *flags); | 788 | raw_spin_lock_irqsave(&ctx->lock, *flags); |
779 | if (ctx != rcu_dereference(task->perf_event_ctxp[ctxn])) { | 789 | if (ctx != rcu_dereference(task->perf_event_ctxp[ctxn])) { |
780 | raw_spin_unlock_irqrestore(&ctx->lock, *flags); | 790 | raw_spin_unlock_irqrestore(&ctx->lock, *flags); |
791 | rcu_read_unlock(); | ||
792 | preempt_enable(); | ||
781 | goto retry; | 793 | goto retry; |
782 | } | 794 | } |
783 | 795 | ||
@@ -787,6 +799,7 @@ retry: | |||
787 | } | 799 | } |
788 | } | 800 | } |
789 | rcu_read_unlock(); | 801 | rcu_read_unlock(); |
802 | preempt_enable(); | ||
790 | return ctx; | 803 | return ctx; |
791 | } | 804 | } |
792 | 805 | ||