Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf offcpu: Parse process id separately

The current target code uses thread id for tracking tasks because
perf_events need to be opened for each task. But we can use tgid in
BPF maps and check it easily.

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Cc: Blake Jones <blakejones@google.com>
Cc: Hao Luo <haoluo@google.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Milian Wolff <milian.wolff@kdab.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Song Liu <songliubraving@fb.com>
Cc: bpf@vger.kernel.org
Link: https://lore.kernel.org/r/20220811185456.194721-3-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Namhyung Kim and committed by
Arnaldo Carvalho de Melo
d6f415ca 07fc958b

+43 -2
+43 -2
tools/perf/util/bpf_off_cpu.c
··· 11 11 #include "util/cpumap.h" 12 12 #include "util/thread_map.h" 13 13 #include "util/cgroup.h" 14 + #include "util/strlist.h" 14 15 #include <bpf/bpf.h> 15 16 16 17 #include "bpf_skel/off_cpu.skel.h" ··· 126 125 { 127 126 int err, fd, i; 128 127 int ncpus = 1, ntasks = 1, ncgrps = 1; 128 + struct strlist *pid_slist = NULL; 129 + struct str_node *pos; 129 130 130 131 if (off_cpu_config(evlist) < 0) { 131 132 pr_err("Failed to config off-cpu BPF event\n"); ··· 146 143 bpf_map__set_max_entries(skel->maps.cpu_filter, ncpus); 147 144 } 148 145 149 - if (target__has_task(target)) { 146 + if (target->pid) { 147 + pid_slist = strlist__new(target->pid, NULL); 148 + if (!pid_slist) { 149 + pr_err("Failed to create a strlist for pid\n"); 150 + return -1; 151 + } 152 + 153 + ntasks = 0; 154 + strlist__for_each_entry(pos, pid_slist) { 155 + char *end_ptr; 156 + int pid = strtol(pos->s, &end_ptr, 10); 157 + 158 + if (pid == INT_MIN || pid == INT_MAX || 159 + (*end_ptr != '\0' && *end_ptr != ',')) 160 + continue; 161 + 162 + ntasks++; 163 + } 164 + bpf_map__set_max_entries(skel->maps.task_filter, ntasks); 165 + } else if (target__has_task(target)) { 150 166 ntasks = perf_thread_map__nr(evlist->core.threads); 151 167 bpf_map__set_max_entries(skel->maps.task_filter, ntasks); 152 168 } ··· 207 185 } 208 186 } 209 187 210 - if (target__has_task(target)) { 188 + if (target->pid) { 189 + u8 val = 1; 190 + 191 + skel->bss->has_task = 1; 192 + skel->bss->uses_tgid = 1; 193 + fd = bpf_map__fd(skel->maps.task_filter); 194 + 195 + strlist__for_each_entry(pos, pid_slist) { 196 + char *end_ptr; 197 + u32 tgid; 198 + int pid = strtol(pos->s, &end_ptr, 10); 199 + 200 + if (pid == INT_MIN || pid == INT_MAX || 201 + (*end_ptr != '\0' && *end_ptr != ',')) 202 + continue; 203 + 204 + tgid = pid; 205 + bpf_map_update_elem(fd, &tgid, &val, BPF_ANY); 206 + } 207 + } else if (target__has_task(target)) { 211 208 u32 pid; 212 209 u8 val = 1; 213 210