summaryrefslogtreecommitdiff
path: root/tools/testing/selftests/powerpc/pmu/ebb/cpu_event_pinned_vs_ebb_test.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-06-12 20:11:38 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2014-06-12 20:11:38 -0700
commitb7c8c1945cfbcfb9d60f5be957b4339c6eee4201 (patch)
treeef27f4b91fc98fcea70b8ef2b7d917c9814a0fbb /tools/testing/selftests/powerpc/pmu/ebb/cpu_event_pinned_vs_ebb_test.c
parent88bbfb4a6267ff90a466ade9762d9a8fff2bb1bb (diff)
parentad718622ab6d500c870772b1b8dda46fa2195e6d (diff)
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
Pull more powerpc updates from Ben Herrenschmidt: "Here are the remaining bits I was mentioning earlier. Mostly bug fixes and new selftests from Michael (yay !). He also removed the WSP platform and A2 core support which were dead before release, so less clutter. One little "feature" I snuck in is the doorbell IPI support for non-virtualized P8 which speeds up IPIs significantly between threads of a core" * 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (34 commits) powerpc/book3s: Fix some ABIv2 issues in machine check code powerpc/book3s: Fix guest MC delivery mechanism to avoid soft lockups in guest. powerpc/book3s: Increment the mce counter during machine_check_early call. powerpc/book3s: Add stack overflow check in machine check handler. powerpc/book3s: Fix machine check handling for unhandled errors powerpc/eeh: Dump PE location code powerpc/powernv: Enable POWER8 doorbell IPIs powerpc/cpuidle: Only clear LPCR decrementer wakeup bit on fast sleep entry powerpc/powernv: Fix killed EEH event powerpc: fix typo 'CONFIG_PMAC' powerpc: fix typo 'CONFIG_PPC_CPU' powerpc/powernv: Don't escalate non-existing frozen PE powerpc/eeh: Report frozen parent PE prior to child PE powerpc/eeh: Clear frozen state for child PE powerpc/powernv: Reduce panic timeout from 180s to 10s powerpc/xmon: avoid format string leaking to printk selftests/powerpc: Add tests of PMU EBBs selftests/powerpc: Add support for skipping tests selftests/powerpc: Put the test in a separate process group selftests/powerpc: Fix instruction loop for ABIv2 (LE) ...
Diffstat (limited to 'tools/testing/selftests/powerpc/pmu/ebb/cpu_event_pinned_vs_ebb_test.c')
-rw-r--r--tools/testing/selftests/powerpc/pmu/ebb/cpu_event_pinned_vs_ebb_test.c93
1 files changed, 93 insertions, 0 deletions
diff --git a/tools/testing/selftests/powerpc/pmu/ebb/cpu_event_pinned_vs_ebb_test.c b/tools/testing/selftests/powerpc/pmu/ebb/cpu_event_pinned_vs_ebb_test.c
new file mode 100644
index 000000000000..d3ed64d5d6c0
--- /dev/null
+++ b/tools/testing/selftests/powerpc/pmu/ebb/cpu_event_pinned_vs_ebb_test.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2014, Michael Ellerman, IBM Corp.
+ * Licensed under GPLv2.
+ */
+
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include "ebb.h"
+
+
+/*
+ * Tests a pinned cpu event vs an EBB - in that order. The pinned cpu event
+ * should remain and the EBB event should fail to enable.
+ */
+
+static int setup_cpu_event(struct event *event, int cpu)
+{
+ event_init_named(event, 0x400FA, "PM_RUN_INST_CMPL");
+
+ event->attr.pinned = 1;
+
+ event->attr.exclude_kernel = 1;
+ event->attr.exclude_hv = 1;
+ event->attr.exclude_idle = 1;
+
+ SKIP_IF(require_paranoia_below(1));
+ FAIL_IF(event_open_with_cpu(event, cpu));
+ FAIL_IF(event_enable(event));
+
+ return 0;
+}
+
+int cpu_event_pinned_vs_ebb(void)
+{
+ union pipe read_pipe, write_pipe;
+ struct event event;
+ int cpu, rc;
+ pid_t pid;
+
+ cpu = pick_online_cpu();
+ FAIL_IF(cpu < 0);
+ FAIL_IF(bind_to_cpu(cpu));
+
+ FAIL_IF(pipe(read_pipe.fds) == -1);
+ FAIL_IF(pipe(write_pipe.fds) == -1);
+
+ pid = fork();
+ if (pid == 0) {
+ /* NB order of pipes looks reversed */
+ exit(ebb_child(write_pipe, read_pipe));
+ }
+
+ /* We setup the cpu event first */
+ rc = setup_cpu_event(&event, cpu);
+ if (rc) {
+ kill_child_and_wait(pid);
+ return rc;
+ }
+
+ /* Signal the child to install its EBB event and wait */
+ if (sync_with_child(read_pipe, write_pipe))
+ /* If it fails, wait for it to exit */
+ goto wait;
+
+ /* Signal the child to run */
+ FAIL_IF(sync_with_child(read_pipe, write_pipe));
+
+wait:
+ /* We expect it to fail to read the event */
+ FAIL_IF(wait_for_child(pid) != 2);
+
+ FAIL_IF(event_disable(&event));
+ FAIL_IF(event_read(&event));
+
+ event_report(&event);
+
+ /* The cpu event should have run */
+ FAIL_IF(event.result.value == 0);
+ FAIL_IF(event.result.enabled != event.result.running);
+
+ return 0;
+}
+
+int main(void)
+{
+ return test_harness(cpu_event_pinned_vs_ebb, "cpu_event_pinned_vs_ebb");
+}