File Index
Files and directories
Sign in
FILE

lib.c

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/powerpc/pmu/lib.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * Copyright 2014, Michael Ellerman, IBM Corp.
  4 */
  5
  6#define _GNU_SOURCE	/* For CPU_ZERO etc. */
  7
  8#include <errno.h>
  9#include <sched.h>
 10#include <setjmp.h>
 11#include <stdlib.h>
 12#include <sys/wait.h>
 13
 14#include "utils.h"
 15#include "lib.h"
 16
 17#define PARENT_TOKEN	0xAA
 18#define CHILD_TOKEN	0x55
 19
 20int sync_with_child(union pipe read_pipe, union pipe write_pipe)
 21{
 22	char c = PARENT_TOKEN;
 23
 24	FAIL_IF(write(write_pipe.write_fd, &c, 1) != 1);
 25	FAIL_IF(read(read_pipe.read_fd, &c, 1) != 1);
 26	if (c != CHILD_TOKEN) /* sometimes expected */
 27		return 1;
 28
 29	return 0;
 30}
 31
 32int wait_for_parent(union pipe read_pipe)
 33{
 34	char c;
 35
 36	FAIL_IF(read(read_pipe.read_fd, &c, 1) != 1);
 37	FAIL_IF(c != PARENT_TOKEN);
 38
 39	return 0;
 40}
 41
 42int notify_parent(union pipe write_pipe)
 43{
 44	char c = CHILD_TOKEN;
 45
 46	FAIL_IF(write(write_pipe.write_fd, &c, 1) != 1);
 47
 48	return 0;
 49}
 50
 51int notify_parent_of_error(union pipe write_pipe)
 52{
 53	char c = ~CHILD_TOKEN;
 54
 55	FAIL_IF(write(write_pipe.write_fd, &c, 1) != 1);
 56
 57	return 0;
 58}
 59
 60int wait_for_child(pid_t child_pid)
 61{
 62	int rc;
 63
 64	if (waitpid(child_pid, &rc, 0) == -1) {
 65		perror("waitpid");
 66		return 1;
 67	}
 68
 69	if (WIFEXITED(rc))
 70		rc = WEXITSTATUS(rc);
 71	else
 72		rc = 1; /* Signal or other */
 73
 74	return rc;
 75}
 76
 77int kill_child_and_wait(pid_t child_pid)
 78{
 79	kill(child_pid, SIGTERM);
 80
 81	return wait_for_child(child_pid);
 82}
 83
 84static int eat_cpu_child(union pipe read_pipe, union pipe write_pipe)
 85{
 86	volatile int i = 0;
 87
 88	/*
 89	 * We are just here to eat cpu and die. So make sure we can be killed,
 90	 * and also don't do any custom SIGTERM handling.
 91	 */
 92	signal(SIGTERM, SIG_DFL);
 93
 94	notify_parent(write_pipe);
 95	wait_for_parent(read_pipe);
 96
 97	/* Soak up cpu forever */
 98	while (1) i++;
 99
100	return 0;
101}
102
103pid_t eat_cpu(int (test_function)(void))
104{
105	union pipe read_pipe, write_pipe;
106	int rc;
107	pid_t pid;
108
109	FAIL_IF(bind_to_cpu(BIND_CPU_ANY) < 0);
110
111	if (pipe(read_pipe.fds) == -1)
112		return -1;
113
114	if (pipe(write_pipe.fds) == -1)
115		return -1;
116
117	pid = fork();
118	if (pid == 0)
119		exit(eat_cpu_child(write_pipe, read_pipe));
120
121	if (sync_with_child(read_pipe, write_pipe)) {
122		rc = -1;
123		goto out;
124	}
125
126	printf("main test running as pid %d\n", getpid());
127
128	rc = test_function();
129out:
130	kill(pid, SIGKILL);
131
132	return rc;
133}
134
135struct addr_range libc, vdso;
136
137int parse_proc_maps(void)
138{
139	unsigned long start, end;
140	char execute, name[128];
141	FILE *f;
142	int rc;
143
144	f = fopen("/proc/self/maps", "r");
145	if (!f) {
146		perror("fopen");
147		return -1;
148	}
149
150	do {
151		/* This skips line with no executable which is what we want */
152		rc = fscanf(f, "%lx-%lx %*c%*c%c%*c %*x %*d:%*d %*d %127s\n",
153			    &start, &end, &execute, name);
154		if (rc <= 0)
155			break;
156
157		if (execute != 'x')
158			continue;
159
160		if (strstr(name, "libc")) {
161			libc.first = start;
162			libc.last = end - 1;
163		} else if (strstr(name, "[vdso]")) {
164			vdso.first = start;
165			vdso.last = end - 1;
166		}
167	} while(1);
168
169	fclose(f);
170
171	return 0;
172}
173
174#define PARANOID_PATH	"/proc/sys/kernel/perf_event_paranoid"
175
176bool require_paranoia_below(int level)
177{
178	int err;
179	long current;
180
181	err = read_long(PARANOID_PATH, &current, 10);
182	if (err) {
183		printf("Couldn't parse " PARANOID_PATH "?\n");
184		return false;
185	}
186
187	return current < level;
188}
~/ Read-only file preview.