From: tip-bot for Jiri Olsa <tipbot@zytor.com>
To: linux-tip-commits@vger.kernel.org
Cc: tglx@linutronix.de, ak@linux.intel.com, peterz@infradead.org,
lukasz.odzioba@intel.com, dsahern@gmail.com, acme@redhat.com,
jolsa@kernel.org, mingo@kernel.org, namhyung@kernel.org,
wangnan0@huawei.com, alexander.shishkin@linux.intel.com,
kan.liang@linux.intel.com, linux-kernel@vger.kernel.org,
hpa@zytor.com
Subject: [tip:perf/core] perf machine: Use last_match threads cache only in single thread mode
Date: Wed, 25 Jul 2018 13:51:34 -0700 [thread overview]
Message-ID: <tip-b57334b9453949bf81281321d14d86d60aee6fde@git.kernel.org> (raw)
In-Reply-To: <20180719143345.12963-4-jolsa@kernel.org>
Commit-ID: b57334b9453949bf81281321d14d86d60aee6fde
Gitweb: https://git.kernel.org/tip/b57334b9453949bf81281321d14d86d60aee6fde
Author: Jiri Olsa <jolsa@kernel.org>
AuthorDate: Thu, 19 Jul 2018 16:33:44 +0200
Committer: Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Tue, 24 Jul 2018 14:53:52 -0300
perf machine: Use last_match threads cache only in single thread mode
There's an issue with using threads::last_match in multithread mode
which is enabled during the perf top synthesize. It might crash with
following assertion:
perf: ...include/linux/refcount.h:109: refcount_inc:
Assertion `!(!refcount_inc_not_zero(r))' failed.
The gdb backtrace looks like this:
0x00007ffff50839fb in raise () from /lib64/libc.so.6
(gdb)
#0 0x00007ffff50839fb in raise () from /lib64/libc.so.6
#1 0x00007ffff5085800 in abort () from /lib64/libc.so.6
#2 0x00007ffff507c0da in __assert_fail_base () from /lib64/libc.so.6
#3 0x00007ffff507c152 in __assert_fail () from /lib64/libc.so.6
#4 0x0000000000535ff9 in refcount_inc (r=0x7fffe8009a70)
at ...include/linux/refcount.h:109
#5 0x0000000000536771 in thread__get (thread=0x7fffe8009a40)
at util/thread.c:115
#6 0x0000000000523cd0 in ____machine__findnew_thread (machine=0xbfde38,
threads=0xbfdf28, pid=2, tid=2, create=true) at util/machine.c:432
#7 0x0000000000523eb4 in __machine__findnew_thread (machine=0xbfde38,
pid=2, tid=2) at util/machine.c:489
#8 0x0000000000523f24 in machine__findnew_thread (machine=0xbfde38,
pid=2, tid=2) at util/machine.c:499
#9 0x0000000000526fbe in machine__process_fork_event (machine=0xbfde38,
...
The failing assertion is this one:
REFCOUNT_WARN(!refcount_inc_not_zero(r), ...
the problem is that we don't serialize access to threads::last_match.
We serialize the access to the threads tree, but we don't care how's
threads::last_match being accessed. Both locked/unlocked paths use
that data and can set it. In multithreaded mode we can end up with
invalid object in thread__get call, like in following paths race:
thread 1
...
machine__findnew_thread
down_write(&threads->lock);
__machine__findnew_thread
____machine__findnew_thread
th = threads->last_match;
if (th->tid == tid) {
thread__get
thread 2
...
machine__find_thread
down_read(&threads->lock);
__machine__findnew_thread
____machine__findnew_thread
th = threads->last_match;
if (th->tid == tid) {
thread__get
thread 3
...
machine__process_fork_event
machine__remove_thread
__machine__remove_thread
threads->last_match = NULL
thread__put
thread__put
Thread 1 and 2 might got stale last_match, before thread 3 clears
it. Thread 1 and 2 then race with thread 3's thread__put and they
might trigger the refcnt == 0 assertion above.
The patch is disabling the last_match cache for multiple thread
mode. It was originally meant for single thread scenarios, where
it's common to have multiple sequential searches of the same
thread.
In multithread mode this does not make sense, because top's threads
processes different /proc entries and so the 'struct threads' object
is queried for various threads. Moreover we'd need to add more locks
to make it work.
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Lukasz Odzioba <lukasz.odzioba@intel.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/20180719143345.12963-4-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/util/machine.c | 25 ++++++++++++++++++++++---
1 file changed, 22 insertions(+), 3 deletions(-)
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 8992fcf42257..b300a3973448 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -413,8 +413,8 @@ out_err:
* the full rbtree:
*/
static struct thread*
-threads__get_last_match(struct threads *threads, struct machine *machine,
- int pid, int tid)
+__threads__get_last_match(struct threads *threads, struct machine *machine,
+ int pid, int tid)
{
struct thread *th;
@@ -431,12 +431,31 @@ threads__get_last_match(struct threads *threads, struct machine *machine,
return NULL;
}
+static struct thread*
+threads__get_last_match(struct threads *threads, struct machine *machine,
+ int pid, int tid)
+{
+ struct thread *th = NULL;
+
+ if (perf_singlethreaded)
+ th = __threads__get_last_match(threads, machine, pid, tid);
+
+ return th;
+}
+
static void
-threads__set_last_match(struct threads *threads, struct thread *th)
+__threads__set_last_match(struct threads *threads, struct thread *th)
{
threads->last_match = th;
}
+static void
+threads__set_last_match(struct threads *threads, struct thread *th)
+{
+ if (perf_singlethreaded)
+ __threads__set_last_match(threads, th);
+}
+
/*
* Caller must eventually drop thread->refcnt returned with a successful
* lookup/new thread inserted.
next prev parent reply other threads:[~2018-07-25 20:52 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-07-19 14:33 [PATCHv2 0/4] perf tools: Fix top crashes Jiri Olsa
2018-07-19 14:33 ` [PATCH 1/4] perf tools: Add threads__get_last_match function Jiri Olsa
2018-07-25 20:50 ` [tip:perf/core] perf machine: " tip-bot for Jiri Olsa
2018-07-19 14:33 ` [PATCH 2/4] perf tools: Add threads__set_last_match function Jiri Olsa
2018-07-25 20:51 ` [tip:perf/core] perf machine: " tip-bot for Jiri Olsa
2018-07-19 14:33 ` [PATCH 3/4] perf tools: Use last_match threads cache only in single thread mode Jiri Olsa
2018-07-25 20:51 ` tip-bot for Jiri Olsa [this message]
2018-07-19 14:33 ` [PATCH 4/4] perf tools: Fix struct comm_str removal crash Jiri Olsa
2018-07-19 15:58 ` Arnaldo Carvalho de Melo
2018-07-19 18:28 ` Arnaldo Carvalho de Melo
2018-07-19 18:31 ` Arnaldo Carvalho de Melo
2018-07-20 1:20 ` Namhyung Kim
2018-07-20 10:17 ` [PATCHv3 " Jiri Olsa
2018-07-20 14:42 ` Arnaldo Carvalho de Melo
2018-07-25 20:52 ` [tip:perf/core] " tip-bot for Jiri Olsa
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=tip-b57334b9453949bf81281321d14d86d60aee6fde@git.kernel.org \
--to=tipbot@zytor.com \
--cc=acme@redhat.com \
--cc=ak@linux.intel.com \
--cc=alexander.shishkin@linux.intel.com \
--cc=dsahern@gmail.com \
--cc=hpa@zytor.com \
--cc=jolsa@kernel.org \
--cc=kan.liang@linux.intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-tip-commits@vger.kernel.org \
--cc=lukasz.odzioba@intel.com \
--cc=mingo@kernel.org \
--cc=namhyung@kernel.org \
--cc=peterz@infradead.org \
--cc=tglx@linutronix.de \
--cc=wangnan0@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome