Skip to content

Commit

Permalink
perf tools: Provide mutex wrappers for pthreads rwlocks
Browse files Browse the repository at this point in the history
Andi reported a performance drop in single threaded perf tools such as
'perf script' due to the growing number of locks being put in place to
allow for multithreaded tools, so wrap the POSIX threads rwlock routines
with the names used for such kinds of locks in the Linux kernel and then
allow for tools to ask for those locks to be used or not.

I.e. a tool may have a multithreaded phase and then switch to single
threaded, like the upcoming patches for the synthesizing of
PERF_RECORD_{FORK,MMAP,etc} for pre-existing processes to then switch to
single threaded mode in 'perf top'.

The init routines will not be conditional, this way starting as single
threaded to then move to multi threaded mode should be possible.

Reported-by: Andi Kleen <ak@linux.intel.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kan Liang <kan.liang@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/20170404161739.GH12903@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
  • Loading branch information
Arnaldo Carvalho de Melo committed Sep 21, 2017
1 parent 6ae8eef commit 0a7c74e
Show file tree
Hide file tree
Showing 18 changed files with 130 additions and 58 deletions.
1 change: 0 additions & 1 deletion tools/perf/builtin-kvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
#include <termios.h>
#include <semaphore.h>
#include <signal.h>
#include <pthread.h>
#include <math.h>

static const char *get_filename_for_perf_kvm(void)
Expand Down
2 changes: 2 additions & 0 deletions tools/perf/builtin-script.c
Original file line number Diff line number Diff line change
Expand Up @@ -2829,6 +2829,8 @@ int cmd_script(int argc, const char **argv)
NULL
};

perf_set_singlethreaded();

setup_scripting();

argc = parse_options_subcommand(argc, argv, options, script_subcommands, script_usage,
Expand Down
1 change: 1 addition & 0 deletions tools/perf/util/Build
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ libperf-y += data.o
libperf-y += tsc.o
libperf-y += cloexec.o
libperf-y += call-path.o
libperf-y += rwsem.o
libperf-y += thread-stack.o
libperf-$(CONFIG_AUXTRACE) += auxtrace.o
libperf-$(CONFIG_AUXTRACE) += intel-pt-decoder/
Expand Down
12 changes: 6 additions & 6 deletions tools/perf/util/dso.c
Original file line number Diff line number Diff line change
Expand Up @@ -1366,9 +1366,9 @@ void __dsos__add(struct dsos *dsos, struct dso *dso)

void dsos__add(struct dsos *dsos, struct dso *dso)
{
pthread_rwlock_wrlock(&dsos->lock);
down_write(&dsos->lock);
__dsos__add(dsos, dso);
pthread_rwlock_unlock(&dsos->lock);
up_write(&dsos->lock);
}

struct dso *__dsos__find(struct dsos *dsos, const char *name, bool cmp_short)
Expand All @@ -1387,9 +1387,9 @@ struct dso *__dsos__find(struct dsos *dsos, const char *name, bool cmp_short)
struct dso *dsos__find(struct dsos *dsos, const char *name, bool cmp_short)
{
struct dso *dso;
pthread_rwlock_rdlock(&dsos->lock);
down_read(&dsos->lock);
dso = __dsos__find(dsos, name, cmp_short);
pthread_rwlock_unlock(&dsos->lock);
up_read(&dsos->lock);
return dso;
}

Expand All @@ -1416,9 +1416,9 @@ struct dso *__dsos__findnew(struct dsos *dsos, const char *name)
struct dso *dsos__findnew(struct dsos *dsos, const char *name)
{
struct dso *dso;
pthread_rwlock_wrlock(&dsos->lock);
down_write(&dsos->lock);
dso = dso__get(__dsos__findnew(dsos, name));
pthread_rwlock_unlock(&dsos->lock);
up_write(&dsos->lock);
return dso;
}

Expand Down
4 changes: 2 additions & 2 deletions tools/perf/util/dso.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include <linux/rbtree.h>
#include <sys/types.h>
#include <stdbool.h>
#include <pthread.h>
#include "rwsem.h"
#include <linux/types.h>
#include <linux/bitops.h>
#include "map.h"
Expand Down Expand Up @@ -129,7 +129,7 @@ struct dso_cache {
struct dsos {
struct list_head head;
struct rb_root root; /* rbtree root sorted by long name */
pthread_rwlock_t lock;
struct rw_semaphore lock;
};

struct auxtrace_cache;
Expand Down
41 changes: 21 additions & 20 deletions tools/perf/util/machine.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ static void dsos__init(struct dsos *dsos)
{
INIT_LIST_HEAD(&dsos->head);
dsos->root = RB_ROOT;
pthread_rwlock_init(&dsos->lock, NULL);
init_rwsem(&dsos->lock);
}

static void machine__threads_init(struct machine *machine)
Expand All @@ -40,7 +40,7 @@ static void machine__threads_init(struct machine *machine)
for (i = 0; i < THREADS__TABLE_SIZE; i++) {
struct threads *threads = &machine->threads[i];
threads->entries = RB_ROOT;
pthread_rwlock_init(&threads->lock, NULL);
init_rwsem(&threads->lock);
threads->nr = 0;
INIT_LIST_HEAD(&threads->dead);
threads->last_match = NULL;
Expand Down Expand Up @@ -130,7 +130,7 @@ static void dsos__purge(struct dsos *dsos)
{
struct dso *pos, *n;

pthread_rwlock_wrlock(&dsos->lock);
down_write(&dsos->lock);

list_for_each_entry_safe(pos, n, &dsos->head, node) {
RB_CLEAR_NODE(&pos->rb_node);
Expand All @@ -139,13 +139,13 @@ static void dsos__purge(struct dsos *dsos)
dso__put(pos);
}

pthread_rwlock_unlock(&dsos->lock);
up_write(&dsos->lock);
}

static void dsos__exit(struct dsos *dsos)
{
dsos__purge(dsos);
pthread_rwlock_destroy(&dsos->lock);
exit_rwsem(&dsos->lock);
}

void machine__delete_threads(struct machine *machine)
Expand All @@ -155,15 +155,15 @@ void machine__delete_threads(struct machine *machine)

for (i = 0; i < THREADS__TABLE_SIZE; i++) {
struct threads *threads = &machine->threads[i];
pthread_rwlock_wrlock(&threads->lock);
down_write(&threads->lock);
nd = rb_first(&threads->entries);
while (nd) {
struct thread *t = rb_entry(nd, struct thread, rb_node);

nd = rb_next(nd);
__machine__remove_thread(machine, t, false);
}
pthread_rwlock_unlock(&threads->lock);
up_write(&threads->lock);
}
}

Expand All @@ -180,7 +180,7 @@ void machine__exit(struct machine *machine)

for (i = 0; i < THREADS__TABLE_SIZE; i++) {
struct threads *threads = &machine->threads[i];
pthread_rwlock_destroy(&threads->lock);
exit_rwsem(&threads->lock);
}
}

Expand Down Expand Up @@ -482,9 +482,9 @@ struct thread *machine__findnew_thread(struct machine *machine, pid_t pid,
struct threads *threads = machine__threads(machine, tid);
struct thread *th;

pthread_rwlock_wrlock(&threads->lock);
down_write(&threads->lock);
th = __machine__findnew_thread(machine, pid, tid);
pthread_rwlock_unlock(&threads->lock);
up_write(&threads->lock);
return th;
}

Expand All @@ -494,9 +494,9 @@ struct thread *machine__find_thread(struct machine *machine, pid_t pid,
struct threads *threads = machine__threads(machine, tid);
struct thread *th;

pthread_rwlock_rdlock(&threads->lock);
down_read(&threads->lock);
th = ____machine__findnew_thread(machine, threads, pid, tid, false);
pthread_rwlock_unlock(&threads->lock);
up_read(&threads->lock);
return th;
}

Expand Down Expand Up @@ -588,7 +588,7 @@ static struct dso *machine__findnew_module_dso(struct machine *machine,
{
struct dso *dso;

pthread_rwlock_wrlock(&machine->dsos.lock);
down_write(&machine->dsos.lock);

dso = __dsos__find(&machine->dsos, m->name, true);
if (!dso) {
Expand All @@ -602,7 +602,7 @@ static struct dso *machine__findnew_module_dso(struct machine *machine,

dso__get(dso);
out_unlock:
pthread_rwlock_unlock(&machine->dsos.lock);
up_write(&machine->dsos.lock);
return dso;
}

Expand Down Expand Up @@ -749,7 +749,8 @@ size_t machine__fprintf(struct machine *machine, FILE *fp)

for (i = 0; i < THREADS__TABLE_SIZE; i++) {
struct threads *threads = &machine->threads[i];
pthread_rwlock_rdlock(&threads->lock);

down_read(&threads->lock);

ret = fprintf(fp, "Threads: %u\n", threads->nr);

Expand All @@ -759,7 +760,7 @@ size_t machine__fprintf(struct machine *machine, FILE *fp)
ret += thread__fprintf(pos, fp);
}

pthread_rwlock_unlock(&threads->lock);
up_read(&threads->lock);
}
return ret;
}
Expand Down Expand Up @@ -1319,7 +1320,7 @@ static int machine__process_kernel_mmap_event(struct machine *machine,
struct dso *kernel = NULL;
struct dso *dso;

pthread_rwlock_rdlock(&machine->dsos.lock);
down_read(&machine->dsos.lock);

list_for_each_entry(dso, &machine->dsos.head, node) {

Expand Down Expand Up @@ -1349,7 +1350,7 @@ static int machine__process_kernel_mmap_event(struct machine *machine,
break;
}

pthread_rwlock_unlock(&machine->dsos.lock);
up_read(&machine->dsos.lock);

if (kernel == NULL)
kernel = machine__findnew_dso(machine, kmmap_prefix);
Expand Down Expand Up @@ -1513,7 +1514,7 @@ static void __machine__remove_thread(struct machine *machine, struct thread *th,

BUG_ON(refcount_read(&th->refcnt) == 0);
if (lock)
pthread_rwlock_wrlock(&threads->lock);
down_write(&threads->lock);
rb_erase_init(&th->rb_node, &threads->entries);
RB_CLEAR_NODE(&th->rb_node);
--threads->nr;
Expand All @@ -1524,7 +1525,7 @@ static void __machine__remove_thread(struct machine *machine, struct thread *th,
*/
list_add_tail(&th->node, &threads->dead);
if (lock)
pthread_rwlock_unlock(&threads->lock);
up_write(&threads->lock);
thread__put(th);
}

Expand Down
3 changes: 2 additions & 1 deletion tools/perf/util/machine.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "map.h"
#include "dso.h"
#include "event.h"
#include "rwsem.h"

struct addr_location;
struct branch_stack;
Expand All @@ -28,7 +29,7 @@ struct vdso_info;

struct threads {
struct rb_root entries;
pthread_rwlock_t lock;
struct rw_semaphore lock;
unsigned int nr;
struct list_head dead;
struct thread *last_match;
Expand Down
34 changes: 17 additions & 17 deletions tools/perf/util/map.c
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,7 @@ u64 map__objdump_2mem(struct map *map, u64 ip)
static void maps__init(struct maps *maps)
{
maps->entries = RB_ROOT;
pthread_rwlock_init(&maps->lock, NULL);
init_rwsem(&maps->lock);
}

void map_groups__init(struct map_groups *mg, struct machine *machine)
Expand Down Expand Up @@ -517,9 +517,9 @@ static void __maps__purge(struct maps *maps)

static void maps__exit(struct maps *maps)
{
pthread_rwlock_wrlock(&maps->lock);
down_write(&maps->lock);
__maps__purge(maps);
pthread_rwlock_unlock(&maps->lock);
up_write(&maps->lock);
}

void map_groups__exit(struct map_groups *mg)
Expand Down Expand Up @@ -586,7 +586,7 @@ struct symbol *maps__find_symbol_by_name(struct maps *maps, const char *name,
struct symbol *sym;
struct rb_node *nd;

pthread_rwlock_rdlock(&maps->lock);
down_read(&maps->lock);

for (nd = rb_first(&maps->entries); nd; nd = rb_next(nd)) {
struct map *pos = rb_entry(nd, struct map, rb_node);
Expand All @@ -602,7 +602,7 @@ struct symbol *maps__find_symbol_by_name(struct maps *maps, const char *name,

sym = NULL;
out:
pthread_rwlock_unlock(&maps->lock);
up_read(&maps->lock);
return sym;
}

Expand Down Expand Up @@ -638,7 +638,7 @@ static size_t maps__fprintf(struct maps *maps, FILE *fp)
size_t printed = 0;
struct rb_node *nd;

pthread_rwlock_rdlock(&maps->lock);
down_read(&maps->lock);

for (nd = rb_first(&maps->entries); nd; nd = rb_next(nd)) {
struct map *pos = rb_entry(nd, struct map, rb_node);
Expand All @@ -650,7 +650,7 @@ static size_t maps__fprintf(struct maps *maps, FILE *fp)
}
}

pthread_rwlock_unlock(&maps->lock);
up_read(&maps->lock);

return printed;
}
Expand Down Expand Up @@ -682,7 +682,7 @@ static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp
struct rb_node *next;
int err = 0;

pthread_rwlock_wrlock(&maps->lock);
down_write(&maps->lock);

root = &maps->entries;
next = rb_first(root);
Expand Down Expand Up @@ -750,7 +750,7 @@ static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp

err = 0;
out:
pthread_rwlock_unlock(&maps->lock);
up_write(&maps->lock);
return err;
}

Expand All @@ -771,7 +771,7 @@ int map_groups__clone(struct thread *thread,
struct map *map;
struct maps *maps = &parent->maps[type];

pthread_rwlock_rdlock(&maps->lock);
down_read(&maps->lock);

for (map = maps__first(maps); map; map = map__next(map)) {
struct map *new = map__clone(map);
Expand All @@ -788,7 +788,7 @@ int map_groups__clone(struct thread *thread,

err = 0;
out_unlock:
pthread_rwlock_unlock(&maps->lock);
up_read(&maps->lock);
return err;
}

Expand All @@ -815,9 +815,9 @@ static void __maps__insert(struct maps *maps, struct map *map)

void maps__insert(struct maps *maps, struct map *map)
{
pthread_rwlock_wrlock(&maps->lock);
down_write(&maps->lock);
__maps__insert(maps, map);
pthread_rwlock_unlock(&maps->lock);
up_write(&maps->lock);
}

static void __maps__remove(struct maps *maps, struct map *map)
Expand All @@ -828,17 +828,17 @@ static void __maps__remove(struct maps *maps, struct map *map)

void maps__remove(struct maps *maps, struct map *map)
{
pthread_rwlock_wrlock(&maps->lock);
down_write(&maps->lock);
__maps__remove(maps, map);
pthread_rwlock_unlock(&maps->lock);
up_write(&maps->lock);
}

struct map *maps__find(struct maps *maps, u64 ip)
{
struct rb_node **p, *parent = NULL;
struct map *m;

pthread_rwlock_rdlock(&maps->lock);
down_read(&maps->lock);

p = &maps->entries.rb_node;
while (*p != NULL) {
Expand All @@ -854,7 +854,7 @@ struct map *maps__find(struct maps *maps, u64 ip)

m = NULL;
out:
pthread_rwlock_unlock(&maps->lock);
up_read(&maps->lock);
return m;
}

Expand Down
Loading

0 comments on commit 0a7c74e

Please sign in to comment.