Skip to content

Commit 9c51f87

Browse files
captain5050acmel
authored andcommitted
perf env: Avoid recursively taking env->bpf_progs.lock
Add variants of perf_env__insert_bpf_prog_info(), perf_env__insert_btf() and perf_env__find_btf prefixed with __ to indicate the env->bpf_progs.lock is assumed held. Call these variants when the lock is held to avoid recursively taking it and potentially having a thread deadlock with itself. Fixes: f8dfeae ("perf bpf: Show more BPF program info in print_bpf_prog_info()") Signed-off-by: Ian Rogers <[email protected]> Acked-by: Jiri Olsa <[email protected]> Acked-by: Song Liu <[email protected]> Cc: Adrian Hunter <[email protected]> Cc: Alexander Shishkin <[email protected]> Cc: Huacai Chen <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: K Prateek Nayak <[email protected]> Cc: Kan Liang <[email protected]> Cc: Mark Rutland <[email protected]> Cc: Ming Wang <[email protected]> Cc: Namhyung Kim <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Ravi Bangoria <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
1 parent 58824fa commit 9c51f87

File tree

5 files changed

+50
-32
lines changed

5 files changed

+50
-32
lines changed

tools/perf/util/bpf-event.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -545,9 +545,9 @@ int evlist__add_bpf_sb_event(struct evlist *evlist, struct perf_env *env)
545545
return evlist__add_sb_event(evlist, &attr, bpf_event__sb_cb, env);
546546
}
547547

548-
void bpf_event__print_bpf_prog_info(struct bpf_prog_info *info,
549-
struct perf_env *env,
550-
FILE *fp)
548+
void __bpf_event__print_bpf_prog_info(struct bpf_prog_info *info,
549+
struct perf_env *env,
550+
FILE *fp)
551551
{
552552
__u32 *prog_lens = (__u32 *)(uintptr_t)(info->jited_func_lens);
553553
__u64 *prog_addrs = (__u64 *)(uintptr_t)(info->jited_ksyms);
@@ -563,7 +563,7 @@ void bpf_event__print_bpf_prog_info(struct bpf_prog_info *info,
563563
if (info->btf_id) {
564564
struct btf_node *node;
565565

566-
node = perf_env__find_btf(env, info->btf_id);
566+
node = __perf_env__find_btf(env, info->btf_id);
567567
if (node)
568568
btf = btf__new((__u8 *)(node->data),
569569
node->data_size);

tools/perf/util/bpf-event.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ struct btf_node {
3333
int machine__process_bpf(struct machine *machine, union perf_event *event,
3434
struct perf_sample *sample);
3535
int evlist__add_bpf_sb_event(struct evlist *evlist, struct perf_env *env);
36-
void bpf_event__print_bpf_prog_info(struct bpf_prog_info *info,
37-
struct perf_env *env,
38-
FILE *fp);
36+
void __bpf_event__print_bpf_prog_info(struct bpf_prog_info *info,
37+
struct perf_env *env,
38+
FILE *fp);
3939
#else
4040
static inline int machine__process_bpf(struct machine *machine __maybe_unused,
4141
union perf_event *event __maybe_unused,
@@ -50,9 +50,9 @@ static inline int evlist__add_bpf_sb_event(struct evlist *evlist __maybe_unused,
5050
return 0;
5151
}
5252

53-
static inline void bpf_event__print_bpf_prog_info(struct bpf_prog_info *info __maybe_unused,
54-
struct perf_env *env __maybe_unused,
55-
FILE *fp __maybe_unused)
53+
static inline void __bpf_event__print_bpf_prog_info(struct bpf_prog_info *info __maybe_unused,
54+
struct perf_env *env __maybe_unused,
55+
FILE *fp __maybe_unused)
5656
{
5757

5858
}

tools/perf/util/env.c

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,19 @@ struct perf_env perf_env;
2424

2525
void perf_env__insert_bpf_prog_info(struct perf_env *env,
2626
struct bpf_prog_info_node *info_node)
27+
{
28+
down_write(&env->bpf_progs.lock);
29+
__perf_env__insert_bpf_prog_info(env, info_node);
30+
up_write(&env->bpf_progs.lock);
31+
}
32+
33+
void __perf_env__insert_bpf_prog_info(struct perf_env *env, struct bpf_prog_info_node *info_node)
2734
{
2835
__u32 prog_id = info_node->info_linear->info.id;
2936
struct bpf_prog_info_node *node;
3037
struct rb_node *parent = NULL;
3138
struct rb_node **p;
3239

33-
down_write(&env->bpf_progs.lock);
3440
p = &env->bpf_progs.infos.rb_node;
3541

3642
while (*p != NULL) {
@@ -42,15 +48,13 @@ void perf_env__insert_bpf_prog_info(struct perf_env *env,
4248
p = &(*p)->rb_right;
4349
} else {
4450
pr_debug("duplicated bpf prog info %u\n", prog_id);
45-
goto out;
51+
return;
4652
}
4753
}
4854

4955
rb_link_node(&info_node->rb_node, parent, p);
5056
rb_insert_color(&info_node->rb_node, &env->bpf_progs.infos);
5157
env->bpf_progs.infos_cnt++;
52-
out:
53-
up_write(&env->bpf_progs.lock);
5458
}
5559

5660
struct bpf_prog_info_node *perf_env__find_bpf_prog_info(struct perf_env *env,
@@ -79,14 +83,22 @@ struct bpf_prog_info_node *perf_env__find_bpf_prog_info(struct perf_env *env,
7983
}
8084

8185
bool perf_env__insert_btf(struct perf_env *env, struct btf_node *btf_node)
86+
{
87+
bool ret;
88+
89+
down_write(&env->bpf_progs.lock);
90+
ret = __perf_env__insert_btf(env, btf_node);
91+
up_write(&env->bpf_progs.lock);
92+
return ret;
93+
}
94+
95+
bool __perf_env__insert_btf(struct perf_env *env, struct btf_node *btf_node)
8296
{
8397
struct rb_node *parent = NULL;
8498
__u32 btf_id = btf_node->id;
8599
struct btf_node *node;
86100
struct rb_node **p;
87-
bool ret = true;
88101

89-
down_write(&env->bpf_progs.lock);
90102
p = &env->bpf_progs.btfs.rb_node;
91103

92104
while (*p != NULL) {
@@ -98,25 +110,31 @@ bool perf_env__insert_btf(struct perf_env *env, struct btf_node *btf_node)
98110
p = &(*p)->rb_right;
99111
} else {
100112
pr_debug("duplicated btf %u\n", btf_id);
101-
ret = false;
102-
goto out;
113+
return false;
103114
}
104115
}
105116

106117
rb_link_node(&btf_node->rb_node, parent, p);
107118
rb_insert_color(&btf_node->rb_node, &env->bpf_progs.btfs);
108119
env->bpf_progs.btfs_cnt++;
109-
out:
110-
up_write(&env->bpf_progs.lock);
111-
return ret;
120+
return true;
112121
}
113122

114123
struct btf_node *perf_env__find_btf(struct perf_env *env, __u32 btf_id)
124+
{
125+
struct btf_node *res;
126+
127+
down_read(&env->bpf_progs.lock);
128+
res = __perf_env__find_btf(env, btf_id);
129+
up_read(&env->bpf_progs.lock);
130+
return res;
131+
}
132+
133+
struct btf_node *__perf_env__find_btf(struct perf_env *env, __u32 btf_id)
115134
{
116135
struct btf_node *node = NULL;
117136
struct rb_node *n;
118137

119-
down_read(&env->bpf_progs.lock);
120138
n = env->bpf_progs.btfs.rb_node;
121139

122140
while (n) {
@@ -126,13 +144,9 @@ struct btf_node *perf_env__find_btf(struct perf_env *env, __u32 btf_id)
126144
else if (btf_id > node->id)
127145
n = n->rb_right;
128146
else
129-
goto out;
147+
return node;
130148
}
131-
node = NULL;
132-
133-
out:
134-
up_read(&env->bpf_progs.lock);
135-
return node;
149+
return NULL;
136150
}
137151

138152
/* purge data in bpf_progs.infos tree */

tools/perf/util/env.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,12 +175,16 @@ const char *perf_env__raw_arch(struct perf_env *env);
175175
int perf_env__nr_cpus_avail(struct perf_env *env);
176176

177177
void perf_env__init(struct perf_env *env);
178+
void __perf_env__insert_bpf_prog_info(struct perf_env *env,
179+
struct bpf_prog_info_node *info_node);
178180
void perf_env__insert_bpf_prog_info(struct perf_env *env,
179181
struct bpf_prog_info_node *info_node);
180182
struct bpf_prog_info_node *perf_env__find_bpf_prog_info(struct perf_env *env,
181183
__u32 prog_id);
182184
bool perf_env__insert_btf(struct perf_env *env, struct btf_node *btf_node);
185+
bool __perf_env__insert_btf(struct perf_env *env, struct btf_node *btf_node);
183186
struct btf_node *perf_env__find_btf(struct perf_env *env, __u32 btf_id);
187+
struct btf_node *__perf_env__find_btf(struct perf_env *env, __u32 btf_id);
184188

185189
int perf_env__numa_node(struct perf_env *env, struct perf_cpu cpu);
186190
char *perf_env__find_pmu_cap(struct perf_env *env, const char *pmu_name,

tools/perf/util/header.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1849,8 +1849,8 @@ static void print_bpf_prog_info(struct feat_fd *ff, FILE *fp)
18491849
node = rb_entry(next, struct bpf_prog_info_node, rb_node);
18501850
next = rb_next(&node->rb_node);
18511851

1852-
bpf_event__print_bpf_prog_info(&node->info_linear->info,
1853-
env, fp);
1852+
__bpf_event__print_bpf_prog_info(&node->info_linear->info,
1853+
env, fp);
18541854
}
18551855

18561856
up_read(&env->bpf_progs.lock);
@@ -3188,7 +3188,7 @@ static int process_bpf_prog_info(struct feat_fd *ff, void *data __maybe_unused)
31883188
/* after reading from file, translate offset to address */
31893189
bpil_offs_to_addr(info_linear);
31903190
info_node->info_linear = info_linear;
3191-
perf_env__insert_bpf_prog_info(env, info_node);
3191+
__perf_env__insert_bpf_prog_info(env, info_node);
31923192
}
31933193

31943194
up_write(&env->bpf_progs.lock);
@@ -3235,7 +3235,7 @@ static int process_bpf_btf(struct feat_fd *ff, void *data __maybe_unused)
32353235
if (__do_read(ff, node->data, data_size))
32363236
goto out;
32373237

3238-
perf_env__insert_btf(env, node);
3238+
__perf_env__insert_btf(env, node);
32393239
node = NULL;
32403240
}
32413241

0 commit comments

Comments
 (0)