Skip to content

Commit 0a7c74e

Browse files
committed
perf tools: Provide mutex wrappers for pthreads rwlocks
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 <[email protected]> Cc: Adrian Hunter <[email protected]> Cc: David Ahern <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: Kan Liang <[email protected]> Cc: Namhyung Kim <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Wang Nan <[email protected]> Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
1 parent 6ae8eef commit 0a7c74e

File tree

18 files changed

+130
-58
lines changed

18 files changed

+130
-58
lines changed

tools/perf/builtin-kvm.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
#include <termios.h>
3535
#include <semaphore.h>
3636
#include <signal.h>
37-
#include <pthread.h>
3837
#include <math.h>
3938

4039
static const char *get_filename_for_perf_kvm(void)

tools/perf/builtin-script.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2829,6 +2829,8 @@ int cmd_script(int argc, const char **argv)
28292829
NULL
28302830
};
28312831

2832+
perf_set_singlethreaded();
2833+
28322834
setup_scripting();
28332835

28342836
argc = parse_options_subcommand(argc, argv, options, script_subcommands, script_usage,

tools/perf/util/Build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ libperf-y += data.o
7979
libperf-y += tsc.o
8080
libperf-y += cloexec.o
8181
libperf-y += call-path.o
82+
libperf-y += rwsem.o
8283
libperf-y += thread-stack.o
8384
libperf-$(CONFIG_AUXTRACE) += auxtrace.o
8485
libperf-$(CONFIG_AUXTRACE) += intel-pt-decoder/

tools/perf/util/dso.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1366,9 +1366,9 @@ void __dsos__add(struct dsos *dsos, struct dso *dso)
13661366

13671367
void dsos__add(struct dsos *dsos, struct dso *dso)
13681368
{
1369-
pthread_rwlock_wrlock(&dsos->lock);
1369+
down_write(&dsos->lock);
13701370
__dsos__add(dsos, dso);
1371-
pthread_rwlock_unlock(&dsos->lock);
1371+
up_write(&dsos->lock);
13721372
}
13731373

13741374
struct dso *__dsos__find(struct dsos *dsos, const char *name, bool cmp_short)
@@ -1387,9 +1387,9 @@ struct dso *__dsos__find(struct dsos *dsos, const char *name, bool cmp_short)
13871387
struct dso *dsos__find(struct dsos *dsos, const char *name, bool cmp_short)
13881388
{
13891389
struct dso *dso;
1390-
pthread_rwlock_rdlock(&dsos->lock);
1390+
down_read(&dsos->lock);
13911391
dso = __dsos__find(dsos, name, cmp_short);
1392-
pthread_rwlock_unlock(&dsos->lock);
1392+
up_read(&dsos->lock);
13931393
return dso;
13941394
}
13951395

@@ -1416,9 +1416,9 @@ struct dso *__dsos__findnew(struct dsos *dsos, const char *name)
14161416
struct dso *dsos__findnew(struct dsos *dsos, const char *name)
14171417
{
14181418
struct dso *dso;
1419-
pthread_rwlock_wrlock(&dsos->lock);
1419+
down_write(&dsos->lock);
14201420
dso = dso__get(__dsos__findnew(dsos, name));
1421-
pthread_rwlock_unlock(&dsos->lock);
1421+
up_write(&dsos->lock);
14221422
return dso;
14231423
}
14241424

tools/perf/util/dso.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#include <linux/rbtree.h>
77
#include <sys/types.h>
88
#include <stdbool.h>
9-
#include <pthread.h>
9+
#include "rwsem.h"
1010
#include <linux/types.h>
1111
#include <linux/bitops.h>
1212
#include "map.h"
@@ -129,7 +129,7 @@ struct dso_cache {
129129
struct dsos {
130130
struct list_head head;
131131
struct rb_root root; /* rbtree root sorted by long name */
132-
pthread_rwlock_t lock;
132+
struct rw_semaphore lock;
133133
};
134134

135135
struct auxtrace_cache;

tools/perf/util/machine.c

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ static void dsos__init(struct dsos *dsos)
3030
{
3131
INIT_LIST_HEAD(&dsos->head);
3232
dsos->root = RB_ROOT;
33-
pthread_rwlock_init(&dsos->lock, NULL);
33+
init_rwsem(&dsos->lock);
3434
}
3535

3636
static void machine__threads_init(struct machine *machine)
@@ -40,7 +40,7 @@ static void machine__threads_init(struct machine *machine)
4040
for (i = 0; i < THREADS__TABLE_SIZE; i++) {
4141
struct threads *threads = &machine->threads[i];
4242
threads->entries = RB_ROOT;
43-
pthread_rwlock_init(&threads->lock, NULL);
43+
init_rwsem(&threads->lock);
4444
threads->nr = 0;
4545
INIT_LIST_HEAD(&threads->dead);
4646
threads->last_match = NULL;
@@ -130,7 +130,7 @@ static void dsos__purge(struct dsos *dsos)
130130
{
131131
struct dso *pos, *n;
132132

133-
pthread_rwlock_wrlock(&dsos->lock);
133+
down_write(&dsos->lock);
134134

135135
list_for_each_entry_safe(pos, n, &dsos->head, node) {
136136
RB_CLEAR_NODE(&pos->rb_node);
@@ -139,13 +139,13 @@ static void dsos__purge(struct dsos *dsos)
139139
dso__put(pos);
140140
}
141141

142-
pthread_rwlock_unlock(&dsos->lock);
142+
up_write(&dsos->lock);
143143
}
144144

145145
static void dsos__exit(struct dsos *dsos)
146146
{
147147
dsos__purge(dsos);
148-
pthread_rwlock_destroy(&dsos->lock);
148+
exit_rwsem(&dsos->lock);
149149
}
150150

151151
void machine__delete_threads(struct machine *machine)
@@ -155,15 +155,15 @@ void machine__delete_threads(struct machine *machine)
155155

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

163163
nd = rb_next(nd);
164164
__machine__remove_thread(machine, t, false);
165165
}
166-
pthread_rwlock_unlock(&threads->lock);
166+
up_write(&threads->lock);
167167
}
168168
}
169169

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

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

@@ -482,9 +482,9 @@ struct thread *machine__findnew_thread(struct machine *machine, pid_t pid,
482482
struct threads *threads = machine__threads(machine, tid);
483483
struct thread *th;
484484

485-
pthread_rwlock_wrlock(&threads->lock);
485+
down_write(&threads->lock);
486486
th = __machine__findnew_thread(machine, pid, tid);
487-
pthread_rwlock_unlock(&threads->lock);
487+
up_write(&threads->lock);
488488
return th;
489489
}
490490

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

497-
pthread_rwlock_rdlock(&threads->lock);
497+
down_read(&threads->lock);
498498
th = ____machine__findnew_thread(machine, threads, pid, tid, false);
499-
pthread_rwlock_unlock(&threads->lock);
499+
up_read(&threads->lock);
500500
return th;
501501
}
502502

@@ -588,7 +588,7 @@ static struct dso *machine__findnew_module_dso(struct machine *machine,
588588
{
589589
struct dso *dso;
590590

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

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

603603
dso__get(dso);
604604
out_unlock:
605-
pthread_rwlock_unlock(&machine->dsos.lock);
605+
up_write(&machine->dsos.lock);
606606
return dso;
607607
}
608608

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

750750
for (i = 0; i < THREADS__TABLE_SIZE; i++) {
751751
struct threads *threads = &machine->threads[i];
752-
pthread_rwlock_rdlock(&threads->lock);
752+
753+
down_read(&threads->lock);
753754

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

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

762-
pthread_rwlock_unlock(&threads->lock);
763+
up_read(&threads->lock);
763764
}
764765
return ret;
765766
}
@@ -1319,7 +1320,7 @@ static int machine__process_kernel_mmap_event(struct machine *machine,
13191320
struct dso *kernel = NULL;
13201321
struct dso *dso;
13211322

1322-
pthread_rwlock_rdlock(&machine->dsos.lock);
1323+
down_read(&machine->dsos.lock);
13231324

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

@@ -1349,7 +1350,7 @@ static int machine__process_kernel_mmap_event(struct machine *machine,
13491350
break;
13501351
}
13511352

1352-
pthread_rwlock_unlock(&machine->dsos.lock);
1353+
up_read(&machine->dsos.lock);
13531354

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

15141515
BUG_ON(refcount_read(&th->refcnt) == 0);
15151516
if (lock)
1516-
pthread_rwlock_wrlock(&threads->lock);
1517+
down_write(&threads->lock);
15171518
rb_erase_init(&th->rb_node, &threads->entries);
15181519
RB_CLEAR_NODE(&th->rb_node);
15191520
--threads->nr;
@@ -1524,7 +1525,7 @@ static void __machine__remove_thread(struct machine *machine, struct thread *th,
15241525
*/
15251526
list_add_tail(&th->node, &threads->dead);
15261527
if (lock)
1527-
pthread_rwlock_unlock(&threads->lock);
1528+
up_write(&threads->lock);
15281529
thread__put(th);
15291530
}
15301531

tools/perf/util/machine.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "map.h"
77
#include "dso.h"
88
#include "event.h"
9+
#include "rwsem.h"
910

1011
struct addr_location;
1112
struct branch_stack;
@@ -28,7 +29,7 @@ struct vdso_info;
2829

2930
struct threads {
3031
struct rb_root entries;
31-
pthread_rwlock_t lock;
32+
struct rw_semaphore lock;
3233
unsigned int nr;
3334
struct list_head dead;
3435
struct thread *last_match;

tools/perf/util/map.c

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -488,7 +488,7 @@ u64 map__objdump_2mem(struct map *map, u64 ip)
488488
static void maps__init(struct maps *maps)
489489
{
490490
maps->entries = RB_ROOT;
491-
pthread_rwlock_init(&maps->lock, NULL);
491+
init_rwsem(&maps->lock);
492492
}
493493

494494
void map_groups__init(struct map_groups *mg, struct machine *machine)
@@ -517,9 +517,9 @@ static void __maps__purge(struct maps *maps)
517517

518518
static void maps__exit(struct maps *maps)
519519
{
520-
pthread_rwlock_wrlock(&maps->lock);
520+
down_write(&maps->lock);
521521
__maps__purge(maps);
522-
pthread_rwlock_unlock(&maps->lock);
522+
up_write(&maps->lock);
523523
}
524524

525525
void map_groups__exit(struct map_groups *mg)
@@ -586,7 +586,7 @@ struct symbol *maps__find_symbol_by_name(struct maps *maps, const char *name,
586586
struct symbol *sym;
587587
struct rb_node *nd;
588588

589-
pthread_rwlock_rdlock(&maps->lock);
589+
down_read(&maps->lock);
590590

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

603603
sym = NULL;
604604
out:
605-
pthread_rwlock_unlock(&maps->lock);
605+
up_read(&maps->lock);
606606
return sym;
607607
}
608608

@@ -638,7 +638,7 @@ static size_t maps__fprintf(struct maps *maps, FILE *fp)
638638
size_t printed = 0;
639639
struct rb_node *nd;
640640

641-
pthread_rwlock_rdlock(&maps->lock);
641+
down_read(&maps->lock);
642642

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

653-
pthread_rwlock_unlock(&maps->lock);
653+
up_read(&maps->lock);
654654

655655
return printed;
656656
}
@@ -682,7 +682,7 @@ static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp
682682
struct rb_node *next;
683683
int err = 0;
684684

685-
pthread_rwlock_wrlock(&maps->lock);
685+
down_write(&maps->lock);
686686

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

751751
err = 0;
752752
out:
753-
pthread_rwlock_unlock(&maps->lock);
753+
up_write(&maps->lock);
754754
return err;
755755
}
756756

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

774-
pthread_rwlock_rdlock(&maps->lock);
774+
down_read(&maps->lock);
775775

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

789789
err = 0;
790790
out_unlock:
791-
pthread_rwlock_unlock(&maps->lock);
791+
up_read(&maps->lock);
792792
return err;
793793
}
794794

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

816816
void maps__insert(struct maps *maps, struct map *map)
817817
{
818-
pthread_rwlock_wrlock(&maps->lock);
818+
down_write(&maps->lock);
819819
__maps__insert(maps, map);
820-
pthread_rwlock_unlock(&maps->lock);
820+
up_write(&maps->lock);
821821
}
822822

823823
static void __maps__remove(struct maps *maps, struct map *map)
@@ -828,17 +828,17 @@ static void __maps__remove(struct maps *maps, struct map *map)
828828

829829
void maps__remove(struct maps *maps, struct map *map)
830830
{
831-
pthread_rwlock_wrlock(&maps->lock);
831+
down_write(&maps->lock);
832832
__maps__remove(maps, map);
833-
pthread_rwlock_unlock(&maps->lock);
833+
up_write(&maps->lock);
834834
}
835835

836836
struct map *maps__find(struct maps *maps, u64 ip)
837837
{
838838
struct rb_node **p, *parent = NULL;
839839
struct map *m;
840840

841-
pthread_rwlock_rdlock(&maps->lock);
841+
down_read(&maps->lock);
842842

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

855855
m = NULL;
856856
out:
857-
pthread_rwlock_unlock(&maps->lock);
857+
up_read(&maps->lock);
858858
return m;
859859
}
860860

0 commit comments

Comments
 (0)