Patch "bpftool: profile online CPUs instead of possible" has been added to the 5.10-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    bpftool: profile online CPUs instead of possible

to the 5.10-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     bpftool-profile-online-cpus-instead-of-possible.patch
and it can be found in the queue-5.10 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 4df2bc21aa26d0d1ac0d8aed89b9488491ae5ae8
Author: Tonghao Zhang <tong@xxxxxxxxxxxxx>
Date:   Thu Feb 2 21:17:01 2023 +0800

    bpftool: profile online CPUs instead of possible
    
    [ Upstream commit 377c16fa3f3c60d21e4b05314c8be034ce37f2eb ]
    
    The number of online cpu may be not equal to possible cpu.
    "bpftool prog profile" can not create pmu event on possible
    but on online cpu.
    
    $ dmidecode -s system-product-name
    PowerEdge R620
    $ cat /sys/devices/system/cpu/possible
    0-47
    $ cat /sys/devices/system/cpu/online
    0-31
    
    Disable cpu dynamically:
    $ echo 0 > /sys/devices/system/cpu/cpuX/online
    
    If one cpu is offline, perf_event_open will return ENODEV.
    To fix this issue:
    * check value returned and skip offline cpu.
    * close pmu_fd immediately on error path, avoid fd leaking.
    
    Fixes: 47c09d6a9f67 ("bpftool: Introduce "prog profile" command")
    Signed-off-by: Tonghao Zhang <tong@xxxxxxxxxxxxx>
    Cc: Quentin Monnet <quentin@xxxxxxxxxxxxx>
    Cc: Alexei Starovoitov <ast@xxxxxxxxxx>
    Cc: Daniel Borkmann <daniel@xxxxxxxxxxxxx>
    Cc: Andrii Nakryiko <andrii@xxxxxxxxxx>
    Cc: Martin KaFai Lau <martin.lau@xxxxxxxxx>
    Cc: Song Liu <song@xxxxxxxxxx>
    Cc: Yonghong Song <yhs@xxxxxx>
    Cc: John Fastabend <john.fastabend@xxxxxxxxx>
    Cc: KP Singh <kpsingh@xxxxxxxxxx>
    Cc: Stanislav Fomichev <sdf@xxxxxxxxxx>
    Cc: Hao Luo <haoluo@xxxxxxxxxx>
    Cc: Jiri Olsa <jolsa@xxxxxxxxxx>
    Acked-by: John Fastabend <john.fastabend@xxxxxxxxx>
    Link: https://lore.kernel.org/r/20230202131701.29519-1-tong@xxxxxxxxxxxxx
    Signed-off-by: Martin KaFai Lau <martin.lau@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c
index 592536904dde2..d2bcce627b320 100644
--- a/tools/bpf/bpftool/prog.c
+++ b/tools/bpf/bpftool/prog.c
@@ -1912,10 +1912,38 @@ static void profile_close_perf_events(struct profiler_bpf *obj)
 	profile_perf_event_cnt = 0;
 }
 
+static int profile_open_perf_event(int mid, int cpu, int map_fd)
+{
+	int pmu_fd;
+
+	pmu_fd = syscall(__NR_perf_event_open, &metrics[mid].attr,
+			 -1 /*pid*/, cpu, -1 /*group_fd*/, 0);
+	if (pmu_fd < 0) {
+		if (errno == ENODEV) {
+			p_info("cpu %d may be offline, skip %s profiling.",
+				cpu, metrics[mid].name);
+			profile_perf_event_cnt++;
+			return 0;
+		}
+		return -1;
+	}
+
+	if (bpf_map_update_elem(map_fd,
+				&profile_perf_event_cnt,
+				&pmu_fd, BPF_ANY) ||
+	    ioctl(pmu_fd, PERF_EVENT_IOC_ENABLE, 0)) {
+		close(pmu_fd);
+		return -1;
+	}
+
+	profile_perf_events[profile_perf_event_cnt++] = pmu_fd;
+	return 0;
+}
+
 static int profile_open_perf_events(struct profiler_bpf *obj)
 {
 	unsigned int cpu, m;
-	int map_fd, pmu_fd;
+	int map_fd;
 
 	profile_perf_events = calloc(
 		sizeof(int), obj->rodata->num_cpu * obj->rodata->num_metric);
@@ -1934,17 +1962,11 @@ static int profile_open_perf_events(struct profiler_bpf *obj)
 		if (!metrics[m].selected)
 			continue;
 		for (cpu = 0; cpu < obj->rodata->num_cpu; cpu++) {
-			pmu_fd = syscall(__NR_perf_event_open, &metrics[m].attr,
-					 -1/*pid*/, cpu, -1/*group_fd*/, 0);
-			if (pmu_fd < 0 ||
-			    bpf_map_update_elem(map_fd, &profile_perf_event_cnt,
-						&pmu_fd, BPF_ANY) ||
-			    ioctl(pmu_fd, PERF_EVENT_IOC_ENABLE, 0)) {
+			if (profile_open_perf_event(m, cpu, map_fd)) {
 				p_err("failed to create event %s on cpu %d",
 				      metrics[m].name, cpu);
 				return -1;
 			}
-			profile_perf_events[profile_perf_event_cnt++] = pmu_fd;
 		}
 	}
 	return 0;



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux