aboutsummaryrefslogtreecommitdiff
path: root/powerpc/pmu/lib.c
diff options
context:
space:
mode:
Diffstat (limited to 'powerpc/pmu/lib.c')
-rw-r--r--powerpc/pmu/lib.c300
1 files changed, 0 insertions, 300 deletions
diff --git a/powerpc/pmu/lib.c b/powerpc/pmu/lib.c
deleted file mode 100644
index 9768dea..0000000
--- a/powerpc/pmu/lib.c
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- * Copyright 2014, Michael Ellerman, IBM Corp.
- * Licensed under GPLv2.
- */
-
-#define _GNU_SOURCE /* For CPU_ZERO etc. */
-
-#include <elf.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <link.h>
-#include <sched.h>
-#include <setjmp.h>
-#include <stdlib.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-
-#include "utils.h"
-#include "lib.h"
-
-
-int pick_online_cpu(void)
-{
- cpu_set_t mask;
- int cpu;
-
- CPU_ZERO(&mask);
-
- if (sched_getaffinity(0, sizeof(mask), &mask)) {
- perror("sched_getaffinity");
- return -1;
- }
-
- /* We prefer a primary thread, but skip 0 */
- for (cpu = 8; cpu < CPU_SETSIZE; cpu += 8)
- if (CPU_ISSET(cpu, &mask))
- return cpu;
-
- /* Search for anything, but in reverse */
- for (cpu = CPU_SETSIZE - 1; cpu >= 0; cpu--)
- if (CPU_ISSET(cpu, &mask))
- return cpu;
-
- printf("No cpus in affinity mask?!\n");
- return -1;
-}
-
-int bind_to_cpu(int cpu)
-{
- cpu_set_t mask;
-
- printf("Binding to cpu %d\n", cpu);
-
- CPU_ZERO(&mask);
- CPU_SET(cpu, &mask);
-
- return sched_setaffinity(0, sizeof(mask), &mask);
-}
-
-#define PARENT_TOKEN 0xAA
-#define CHILD_TOKEN 0x55
-
-int sync_with_child(union pipe read_pipe, union pipe write_pipe)
-{
- char c = PARENT_TOKEN;
-
- FAIL_IF(write(write_pipe.write_fd, &c, 1) != 1);
- FAIL_IF(read(read_pipe.read_fd, &c, 1) != 1);
- if (c != CHILD_TOKEN) /* sometimes expected */
- return 1;
-
- return 0;
-}
-
-int wait_for_parent(union pipe read_pipe)
-{
- char c;
-
- FAIL_IF(read(read_pipe.read_fd, &c, 1) != 1);
- FAIL_IF(c != PARENT_TOKEN);
-
- return 0;
-}
-
-int notify_parent(union pipe write_pipe)
-{
- char c = CHILD_TOKEN;
-
- FAIL_IF(write(write_pipe.write_fd, &c, 1) != 1);
-
- return 0;
-}
-
-int notify_parent_of_error(union pipe write_pipe)
-{
- char c = ~CHILD_TOKEN;
-
- FAIL_IF(write(write_pipe.write_fd, &c, 1) != 1);
-
- return 0;
-}
-
-int wait_for_child(pid_t child_pid)
-{
- int rc;
-
- if (waitpid(child_pid, &rc, 0) == -1) {
- perror("waitpid");
- return 1;
- }
-
- if (WIFEXITED(rc))
- rc = WEXITSTATUS(rc);
- else
- rc = 1; /* Signal or other */
-
- return rc;
-}
-
-int kill_child_and_wait(pid_t child_pid)
-{
- kill(child_pid, SIGTERM);
-
- return wait_for_child(child_pid);
-}
-
-static int eat_cpu_child(union pipe read_pipe, union pipe write_pipe)
-{
- volatile int i = 0;
-
- /*
- * We are just here to eat cpu and die. So make sure we can be killed,
- * and also don't do any custom SIGTERM handling.
- */
- signal(SIGTERM, SIG_DFL);
-
- notify_parent(write_pipe);
- wait_for_parent(read_pipe);
-
- /* Soak up cpu forever */
- while (1) i++;
-
- return 0;
-}
-
-pid_t eat_cpu(int (test_function)(void))
-{
- union pipe read_pipe, write_pipe;
- int cpu, rc;
- pid_t pid;
-
- cpu = pick_online_cpu();
- FAIL_IF(cpu < 0);
- FAIL_IF(bind_to_cpu(cpu));
-
- if (pipe(read_pipe.fds) == -1)
- return -1;
-
- if (pipe(write_pipe.fds) == -1)
- return -1;
-
- pid = fork();
- if (pid == 0)
- exit(eat_cpu_child(write_pipe, read_pipe));
-
- if (sync_with_child(read_pipe, write_pipe)) {
- rc = -1;
- goto out;
- }
-
- printf("main test running as pid %d\n", getpid());
-
- rc = test_function();
-out:
- kill(pid, SIGKILL);
-
- return rc;
-}
-
-struct addr_range libc, vdso;
-
-int parse_proc_maps(void)
-{
- unsigned long start, end;
- char execute, name[128];
- FILE *f;
- int rc;
-
- f = fopen("/proc/self/maps", "r");
- if (!f) {
- perror("fopen");
- return -1;
- }
-
- do {
- /* This skips line with no executable which is what we want */
- rc = fscanf(f, "%lx-%lx %*c%*c%c%*c %*x %*d:%*d %*d %127s\n",
- &start, &end, &execute, name);
- if (rc <= 0)
- break;
-
- if (execute != 'x')
- continue;
-
- if (strstr(name, "libc")) {
- libc.first = start;
- libc.last = end - 1;
- } else if (strstr(name, "[vdso]")) {
- vdso.first = start;
- vdso.last = end - 1;
- }
- } while(1);
-
- fclose(f);
-
- return 0;
-}
-
-#define PARANOID_PATH "/proc/sys/kernel/perf_event_paranoid"
-
-bool require_paranoia_below(int level)
-{
- unsigned long current;
- char *end, buf[16];
- FILE *f;
- int rc;
-
- rc = -1;
-
- f = fopen(PARANOID_PATH, "r");
- if (!f) {
- perror("fopen");
- goto out;
- }
-
- if (!fgets(buf, sizeof(buf), f)) {
- printf("Couldn't read " PARANOID_PATH "?\n");
- goto out_close;
- }
-
- current = strtoul(buf, &end, 10);
-
- if (end == buf) {
- printf("Couldn't parse " PARANOID_PATH "?\n");
- goto out_close;
- }
-
- if (current >= level)
- goto out;
-
- rc = 0;
-out_close:
- fclose(f);
-out:
- return rc;
-}
-
-static char auxv[4096];
-
-void *get_auxv_entry(int type)
-{
- ElfW(auxv_t) *p;
- void *result;
- ssize_t num;
- int fd;
-
- fd = open("/proc/self/auxv", O_RDONLY);
- if (fd == -1) {
- perror("open");
- return NULL;
- }
-
- result = NULL;
-
- num = read(fd, auxv, sizeof(auxv));
- if (num < 0) {
- perror("read");
- goto out;
- }
-
- if (num > sizeof(auxv)) {
- printf("Overflowed auxv buffer\n");
- goto out;
- }
-
- p = (ElfW(auxv_t) *)auxv;
-
- while (p->a_type != AT_NULL) {
- if (p->a_type == type) {
- result = (void *)p->a_un.a_val;
- break;
- }
-
- p++;
- }
-out:
- close(fd);
- return result;
-}