xref: /linux/tools/testing/selftests/powerpc/pmu/event.c (revision cb96143defbd5516c351595d56b608ed915b525e)
1*cb96143dSMichael Ellerman /*
2*cb96143dSMichael Ellerman  * Copyright 2013, Michael Ellerman, IBM Corp.
3*cb96143dSMichael Ellerman  * Licensed under GPLv2.
4*cb96143dSMichael Ellerman  */
5*cb96143dSMichael Ellerman 
6*cb96143dSMichael Ellerman #define _GNU_SOURCE
7*cb96143dSMichael Ellerman #include <unistd.h>
8*cb96143dSMichael Ellerman #include <sys/syscall.h>
9*cb96143dSMichael Ellerman #include <string.h>
10*cb96143dSMichael Ellerman #include <stdio.h>
11*cb96143dSMichael Ellerman #include <sys/ioctl.h>
12*cb96143dSMichael Ellerman 
13*cb96143dSMichael Ellerman #include "event.h"
14*cb96143dSMichael Ellerman 
15*cb96143dSMichael Ellerman 
16*cb96143dSMichael Ellerman int perf_event_open(struct perf_event_attr *attr, pid_t pid, int cpu,
17*cb96143dSMichael Ellerman 		int group_fd, unsigned long flags)
18*cb96143dSMichael Ellerman {
19*cb96143dSMichael Ellerman 	return syscall(__NR_perf_event_open, attr, pid, cpu,
20*cb96143dSMichael Ellerman 			   group_fd, flags);
21*cb96143dSMichael Ellerman }
22*cb96143dSMichael Ellerman 
23*cb96143dSMichael Ellerman void event_init_opts(struct event *e, u64 config, int type, char *name)
24*cb96143dSMichael Ellerman {
25*cb96143dSMichael Ellerman 	memset(e, 0, sizeof(*e));
26*cb96143dSMichael Ellerman 
27*cb96143dSMichael Ellerman 	e->name = name;
28*cb96143dSMichael Ellerman 
29*cb96143dSMichael Ellerman 	e->attr.type = type;
30*cb96143dSMichael Ellerman 	e->attr.config = config;
31*cb96143dSMichael Ellerman 	e->attr.size = sizeof(e->attr);
32*cb96143dSMichael Ellerman 	/* This has to match the structure layout in the header */
33*cb96143dSMichael Ellerman 	e->attr.read_format = PERF_FORMAT_TOTAL_TIME_ENABLED | \
34*cb96143dSMichael Ellerman 				  PERF_FORMAT_TOTAL_TIME_RUNNING;
35*cb96143dSMichael Ellerman }
36*cb96143dSMichael Ellerman 
37*cb96143dSMichael Ellerman void event_init_named(struct event *e, u64 config, char *name)
38*cb96143dSMichael Ellerman {
39*cb96143dSMichael Ellerman 	event_init_opts(e, config, PERF_TYPE_RAW, name);
40*cb96143dSMichael Ellerman }
41*cb96143dSMichael Ellerman 
42*cb96143dSMichael Ellerman #define PERF_CURRENT_PID	0
43*cb96143dSMichael Ellerman #define PERF_NO_CPU		-1
44*cb96143dSMichael Ellerman #define PERF_NO_GROUP		-1
45*cb96143dSMichael Ellerman 
46*cb96143dSMichael Ellerman int event_open_with_options(struct event *e, pid_t pid, int cpu, int group_fd)
47*cb96143dSMichael Ellerman {
48*cb96143dSMichael Ellerman 	e->fd = perf_event_open(&e->attr, pid, cpu, group_fd, 0);
49*cb96143dSMichael Ellerman 	if (e->fd == -1) {
50*cb96143dSMichael Ellerman 		perror("perf_event_open");
51*cb96143dSMichael Ellerman 		return -1;
52*cb96143dSMichael Ellerman 	}
53*cb96143dSMichael Ellerman 
54*cb96143dSMichael Ellerman 	return 0;
55*cb96143dSMichael Ellerman }
56*cb96143dSMichael Ellerman 
57*cb96143dSMichael Ellerman int event_open_with_group(struct event *e, int group_fd)
58*cb96143dSMichael Ellerman {
59*cb96143dSMichael Ellerman 	return event_open_with_options(e, PERF_CURRENT_PID, PERF_NO_CPU, group_fd);
60*cb96143dSMichael Ellerman }
61*cb96143dSMichael Ellerman 
62*cb96143dSMichael Ellerman int event_open(struct event *e)
63*cb96143dSMichael Ellerman {
64*cb96143dSMichael Ellerman 	return event_open_with_options(e, PERF_CURRENT_PID, PERF_NO_CPU, PERF_NO_GROUP);
65*cb96143dSMichael Ellerman }
66*cb96143dSMichael Ellerman 
67*cb96143dSMichael Ellerman void event_close(struct event *e)
68*cb96143dSMichael Ellerman {
69*cb96143dSMichael Ellerman 	close(e->fd);
70*cb96143dSMichael Ellerman }
71*cb96143dSMichael Ellerman 
72*cb96143dSMichael Ellerman int event_reset(struct event *e)
73*cb96143dSMichael Ellerman {
74*cb96143dSMichael Ellerman 	return ioctl(e->fd, PERF_EVENT_IOC_RESET);
75*cb96143dSMichael Ellerman }
76*cb96143dSMichael Ellerman 
77*cb96143dSMichael Ellerman int event_read(struct event *e)
78*cb96143dSMichael Ellerman {
79*cb96143dSMichael Ellerman 	int rc;
80*cb96143dSMichael Ellerman 
81*cb96143dSMichael Ellerman 	rc = read(e->fd, &e->result, sizeof(e->result));
82*cb96143dSMichael Ellerman 	if (rc != sizeof(e->result)) {
83*cb96143dSMichael Ellerman 		fprintf(stderr, "read error on event %p!\n", e);
84*cb96143dSMichael Ellerman 		return -1;
85*cb96143dSMichael Ellerman 	}
86*cb96143dSMichael Ellerman 
87*cb96143dSMichael Ellerman 	return 0;
88*cb96143dSMichael Ellerman }
89*cb96143dSMichael Ellerman 
90*cb96143dSMichael Ellerman void event_report_justified(struct event *e, int name_width, int result_width)
91*cb96143dSMichael Ellerman {
92*cb96143dSMichael Ellerman 	printf("%*s: result %*llu ", name_width, e->name, result_width,
93*cb96143dSMichael Ellerman 	       e->result.value);
94*cb96143dSMichael Ellerman 
95*cb96143dSMichael Ellerman 	if (e->result.running == e->result.enabled)
96*cb96143dSMichael Ellerman 		printf("running/enabled %llu\n", e->result.running);
97*cb96143dSMichael Ellerman 	else
98*cb96143dSMichael Ellerman 		printf("running %llu enabled %llu\n", e->result.running,
99*cb96143dSMichael Ellerman 			e->result.enabled);
100*cb96143dSMichael Ellerman }
101*cb96143dSMichael Ellerman 
102*cb96143dSMichael Ellerman void event_report(struct event *e)
103*cb96143dSMichael Ellerman {
104*cb96143dSMichael Ellerman 	event_report_justified(e, 0, 0);
105*cb96143dSMichael Ellerman }
106