diff mbox series

[testsuite] tests/perf_event: don't assume CPU#0 is online

Message ID 20210923101618.599881-1-omosnace@redhat.com (mailing list archive)
State Accepted
Delegated to: Ondrej Mosnáček
Headers show
Series [testsuite] tests/perf_event: don't assume CPU#0 is online | expand

Commit Message

Ondrej Mosnacek Sept. 23, 2021, 10:16 a.m. UTC
The perf_event test currently uses hard-coded 0 as the CPU index.
Howver, if CPU#0 happens to be offline, the test then fails because
perf_event_open(2) returns -ENODEV.

To fix this, try to find the index of the first online CPU and use that
instead of the hard-coded value.

Verified to work well on a machine with the first 8 CPU cores offline.

Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
---
 tests/perf_event/perf_event.c | 23 ++++++++++++++---------
 tests/perf_event/test         | 32 +++++++++++++++++++++++---------
 2 files changed, 37 insertions(+), 18 deletions(-)

Comments

Ondrej Mosnacek Sept. 27, 2021, 8:35 a.m. UTC | #1
On Thu, Sep 23, 2021 at 12:16 PM Ondrej Mosnacek <omosnace@redhat.com> wrote:
> The perf_event test currently uses hard-coded 0 as the CPU index.
> Howver, if CPU#0 happens to be offline, the test then fails because
> perf_event_open(2) returns -ENODEV.
>
> To fix this, try to find the index of the first online CPU and use that
> instead of the hard-coded value.
>
> Verified to work well on a machine with the first 8 CPU cores offline.
>
> Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
> ---
>  tests/perf_event/perf_event.c | 23 ++++++++++++++---------
>  tests/perf_event/test         | 32 +++++++++++++++++++++++---------
>  2 files changed, 37 insertions(+), 18 deletions(-)

Now applied [1], along with a small workaround for module metadata
issue on F33 [2].

[1] https://github.com/SELinuxProject/selinux-testsuite/commit/7d737e1605f62ccce5ff36e8d1643afd66fc9abf
[2] https://github.com/SELinuxProject/selinux-testsuite/commit/29c42c865a9f43a15ae72ebd19642c3d88a7d5ce
diff mbox series

Patch

diff --git a/tests/perf_event/perf_event.c b/tests/perf_event/perf_event.c
index 453aa91..0e8bdce 100644
--- a/tests/perf_event/perf_event.c
+++ b/tests/perf_event/perf_event.c
@@ -20,13 +20,14 @@  enum {
 static void print_usage(char *progname)
 {
 	fprintf(stderr,
-		"usage:  %s [-f|-m] [-v] EVENT_ID\n"
+		"usage:  %s [-f|-m] [-v] CPU EVENT_ID\n"
 		"Where:\n\t"
+		"CPU       target CPU (must be online)\n\n\t"
 		"EVENT_ID  target ftrace event ID\n\n\t"
-		"-f  Read perf_event info using read(2)\n\t"
-		"-m  Read perf_event info using mmap(2)\n\t"
-		"    Default is to use read(2) and mmap(2)\n\t"
-		"-v  Print information\n", progname);
+		"-f        Read perf_event info using read(2)\n\t"
+		"-m        Read perf_event info using mmap(2)\n\t"
+		"          Default is to use read(2) and mmap(2)\n\t"
+		"-v        Print information\n", progname);
 	exit(-1);
 }
 
@@ -39,7 +40,7 @@  static long perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
 
 int main(int argc, char **argv)
 {
-	int opt, result, page_size, mmap_size, fd;
+	int opt, result, page_size, mmap_size, fd, cpu;
 	long long count, event_id;
 	bool verbose = false;
 	char *context;
@@ -65,10 +66,14 @@  int main(int argc, char **argv)
 		}
 	}
 
-	if ((argc - optind) != 1)
+	if ((argc - optind) != 2)
 		print_usage(argv[0]);
 
-	event_id = atoll(argv[optind]);
+	cpu = atoi(argv[optind]);
+	if (cpu < 0)
+		print_usage(argv[0]);
+
+	event_id = atoll(argv[optind + 1]);
 	if (event_id < 0)
 		print_usage(argv[0]);
 
@@ -90,7 +95,7 @@  int main(int argc, char **argv)
 	pe_attr.disabled = 1;
 	pe_attr.exclude_hv = 1;
 
-	fd = perf_event_open(&pe_attr, -1, 0, -1, 0);
+	fd = perf_event_open(&pe_attr, -1, cpu, -1, 0);
 	if (fd < 0) {
 		fprintf(stderr, "Failed perf_event_open(): %s\n",
 			strerror(errno));
diff --git a/tests/perf_event/test b/tests/perf_event/test
index 380d9cc..c336477 100755
--- a/tests/perf_event/test
+++ b/tests/perf_event/test
@@ -48,56 +48,70 @@  BEGIN {
     plan tests => $test_count;
 }
 
+# find some CPU that is online
+for ( $cpu = 0 ; -e "/sys/devices/system/cpu/cpu$cpu" ; $cpu++ ) {
+
+    # if the "online" file doesn't exist, the CPU can't be offline
+    last unless -e "/sys/devices/system/cpu/cpu$cpu/online";
+
+    $online = `cat /sys/devices/system/cpu/cpu$cpu/online`;
+    chomp($online);
+    last if ( $online eq "1" );
+}
+
 $event_id = `cat /sys/kernel/debug/tracing/events/ftrace/function/id`;
 chomp($event_id);
 
 # perf_event { open cpu kernel tracepoint read write };
 print "Test perf_event\n";
-$result = system "runcon -t test_perf_t $basedir/perf_event $v $event_id";
+$result = system "runcon -t test_perf_t $basedir/perf_event $v $cpu $event_id";
 ok( $result eq 0 );
 
 if ($capability) {
 
     # Deny capability { perfmon } - EACCES perf_event_open(2)
     $result = system
-      "runcon -t test_perf_no_cap_t $basedir/perf_event $v $event_id 2>&1";
+      "runcon -t test_perf_no_cap_t $basedir/perf_event $v $cpu $event_id 2>&1";
     ok( $result >> 8 eq 1 );
 }
 
 # Deny perf_event { open } - EACCES perf_event_open(2)
 $result =
-  system "runcon -t test_perf_no_open_t $basedir/perf_event $v $event_id 2>&1";
+  system
+  "runcon -t test_perf_no_open_t $basedir/perf_event $v $cpu $event_id 2>&1";
 ok( $result >> 8 eq 1 );
 
 # Deny perf_event { cpu } - EACCES perf_event_open(2)
 $result =
-  system "runcon -t test_perf_no_cpu_t $basedir/perf_event $v $event_id 2>&1";
+  system
+  "runcon -t test_perf_no_cpu_t $basedir/perf_event $v $cpu $event_id 2>&1";
 ok( $result >> 8 eq 1 );
 
 # Deny perf_event { kernel } - EACCES perf_event_open(2)
 $result = system
-  "runcon -t test_perf_no_kernel_t $basedir/perf_event $v $event_id 2>&1";
+  "runcon -t test_perf_no_kernel_t $basedir/perf_event $v $cpu $event_id 2>&1";
 ok( $result >> 8 eq 1 );
 
 # Deny perf_event { tracepoint } - EACCES perf_event_open(2)
 $result =
   system
-  "runcon -t test_perf_no_tracepoint_t $basedir/perf_event $v $event_id 2>&1";
+"runcon -t test_perf_no_tracepoint_t $basedir/perf_event $v $cpu $event_id 2>&1";
 ok( $result >> 8 eq 1 );
 
 # Deny perf_event { read } - EACCES mmap(2)
 $result = system
-  "runcon -t test_perf_no_read_t $basedir/perf_event -m $v $event_id 2>&1";
+  "runcon -t test_perf_no_read_t $basedir/perf_event -m $v $cpu $event_id 2>&1";
 ok( $result >> 8 eq 6 );
 
 # Deny perf_event { read } - EACCES read(2)
 $result = system
-  "runcon -t test_perf_no_read_t $basedir/perf_event -f $v $event_id 2>&1";
+  "runcon -t test_perf_no_read_t $basedir/perf_event -f $v $cpu $event_id 2>&1";
 ok( $result >> 8 eq 7 );
 
 # Deny perf_event { write } - EACCES ioctl(2) write
 $result =
-  system "runcon -t test_perf_no_write_t $basedir/perf_event $v $event_id 2>&1";
+  system
+  "runcon -t test_perf_no_write_t $basedir/perf_event $v $cpu $event_id 2>&1";
 ok( $result >> 8 eq 2 );
 
 exit;