xref: /aosp_15_r20/external/igt-gpu-tools/tests/perf.c (revision d83cc019efdc2edc6c4b16e9034a3ceb8d35d77c)
1*d83cc019SAndroid Build Coastguard Worker /*
2*d83cc019SAndroid Build Coastguard Worker  * Copyright © 2016 Intel Corporation
3*d83cc019SAndroid Build Coastguard Worker  *
4*d83cc019SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
5*d83cc019SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
6*d83cc019SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
7*d83cc019SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*d83cc019SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
9*d83cc019SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
10*d83cc019SAndroid Build Coastguard Worker  *
11*d83cc019SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the next
12*d83cc019SAndroid Build Coastguard Worker  * paragraph) shall be included in all copies or substantial portions of the
13*d83cc019SAndroid Build Coastguard Worker  * Software.
14*d83cc019SAndroid Build Coastguard Worker  *
15*d83cc019SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*d83cc019SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*d83cc019SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18*d83cc019SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*d83cc019SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*d83cc019SAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*d83cc019SAndroid Build Coastguard Worker  * IN THE SOFTWARE.
22*d83cc019SAndroid Build Coastguard Worker  *
23*d83cc019SAndroid Build Coastguard Worker  */
24*d83cc019SAndroid Build Coastguard Worker 
25*d83cc019SAndroid Build Coastguard Worker #include <stdlib.h>
26*d83cc019SAndroid Build Coastguard Worker #include <stdio.h>
27*d83cc019SAndroid Build Coastguard Worker #include <string.h>
28*d83cc019SAndroid Build Coastguard Worker #include <fcntl.h>
29*d83cc019SAndroid Build Coastguard Worker #include <inttypes.h>
30*d83cc019SAndroid Build Coastguard Worker #include <errno.h>
31*d83cc019SAndroid Build Coastguard Worker #include <signal.h>
32*d83cc019SAndroid Build Coastguard Worker #include <sys/stat.h>
33*d83cc019SAndroid Build Coastguard Worker #include <sys/time.h>
34*d83cc019SAndroid Build Coastguard Worker #include <sys/times.h>
35*d83cc019SAndroid Build Coastguard Worker #include <sys/types.h>
36*d83cc019SAndroid Build Coastguard Worker #include <dirent.h>
37*d83cc019SAndroid Build Coastguard Worker #include <time.h>
38*d83cc019SAndroid Build Coastguard Worker #include <poll.h>
39*d83cc019SAndroid Build Coastguard Worker #include <math.h>
40*d83cc019SAndroid Build Coastguard Worker 
41*d83cc019SAndroid Build Coastguard Worker #include "igt.h"
42*d83cc019SAndroid Build Coastguard Worker #include "igt_sysfs.h"
43*d83cc019SAndroid Build Coastguard Worker #include "drm.h"
44*d83cc019SAndroid Build Coastguard Worker 
45*d83cc019SAndroid Build Coastguard Worker IGT_TEST_DESCRIPTION("Test the i915 perf metrics streaming interface");
46*d83cc019SAndroid Build Coastguard Worker 
47*d83cc019SAndroid Build Coastguard Worker #define GEN6_MI_REPORT_PERF_COUNT ((0x28 << 23) | (3 - 2))
48*d83cc019SAndroid Build Coastguard Worker #define GEN8_MI_REPORT_PERF_COUNT ((0x28 << 23) | (4 - 2))
49*d83cc019SAndroid Build Coastguard Worker 
50*d83cc019SAndroid Build Coastguard Worker #define OAREPORT_REASON_MASK           0x3f
51*d83cc019SAndroid Build Coastguard Worker #define OAREPORT_REASON_SHIFT          19
52*d83cc019SAndroid Build Coastguard Worker #define OAREPORT_REASON_TIMER          (1<<0)
53*d83cc019SAndroid Build Coastguard Worker #define OAREPORT_REASON_INTERNAL       (3<<1)
54*d83cc019SAndroid Build Coastguard Worker #define OAREPORT_REASON_CTX_SWITCH     (1<<3)
55*d83cc019SAndroid Build Coastguard Worker #define OAREPORT_REASON_GO             (1<<4)
56*d83cc019SAndroid Build Coastguard Worker #define OAREPORT_REASON_CLK_RATIO      (1<<5)
57*d83cc019SAndroid Build Coastguard Worker 
58*d83cc019SAndroid Build Coastguard Worker #define GFX_OP_PIPE_CONTROL     ((3 << 29) | (3 << 27) | (2 << 24))
59*d83cc019SAndroid Build Coastguard Worker #define PIPE_CONTROL_CS_STALL	   (1 << 20)
60*d83cc019SAndroid Build Coastguard Worker #define PIPE_CONTROL_GLOBAL_SNAPSHOT_COUNT_RESET	(1 << 19)
61*d83cc019SAndroid Build Coastguard Worker #define PIPE_CONTROL_TLB_INVALIDATE     (1 << 18)
62*d83cc019SAndroid Build Coastguard Worker #define PIPE_CONTROL_SYNC_GFDT	  (1 << 17)
63*d83cc019SAndroid Build Coastguard Worker #define PIPE_CONTROL_MEDIA_STATE_CLEAR  (1 << 16)
64*d83cc019SAndroid Build Coastguard Worker #define PIPE_CONTROL_NO_WRITE	   (0 << 14)
65*d83cc019SAndroid Build Coastguard Worker #define PIPE_CONTROL_WRITE_IMMEDIATE    (1 << 14)
66*d83cc019SAndroid Build Coastguard Worker #define PIPE_CONTROL_WRITE_DEPTH_COUNT  (2 << 14)
67*d83cc019SAndroid Build Coastguard Worker #define PIPE_CONTROL_WRITE_TIMESTAMP    (3 << 14)
68*d83cc019SAndroid Build Coastguard Worker #define PIPE_CONTROL_DEPTH_STALL	(1 << 13)
69*d83cc019SAndroid Build Coastguard Worker #define PIPE_CONTROL_RENDER_TARGET_FLUSH (1 << 12)
70*d83cc019SAndroid Build Coastguard Worker #define PIPE_CONTROL_INSTRUCTION_INVALIDATE (1 << 11)
71*d83cc019SAndroid Build Coastguard Worker #define PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE   (1 << 10) /* GM45+ only */
72*d83cc019SAndroid Build Coastguard Worker #define PIPE_CONTROL_ISP_DIS	    (1 << 9)
73*d83cc019SAndroid Build Coastguard Worker #define PIPE_CONTROL_INTERRUPT_ENABLE   (1 << 8)
74*d83cc019SAndroid Build Coastguard Worker #define PIPE_CONTROL_FLUSH_ENABLE       (1 << 7) /* Gen7+ only */
75*d83cc019SAndroid Build Coastguard Worker /* GT */
76*d83cc019SAndroid Build Coastguard Worker #define PIPE_CONTROL_DATA_CACHE_INVALIDATE      (1 << 5)
77*d83cc019SAndroid Build Coastguard Worker #define PIPE_CONTROL_VF_CACHE_INVALIDATE	(1 << 4)
78*d83cc019SAndroid Build Coastguard Worker #define PIPE_CONTROL_CONST_CACHE_INVALIDATE     (1 << 3)
79*d83cc019SAndroid Build Coastguard Worker #define PIPE_CONTROL_STATE_CACHE_INVALIDATE     (1 << 2)
80*d83cc019SAndroid Build Coastguard Worker #define PIPE_CONTROL_STALL_AT_SCOREBOARD	(1 << 1)
81*d83cc019SAndroid Build Coastguard Worker #define PIPE_CONTROL_DEPTH_CACHE_FLUSH	  (1 << 0)
82*d83cc019SAndroid Build Coastguard Worker #define PIPE_CONTROL_PPGTT_WRITE	(0 << 2)
83*d83cc019SAndroid Build Coastguard Worker #define PIPE_CONTROL_GLOBAL_GTT_WRITE   (1 << 2)
84*d83cc019SAndroid Build Coastguard Worker 
85*d83cc019SAndroid Build Coastguard Worker #define MAX_OA_BUF_SIZE (16 * 1024 * 1024)
86*d83cc019SAndroid Build Coastguard Worker 
87*d83cc019SAndroid Build Coastguard Worker struct accumulator {
88*d83cc019SAndroid Build Coastguard Worker #define MAX_RAW_OA_COUNTERS 62
89*d83cc019SAndroid Build Coastguard Worker 	enum drm_i915_oa_format format;
90*d83cc019SAndroid Build Coastguard Worker 
91*d83cc019SAndroid Build Coastguard Worker 	uint64_t deltas[MAX_RAW_OA_COUNTERS];
92*d83cc019SAndroid Build Coastguard Worker };
93*d83cc019SAndroid Build Coastguard Worker 
94*d83cc019SAndroid Build Coastguard Worker struct oa_format {
95*d83cc019SAndroid Build Coastguard Worker 	const char *name;
96*d83cc019SAndroid Build Coastguard Worker 	size_t size;
97*d83cc019SAndroid Build Coastguard Worker 	int a40_high_off; /* bytes */
98*d83cc019SAndroid Build Coastguard Worker 	int a40_low_off;
99*d83cc019SAndroid Build Coastguard Worker 	int n_a40;
100*d83cc019SAndroid Build Coastguard Worker 	int a_off;
101*d83cc019SAndroid Build Coastguard Worker 	int n_a;
102*d83cc019SAndroid Build Coastguard Worker 	int first_a;
103*d83cc019SAndroid Build Coastguard Worker 	int b_off;
104*d83cc019SAndroid Build Coastguard Worker 	int n_b;
105*d83cc019SAndroid Build Coastguard Worker 	int c_off;
106*d83cc019SAndroid Build Coastguard Worker 	int n_c;
107*d83cc019SAndroid Build Coastguard Worker };
108*d83cc019SAndroid Build Coastguard Worker 
109*d83cc019SAndroid Build Coastguard Worker static struct oa_format hsw_oa_formats[I915_OA_FORMAT_MAX] = {
110*d83cc019SAndroid Build Coastguard Worker 	[I915_OA_FORMAT_A13] = { /* HSW only */
111*d83cc019SAndroid Build Coastguard Worker 		"A13", .size = 64,
112*d83cc019SAndroid Build Coastguard Worker 		.a_off = 12, .n_a = 13, },
113*d83cc019SAndroid Build Coastguard Worker 	[I915_OA_FORMAT_A29] = { /* HSW only */
114*d83cc019SAndroid Build Coastguard Worker 		"A29", .size = 128,
115*d83cc019SAndroid Build Coastguard Worker 		.a_off = 12, .n_a = 29, },
116*d83cc019SAndroid Build Coastguard Worker 	[I915_OA_FORMAT_A13_B8_C8] = { /* HSW only */
117*d83cc019SAndroid Build Coastguard Worker 		"A13_B8_C8", .size = 128,
118*d83cc019SAndroid Build Coastguard Worker 		.a_off = 12, .n_a = 13,
119*d83cc019SAndroid Build Coastguard Worker 		.b_off = 64, .n_b = 8,
120*d83cc019SAndroid Build Coastguard Worker 		.c_off = 96, .n_c = 8, },
121*d83cc019SAndroid Build Coastguard Worker 	[I915_OA_FORMAT_A45_B8_C8] = { /* HSW only */
122*d83cc019SAndroid Build Coastguard Worker 		"A45_B8_C8", .size = 256,
123*d83cc019SAndroid Build Coastguard Worker 		.a_off = 12,  .n_a = 45,
124*d83cc019SAndroid Build Coastguard Worker 		.b_off = 192, .n_b = 8,
125*d83cc019SAndroid Build Coastguard Worker 		.c_off = 224, .n_c = 8, },
126*d83cc019SAndroid Build Coastguard Worker 	[I915_OA_FORMAT_B4_C8] = { /* HSW only */
127*d83cc019SAndroid Build Coastguard Worker 		"B4_C8", .size = 64,
128*d83cc019SAndroid Build Coastguard Worker 		.b_off = 16, .n_b = 4,
129*d83cc019SAndroid Build Coastguard Worker 		.c_off = 32, .n_c = 8, },
130*d83cc019SAndroid Build Coastguard Worker 	[I915_OA_FORMAT_B4_C8_A16] = { /* HSW only */
131*d83cc019SAndroid Build Coastguard Worker 		"B4_C8_A16", .size = 128,
132*d83cc019SAndroid Build Coastguard Worker 		.b_off = 16, .n_b = 4,
133*d83cc019SAndroid Build Coastguard Worker 		.c_off = 32, .n_c = 8,
134*d83cc019SAndroid Build Coastguard Worker 		.a_off = 60, .n_a = 16, .first_a = 29, },
135*d83cc019SAndroid Build Coastguard Worker 	[I915_OA_FORMAT_C4_B8] = { /* HSW+ (header differs from HSW-Gen8+) */
136*d83cc019SAndroid Build Coastguard Worker 		"C4_B8", .size = 64,
137*d83cc019SAndroid Build Coastguard Worker 		.c_off = 16, .n_c = 4,
138*d83cc019SAndroid Build Coastguard Worker 		.b_off = 28, .n_b = 8 },
139*d83cc019SAndroid Build Coastguard Worker };
140*d83cc019SAndroid Build Coastguard Worker 
141*d83cc019SAndroid Build Coastguard Worker static struct oa_format gen8_oa_formats[I915_OA_FORMAT_MAX] = {
142*d83cc019SAndroid Build Coastguard Worker 	[I915_OA_FORMAT_A12] = {
143*d83cc019SAndroid Build Coastguard Worker 		"A12", .size = 64,
144*d83cc019SAndroid Build Coastguard Worker 		.a_off = 12, .n_a = 12, .first_a = 7, },
145*d83cc019SAndroid Build Coastguard Worker 	[I915_OA_FORMAT_A12_B8_C8] = {
146*d83cc019SAndroid Build Coastguard Worker 		"A12_B8_C8", .size = 128,
147*d83cc019SAndroid Build Coastguard Worker 		.a_off = 12, .n_a = 12,
148*d83cc019SAndroid Build Coastguard Worker 		.b_off = 64, .n_b = 8,
149*d83cc019SAndroid Build Coastguard Worker 		.c_off = 96, .n_c = 8, .first_a = 7, },
150*d83cc019SAndroid Build Coastguard Worker 	[I915_OA_FORMAT_A32u40_A4u32_B8_C8] = {
151*d83cc019SAndroid Build Coastguard Worker 		"A32u40_A4u32_B8_C8", .size = 256,
152*d83cc019SAndroid Build Coastguard Worker 		.a40_high_off = 160, .a40_low_off = 16, .n_a40 = 32,
153*d83cc019SAndroid Build Coastguard Worker 		.a_off = 144, .n_a = 4, .first_a = 32,
154*d83cc019SAndroid Build Coastguard Worker 		.b_off = 192, .n_b = 8,
155*d83cc019SAndroid Build Coastguard Worker 		.c_off = 224, .n_c = 8, },
156*d83cc019SAndroid Build Coastguard Worker 	[I915_OA_FORMAT_C4_B8] = {
157*d83cc019SAndroid Build Coastguard Worker 		"C4_B8", .size = 64,
158*d83cc019SAndroid Build Coastguard Worker 		.c_off = 16, .n_c = 4,
159*d83cc019SAndroid Build Coastguard Worker 		.b_off = 32, .n_b = 8, },
160*d83cc019SAndroid Build Coastguard Worker };
161*d83cc019SAndroid Build Coastguard Worker 
162*d83cc019SAndroid Build Coastguard Worker static bool hsw_undefined_a_counters[45] = {
163*d83cc019SAndroid Build Coastguard Worker 	[4] = true,
164*d83cc019SAndroid Build Coastguard Worker 	[6] = true,
165*d83cc019SAndroid Build Coastguard Worker 	[9] = true,
166*d83cc019SAndroid Build Coastguard Worker 	[11] = true,
167*d83cc019SAndroid Build Coastguard Worker 	[14] = true,
168*d83cc019SAndroid Build Coastguard Worker 	[16] = true,
169*d83cc019SAndroid Build Coastguard Worker 	[19] = true,
170*d83cc019SAndroid Build Coastguard Worker 	[21] = true,
171*d83cc019SAndroid Build Coastguard Worker 	[24] = true,
172*d83cc019SAndroid Build Coastguard Worker 	[26] = true,
173*d83cc019SAndroid Build Coastguard Worker 	[29] = true,
174*d83cc019SAndroid Build Coastguard Worker 	[31] = true,
175*d83cc019SAndroid Build Coastguard Worker 	[34] = true,
176*d83cc019SAndroid Build Coastguard Worker 	[43] = true,
177*d83cc019SAndroid Build Coastguard Worker 	[44] = true,
178*d83cc019SAndroid Build Coastguard Worker };
179*d83cc019SAndroid Build Coastguard Worker 
180*d83cc019SAndroid Build Coastguard Worker /* No A counters currently reserved/undefined for gen8+ so far */
181*d83cc019SAndroid Build Coastguard Worker static bool gen8_undefined_a_counters[45];
182*d83cc019SAndroid Build Coastguard Worker 
183*d83cc019SAndroid Build Coastguard Worker static int drm_fd = -1;
184*d83cc019SAndroid Build Coastguard Worker static int sysfs = -1;
185*d83cc019SAndroid Build Coastguard Worker static int pm_fd = -1;
186*d83cc019SAndroid Build Coastguard Worker static int stream_fd = -1;
187*d83cc019SAndroid Build Coastguard Worker static uint32_t devid;
188*d83cc019SAndroid Build Coastguard Worker static int n_eus;
189*d83cc019SAndroid Build Coastguard Worker 
190*d83cc019SAndroid Build Coastguard Worker static uint64_t test_metric_set_id = UINT64_MAX;
191*d83cc019SAndroid Build Coastguard Worker 
192*d83cc019SAndroid Build Coastguard Worker static uint64_t timestamp_frequency = 12500000;
193*d83cc019SAndroid Build Coastguard Worker static uint64_t gt_max_freq_mhz = 0;
194*d83cc019SAndroid Build Coastguard Worker static enum drm_i915_oa_format test_oa_format;
195*d83cc019SAndroid Build Coastguard Worker static bool *undefined_a_counters;
196*d83cc019SAndroid Build Coastguard Worker static uint64_t oa_exp_1_millisec;
197*d83cc019SAndroid Build Coastguard Worker 
198*d83cc019SAndroid Build Coastguard Worker static igt_render_copyfunc_t render_copy = NULL;
199*d83cc019SAndroid Build Coastguard Worker static uint32_t (*read_report_ticks)(uint32_t *report,
200*d83cc019SAndroid Build Coastguard Worker 				     enum drm_i915_oa_format format);
201*d83cc019SAndroid Build Coastguard Worker static void (*sanity_check_reports)(uint32_t *oa_report0, uint32_t *oa_report1,
202*d83cc019SAndroid Build Coastguard Worker 				    enum drm_i915_oa_format format);
203*d83cc019SAndroid Build Coastguard Worker 
204*d83cc019SAndroid Build Coastguard Worker static struct oa_format
get_oa_format(enum drm_i915_oa_format format)205*d83cc019SAndroid Build Coastguard Worker get_oa_format(enum drm_i915_oa_format format)
206*d83cc019SAndroid Build Coastguard Worker {
207*d83cc019SAndroid Build Coastguard Worker 	if (IS_HASWELL(devid))
208*d83cc019SAndroid Build Coastguard Worker 		return hsw_oa_formats[format];
209*d83cc019SAndroid Build Coastguard Worker 	return gen8_oa_formats[format];
210*d83cc019SAndroid Build Coastguard Worker }
211*d83cc019SAndroid Build Coastguard Worker 
212*d83cc019SAndroid Build Coastguard Worker static void
__perf_close(int fd)213*d83cc019SAndroid Build Coastguard Worker __perf_close(int fd)
214*d83cc019SAndroid Build Coastguard Worker {
215*d83cc019SAndroid Build Coastguard Worker 	close(fd);
216*d83cc019SAndroid Build Coastguard Worker 	stream_fd = -1;
217*d83cc019SAndroid Build Coastguard Worker 
218*d83cc019SAndroid Build Coastguard Worker 	if (pm_fd >= 0) {
219*d83cc019SAndroid Build Coastguard Worker 		close(pm_fd);
220*d83cc019SAndroid Build Coastguard Worker 		pm_fd = -1;
221*d83cc019SAndroid Build Coastguard Worker 	}
222*d83cc019SAndroid Build Coastguard Worker }
223*d83cc019SAndroid Build Coastguard Worker 
224*d83cc019SAndroid Build Coastguard Worker static int
__perf_open(int fd,struct drm_i915_perf_open_param * param,bool prevent_pm)225*d83cc019SAndroid Build Coastguard Worker __perf_open(int fd, struct drm_i915_perf_open_param *param, bool prevent_pm)
226*d83cc019SAndroid Build Coastguard Worker {
227*d83cc019SAndroid Build Coastguard Worker 	int ret;
228*d83cc019SAndroid Build Coastguard Worker 	int32_t pm_value = 0;
229*d83cc019SAndroid Build Coastguard Worker 
230*d83cc019SAndroid Build Coastguard Worker 	if (stream_fd >= 0)
231*d83cc019SAndroid Build Coastguard Worker 		__perf_close(stream_fd);
232*d83cc019SAndroid Build Coastguard Worker 	if (pm_fd >= 0) {
233*d83cc019SAndroid Build Coastguard Worker 		close(pm_fd);
234*d83cc019SAndroid Build Coastguard Worker 		pm_fd = -1;
235*d83cc019SAndroid Build Coastguard Worker 	}
236*d83cc019SAndroid Build Coastguard Worker 
237*d83cc019SAndroid Build Coastguard Worker 	ret = igt_ioctl(fd, DRM_IOCTL_I915_PERF_OPEN, param);
238*d83cc019SAndroid Build Coastguard Worker 
239*d83cc019SAndroid Build Coastguard Worker 	igt_assert(ret >= 0);
240*d83cc019SAndroid Build Coastguard Worker 	errno = 0;
241*d83cc019SAndroid Build Coastguard Worker 
242*d83cc019SAndroid Build Coastguard Worker 	if (prevent_pm) {
243*d83cc019SAndroid Build Coastguard Worker 		pm_fd = open("/dev/cpu_dma_latency", O_RDWR);
244*d83cc019SAndroid Build Coastguard Worker 		igt_assert(pm_fd >= 0);
245*d83cc019SAndroid Build Coastguard Worker 
246*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(write(pm_fd, &pm_value, sizeof(pm_value)), sizeof(pm_value));
247*d83cc019SAndroid Build Coastguard Worker 	}
248*d83cc019SAndroid Build Coastguard Worker 
249*d83cc019SAndroid Build Coastguard Worker 	return ret;
250*d83cc019SAndroid Build Coastguard Worker }
251*d83cc019SAndroid Build Coastguard Worker 
252*d83cc019SAndroid Build Coastguard Worker static int
lookup_format(int i915_perf_fmt_id)253*d83cc019SAndroid Build Coastguard Worker lookup_format(int i915_perf_fmt_id)
254*d83cc019SAndroid Build Coastguard Worker {
255*d83cc019SAndroid Build Coastguard Worker 	igt_assert(i915_perf_fmt_id < I915_OA_FORMAT_MAX);
256*d83cc019SAndroid Build Coastguard Worker 	igt_assert(get_oa_format(i915_perf_fmt_id).name);
257*d83cc019SAndroid Build Coastguard Worker 
258*d83cc019SAndroid Build Coastguard Worker 	return i915_perf_fmt_id;
259*d83cc019SAndroid Build Coastguard Worker }
260*d83cc019SAndroid Build Coastguard Worker 
261*d83cc019SAndroid Build Coastguard Worker static uint64_t
read_u64_file(const char * path)262*d83cc019SAndroid Build Coastguard Worker read_u64_file(const char *path)
263*d83cc019SAndroid Build Coastguard Worker {
264*d83cc019SAndroid Build Coastguard Worker 	FILE *f;
265*d83cc019SAndroid Build Coastguard Worker 	uint64_t val;
266*d83cc019SAndroid Build Coastguard Worker 
267*d83cc019SAndroid Build Coastguard Worker 	f = fopen(path, "r");
268*d83cc019SAndroid Build Coastguard Worker 	igt_assert(f);
269*d83cc019SAndroid Build Coastguard Worker 
270*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(fscanf(f, "%"PRIu64, &val), 1);
271*d83cc019SAndroid Build Coastguard Worker 
272*d83cc019SAndroid Build Coastguard Worker 	fclose(f);
273*d83cc019SAndroid Build Coastguard Worker 
274*d83cc019SAndroid Build Coastguard Worker 	return val;
275*d83cc019SAndroid Build Coastguard Worker }
276*d83cc019SAndroid Build Coastguard Worker 
277*d83cc019SAndroid Build Coastguard Worker static void
write_u64_file(const char * path,uint64_t val)278*d83cc019SAndroid Build Coastguard Worker write_u64_file(const char *path, uint64_t val)
279*d83cc019SAndroid Build Coastguard Worker {
280*d83cc019SAndroid Build Coastguard Worker 	FILE *f;
281*d83cc019SAndroid Build Coastguard Worker 
282*d83cc019SAndroid Build Coastguard Worker 	f = fopen(path, "w");
283*d83cc019SAndroid Build Coastguard Worker 	igt_assert(f);
284*d83cc019SAndroid Build Coastguard Worker 
285*d83cc019SAndroid Build Coastguard Worker 	igt_assert(fprintf(f, "%"PRIu64, val) > 0);
286*d83cc019SAndroid Build Coastguard Worker 
287*d83cc019SAndroid Build Coastguard Worker 	fclose(f);
288*d83cc019SAndroid Build Coastguard Worker }
289*d83cc019SAndroid Build Coastguard Worker 
290*d83cc019SAndroid Build Coastguard Worker static bool
try_sysfs_read_u64(const char * path,uint64_t * val)291*d83cc019SAndroid Build Coastguard Worker try_sysfs_read_u64(const char *path, uint64_t *val)
292*d83cc019SAndroid Build Coastguard Worker {
293*d83cc019SAndroid Build Coastguard Worker 	return igt_sysfs_scanf(sysfs, path, "%"PRIu64, val) == 1;
294*d83cc019SAndroid Build Coastguard Worker }
295*d83cc019SAndroid Build Coastguard Worker 
296*d83cc019SAndroid Build Coastguard Worker static unsigned long
sysfs_read(const char * path)297*d83cc019SAndroid Build Coastguard Worker sysfs_read(const char *path)
298*d83cc019SAndroid Build Coastguard Worker {
299*d83cc019SAndroid Build Coastguard Worker 	unsigned long value;
300*d83cc019SAndroid Build Coastguard Worker 
301*d83cc019SAndroid Build Coastguard Worker 	igt_assert(igt_sysfs_scanf(sysfs, path, "%lu", &value) == 1);
302*d83cc019SAndroid Build Coastguard Worker 
303*d83cc019SAndroid Build Coastguard Worker 	return value;
304*d83cc019SAndroid Build Coastguard Worker }
305*d83cc019SAndroid Build Coastguard Worker 
306*d83cc019SAndroid Build Coastguard Worker /* XXX: For Haswell this utility is only applicable to the render basic
307*d83cc019SAndroid Build Coastguard Worker  * metric set.
308*d83cc019SAndroid Build Coastguard Worker  *
309*d83cc019SAndroid Build Coastguard Worker  * C2 corresponds to a clock counter for the Haswell render basic metric set
310*d83cc019SAndroid Build Coastguard Worker  * but it's not included in all of the formats.
311*d83cc019SAndroid Build Coastguard Worker  */
312*d83cc019SAndroid Build Coastguard Worker static uint32_t
hsw_read_report_ticks(uint32_t * report,enum drm_i915_oa_format format)313*d83cc019SAndroid Build Coastguard Worker hsw_read_report_ticks(uint32_t *report, enum drm_i915_oa_format format)
314*d83cc019SAndroid Build Coastguard Worker {
315*d83cc019SAndroid Build Coastguard Worker 	uint32_t *c = (uint32_t *)(((uint8_t *)report) + get_oa_format(format).c_off);
316*d83cc019SAndroid Build Coastguard Worker 
317*d83cc019SAndroid Build Coastguard Worker 	igt_assert_neq(get_oa_format(format).n_c, 0);
318*d83cc019SAndroid Build Coastguard Worker 
319*d83cc019SAndroid Build Coastguard Worker 	return c[2];
320*d83cc019SAndroid Build Coastguard Worker }
321*d83cc019SAndroid Build Coastguard Worker 
322*d83cc019SAndroid Build Coastguard Worker static uint32_t
gen8_read_report_ticks(uint32_t * report,enum drm_i915_oa_format format)323*d83cc019SAndroid Build Coastguard Worker gen8_read_report_ticks(uint32_t *report, enum drm_i915_oa_format format)
324*d83cc019SAndroid Build Coastguard Worker {
325*d83cc019SAndroid Build Coastguard Worker 	return report[3];
326*d83cc019SAndroid Build Coastguard Worker }
327*d83cc019SAndroid Build Coastguard Worker 
328*d83cc019SAndroid Build Coastguard Worker static void
gen8_read_report_clock_ratios(uint32_t * report,uint32_t * slice_freq_mhz,uint32_t * unslice_freq_mhz)329*d83cc019SAndroid Build Coastguard Worker gen8_read_report_clock_ratios(uint32_t *report,
330*d83cc019SAndroid Build Coastguard Worker 			      uint32_t *slice_freq_mhz,
331*d83cc019SAndroid Build Coastguard Worker 			      uint32_t *unslice_freq_mhz)
332*d83cc019SAndroid Build Coastguard Worker {
333*d83cc019SAndroid Build Coastguard Worker 	uint32_t unslice_freq = report[0] & 0x1ff;
334*d83cc019SAndroid Build Coastguard Worker 	uint32_t slice_freq_low = (report[0] >> 25) & 0x7f;
335*d83cc019SAndroid Build Coastguard Worker 	uint32_t slice_freq_high = (report[0] >> 9) & 0x3;
336*d83cc019SAndroid Build Coastguard Worker 	uint32_t slice_freq = slice_freq_low | (slice_freq_high << 7);
337*d83cc019SAndroid Build Coastguard Worker 
338*d83cc019SAndroid Build Coastguard Worker 	*slice_freq_mhz = (slice_freq * 16666) / 1000;
339*d83cc019SAndroid Build Coastguard Worker 	*unslice_freq_mhz = (unslice_freq * 16666) / 1000;
340*d83cc019SAndroid Build Coastguard Worker }
341*d83cc019SAndroid Build Coastguard Worker 
342*d83cc019SAndroid Build Coastguard Worker static const char *
gen8_read_report_reason(const uint32_t * report)343*d83cc019SAndroid Build Coastguard Worker gen8_read_report_reason(const uint32_t *report)
344*d83cc019SAndroid Build Coastguard Worker {
345*d83cc019SAndroid Build Coastguard Worker 	uint32_t reason = ((report[0] >> OAREPORT_REASON_SHIFT) &
346*d83cc019SAndroid Build Coastguard Worker 			   OAREPORT_REASON_MASK);
347*d83cc019SAndroid Build Coastguard Worker 
348*d83cc019SAndroid Build Coastguard Worker 	if (reason & (1<<0))
349*d83cc019SAndroid Build Coastguard Worker 		return "timer";
350*d83cc019SAndroid Build Coastguard Worker 	else if (reason & (1<<1))
351*d83cc019SAndroid Build Coastguard Worker 	      return "internal trigger 1";
352*d83cc019SAndroid Build Coastguard Worker 	else if (reason & (1<<2))
353*d83cc019SAndroid Build Coastguard Worker 	      return "internal trigger 2";
354*d83cc019SAndroid Build Coastguard Worker 	else if (reason & (1<<3))
355*d83cc019SAndroid Build Coastguard Worker 	      return "context switch";
356*d83cc019SAndroid Build Coastguard Worker 	else if (reason & (1<<4))
357*d83cc019SAndroid Build Coastguard Worker 	      return "GO 1->0 transition (enter RC6)";
358*d83cc019SAndroid Build Coastguard Worker 	else if (reason & (1<<5))
359*d83cc019SAndroid Build Coastguard Worker 		return "[un]slice clock ratio change";
360*d83cc019SAndroid Build Coastguard Worker 	else
361*d83cc019SAndroid Build Coastguard Worker 		return "unknown";
362*d83cc019SAndroid Build Coastguard Worker }
363*d83cc019SAndroid Build Coastguard Worker 
364*d83cc019SAndroid Build Coastguard Worker static uint64_t
timebase_scale(uint32_t u32_delta)365*d83cc019SAndroid Build Coastguard Worker timebase_scale(uint32_t u32_delta)
366*d83cc019SAndroid Build Coastguard Worker {
367*d83cc019SAndroid Build Coastguard Worker 	return ((uint64_t)u32_delta * NSEC_PER_SEC) / timestamp_frequency;
368*d83cc019SAndroid Build Coastguard Worker }
369*d83cc019SAndroid Build Coastguard Worker 
370*d83cc019SAndroid Build Coastguard Worker /* Returns: the largest OA exponent that will still result in a sampling period
371*d83cc019SAndroid Build Coastguard Worker  * less than or equal to the given @period.
372*d83cc019SAndroid Build Coastguard Worker  */
373*d83cc019SAndroid Build Coastguard Worker static int
max_oa_exponent_for_period_lte(uint64_t period)374*d83cc019SAndroid Build Coastguard Worker max_oa_exponent_for_period_lte(uint64_t period)
375*d83cc019SAndroid Build Coastguard Worker {
376*d83cc019SAndroid Build Coastguard Worker 	/* NB: timebase_scale() takes a uint32_t and an exponent of 30
377*d83cc019SAndroid Build Coastguard Worker 	 * would already represent a period of ~3 minutes so there's
378*d83cc019SAndroid Build Coastguard Worker 	 * really no need to consider higher exponents.
379*d83cc019SAndroid Build Coastguard Worker 	 */
380*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; i < 30; i++) {
381*d83cc019SAndroid Build Coastguard Worker 		uint64_t oa_period = timebase_scale(2 << i);
382*d83cc019SAndroid Build Coastguard Worker 
383*d83cc019SAndroid Build Coastguard Worker 		if (oa_period > period)
384*d83cc019SAndroid Build Coastguard Worker 			return max(0, i - 1);
385*d83cc019SAndroid Build Coastguard Worker 	}
386*d83cc019SAndroid Build Coastguard Worker 
387*d83cc019SAndroid Build Coastguard Worker 	igt_assert(!"reached");
388*d83cc019SAndroid Build Coastguard Worker 	return -1;
389*d83cc019SAndroid Build Coastguard Worker }
390*d83cc019SAndroid Build Coastguard Worker 
391*d83cc019SAndroid Build Coastguard Worker /* Return: the largest OA exponent that will still result in a sampling
392*d83cc019SAndroid Build Coastguard Worker  * frequency greater than the given @frequency.
393*d83cc019SAndroid Build Coastguard Worker  */
394*d83cc019SAndroid Build Coastguard Worker static int
max_oa_exponent_for_freq_gt(uint64_t frequency)395*d83cc019SAndroid Build Coastguard Worker max_oa_exponent_for_freq_gt(uint64_t frequency)
396*d83cc019SAndroid Build Coastguard Worker {
397*d83cc019SAndroid Build Coastguard Worker 	uint64_t period = NSEC_PER_SEC / frequency;
398*d83cc019SAndroid Build Coastguard Worker 
399*d83cc019SAndroid Build Coastguard Worker 	igt_assert_neq(period, 0);
400*d83cc019SAndroid Build Coastguard Worker 
401*d83cc019SAndroid Build Coastguard Worker 	return max_oa_exponent_for_period_lte(period - 1);
402*d83cc019SAndroid Build Coastguard Worker }
403*d83cc019SAndroid Build Coastguard Worker 
404*d83cc019SAndroid Build Coastguard Worker static uint64_t
oa_exponent_to_ns(int exponent)405*d83cc019SAndroid Build Coastguard Worker oa_exponent_to_ns(int exponent)
406*d83cc019SAndroid Build Coastguard Worker {
407*d83cc019SAndroid Build Coastguard Worker        return 1000000000ULL * (2ULL << exponent) / timestamp_frequency;
408*d83cc019SAndroid Build Coastguard Worker }
409*d83cc019SAndroid Build Coastguard Worker 
410*d83cc019SAndroid Build Coastguard Worker static bool
oa_report_is_periodic(uint32_t oa_exponent,const uint32_t * report)411*d83cc019SAndroid Build Coastguard Worker oa_report_is_periodic(uint32_t oa_exponent, const uint32_t *report)
412*d83cc019SAndroid Build Coastguard Worker {
413*d83cc019SAndroid Build Coastguard Worker 	if (IS_HASWELL(devid)) {
414*d83cc019SAndroid Build Coastguard Worker 		/* For Haswell we don't have a documented report reason field
415*d83cc019SAndroid Build Coastguard Worker 		 * (though empirically report[0] bit 10 does seem to correlate
416*d83cc019SAndroid Build Coastguard Worker 		 * with a timer trigger reason) so we instead infer which
417*d83cc019SAndroid Build Coastguard Worker 		 * reports are timer triggered by checking if the least
418*d83cc019SAndroid Build Coastguard Worker 		 * significant bits are zero and the exponent bit is set.
419*d83cc019SAndroid Build Coastguard Worker 		 */
420*d83cc019SAndroid Build Coastguard Worker 		uint32_t oa_exponent_mask = (1 << (oa_exponent + 1)) - 1;
421*d83cc019SAndroid Build Coastguard Worker 
422*d83cc019SAndroid Build Coastguard Worker 		if ((report[1] & oa_exponent_mask) == (1 << oa_exponent))
423*d83cc019SAndroid Build Coastguard Worker 			return true;
424*d83cc019SAndroid Build Coastguard Worker 	} else {
425*d83cc019SAndroid Build Coastguard Worker 		if ((report[0] >> OAREPORT_REASON_SHIFT) &
426*d83cc019SAndroid Build Coastguard Worker 		    OAREPORT_REASON_TIMER)
427*d83cc019SAndroid Build Coastguard Worker 			return true;
428*d83cc019SAndroid Build Coastguard Worker 	}
429*d83cc019SAndroid Build Coastguard Worker 
430*d83cc019SAndroid Build Coastguard Worker 	return false;
431*d83cc019SAndroid Build Coastguard Worker }
432*d83cc019SAndroid Build Coastguard Worker 
433*d83cc019SAndroid Build Coastguard Worker static bool
oa_report_ctx_is_valid(uint32_t * report)434*d83cc019SAndroid Build Coastguard Worker oa_report_ctx_is_valid(uint32_t *report)
435*d83cc019SAndroid Build Coastguard Worker {
436*d83cc019SAndroid Build Coastguard Worker 	if (IS_HASWELL(devid)) {
437*d83cc019SAndroid Build Coastguard Worker 		return false; /* TODO */
438*d83cc019SAndroid Build Coastguard Worker 	} else if (IS_GEN8(devid)) {
439*d83cc019SAndroid Build Coastguard Worker 		return report[0] & (1ul << 25);
440*d83cc019SAndroid Build Coastguard Worker 	} else if (AT_LEAST_GEN(devid, 9)) {
441*d83cc019SAndroid Build Coastguard Worker 		return report[0] & (1ul << 16);
442*d83cc019SAndroid Build Coastguard Worker 	}
443*d83cc019SAndroid Build Coastguard Worker 
444*d83cc019SAndroid Build Coastguard Worker 	igt_assert(!"Please update this function for newer Gen");
445*d83cc019SAndroid Build Coastguard Worker }
446*d83cc019SAndroid Build Coastguard Worker 
447*d83cc019SAndroid Build Coastguard Worker static uint32_t
oa_report_get_ctx_id(uint32_t * report)448*d83cc019SAndroid Build Coastguard Worker oa_report_get_ctx_id(uint32_t *report)
449*d83cc019SAndroid Build Coastguard Worker {
450*d83cc019SAndroid Build Coastguard Worker 	if (!oa_report_ctx_is_valid(report))
451*d83cc019SAndroid Build Coastguard Worker 		return 0xffffffff;
452*d83cc019SAndroid Build Coastguard Worker 	return report[2];
453*d83cc019SAndroid Build Coastguard Worker }
454*d83cc019SAndroid Build Coastguard Worker 
455*d83cc019SAndroid Build Coastguard Worker static void
scratch_buf_memset(drm_intel_bo * bo,int width,int height,uint32_t color)456*d83cc019SAndroid Build Coastguard Worker scratch_buf_memset(drm_intel_bo *bo, int width, int height, uint32_t color)
457*d83cc019SAndroid Build Coastguard Worker {
458*d83cc019SAndroid Build Coastguard Worker 	int ret;
459*d83cc019SAndroid Build Coastguard Worker 
460*d83cc019SAndroid Build Coastguard Worker 	ret = drm_intel_bo_map(bo, true /* writable */);
461*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(ret, 0);
462*d83cc019SAndroid Build Coastguard Worker 
463*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; i < width * height; i++)
464*d83cc019SAndroid Build Coastguard Worker 		((uint32_t *)bo->virtual)[i] = color;
465*d83cc019SAndroid Build Coastguard Worker 
466*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bo_unmap(bo);
467*d83cc019SAndroid Build Coastguard Worker }
468*d83cc019SAndroid Build Coastguard Worker 
469*d83cc019SAndroid Build Coastguard Worker static void
scratch_buf_init(drm_intel_bufmgr * bufmgr,struct igt_buf * buf,int width,int height,uint32_t color)470*d83cc019SAndroid Build Coastguard Worker scratch_buf_init(drm_intel_bufmgr *bufmgr,
471*d83cc019SAndroid Build Coastguard Worker 		 struct igt_buf *buf,
472*d83cc019SAndroid Build Coastguard Worker 		 int width, int height,
473*d83cc019SAndroid Build Coastguard Worker 		 uint32_t color)
474*d83cc019SAndroid Build Coastguard Worker {
475*d83cc019SAndroid Build Coastguard Worker 	size_t stride = width * 4;
476*d83cc019SAndroid Build Coastguard Worker 	size_t size = stride * height;
477*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bo *bo = drm_intel_bo_alloc(bufmgr, "", size, 4096);
478*d83cc019SAndroid Build Coastguard Worker 
479*d83cc019SAndroid Build Coastguard Worker 	scratch_buf_memset(bo, width, height, color);
480*d83cc019SAndroid Build Coastguard Worker 
481*d83cc019SAndroid Build Coastguard Worker 	memset(buf, 0, sizeof(*buf));
482*d83cc019SAndroid Build Coastguard Worker 
483*d83cc019SAndroid Build Coastguard Worker 	buf->bo = bo;
484*d83cc019SAndroid Build Coastguard Worker 	buf->stride = stride;
485*d83cc019SAndroid Build Coastguard Worker 	buf->tiling = I915_TILING_NONE;
486*d83cc019SAndroid Build Coastguard Worker 	buf->size = size;
487*d83cc019SAndroid Build Coastguard Worker 	buf->bpp = 32;
488*d83cc019SAndroid Build Coastguard Worker }
489*d83cc019SAndroid Build Coastguard Worker 
490*d83cc019SAndroid Build Coastguard Worker static void
emit_report_perf_count(struct intel_batchbuffer * batch,drm_intel_bo * dst_bo,int dst_offset,uint32_t report_id)491*d83cc019SAndroid Build Coastguard Worker emit_report_perf_count(struct intel_batchbuffer *batch,
492*d83cc019SAndroid Build Coastguard Worker 		       drm_intel_bo *dst_bo,
493*d83cc019SAndroid Build Coastguard Worker 		       int dst_offset,
494*d83cc019SAndroid Build Coastguard Worker 		       uint32_t report_id)
495*d83cc019SAndroid Build Coastguard Worker {
496*d83cc019SAndroid Build Coastguard Worker 	if (IS_HASWELL(devid)) {
497*d83cc019SAndroid Build Coastguard Worker 		BEGIN_BATCH(3, 1);
498*d83cc019SAndroid Build Coastguard Worker 		OUT_BATCH(GEN6_MI_REPORT_PERF_COUNT);
499*d83cc019SAndroid Build Coastguard Worker 		OUT_RELOC(dst_bo, I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
500*d83cc019SAndroid Build Coastguard Worker 			  dst_offset);
501*d83cc019SAndroid Build Coastguard Worker 		OUT_BATCH(report_id);
502*d83cc019SAndroid Build Coastguard Worker 		ADVANCE_BATCH();
503*d83cc019SAndroid Build Coastguard Worker 	} else {
504*d83cc019SAndroid Build Coastguard Worker 		/* XXX: NB: n dwords arg is actually magic since it internally
505*d83cc019SAndroid Build Coastguard Worker 		 * automatically accounts for larger addresses on gen >= 8...
506*d83cc019SAndroid Build Coastguard Worker 		 */
507*d83cc019SAndroid Build Coastguard Worker 		BEGIN_BATCH(3, 1);
508*d83cc019SAndroid Build Coastguard Worker 		OUT_BATCH(GEN8_MI_REPORT_PERF_COUNT);
509*d83cc019SAndroid Build Coastguard Worker 		OUT_RELOC(dst_bo, I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
510*d83cc019SAndroid Build Coastguard Worker 			  dst_offset);
511*d83cc019SAndroid Build Coastguard Worker 		OUT_BATCH(report_id);
512*d83cc019SAndroid Build Coastguard Worker 		ADVANCE_BATCH();
513*d83cc019SAndroid Build Coastguard Worker 	}
514*d83cc019SAndroid Build Coastguard Worker }
515*d83cc019SAndroid Build Coastguard Worker 
516*d83cc019SAndroid Build Coastguard Worker static void
hsw_sanity_check_render_basic_reports(uint32_t * oa_report0,uint32_t * oa_report1,enum drm_i915_oa_format fmt)517*d83cc019SAndroid Build Coastguard Worker hsw_sanity_check_render_basic_reports(uint32_t *oa_report0, uint32_t *oa_report1,
518*d83cc019SAndroid Build Coastguard Worker 				      enum drm_i915_oa_format fmt)
519*d83cc019SAndroid Build Coastguard Worker {
520*d83cc019SAndroid Build Coastguard Worker 	uint32_t time_delta = timebase_scale(oa_report1[1] - oa_report0[1]);
521*d83cc019SAndroid Build Coastguard Worker 	uint32_t clock_delta;
522*d83cc019SAndroid Build Coastguard Worker 	uint32_t max_delta;
523*d83cc019SAndroid Build Coastguard Worker 	struct oa_format format = get_oa_format(fmt);
524*d83cc019SAndroid Build Coastguard Worker 
525*d83cc019SAndroid Build Coastguard Worker 	igt_assert_neq(time_delta, 0);
526*d83cc019SAndroid Build Coastguard Worker 
527*d83cc019SAndroid Build Coastguard Worker 	/* As a special case we have to consider that on Haswell we
528*d83cc019SAndroid Build Coastguard Worker 	 * can't explicitly derive a clock delta for all OA report
529*d83cc019SAndroid Build Coastguard Worker 	 * formats...
530*d83cc019SAndroid Build Coastguard Worker 	 */
531*d83cc019SAndroid Build Coastguard Worker 	if (format.n_c == 0) {
532*d83cc019SAndroid Build Coastguard Worker 		/* Assume running at max freq for sake of
533*d83cc019SAndroid Build Coastguard Worker 		 * below sanity check on counters... */
534*d83cc019SAndroid Build Coastguard Worker 		clock_delta = (gt_max_freq_mhz *
535*d83cc019SAndroid Build Coastguard Worker 			       (uint64_t)time_delta) / 1000;
536*d83cc019SAndroid Build Coastguard Worker 	} else {
537*d83cc019SAndroid Build Coastguard Worker 		uint32_t ticks0 = read_report_ticks(oa_report0, fmt);
538*d83cc019SAndroid Build Coastguard Worker 		uint32_t ticks1 = read_report_ticks(oa_report1, fmt);
539*d83cc019SAndroid Build Coastguard Worker 		uint64_t freq;
540*d83cc019SAndroid Build Coastguard Worker 
541*d83cc019SAndroid Build Coastguard Worker 		clock_delta = ticks1 - ticks0;
542*d83cc019SAndroid Build Coastguard Worker 
543*d83cc019SAndroid Build Coastguard Worker 		igt_assert_neq(clock_delta, 0);
544*d83cc019SAndroid Build Coastguard Worker 
545*d83cc019SAndroid Build Coastguard Worker 		freq = ((uint64_t)clock_delta * 1000) / time_delta;
546*d83cc019SAndroid Build Coastguard Worker 		igt_debug("freq = %"PRIu64"\n", freq);
547*d83cc019SAndroid Build Coastguard Worker 
548*d83cc019SAndroid Build Coastguard Worker 		igt_assert(freq <= gt_max_freq_mhz);
549*d83cc019SAndroid Build Coastguard Worker 	}
550*d83cc019SAndroid Build Coastguard Worker 
551*d83cc019SAndroid Build Coastguard Worker 	igt_debug("clock delta = %"PRIu32"\n", clock_delta);
552*d83cc019SAndroid Build Coastguard Worker 
553*d83cc019SAndroid Build Coastguard Worker 	/* The maximum rate for any HSW counter =
554*d83cc019SAndroid Build Coastguard Worker 	 *   clock_delta * N EUs
555*d83cc019SAndroid Build Coastguard Worker 	 *
556*d83cc019SAndroid Build Coastguard Worker 	 * Sanity check that no counters exceed this delta.
557*d83cc019SAndroid Build Coastguard Worker 	 */
558*d83cc019SAndroid Build Coastguard Worker 	max_delta = clock_delta * n_eus;
559*d83cc019SAndroid Build Coastguard Worker 
560*d83cc019SAndroid Build Coastguard Worker 	/* 40bit A counters were only introduced for Gen8+ */
561*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(format.n_a40, 0);
562*d83cc019SAndroid Build Coastguard Worker 
563*d83cc019SAndroid Build Coastguard Worker 	for (int j = 0; j < format.n_a; j++) {
564*d83cc019SAndroid Build Coastguard Worker 		uint32_t *a0 = (uint32_t *)(((uint8_t *)oa_report0) +
565*d83cc019SAndroid Build Coastguard Worker 					    format.a_off);
566*d83cc019SAndroid Build Coastguard Worker 		uint32_t *a1 = (uint32_t *)(((uint8_t *)oa_report1) +
567*d83cc019SAndroid Build Coastguard Worker 					    format.a_off);
568*d83cc019SAndroid Build Coastguard Worker 		int a_id = format.first_a + j;
569*d83cc019SAndroid Build Coastguard Worker 		uint32_t delta = a1[j] - a0[j];
570*d83cc019SAndroid Build Coastguard Worker 
571*d83cc019SAndroid Build Coastguard Worker 		if (undefined_a_counters[a_id])
572*d83cc019SAndroid Build Coastguard Worker 			continue;
573*d83cc019SAndroid Build Coastguard Worker 
574*d83cc019SAndroid Build Coastguard Worker 		igt_debug("A%d: delta = %"PRIu32"\n", a_id, delta);
575*d83cc019SAndroid Build Coastguard Worker 		igt_assert(delta <= max_delta);
576*d83cc019SAndroid Build Coastguard Worker 	}
577*d83cc019SAndroid Build Coastguard Worker 
578*d83cc019SAndroid Build Coastguard Worker 	for (int j = 0; j < format.n_b; j++) {
579*d83cc019SAndroid Build Coastguard Worker 		uint32_t *b0 = (uint32_t *)(((uint8_t *)oa_report0) +
580*d83cc019SAndroid Build Coastguard Worker 					    format.b_off);
581*d83cc019SAndroid Build Coastguard Worker 		uint32_t *b1 = (uint32_t *)(((uint8_t *)oa_report1) +
582*d83cc019SAndroid Build Coastguard Worker 					    format.b_off);
583*d83cc019SAndroid Build Coastguard Worker 		uint32_t delta = b1[j] - b0[j];
584*d83cc019SAndroid Build Coastguard Worker 
585*d83cc019SAndroid Build Coastguard Worker 		igt_debug("B%d: delta = %"PRIu32"\n", j, delta);
586*d83cc019SAndroid Build Coastguard Worker 		igt_assert(delta <= max_delta);
587*d83cc019SAndroid Build Coastguard Worker 	}
588*d83cc019SAndroid Build Coastguard Worker 
589*d83cc019SAndroid Build Coastguard Worker 	for (int j = 0; j < format.n_c; j++) {
590*d83cc019SAndroid Build Coastguard Worker 		uint32_t *c0 = (uint32_t *)(((uint8_t *)oa_report0) +
591*d83cc019SAndroid Build Coastguard Worker 					    format.c_off);
592*d83cc019SAndroid Build Coastguard Worker 		uint32_t *c1 = (uint32_t *)(((uint8_t *)oa_report1) +
593*d83cc019SAndroid Build Coastguard Worker 					    format.c_off);
594*d83cc019SAndroid Build Coastguard Worker 		uint32_t delta = c1[j] - c0[j];
595*d83cc019SAndroid Build Coastguard Worker 
596*d83cc019SAndroid Build Coastguard Worker 		igt_debug("C%d: delta = %"PRIu32"\n", j, delta);
597*d83cc019SAndroid Build Coastguard Worker 		igt_assert(delta <= max_delta);
598*d83cc019SAndroid Build Coastguard Worker 	}
599*d83cc019SAndroid Build Coastguard Worker }
600*d83cc019SAndroid Build Coastguard Worker 
601*d83cc019SAndroid Build Coastguard Worker static uint64_t
gen8_read_40bit_a_counter(uint32_t * report,enum drm_i915_oa_format fmt,int a_id)602*d83cc019SAndroid Build Coastguard Worker gen8_read_40bit_a_counter(uint32_t *report, enum drm_i915_oa_format fmt, int a_id)
603*d83cc019SAndroid Build Coastguard Worker {
604*d83cc019SAndroid Build Coastguard Worker 	struct oa_format format = get_oa_format(fmt);
605*d83cc019SAndroid Build Coastguard Worker 	uint8_t *a40_high = (((uint8_t *)report) + format.a40_high_off);
606*d83cc019SAndroid Build Coastguard Worker 	uint32_t *a40_low = (uint32_t *)(((uint8_t *)report) +
607*d83cc019SAndroid Build Coastguard Worker 					 format.a40_low_off);
608*d83cc019SAndroid Build Coastguard Worker 	uint64_t high = (uint64_t)(a40_high[a_id]) << 32;
609*d83cc019SAndroid Build Coastguard Worker 
610*d83cc019SAndroid Build Coastguard Worker 	return a40_low[a_id] | high;
611*d83cc019SAndroid Build Coastguard Worker }
612*d83cc019SAndroid Build Coastguard Worker 
613*d83cc019SAndroid Build Coastguard Worker static uint64_t
gen8_40bit_a_delta(uint64_t value0,uint64_t value1)614*d83cc019SAndroid Build Coastguard Worker gen8_40bit_a_delta(uint64_t value0, uint64_t value1)
615*d83cc019SAndroid Build Coastguard Worker {
616*d83cc019SAndroid Build Coastguard Worker 	if (value0 > value1)
617*d83cc019SAndroid Build Coastguard Worker 		return (1ULL << 40) + value1 - value0;
618*d83cc019SAndroid Build Coastguard Worker 	else
619*d83cc019SAndroid Build Coastguard Worker 		return value1 - value0;
620*d83cc019SAndroid Build Coastguard Worker }
621*d83cc019SAndroid Build Coastguard Worker 
622*d83cc019SAndroid Build Coastguard Worker static void
accumulate_uint32(size_t offset,uint32_t * report0,uint32_t * report1,uint64_t * delta)623*d83cc019SAndroid Build Coastguard Worker accumulate_uint32(size_t offset,
624*d83cc019SAndroid Build Coastguard Worker 		  uint32_t *report0,
625*d83cc019SAndroid Build Coastguard Worker                   uint32_t *report1,
626*d83cc019SAndroid Build Coastguard Worker                   uint64_t *delta)
627*d83cc019SAndroid Build Coastguard Worker {
628*d83cc019SAndroid Build Coastguard Worker 	uint32_t value0 = *(uint32_t *)(((uint8_t *)report0) + offset);
629*d83cc019SAndroid Build Coastguard Worker 	uint32_t value1 = *(uint32_t *)(((uint8_t *)report1) + offset);
630*d83cc019SAndroid Build Coastguard Worker 
631*d83cc019SAndroid Build Coastguard Worker 	*delta += (uint32_t)(value1 - value0);
632*d83cc019SAndroid Build Coastguard Worker }
633*d83cc019SAndroid Build Coastguard Worker 
634*d83cc019SAndroid Build Coastguard Worker static void
accumulate_uint40(int a_index,uint32_t * report0,uint32_t * report1,enum drm_i915_oa_format format,uint64_t * delta)635*d83cc019SAndroid Build Coastguard Worker accumulate_uint40(int a_index,
636*d83cc019SAndroid Build Coastguard Worker                   uint32_t *report0,
637*d83cc019SAndroid Build Coastguard Worker                   uint32_t *report1,
638*d83cc019SAndroid Build Coastguard Worker 		  enum drm_i915_oa_format format,
639*d83cc019SAndroid Build Coastguard Worker                   uint64_t *delta)
640*d83cc019SAndroid Build Coastguard Worker {
641*d83cc019SAndroid Build Coastguard Worker 	uint64_t value0 = gen8_read_40bit_a_counter(report0, format, a_index),
642*d83cc019SAndroid Build Coastguard Worker 		 value1 = gen8_read_40bit_a_counter(report1, format, a_index);
643*d83cc019SAndroid Build Coastguard Worker 
644*d83cc019SAndroid Build Coastguard Worker 	*delta += gen8_40bit_a_delta(value0, value1);
645*d83cc019SAndroid Build Coastguard Worker }
646*d83cc019SAndroid Build Coastguard Worker 
647*d83cc019SAndroid Build Coastguard Worker static void
accumulate_reports(struct accumulator * accumulator,uint32_t * start,uint32_t * end)648*d83cc019SAndroid Build Coastguard Worker accumulate_reports(struct accumulator *accumulator,
649*d83cc019SAndroid Build Coastguard Worker 		   uint32_t *start,
650*d83cc019SAndroid Build Coastguard Worker 		   uint32_t *end)
651*d83cc019SAndroid Build Coastguard Worker {
652*d83cc019SAndroid Build Coastguard Worker 	struct oa_format format = get_oa_format(accumulator->format);
653*d83cc019SAndroid Build Coastguard Worker 	uint64_t *deltas = accumulator->deltas;
654*d83cc019SAndroid Build Coastguard Worker 	int idx = 0;
655*d83cc019SAndroid Build Coastguard Worker 
656*d83cc019SAndroid Build Coastguard Worker 	if (intel_gen(devid) >= 8) {
657*d83cc019SAndroid Build Coastguard Worker 		/* timestamp */
658*d83cc019SAndroid Build Coastguard Worker 		accumulate_uint32(4, start, end, deltas + idx++);
659*d83cc019SAndroid Build Coastguard Worker 
660*d83cc019SAndroid Build Coastguard Worker 		/* clock cycles */
661*d83cc019SAndroid Build Coastguard Worker 		accumulate_uint32(12, start, end, deltas + idx++);
662*d83cc019SAndroid Build Coastguard Worker 	} else {
663*d83cc019SAndroid Build Coastguard Worker 		/* timestamp */
664*d83cc019SAndroid Build Coastguard Worker 		accumulate_uint32(4, start, end, deltas + idx++);
665*d83cc019SAndroid Build Coastguard Worker 	}
666*d83cc019SAndroid Build Coastguard Worker 
667*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; i < format.n_a40; i++) {
668*d83cc019SAndroid Build Coastguard Worker 		accumulate_uint40(i, start, end, accumulator->format,
669*d83cc019SAndroid Build Coastguard Worker 				  deltas + idx++);
670*d83cc019SAndroid Build Coastguard Worker 	}
671*d83cc019SAndroid Build Coastguard Worker 
672*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; i < format.n_a; i++) {
673*d83cc019SAndroid Build Coastguard Worker 		accumulate_uint32(format.a_off + 4 * i,
674*d83cc019SAndroid Build Coastguard Worker 				  start, end, deltas + idx++);
675*d83cc019SAndroid Build Coastguard Worker 	}
676*d83cc019SAndroid Build Coastguard Worker 
677*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; i < format.n_b; i++) {
678*d83cc019SAndroid Build Coastguard Worker 		accumulate_uint32(format.b_off + 4 * i,
679*d83cc019SAndroid Build Coastguard Worker 				  start, end, deltas + idx++);
680*d83cc019SAndroid Build Coastguard Worker 	}
681*d83cc019SAndroid Build Coastguard Worker 
682*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; i < format.n_c; i++) {
683*d83cc019SAndroid Build Coastguard Worker 		accumulate_uint32(format.c_off + 4 * i,
684*d83cc019SAndroid Build Coastguard Worker 				  start, end, deltas + idx++);
685*d83cc019SAndroid Build Coastguard Worker 	}
686*d83cc019SAndroid Build Coastguard Worker }
687*d83cc019SAndroid Build Coastguard Worker 
688*d83cc019SAndroid Build Coastguard Worker static void
accumulator_print(struct accumulator * accumulator,const char * title)689*d83cc019SAndroid Build Coastguard Worker accumulator_print(struct accumulator *accumulator, const char *title)
690*d83cc019SAndroid Build Coastguard Worker {
691*d83cc019SAndroid Build Coastguard Worker 	struct oa_format format = get_oa_format(accumulator->format);
692*d83cc019SAndroid Build Coastguard Worker 	uint64_t *deltas = accumulator->deltas;
693*d83cc019SAndroid Build Coastguard Worker 	int idx = 0;
694*d83cc019SAndroid Build Coastguard Worker 
695*d83cc019SAndroid Build Coastguard Worker 	igt_debug("%s:\n", title);
696*d83cc019SAndroid Build Coastguard Worker 	if (intel_gen(devid) >= 8) {
697*d83cc019SAndroid Build Coastguard Worker 		igt_debug("\ttime delta = %"PRIu64"\n", deltas[idx++]);
698*d83cc019SAndroid Build Coastguard Worker 		igt_debug("\tclock cycle delta = %"PRIu64"\n", deltas[idx++]);
699*d83cc019SAndroid Build Coastguard Worker 
700*d83cc019SAndroid Build Coastguard Worker 		for (int i = 0; i < format.n_a40; i++)
701*d83cc019SAndroid Build Coastguard Worker 			igt_debug("\tA%u = %"PRIu64"\n", i, deltas[idx++]);
702*d83cc019SAndroid Build Coastguard Worker 	} else {
703*d83cc019SAndroid Build Coastguard Worker 		igt_debug("\ttime delta = %"PRIu64"\n", deltas[idx++]);
704*d83cc019SAndroid Build Coastguard Worker 	}
705*d83cc019SAndroid Build Coastguard Worker 
706*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; i < format.n_a; i++) {
707*d83cc019SAndroid Build Coastguard Worker 		int a_id = format.first_a + i;
708*d83cc019SAndroid Build Coastguard Worker 		igt_debug("\tA%u = %"PRIu64"\n", a_id, deltas[idx++]);
709*d83cc019SAndroid Build Coastguard Worker 	}
710*d83cc019SAndroid Build Coastguard Worker 
711*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; i < format.n_a; i++)
712*d83cc019SAndroid Build Coastguard Worker 		igt_debug("\tB%u = %"PRIu64"\n", i, deltas[idx++]);
713*d83cc019SAndroid Build Coastguard Worker 
714*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; i < format.n_c; i++)
715*d83cc019SAndroid Build Coastguard Worker 		igt_debug("\tC%u = %"PRIu64"\n", i, deltas[idx++]);
716*d83cc019SAndroid Build Coastguard Worker }
717*d83cc019SAndroid Build Coastguard Worker 
718*d83cc019SAndroid Build Coastguard Worker /* The TestOa metric set is designed so */
719*d83cc019SAndroid Build Coastguard Worker static void
gen8_sanity_check_test_oa_reports(uint32_t * oa_report0,uint32_t * oa_report1,enum drm_i915_oa_format fmt)720*d83cc019SAndroid Build Coastguard Worker gen8_sanity_check_test_oa_reports(uint32_t *oa_report0, uint32_t *oa_report1,
721*d83cc019SAndroid Build Coastguard Worker 				  enum drm_i915_oa_format fmt)
722*d83cc019SAndroid Build Coastguard Worker {
723*d83cc019SAndroid Build Coastguard Worker 	struct oa_format format = get_oa_format(fmt);
724*d83cc019SAndroid Build Coastguard Worker 	uint32_t time_delta = timebase_scale(oa_report1[1] - oa_report0[1]);
725*d83cc019SAndroid Build Coastguard Worker 	uint32_t ticks0 = read_report_ticks(oa_report0, fmt);
726*d83cc019SAndroid Build Coastguard Worker 	uint32_t ticks1 = read_report_ticks(oa_report1, fmt);
727*d83cc019SAndroid Build Coastguard Worker 	uint32_t clock_delta = ticks1 - ticks0;
728*d83cc019SAndroid Build Coastguard Worker 	uint32_t max_delta;
729*d83cc019SAndroid Build Coastguard Worker 	uint64_t freq;
730*d83cc019SAndroid Build Coastguard Worker 	uint32_t *rpt0_b = (uint32_t *)(((uint8_t *)oa_report0) +
731*d83cc019SAndroid Build Coastguard Worker 					format.b_off);
732*d83cc019SAndroid Build Coastguard Worker 	uint32_t *rpt1_b = (uint32_t *)(((uint8_t *)oa_report1) +
733*d83cc019SAndroid Build Coastguard Worker 					format.b_off);
734*d83cc019SAndroid Build Coastguard Worker 	uint32_t b;
735*d83cc019SAndroid Build Coastguard Worker 	uint32_t ref;
736*d83cc019SAndroid Build Coastguard Worker 
737*d83cc019SAndroid Build Coastguard Worker 
738*d83cc019SAndroid Build Coastguard Worker 	igt_assert_neq(time_delta, 0);
739*d83cc019SAndroid Build Coastguard Worker 	igt_assert_neq(clock_delta, 0);
740*d83cc019SAndroid Build Coastguard Worker 
741*d83cc019SAndroid Build Coastguard Worker 	freq = ((uint64_t)clock_delta * 1000) / time_delta;
742*d83cc019SAndroid Build Coastguard Worker 	igt_debug("freq = %"PRIu64"\n", freq);
743*d83cc019SAndroid Build Coastguard Worker 
744*d83cc019SAndroid Build Coastguard Worker 	igt_assert(freq <= gt_max_freq_mhz);
745*d83cc019SAndroid Build Coastguard Worker 
746*d83cc019SAndroid Build Coastguard Worker 	igt_debug("clock delta = %"PRIu32"\n", clock_delta);
747*d83cc019SAndroid Build Coastguard Worker 
748*d83cc019SAndroid Build Coastguard Worker 	max_delta = clock_delta * n_eus;
749*d83cc019SAndroid Build Coastguard Worker 
750*d83cc019SAndroid Build Coastguard Worker 	/* Gen8+ has some 40bit A counters... */
751*d83cc019SAndroid Build Coastguard Worker 	for (int j = 0; j < format.n_a40; j++) {
752*d83cc019SAndroid Build Coastguard Worker 		uint64_t value0 = gen8_read_40bit_a_counter(oa_report0, fmt, j);
753*d83cc019SAndroid Build Coastguard Worker 		uint64_t value1 = gen8_read_40bit_a_counter(oa_report1, fmt, j);
754*d83cc019SAndroid Build Coastguard Worker 		uint64_t delta = gen8_40bit_a_delta(value0, value1);
755*d83cc019SAndroid Build Coastguard Worker 
756*d83cc019SAndroid Build Coastguard Worker 		if (undefined_a_counters[j])
757*d83cc019SAndroid Build Coastguard Worker 			continue;
758*d83cc019SAndroid Build Coastguard Worker 
759*d83cc019SAndroid Build Coastguard Worker 		igt_debug("A%d: delta = %"PRIu64"\n", j, delta);
760*d83cc019SAndroid Build Coastguard Worker 		igt_assert(delta <= max_delta);
761*d83cc019SAndroid Build Coastguard Worker 	}
762*d83cc019SAndroid Build Coastguard Worker 
763*d83cc019SAndroid Build Coastguard Worker 	for (int j = 0; j < format.n_a; j++) {
764*d83cc019SAndroid Build Coastguard Worker 		uint32_t *a0 = (uint32_t *)(((uint8_t *)oa_report0) +
765*d83cc019SAndroid Build Coastguard Worker 					    format.a_off);
766*d83cc019SAndroid Build Coastguard Worker 		uint32_t *a1 = (uint32_t *)(((uint8_t *)oa_report1) +
767*d83cc019SAndroid Build Coastguard Worker 					    format.a_off);
768*d83cc019SAndroid Build Coastguard Worker 		int a_id = format.first_a + j;
769*d83cc019SAndroid Build Coastguard Worker 		uint32_t delta = a1[j] - a0[j];
770*d83cc019SAndroid Build Coastguard Worker 
771*d83cc019SAndroid Build Coastguard Worker 		if (undefined_a_counters[a_id])
772*d83cc019SAndroid Build Coastguard Worker 			continue;
773*d83cc019SAndroid Build Coastguard Worker 
774*d83cc019SAndroid Build Coastguard Worker 		igt_debug("A%d: delta = %"PRIu32"\n", a_id, delta);
775*d83cc019SAndroid Build Coastguard Worker 		igt_assert(delta <= max_delta);
776*d83cc019SAndroid Build Coastguard Worker 	}
777*d83cc019SAndroid Build Coastguard Worker 
778*d83cc019SAndroid Build Coastguard Worker 	/* The TestOa metric set defines all B counters to be a
779*d83cc019SAndroid Build Coastguard Worker 	 * multiple of the gpu clock
780*d83cc019SAndroid Build Coastguard Worker 	 */
781*d83cc019SAndroid Build Coastguard Worker 	if (format.n_b) {
782*d83cc019SAndroid Build Coastguard Worker 		b = rpt1_b[0] - rpt0_b[0];
783*d83cc019SAndroid Build Coastguard Worker 		igt_debug("B0: delta = %"PRIu32"\n", b);
784*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(b, 0);
785*d83cc019SAndroid Build Coastguard Worker 
786*d83cc019SAndroid Build Coastguard Worker 		b = rpt1_b[1] - rpt0_b[1];
787*d83cc019SAndroid Build Coastguard Worker 		igt_debug("B1: delta = %"PRIu32"\n", b);
788*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(b, clock_delta);
789*d83cc019SAndroid Build Coastguard Worker 
790*d83cc019SAndroid Build Coastguard Worker 		b = rpt1_b[2] - rpt0_b[2];
791*d83cc019SAndroid Build Coastguard Worker 		igt_debug("B2: delta = %"PRIu32"\n", b);
792*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(b, clock_delta);
793*d83cc019SAndroid Build Coastguard Worker 
794*d83cc019SAndroid Build Coastguard Worker 		b = rpt1_b[3] - rpt0_b[3];
795*d83cc019SAndroid Build Coastguard Worker 		ref = clock_delta / 2;
796*d83cc019SAndroid Build Coastguard Worker 		igt_debug("B3: delta = %"PRIu32"\n", b);
797*d83cc019SAndroid Build Coastguard Worker 		igt_assert(b >= ref - 1 && b <= ref + 1);
798*d83cc019SAndroid Build Coastguard Worker 
799*d83cc019SAndroid Build Coastguard Worker 		b = rpt1_b[4] - rpt0_b[4];
800*d83cc019SAndroid Build Coastguard Worker 		ref = clock_delta / 3;
801*d83cc019SAndroid Build Coastguard Worker 		igt_debug("B4: delta = %"PRIu32"\n", b);
802*d83cc019SAndroid Build Coastguard Worker 		igt_assert(b >= ref - 1 && b <= ref + 1);
803*d83cc019SAndroid Build Coastguard Worker 
804*d83cc019SAndroid Build Coastguard Worker 		b = rpt1_b[5] - rpt0_b[5];
805*d83cc019SAndroid Build Coastguard Worker 		ref = clock_delta / 3;
806*d83cc019SAndroid Build Coastguard Worker 		igt_debug("B5: delta = %"PRIu32"\n", b);
807*d83cc019SAndroid Build Coastguard Worker 		igt_assert(b >= ref - 1 && b <= ref + 1);
808*d83cc019SAndroid Build Coastguard Worker 
809*d83cc019SAndroid Build Coastguard Worker 		b = rpt1_b[6] - rpt0_b[6];
810*d83cc019SAndroid Build Coastguard Worker 		ref = clock_delta / 6;
811*d83cc019SAndroid Build Coastguard Worker 		igt_debug("B6: delta = %"PRIu32"\n", b);
812*d83cc019SAndroid Build Coastguard Worker 		igt_assert(b >= ref - 1 && b <= ref + 1);
813*d83cc019SAndroid Build Coastguard Worker 
814*d83cc019SAndroid Build Coastguard Worker 		b = rpt1_b[7] - rpt0_b[7];
815*d83cc019SAndroid Build Coastguard Worker 		ref = clock_delta * 2 / 3;
816*d83cc019SAndroid Build Coastguard Worker 		igt_debug("B7: delta = %"PRIu32"\n", b);
817*d83cc019SAndroid Build Coastguard Worker 		igt_assert(b >= ref - 1 && b <= ref + 1);
818*d83cc019SAndroid Build Coastguard Worker 	}
819*d83cc019SAndroid Build Coastguard Worker 
820*d83cc019SAndroid Build Coastguard Worker 	for (int j = 0; j < format.n_c; j++) {
821*d83cc019SAndroid Build Coastguard Worker 		uint32_t *c0 = (uint32_t *)(((uint8_t *)oa_report0) +
822*d83cc019SAndroid Build Coastguard Worker 					    format.c_off);
823*d83cc019SAndroid Build Coastguard Worker 		uint32_t *c1 = (uint32_t *)(((uint8_t *)oa_report1) +
824*d83cc019SAndroid Build Coastguard Worker 					    format.c_off);
825*d83cc019SAndroid Build Coastguard Worker 		uint32_t delta = c1[j] - c0[j];
826*d83cc019SAndroid Build Coastguard Worker 
827*d83cc019SAndroid Build Coastguard Worker 		igt_debug("C%d: delta = %"PRIu32"\n", j, delta);
828*d83cc019SAndroid Build Coastguard Worker 		igt_assert(delta <= max_delta);
829*d83cc019SAndroid Build Coastguard Worker 	}
830*d83cc019SAndroid Build Coastguard Worker }
831*d83cc019SAndroid Build Coastguard Worker 
832*d83cc019SAndroid Build Coastguard Worker static uint64_t
get_cs_timestamp_frequency(void)833*d83cc019SAndroid Build Coastguard Worker get_cs_timestamp_frequency(void)
834*d83cc019SAndroid Build Coastguard Worker {
835*d83cc019SAndroid Build Coastguard Worker 	int cs_ts_freq = 0;
836*d83cc019SAndroid Build Coastguard Worker 	drm_i915_getparam_t gp;
837*d83cc019SAndroid Build Coastguard Worker 
838*d83cc019SAndroid Build Coastguard Worker 	gp.param = I915_PARAM_CS_TIMESTAMP_FREQUENCY;
839*d83cc019SAndroid Build Coastguard Worker 	gp.value = &cs_ts_freq;
840*d83cc019SAndroid Build Coastguard Worker 	if (igt_ioctl(drm_fd, DRM_IOCTL_I915_GETPARAM, &gp) == 0)
841*d83cc019SAndroid Build Coastguard Worker 		return cs_ts_freq;
842*d83cc019SAndroid Build Coastguard Worker 
843*d83cc019SAndroid Build Coastguard Worker 	igt_debug("Couldn't query CS timestamp frequency, trying to guess based on PCI-id\n");
844*d83cc019SAndroid Build Coastguard Worker 
845*d83cc019SAndroid Build Coastguard Worker 	if (IS_GEN7(devid) || IS_GEN8(devid))
846*d83cc019SAndroid Build Coastguard Worker 		return 12500000;
847*d83cc019SAndroid Build Coastguard Worker 	if (IS_SKYLAKE(devid) || IS_KABYLAKE(devid) || IS_COFFEELAKE(devid))
848*d83cc019SAndroid Build Coastguard Worker 		return 12000000;
849*d83cc019SAndroid Build Coastguard Worker 	if (IS_BROXTON(devid) || IS_GEMINILAKE(devid))
850*d83cc019SAndroid Build Coastguard Worker 		return 19200000;
851*d83cc019SAndroid Build Coastguard Worker 
852*d83cc019SAndroid Build Coastguard Worker 	igt_skip("Kernel with PARAM_CS_TIMESTAMP_FREQUENCY support required\n");
853*d83cc019SAndroid Build Coastguard Worker }
854*d83cc019SAndroid Build Coastguard Worker 
855*d83cc019SAndroid Build Coastguard Worker static bool
init_sys_info(void)856*d83cc019SAndroid Build Coastguard Worker init_sys_info(void)
857*d83cc019SAndroid Build Coastguard Worker {
858*d83cc019SAndroid Build Coastguard Worker 	const char *test_set_name = NULL;
859*d83cc019SAndroid Build Coastguard Worker 	const char *test_set_uuid = NULL;
860*d83cc019SAndroid Build Coastguard Worker 	char buf[256];
861*d83cc019SAndroid Build Coastguard Worker 
862*d83cc019SAndroid Build Coastguard Worker 	igt_assert_neq(devid, 0);
863*d83cc019SAndroid Build Coastguard Worker 
864*d83cc019SAndroid Build Coastguard Worker 	timestamp_frequency = get_cs_timestamp_frequency();
865*d83cc019SAndroid Build Coastguard Worker 	igt_assert_neq(timestamp_frequency, 0);
866*d83cc019SAndroid Build Coastguard Worker 
867*d83cc019SAndroid Build Coastguard Worker 	if (IS_HASWELL(devid)) {
868*d83cc019SAndroid Build Coastguard Worker 		/* We don't have a TestOa metric set for Haswell so use
869*d83cc019SAndroid Build Coastguard Worker 		 * RenderBasic
870*d83cc019SAndroid Build Coastguard Worker 		 */
871*d83cc019SAndroid Build Coastguard Worker 		test_set_name = "RenderBasic";
872*d83cc019SAndroid Build Coastguard Worker 		test_set_uuid = "403d8832-1a27-4aa6-a64e-f5389ce7b212";
873*d83cc019SAndroid Build Coastguard Worker 		test_oa_format = I915_OA_FORMAT_A45_B8_C8;
874*d83cc019SAndroid Build Coastguard Worker 		undefined_a_counters = hsw_undefined_a_counters;
875*d83cc019SAndroid Build Coastguard Worker 		read_report_ticks = hsw_read_report_ticks;
876*d83cc019SAndroid Build Coastguard Worker 		sanity_check_reports = hsw_sanity_check_render_basic_reports;
877*d83cc019SAndroid Build Coastguard Worker 
878*d83cc019SAndroid Build Coastguard Worker 		if (intel_gt(devid) == 0)
879*d83cc019SAndroid Build Coastguard Worker 			n_eus = 10;
880*d83cc019SAndroid Build Coastguard Worker 		else if (intel_gt(devid) == 1)
881*d83cc019SAndroid Build Coastguard Worker 			n_eus = 20;
882*d83cc019SAndroid Build Coastguard Worker 		else if (intel_gt(devid) == 2)
883*d83cc019SAndroid Build Coastguard Worker 			n_eus = 40;
884*d83cc019SAndroid Build Coastguard Worker 		else {
885*d83cc019SAndroid Build Coastguard Worker 			igt_assert(!"reached");
886*d83cc019SAndroid Build Coastguard Worker 			return false;
887*d83cc019SAndroid Build Coastguard Worker 		}
888*d83cc019SAndroid Build Coastguard Worker 	} else {
889*d83cc019SAndroid Build Coastguard Worker 		drm_i915_getparam_t gp;
890*d83cc019SAndroid Build Coastguard Worker 
891*d83cc019SAndroid Build Coastguard Worker 		test_set_name = "TestOa";
892*d83cc019SAndroid Build Coastguard Worker 		test_oa_format = I915_OA_FORMAT_A32u40_A4u32_B8_C8;
893*d83cc019SAndroid Build Coastguard Worker 		undefined_a_counters = gen8_undefined_a_counters;
894*d83cc019SAndroid Build Coastguard Worker 		read_report_ticks = gen8_read_report_ticks;
895*d83cc019SAndroid Build Coastguard Worker 		sanity_check_reports = gen8_sanity_check_test_oa_reports;
896*d83cc019SAndroid Build Coastguard Worker 
897*d83cc019SAndroid Build Coastguard Worker 		if (IS_BROADWELL(devid)) {
898*d83cc019SAndroid Build Coastguard Worker 			test_set_uuid = "d6de6f55-e526-4f79-a6a6-d7315c09044e";
899*d83cc019SAndroid Build Coastguard Worker 		} else if (IS_CHERRYVIEW(devid)) {
900*d83cc019SAndroid Build Coastguard Worker 			test_set_uuid = "4a534b07-cba3-414d-8d60-874830e883aa";
901*d83cc019SAndroid Build Coastguard Worker 		} else if (IS_SKYLAKE(devid)) {
902*d83cc019SAndroid Build Coastguard Worker 			switch (intel_gt(devid)) {
903*d83cc019SAndroid Build Coastguard Worker 			case 1:
904*d83cc019SAndroid Build Coastguard Worker 				test_set_uuid = "1651949f-0ac0-4cb1-a06f-dafd74a407d1";
905*d83cc019SAndroid Build Coastguard Worker 				break;
906*d83cc019SAndroid Build Coastguard Worker 			case 2:
907*d83cc019SAndroid Build Coastguard Worker 				test_set_uuid = "2b985803-d3c9-4629-8a4f-634bfecba0e8";
908*d83cc019SAndroid Build Coastguard Worker 				break;
909*d83cc019SAndroid Build Coastguard Worker 			case 3:
910*d83cc019SAndroid Build Coastguard Worker 				test_set_uuid = "882fa433-1f4a-4a67-a962-c741888fe5f5";
911*d83cc019SAndroid Build Coastguard Worker 				break;
912*d83cc019SAndroid Build Coastguard Worker 			default:
913*d83cc019SAndroid Build Coastguard Worker 				igt_debug("unsupported Skylake GT size\n");
914*d83cc019SAndroid Build Coastguard Worker 				return false;
915*d83cc019SAndroid Build Coastguard Worker 			}
916*d83cc019SAndroid Build Coastguard Worker 		} else if (IS_BROXTON(devid)) {
917*d83cc019SAndroid Build Coastguard Worker 			test_set_uuid = "5ee72f5c-092f-421e-8b70-225f7c3e9612";
918*d83cc019SAndroid Build Coastguard Worker 		} else if (IS_KABYLAKE(devid)) {
919*d83cc019SAndroid Build Coastguard Worker 			switch (intel_gt(devid)) {
920*d83cc019SAndroid Build Coastguard Worker 			case 1:
921*d83cc019SAndroid Build Coastguard Worker 				test_set_uuid = "baa3c7e4-52b6-4b85-801e-465a94b746dd";
922*d83cc019SAndroid Build Coastguard Worker 				break;
923*d83cc019SAndroid Build Coastguard Worker 			case 2:
924*d83cc019SAndroid Build Coastguard Worker 				test_set_uuid = "f1792f32-6db2-4b50-b4b2-557128f1688d";
925*d83cc019SAndroid Build Coastguard Worker 				break;
926*d83cc019SAndroid Build Coastguard Worker 			default:
927*d83cc019SAndroid Build Coastguard Worker 				igt_debug("unsupported Kabylake GT size\n");
928*d83cc019SAndroid Build Coastguard Worker 				return false;
929*d83cc019SAndroid Build Coastguard Worker 			}
930*d83cc019SAndroid Build Coastguard Worker 		} else if (IS_GEMINILAKE(devid)) {
931*d83cc019SAndroid Build Coastguard Worker 			test_set_uuid = "dd3fd789-e783-4204-8cd0-b671bbccb0cf";
932*d83cc019SAndroid Build Coastguard Worker 		} else if (IS_COFFEELAKE(devid)) {
933*d83cc019SAndroid Build Coastguard Worker 			switch (intel_gt(devid)) {
934*d83cc019SAndroid Build Coastguard Worker 			case 1:
935*d83cc019SAndroid Build Coastguard Worker 				test_set_uuid = "74fb4902-d3d3-4237-9e90-cbdc68d0a446";
936*d83cc019SAndroid Build Coastguard Worker 				break;
937*d83cc019SAndroid Build Coastguard Worker 			case 2:
938*d83cc019SAndroid Build Coastguard Worker 				test_set_uuid = "577e8e2c-3fa0-4875-8743-3538d585e3b0";
939*d83cc019SAndroid Build Coastguard Worker 				break;
940*d83cc019SAndroid Build Coastguard Worker 			default:
941*d83cc019SAndroid Build Coastguard Worker 				igt_debug("unsupported Coffeelake GT size\n");
942*d83cc019SAndroid Build Coastguard Worker 				return false;
943*d83cc019SAndroid Build Coastguard Worker 			}
944*d83cc019SAndroid Build Coastguard Worker 		} else if (IS_CANNONLAKE(devid)) {
945*d83cc019SAndroid Build Coastguard Worker 			test_set_uuid = "db41edd4-d8e7-4730-ad11-b9a2d6833503";
946*d83cc019SAndroid Build Coastguard Worker 		} else if (IS_ICELAKE(devid)) {
947*d83cc019SAndroid Build Coastguard Worker 			test_set_uuid = "a291665e-244b-4b76-9b9a-01de9d3c8068";
948*d83cc019SAndroid Build Coastguard Worker 		} else {
949*d83cc019SAndroid Build Coastguard Worker 			igt_debug("unsupported GT\n");
950*d83cc019SAndroid Build Coastguard Worker 			return false;
951*d83cc019SAndroid Build Coastguard Worker 		}
952*d83cc019SAndroid Build Coastguard Worker 
953*d83cc019SAndroid Build Coastguard Worker 		gp.param = I915_PARAM_EU_TOTAL;
954*d83cc019SAndroid Build Coastguard Worker 		gp.value = &n_eus;
955*d83cc019SAndroid Build Coastguard Worker 		do_ioctl(drm_fd, DRM_IOCTL_I915_GETPARAM, &gp);
956*d83cc019SAndroid Build Coastguard Worker 	}
957*d83cc019SAndroid Build Coastguard Worker 
958*d83cc019SAndroid Build Coastguard Worker 	igt_debug("%s metric set UUID = %s\n",
959*d83cc019SAndroid Build Coastguard Worker 		  test_set_name,
960*d83cc019SAndroid Build Coastguard Worker 		  test_set_uuid);
961*d83cc019SAndroid Build Coastguard Worker 
962*d83cc019SAndroid Build Coastguard Worker 	oa_exp_1_millisec = max_oa_exponent_for_period_lte(1000000);
963*d83cc019SAndroid Build Coastguard Worker 
964*d83cc019SAndroid Build Coastguard Worker 	snprintf(buf, sizeof(buf), "metrics/%s/id", test_set_uuid);
965*d83cc019SAndroid Build Coastguard Worker 
966*d83cc019SAndroid Build Coastguard Worker 	return try_sysfs_read_u64(buf, &test_metric_set_id);
967*d83cc019SAndroid Build Coastguard Worker }
968*d83cc019SAndroid Build Coastguard Worker 
969*d83cc019SAndroid Build Coastguard Worker static int
i915_read_reports_until_timestamp(enum drm_i915_oa_format oa_format,uint8_t * buf,uint32_t max_size,uint32_t start_timestamp,uint32_t end_timestamp)970*d83cc019SAndroid Build Coastguard Worker i915_read_reports_until_timestamp(enum drm_i915_oa_format oa_format,
971*d83cc019SAndroid Build Coastguard Worker 				  uint8_t *buf,
972*d83cc019SAndroid Build Coastguard Worker 				  uint32_t max_size,
973*d83cc019SAndroid Build Coastguard Worker 				  uint32_t start_timestamp,
974*d83cc019SAndroid Build Coastguard Worker 				  uint32_t end_timestamp)
975*d83cc019SAndroid Build Coastguard Worker {
976*d83cc019SAndroid Build Coastguard Worker 	size_t format_size = get_oa_format(oa_format).size;
977*d83cc019SAndroid Build Coastguard Worker 	uint32_t last_seen_timestamp = start_timestamp;
978*d83cc019SAndroid Build Coastguard Worker 	int total_len = 0;
979*d83cc019SAndroid Build Coastguard Worker 
980*d83cc019SAndroid Build Coastguard Worker 	while (last_seen_timestamp < end_timestamp) {
981*d83cc019SAndroid Build Coastguard Worker 		int offset, len;
982*d83cc019SAndroid Build Coastguard Worker 
983*d83cc019SAndroid Build Coastguard Worker 		/* Running out of space. */
984*d83cc019SAndroid Build Coastguard Worker 		if ((max_size - total_len) < format_size) {
985*d83cc019SAndroid Build Coastguard Worker 			igt_warn("run out of space before reaching "
986*d83cc019SAndroid Build Coastguard Worker 				 "end timestamp (%u/%u)\n",
987*d83cc019SAndroid Build Coastguard Worker 				 last_seen_timestamp, end_timestamp);
988*d83cc019SAndroid Build Coastguard Worker 			return -1;
989*d83cc019SAndroid Build Coastguard Worker 		}
990*d83cc019SAndroid Build Coastguard Worker 
991*d83cc019SAndroid Build Coastguard Worker 		while ((len = read(stream_fd, &buf[total_len],
992*d83cc019SAndroid Build Coastguard Worker 				   max_size - total_len)) < 0 &&
993*d83cc019SAndroid Build Coastguard Worker 		       errno == EINTR)
994*d83cc019SAndroid Build Coastguard Worker 			;
995*d83cc019SAndroid Build Coastguard Worker 
996*d83cc019SAndroid Build Coastguard Worker 		/* Intentionally return an error. */
997*d83cc019SAndroid Build Coastguard Worker 		if (len <= 0) {
998*d83cc019SAndroid Build Coastguard Worker 			if (errno == EAGAIN)
999*d83cc019SAndroid Build Coastguard Worker 				return total_len;
1000*d83cc019SAndroid Build Coastguard Worker 			else {
1001*d83cc019SAndroid Build Coastguard Worker 				igt_warn("error read OA stream : %i\n", errno);
1002*d83cc019SAndroid Build Coastguard Worker 				return -1;
1003*d83cc019SAndroid Build Coastguard Worker 			}
1004*d83cc019SAndroid Build Coastguard Worker 		}
1005*d83cc019SAndroid Build Coastguard Worker 
1006*d83cc019SAndroid Build Coastguard Worker 		offset = total_len;
1007*d83cc019SAndroid Build Coastguard Worker 		total_len += len;
1008*d83cc019SAndroid Build Coastguard Worker 
1009*d83cc019SAndroid Build Coastguard Worker 		while (offset < total_len) {
1010*d83cc019SAndroid Build Coastguard Worker 			const struct drm_i915_perf_record_header *header =
1011*d83cc019SAndroid Build Coastguard Worker 				(const struct drm_i915_perf_record_header *) &buf[offset];
1012*d83cc019SAndroid Build Coastguard Worker 			uint32_t *report = (uint32_t *) (header + 1);
1013*d83cc019SAndroid Build Coastguard Worker 
1014*d83cc019SAndroid Build Coastguard Worker 			if (header->type == DRM_I915_PERF_RECORD_SAMPLE)
1015*d83cc019SAndroid Build Coastguard Worker 				last_seen_timestamp = report[1];
1016*d83cc019SAndroid Build Coastguard Worker 
1017*d83cc019SAndroid Build Coastguard Worker 			offset += header->size;
1018*d83cc019SAndroid Build Coastguard Worker 		}
1019*d83cc019SAndroid Build Coastguard Worker 	}
1020*d83cc019SAndroid Build Coastguard Worker 
1021*d83cc019SAndroid Build Coastguard Worker 	return total_len;
1022*d83cc019SAndroid Build Coastguard Worker }
1023*d83cc019SAndroid Build Coastguard Worker 
1024*d83cc019SAndroid Build Coastguard Worker /* CAP_SYS_ADMIN is required to open system wide metrics, unless the system
1025*d83cc019SAndroid Build Coastguard Worker  * control parameter dev.i915.perf_stream_paranoid == 0 */
1026*d83cc019SAndroid Build Coastguard Worker static void
test_system_wide_paranoid(void)1027*d83cc019SAndroid Build Coastguard Worker test_system_wide_paranoid(void)
1028*d83cc019SAndroid Build Coastguard Worker {
1029*d83cc019SAndroid Build Coastguard Worker 	igt_fork(child, 1) {
1030*d83cc019SAndroid Build Coastguard Worker 		uint64_t properties[] = {
1031*d83cc019SAndroid Build Coastguard Worker 			/* Include OA reports in samples */
1032*d83cc019SAndroid Build Coastguard Worker 			DRM_I915_PERF_PROP_SAMPLE_OA, true,
1033*d83cc019SAndroid Build Coastguard Worker 
1034*d83cc019SAndroid Build Coastguard Worker 			/* OA unit configuration */
1035*d83cc019SAndroid Build Coastguard Worker 			DRM_I915_PERF_PROP_OA_METRICS_SET, test_metric_set_id,
1036*d83cc019SAndroid Build Coastguard Worker 			DRM_I915_PERF_PROP_OA_FORMAT, test_oa_format,
1037*d83cc019SAndroid Build Coastguard Worker 			DRM_I915_PERF_PROP_OA_EXPONENT, oa_exp_1_millisec,
1038*d83cc019SAndroid Build Coastguard Worker 		};
1039*d83cc019SAndroid Build Coastguard Worker 		struct drm_i915_perf_open_param param = {
1040*d83cc019SAndroid Build Coastguard Worker 			.flags = I915_PERF_FLAG_FD_CLOEXEC |
1041*d83cc019SAndroid Build Coastguard Worker 				I915_PERF_FLAG_FD_NONBLOCK,
1042*d83cc019SAndroid Build Coastguard Worker 			.num_properties = sizeof(properties) / 16,
1043*d83cc019SAndroid Build Coastguard Worker 			.properties_ptr = to_user_pointer(properties),
1044*d83cc019SAndroid Build Coastguard Worker 		};
1045*d83cc019SAndroid Build Coastguard Worker 
1046*d83cc019SAndroid Build Coastguard Worker 		write_u64_file("/proc/sys/dev/i915/perf_stream_paranoid", 1);
1047*d83cc019SAndroid Build Coastguard Worker 
1048*d83cc019SAndroid Build Coastguard Worker 		igt_drop_root();
1049*d83cc019SAndroid Build Coastguard Worker 
1050*d83cc019SAndroid Build Coastguard Worker 		do_ioctl_err(drm_fd, DRM_IOCTL_I915_PERF_OPEN, &param, EACCES);
1051*d83cc019SAndroid Build Coastguard Worker 	}
1052*d83cc019SAndroid Build Coastguard Worker 
1053*d83cc019SAndroid Build Coastguard Worker 	igt_waitchildren();
1054*d83cc019SAndroid Build Coastguard Worker 
1055*d83cc019SAndroid Build Coastguard Worker 	igt_fork(child, 1) {
1056*d83cc019SAndroid Build Coastguard Worker 		uint64_t properties[] = {
1057*d83cc019SAndroid Build Coastguard Worker 			/* Include OA reports in samples */
1058*d83cc019SAndroid Build Coastguard Worker 			DRM_I915_PERF_PROP_SAMPLE_OA, true,
1059*d83cc019SAndroid Build Coastguard Worker 
1060*d83cc019SAndroid Build Coastguard Worker 			/* OA unit configuration */
1061*d83cc019SAndroid Build Coastguard Worker 			DRM_I915_PERF_PROP_OA_METRICS_SET, test_metric_set_id,
1062*d83cc019SAndroid Build Coastguard Worker 			DRM_I915_PERF_PROP_OA_FORMAT, test_oa_format,
1063*d83cc019SAndroid Build Coastguard Worker 			DRM_I915_PERF_PROP_OA_EXPONENT, oa_exp_1_millisec,
1064*d83cc019SAndroid Build Coastguard Worker 		};
1065*d83cc019SAndroid Build Coastguard Worker 		struct drm_i915_perf_open_param param = {
1066*d83cc019SAndroid Build Coastguard Worker 			.flags = I915_PERF_FLAG_FD_CLOEXEC |
1067*d83cc019SAndroid Build Coastguard Worker 				I915_PERF_FLAG_FD_NONBLOCK,
1068*d83cc019SAndroid Build Coastguard Worker 			.num_properties = sizeof(properties) / 16,
1069*d83cc019SAndroid Build Coastguard Worker 			.properties_ptr = to_user_pointer(properties),
1070*d83cc019SAndroid Build Coastguard Worker 		};
1071*d83cc019SAndroid Build Coastguard Worker 		write_u64_file("/proc/sys/dev/i915/perf_stream_paranoid", 0);
1072*d83cc019SAndroid Build Coastguard Worker 
1073*d83cc019SAndroid Build Coastguard Worker 		igt_drop_root();
1074*d83cc019SAndroid Build Coastguard Worker 
1075*d83cc019SAndroid Build Coastguard Worker 		stream_fd = __perf_open(drm_fd, &param, false);
1076*d83cc019SAndroid Build Coastguard Worker 		__perf_close(stream_fd);
1077*d83cc019SAndroid Build Coastguard Worker 	}
1078*d83cc019SAndroid Build Coastguard Worker 
1079*d83cc019SAndroid Build Coastguard Worker 	igt_waitchildren();
1080*d83cc019SAndroid Build Coastguard Worker 
1081*d83cc019SAndroid Build Coastguard Worker 	/* leave in paranoid state */
1082*d83cc019SAndroid Build Coastguard Worker 	write_u64_file("/proc/sys/dev/i915/perf_stream_paranoid", 1);
1083*d83cc019SAndroid Build Coastguard Worker }
1084*d83cc019SAndroid Build Coastguard Worker 
1085*d83cc019SAndroid Build Coastguard Worker static void
test_invalid_open_flags(void)1086*d83cc019SAndroid Build Coastguard Worker test_invalid_open_flags(void)
1087*d83cc019SAndroid Build Coastguard Worker {
1088*d83cc019SAndroid Build Coastguard Worker 	uint64_t properties[] = {
1089*d83cc019SAndroid Build Coastguard Worker 		/* Include OA reports in samples */
1090*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_SAMPLE_OA, true,
1091*d83cc019SAndroid Build Coastguard Worker 
1092*d83cc019SAndroid Build Coastguard Worker 		/* OA unit configuration */
1093*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_METRICS_SET, test_metric_set_id,
1094*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_FORMAT, test_oa_format,
1095*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_EXPONENT, oa_exp_1_millisec,
1096*d83cc019SAndroid Build Coastguard Worker 	};
1097*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_perf_open_param param = {
1098*d83cc019SAndroid Build Coastguard Worker 		.flags = ~0, /* Undefined flag bits set! */
1099*d83cc019SAndroid Build Coastguard Worker 		.num_properties = sizeof(properties) / 16,
1100*d83cc019SAndroid Build Coastguard Worker 		.properties_ptr = to_user_pointer(properties),
1101*d83cc019SAndroid Build Coastguard Worker 	};
1102*d83cc019SAndroid Build Coastguard Worker 
1103*d83cc019SAndroid Build Coastguard Worker 	do_ioctl_err(drm_fd, DRM_IOCTL_I915_PERF_OPEN, &param, EINVAL);
1104*d83cc019SAndroid Build Coastguard Worker }
1105*d83cc019SAndroid Build Coastguard Worker 
1106*d83cc019SAndroid Build Coastguard Worker static void
test_invalid_oa_metric_set_id(void)1107*d83cc019SAndroid Build Coastguard Worker test_invalid_oa_metric_set_id(void)
1108*d83cc019SAndroid Build Coastguard Worker {
1109*d83cc019SAndroid Build Coastguard Worker 	uint64_t properties[] = {
1110*d83cc019SAndroid Build Coastguard Worker 		/* Include OA reports in samples */
1111*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_SAMPLE_OA, true,
1112*d83cc019SAndroid Build Coastguard Worker 
1113*d83cc019SAndroid Build Coastguard Worker 		/* OA unit configuration */
1114*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_FORMAT, test_oa_format,
1115*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_EXPONENT, oa_exp_1_millisec,
1116*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_METRICS_SET, UINT64_MAX,
1117*d83cc019SAndroid Build Coastguard Worker 	};
1118*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_perf_open_param param = {
1119*d83cc019SAndroid Build Coastguard Worker 		.flags = I915_PERF_FLAG_FD_CLOEXEC |
1120*d83cc019SAndroid Build Coastguard Worker 			I915_PERF_FLAG_FD_NONBLOCK,
1121*d83cc019SAndroid Build Coastguard Worker 		.num_properties = sizeof(properties) / 16,
1122*d83cc019SAndroid Build Coastguard Worker 		.properties_ptr = to_user_pointer(properties),
1123*d83cc019SAndroid Build Coastguard Worker 	};
1124*d83cc019SAndroid Build Coastguard Worker 
1125*d83cc019SAndroid Build Coastguard Worker 	do_ioctl_err(drm_fd, DRM_IOCTL_I915_PERF_OPEN, &param, EINVAL);
1126*d83cc019SAndroid Build Coastguard Worker 
1127*d83cc019SAndroid Build Coastguard Worker 	properties[ARRAY_SIZE(properties) - 1] = 0; /* ID 0 is also be reserved as invalid */
1128*d83cc019SAndroid Build Coastguard Worker 	do_ioctl_err(drm_fd, DRM_IOCTL_I915_PERF_OPEN, &param, EINVAL);
1129*d83cc019SAndroid Build Coastguard Worker 
1130*d83cc019SAndroid Build Coastguard Worker 	/* Check that we aren't just seeing false positives... */
1131*d83cc019SAndroid Build Coastguard Worker 	properties[ARRAY_SIZE(properties) - 1] = test_metric_set_id;
1132*d83cc019SAndroid Build Coastguard Worker 	stream_fd = __perf_open(drm_fd, &param, false);
1133*d83cc019SAndroid Build Coastguard Worker 	__perf_close(stream_fd);
1134*d83cc019SAndroid Build Coastguard Worker 
1135*d83cc019SAndroid Build Coastguard Worker 	/* There's no valid default OA metric set ID... */
1136*d83cc019SAndroid Build Coastguard Worker 	param.num_properties--;
1137*d83cc019SAndroid Build Coastguard Worker 	do_ioctl_err(drm_fd, DRM_IOCTL_I915_PERF_OPEN, &param, EINVAL);
1138*d83cc019SAndroid Build Coastguard Worker }
1139*d83cc019SAndroid Build Coastguard Worker 
1140*d83cc019SAndroid Build Coastguard Worker static void
test_invalid_oa_format_id(void)1141*d83cc019SAndroid Build Coastguard Worker test_invalid_oa_format_id(void)
1142*d83cc019SAndroid Build Coastguard Worker {
1143*d83cc019SAndroid Build Coastguard Worker 	uint64_t properties[] = {
1144*d83cc019SAndroid Build Coastguard Worker 		/* Include OA reports in samples */
1145*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_SAMPLE_OA, true,
1146*d83cc019SAndroid Build Coastguard Worker 
1147*d83cc019SAndroid Build Coastguard Worker 		/* OA unit configuration */
1148*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_METRICS_SET, test_metric_set_id,
1149*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_EXPONENT, oa_exp_1_millisec,
1150*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_FORMAT, UINT64_MAX,
1151*d83cc019SAndroid Build Coastguard Worker 	};
1152*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_perf_open_param param = {
1153*d83cc019SAndroid Build Coastguard Worker 		.flags = I915_PERF_FLAG_FD_CLOEXEC |
1154*d83cc019SAndroid Build Coastguard Worker 			I915_PERF_FLAG_FD_NONBLOCK,
1155*d83cc019SAndroid Build Coastguard Worker 		.num_properties = sizeof(properties) / 16,
1156*d83cc019SAndroid Build Coastguard Worker 		.properties_ptr = to_user_pointer(properties),
1157*d83cc019SAndroid Build Coastguard Worker 	};
1158*d83cc019SAndroid Build Coastguard Worker 
1159*d83cc019SAndroid Build Coastguard Worker 	do_ioctl_err(drm_fd, DRM_IOCTL_I915_PERF_OPEN, &param, EINVAL);
1160*d83cc019SAndroid Build Coastguard Worker 
1161*d83cc019SAndroid Build Coastguard Worker 	properties[ARRAY_SIZE(properties) - 1] = 0; /* ID 0 is also be reserved as invalid */
1162*d83cc019SAndroid Build Coastguard Worker 	do_ioctl_err(drm_fd, DRM_IOCTL_I915_PERF_OPEN, &param, EINVAL);
1163*d83cc019SAndroid Build Coastguard Worker 
1164*d83cc019SAndroid Build Coastguard Worker 	/* Check that we aren't just seeing false positives... */
1165*d83cc019SAndroid Build Coastguard Worker 	properties[ARRAY_SIZE(properties) - 1] = test_oa_format;
1166*d83cc019SAndroid Build Coastguard Worker 	stream_fd = __perf_open(drm_fd, &param, false);
1167*d83cc019SAndroid Build Coastguard Worker 	__perf_close(stream_fd);
1168*d83cc019SAndroid Build Coastguard Worker 
1169*d83cc019SAndroid Build Coastguard Worker 	/* There's no valid default OA format... */
1170*d83cc019SAndroid Build Coastguard Worker 	param.num_properties--;
1171*d83cc019SAndroid Build Coastguard Worker 	do_ioctl_err(drm_fd, DRM_IOCTL_I915_PERF_OPEN, &param, EINVAL);
1172*d83cc019SAndroid Build Coastguard Worker }
1173*d83cc019SAndroid Build Coastguard Worker 
1174*d83cc019SAndroid Build Coastguard Worker static void
test_missing_sample_flags(void)1175*d83cc019SAndroid Build Coastguard Worker test_missing_sample_flags(void)
1176*d83cc019SAndroid Build Coastguard Worker {
1177*d83cc019SAndroid Build Coastguard Worker 	uint64_t properties[] = {
1178*d83cc019SAndroid Build Coastguard Worker 		/* No _PROP_SAMPLE_xyz flags */
1179*d83cc019SAndroid Build Coastguard Worker 
1180*d83cc019SAndroid Build Coastguard Worker 		/* OA unit configuration */
1181*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_METRICS_SET, test_metric_set_id,
1182*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_EXPONENT, oa_exp_1_millisec,
1183*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_FORMAT, test_oa_format,
1184*d83cc019SAndroid Build Coastguard Worker 	};
1185*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_perf_open_param param = {
1186*d83cc019SAndroid Build Coastguard Worker 		.flags = I915_PERF_FLAG_FD_CLOEXEC,
1187*d83cc019SAndroid Build Coastguard Worker 		.num_properties = sizeof(properties) / 16,
1188*d83cc019SAndroid Build Coastguard Worker 		.properties_ptr = to_user_pointer(properties),
1189*d83cc019SAndroid Build Coastguard Worker 	};
1190*d83cc019SAndroid Build Coastguard Worker 
1191*d83cc019SAndroid Build Coastguard Worker 	do_ioctl_err(drm_fd, DRM_IOCTL_I915_PERF_OPEN, &param, EINVAL);
1192*d83cc019SAndroid Build Coastguard Worker }
1193*d83cc019SAndroid Build Coastguard Worker 
1194*d83cc019SAndroid Build Coastguard Worker static void
read_2_oa_reports(int format_id,int exponent,uint32_t * oa_report0,uint32_t * oa_report1,bool timer_only)1195*d83cc019SAndroid Build Coastguard Worker read_2_oa_reports(int format_id,
1196*d83cc019SAndroid Build Coastguard Worker 		  int exponent,
1197*d83cc019SAndroid Build Coastguard Worker 		  uint32_t *oa_report0,
1198*d83cc019SAndroid Build Coastguard Worker 		  uint32_t *oa_report1,
1199*d83cc019SAndroid Build Coastguard Worker 		  bool timer_only)
1200*d83cc019SAndroid Build Coastguard Worker {
1201*d83cc019SAndroid Build Coastguard Worker 	size_t format_size = get_oa_format(format_id).size;
1202*d83cc019SAndroid Build Coastguard Worker 	size_t sample_size = (sizeof(struct drm_i915_perf_record_header) +
1203*d83cc019SAndroid Build Coastguard Worker 			      format_size);
1204*d83cc019SAndroid Build Coastguard Worker 	const struct drm_i915_perf_record_header *header;
1205*d83cc019SAndroid Build Coastguard Worker 	uint32_t exponent_mask = (1 << (exponent + 1)) - 1;
1206*d83cc019SAndroid Build Coastguard Worker 
1207*d83cc019SAndroid Build Coastguard Worker 	/* Note: we allocate a large buffer so that each read() iteration
1208*d83cc019SAndroid Build Coastguard Worker 	 * should scrape *all* pending records.
1209*d83cc019SAndroid Build Coastguard Worker 	 *
1210*d83cc019SAndroid Build Coastguard Worker 	 * The largest buffer the OA unit supports is 16MB.
1211*d83cc019SAndroid Build Coastguard Worker 	 *
1212*d83cc019SAndroid Build Coastguard Worker 	 * Being sure we are fetching all buffered reports allows us to
1213*d83cc019SAndroid Build Coastguard Worker 	 * potentially throw away / skip all reports whenever we see
1214*d83cc019SAndroid Build Coastguard Worker 	 * a _REPORT_LOST notification as a way of being sure are
1215*d83cc019SAndroid Build Coastguard Worker 	 * measurements aren't skewed by a lost report.
1216*d83cc019SAndroid Build Coastguard Worker 	 *
1217*d83cc019SAndroid Build Coastguard Worker 	 * Note: that is is useful for some tests but also not something
1218*d83cc019SAndroid Build Coastguard Worker 	 * applications would be expected to resort to. Lost reports are
1219*d83cc019SAndroid Build Coastguard Worker 	 * somewhat unpredictable but typically don't pose a problem - except
1220*d83cc019SAndroid Build Coastguard Worker 	 * to indicate that the OA unit may be over taxed if lots of reports
1221*d83cc019SAndroid Build Coastguard Worker 	 * are being lost.
1222*d83cc019SAndroid Build Coastguard Worker 	 */
1223*d83cc019SAndroid Build Coastguard Worker 	int max_reports = MAX_OA_BUF_SIZE / format_size;
1224*d83cc019SAndroid Build Coastguard Worker 	int buf_size = sample_size * max_reports * 1.5;
1225*d83cc019SAndroid Build Coastguard Worker 	uint8_t *buf = malloc(buf_size);
1226*d83cc019SAndroid Build Coastguard Worker 	int n = 0;
1227*d83cc019SAndroid Build Coastguard Worker 
1228*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; i < 1000; i++) {
1229*d83cc019SAndroid Build Coastguard Worker 		ssize_t len;
1230*d83cc019SAndroid Build Coastguard Worker 
1231*d83cc019SAndroid Build Coastguard Worker 		while ((len = read(stream_fd, buf, buf_size)) < 0 &&
1232*d83cc019SAndroid Build Coastguard Worker 		       errno == EINTR)
1233*d83cc019SAndroid Build Coastguard Worker 			;
1234*d83cc019SAndroid Build Coastguard Worker 
1235*d83cc019SAndroid Build Coastguard Worker 		igt_assert(len > 0);
1236*d83cc019SAndroid Build Coastguard Worker 		igt_debug("read %d bytes\n", (int)len);
1237*d83cc019SAndroid Build Coastguard Worker 
1238*d83cc019SAndroid Build Coastguard Worker 		for (size_t offset = 0; offset < len; offset += header->size) {
1239*d83cc019SAndroid Build Coastguard Worker 			const uint32_t *report;
1240*d83cc019SAndroid Build Coastguard Worker 
1241*d83cc019SAndroid Build Coastguard Worker 			header = (void *)(buf + offset);
1242*d83cc019SAndroid Build Coastguard Worker 
1243*d83cc019SAndroid Build Coastguard Worker 			igt_assert_eq(header->pad, 0); /* Reserved */
1244*d83cc019SAndroid Build Coastguard Worker 
1245*d83cc019SAndroid Build Coastguard Worker 			/* Currently the only test that should ever expect to
1246*d83cc019SAndroid Build Coastguard Worker 			 * see a _BUFFER_LOST error is the buffer_fill test,
1247*d83cc019SAndroid Build Coastguard Worker 			 * otherwise something bad has probably happened...
1248*d83cc019SAndroid Build Coastguard Worker 			 */
1249*d83cc019SAndroid Build Coastguard Worker 			igt_assert_neq(header->type, DRM_I915_PERF_RECORD_OA_BUFFER_LOST);
1250*d83cc019SAndroid Build Coastguard Worker 
1251*d83cc019SAndroid Build Coastguard Worker 			/* At high sampling frequencies the OA HW might not be
1252*d83cc019SAndroid Build Coastguard Worker 			 * able to cope with all write requests and will notify
1253*d83cc019SAndroid Build Coastguard Worker 			 * us that a report was lost. We restart our read of
1254*d83cc019SAndroid Build Coastguard Worker 			 * two sequential reports due to the timeline blip this
1255*d83cc019SAndroid Build Coastguard Worker 			 * implies
1256*d83cc019SAndroid Build Coastguard Worker 			 */
1257*d83cc019SAndroid Build Coastguard Worker 			if (header->type == DRM_I915_PERF_RECORD_OA_REPORT_LOST) {
1258*d83cc019SAndroid Build Coastguard Worker 				igt_debug("read restart: OA trigger collision / report lost\n");
1259*d83cc019SAndroid Build Coastguard Worker 				n = 0;
1260*d83cc019SAndroid Build Coastguard Worker 
1261*d83cc019SAndroid Build Coastguard Worker 				/* XXX: break, because we don't know where
1262*d83cc019SAndroid Build Coastguard Worker 				 * within the series of already read reports
1263*d83cc019SAndroid Build Coastguard Worker 				 * there could be a blip from the lost report.
1264*d83cc019SAndroid Build Coastguard Worker 				 */
1265*d83cc019SAndroid Build Coastguard Worker 				break;
1266*d83cc019SAndroid Build Coastguard Worker 			}
1267*d83cc019SAndroid Build Coastguard Worker 
1268*d83cc019SAndroid Build Coastguard Worker 			/* Currently the only other record type expected is a
1269*d83cc019SAndroid Build Coastguard Worker 			 * _SAMPLE. Notably this test will need updating if
1270*d83cc019SAndroid Build Coastguard Worker 			 * i915-perf is extended in the future with additional
1271*d83cc019SAndroid Build Coastguard Worker 			 * record types.
1272*d83cc019SAndroid Build Coastguard Worker 			 */
1273*d83cc019SAndroid Build Coastguard Worker 			igt_assert_eq(header->type, DRM_I915_PERF_RECORD_SAMPLE);
1274*d83cc019SAndroid Build Coastguard Worker 
1275*d83cc019SAndroid Build Coastguard Worker 			igt_assert_eq(header->size, sample_size);
1276*d83cc019SAndroid Build Coastguard Worker 
1277*d83cc019SAndroid Build Coastguard Worker 			report = (const void *)(header + 1);
1278*d83cc019SAndroid Build Coastguard Worker 
1279*d83cc019SAndroid Build Coastguard Worker 			igt_debug("read report: reason = %x, timestamp = %x, exponent mask=%x\n",
1280*d83cc019SAndroid Build Coastguard Worker 				  report[0], report[1], exponent_mask);
1281*d83cc019SAndroid Build Coastguard Worker 
1282*d83cc019SAndroid Build Coastguard Worker 			/* Don't expect zero for timestamps */
1283*d83cc019SAndroid Build Coastguard Worker 			igt_assert_neq(report[1], 0);
1284*d83cc019SAndroid Build Coastguard Worker 
1285*d83cc019SAndroid Build Coastguard Worker 			if (timer_only) {
1286*d83cc019SAndroid Build Coastguard Worker 				if (!oa_report_is_periodic(exponent, report)) {
1287*d83cc019SAndroid Build Coastguard Worker 					igt_debug("skipping non timer report\n");
1288*d83cc019SAndroid Build Coastguard Worker 					continue;
1289*d83cc019SAndroid Build Coastguard Worker 				}
1290*d83cc019SAndroid Build Coastguard Worker 			}
1291*d83cc019SAndroid Build Coastguard Worker 
1292*d83cc019SAndroid Build Coastguard Worker 			if (n++ == 0)
1293*d83cc019SAndroid Build Coastguard Worker 				memcpy(oa_report0, report, format_size);
1294*d83cc019SAndroid Build Coastguard Worker 			else {
1295*d83cc019SAndroid Build Coastguard Worker 				memcpy(oa_report1, report, format_size);
1296*d83cc019SAndroid Build Coastguard Worker 				free(buf);
1297*d83cc019SAndroid Build Coastguard Worker 				return;
1298*d83cc019SAndroid Build Coastguard Worker 			}
1299*d83cc019SAndroid Build Coastguard Worker 		}
1300*d83cc019SAndroid Build Coastguard Worker 	}
1301*d83cc019SAndroid Build Coastguard Worker 
1302*d83cc019SAndroid Build Coastguard Worker 	free(buf);
1303*d83cc019SAndroid Build Coastguard Worker 
1304*d83cc019SAndroid Build Coastguard Worker 	igt_assert(!"reached");
1305*d83cc019SAndroid Build Coastguard Worker }
1306*d83cc019SAndroid Build Coastguard Worker 
1307*d83cc019SAndroid Build Coastguard Worker static void
open_and_read_2_oa_reports(int format_id,int exponent,uint32_t * oa_report0,uint32_t * oa_report1,bool timer_only)1308*d83cc019SAndroid Build Coastguard Worker open_and_read_2_oa_reports(int format_id,
1309*d83cc019SAndroid Build Coastguard Worker 			   int exponent,
1310*d83cc019SAndroid Build Coastguard Worker 			   uint32_t *oa_report0,
1311*d83cc019SAndroid Build Coastguard Worker 			   uint32_t *oa_report1,
1312*d83cc019SAndroid Build Coastguard Worker 			   bool timer_only)
1313*d83cc019SAndroid Build Coastguard Worker {
1314*d83cc019SAndroid Build Coastguard Worker 	uint64_t properties[] = {
1315*d83cc019SAndroid Build Coastguard Worker 		/* Include OA reports in samples */
1316*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_SAMPLE_OA, true,
1317*d83cc019SAndroid Build Coastguard Worker 
1318*d83cc019SAndroid Build Coastguard Worker 		/* OA unit configuration */
1319*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_METRICS_SET, test_metric_set_id,
1320*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_FORMAT, format_id,
1321*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_EXPONENT, exponent,
1322*d83cc019SAndroid Build Coastguard Worker 
1323*d83cc019SAndroid Build Coastguard Worker 	};
1324*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_perf_open_param param = {
1325*d83cc019SAndroid Build Coastguard Worker 		.flags = I915_PERF_FLAG_FD_CLOEXEC,
1326*d83cc019SAndroid Build Coastguard Worker 		.num_properties = sizeof(properties) / 16,
1327*d83cc019SAndroid Build Coastguard Worker 		.properties_ptr = to_user_pointer(properties),
1328*d83cc019SAndroid Build Coastguard Worker 	};
1329*d83cc019SAndroid Build Coastguard Worker 
1330*d83cc019SAndroid Build Coastguard Worker 	stream_fd = __perf_open(drm_fd, &param, false);
1331*d83cc019SAndroid Build Coastguard Worker 
1332*d83cc019SAndroid Build Coastguard Worker 	read_2_oa_reports(format_id, exponent,
1333*d83cc019SAndroid Build Coastguard Worker 			  oa_report0, oa_report1, timer_only);
1334*d83cc019SAndroid Build Coastguard Worker 
1335*d83cc019SAndroid Build Coastguard Worker 	__perf_close(stream_fd);
1336*d83cc019SAndroid Build Coastguard Worker }
1337*d83cc019SAndroid Build Coastguard Worker 
1338*d83cc019SAndroid Build Coastguard Worker static void
print_reports(uint32_t * oa_report0,uint32_t * oa_report1,int fmt)1339*d83cc019SAndroid Build Coastguard Worker print_reports(uint32_t *oa_report0, uint32_t *oa_report1, int fmt)
1340*d83cc019SAndroid Build Coastguard Worker {
1341*d83cc019SAndroid Build Coastguard Worker 	struct oa_format format = get_oa_format(fmt);
1342*d83cc019SAndroid Build Coastguard Worker 
1343*d83cc019SAndroid Build Coastguard Worker 	igt_debug("TIMESTAMP: 1st = %"PRIu32", 2nd = %"PRIu32", delta = %"PRIu32"\n",
1344*d83cc019SAndroid Build Coastguard Worker 		  oa_report0[1], oa_report1[1], oa_report1[1] - oa_report0[1]);
1345*d83cc019SAndroid Build Coastguard Worker 
1346*d83cc019SAndroid Build Coastguard Worker 	if (IS_HASWELL(devid) && format.n_c == 0) {
1347*d83cc019SAndroid Build Coastguard Worker 		igt_debug("CLOCK = N/A\n");
1348*d83cc019SAndroid Build Coastguard Worker 	} else {
1349*d83cc019SAndroid Build Coastguard Worker 		uint32_t clock0 = read_report_ticks(oa_report0, fmt);
1350*d83cc019SAndroid Build Coastguard Worker 		uint32_t clock1 = read_report_ticks(oa_report1, fmt);
1351*d83cc019SAndroid Build Coastguard Worker 
1352*d83cc019SAndroid Build Coastguard Worker 		igt_debug("CLOCK: 1st = %"PRIu32", 2nd = %"PRIu32", delta = %"PRIu32"\n",
1353*d83cc019SAndroid Build Coastguard Worker 			  clock0, clock1, clock1 - clock0);
1354*d83cc019SAndroid Build Coastguard Worker 	}
1355*d83cc019SAndroid Build Coastguard Worker 
1356*d83cc019SAndroid Build Coastguard Worker 	if (intel_gen(devid) >= 8) {
1357*d83cc019SAndroid Build Coastguard Worker 		uint32_t slice_freq0, slice_freq1, unslice_freq0, unslice_freq1;
1358*d83cc019SAndroid Build Coastguard Worker 		const char *reason0 = gen8_read_report_reason(oa_report0);
1359*d83cc019SAndroid Build Coastguard Worker 		const char *reason1 = gen8_read_report_reason(oa_report1);
1360*d83cc019SAndroid Build Coastguard Worker 
1361*d83cc019SAndroid Build Coastguard Worker 		igt_debug("CTX ID: 1st = %"PRIu32", 2nd = %"PRIu32"\n",
1362*d83cc019SAndroid Build Coastguard Worker 			  oa_report0[2], oa_report1[2]);
1363*d83cc019SAndroid Build Coastguard Worker 
1364*d83cc019SAndroid Build Coastguard Worker 		gen8_read_report_clock_ratios(oa_report0,
1365*d83cc019SAndroid Build Coastguard Worker 					      &slice_freq0, &unslice_freq0);
1366*d83cc019SAndroid Build Coastguard Worker 		gen8_read_report_clock_ratios(oa_report1,
1367*d83cc019SAndroid Build Coastguard Worker 					      &slice_freq1, &unslice_freq1);
1368*d83cc019SAndroid Build Coastguard Worker 
1369*d83cc019SAndroid Build Coastguard Worker 		igt_debug("SLICE CLK: 1st = %umhz, 2nd = %umhz, delta = %d\n",
1370*d83cc019SAndroid Build Coastguard Worker 			  slice_freq0, slice_freq1,
1371*d83cc019SAndroid Build Coastguard Worker 			  ((int)slice_freq1 - (int)slice_freq0));
1372*d83cc019SAndroid Build Coastguard Worker 		igt_debug("UNSLICE CLK: 1st = %umhz, 2nd = %umhz, delta = %d\n",
1373*d83cc019SAndroid Build Coastguard Worker 			  unslice_freq0, unslice_freq1,
1374*d83cc019SAndroid Build Coastguard Worker 			  ((int)unslice_freq1 - (int)unslice_freq0));
1375*d83cc019SAndroid Build Coastguard Worker 
1376*d83cc019SAndroid Build Coastguard Worker 		igt_debug("REASONS: 1st = \"%s\", 2nd = \"%s\"\n", reason0, reason1);
1377*d83cc019SAndroid Build Coastguard Worker 	}
1378*d83cc019SAndroid Build Coastguard Worker 
1379*d83cc019SAndroid Build Coastguard Worker 	/* Gen8+ has some 40bit A counters... */
1380*d83cc019SAndroid Build Coastguard Worker 	for (int j = 0; j < format.n_a40; j++) {
1381*d83cc019SAndroid Build Coastguard Worker 		uint64_t value0 = gen8_read_40bit_a_counter(oa_report0, fmt, j);
1382*d83cc019SAndroid Build Coastguard Worker 		uint64_t value1 = gen8_read_40bit_a_counter(oa_report1, fmt, j);
1383*d83cc019SAndroid Build Coastguard Worker 		uint64_t delta = gen8_40bit_a_delta(value0, value1);
1384*d83cc019SAndroid Build Coastguard Worker 
1385*d83cc019SAndroid Build Coastguard Worker 		if (undefined_a_counters[j])
1386*d83cc019SAndroid Build Coastguard Worker 			continue;
1387*d83cc019SAndroid Build Coastguard Worker 
1388*d83cc019SAndroid Build Coastguard Worker 		igt_debug("A%d: 1st = %"PRIu64", 2nd = %"PRIu64", delta = %"PRIu64"\n",
1389*d83cc019SAndroid Build Coastguard Worker 			  j, value0, value1, delta);
1390*d83cc019SAndroid Build Coastguard Worker 	}
1391*d83cc019SAndroid Build Coastguard Worker 
1392*d83cc019SAndroid Build Coastguard Worker 	for (int j = 0; j < format.n_a; j++) {
1393*d83cc019SAndroid Build Coastguard Worker 		uint32_t *a0 = (uint32_t *)(((uint8_t *)oa_report0) +
1394*d83cc019SAndroid Build Coastguard Worker 					    format.a_off);
1395*d83cc019SAndroid Build Coastguard Worker 		uint32_t *a1 = (uint32_t *)(((uint8_t *)oa_report1) +
1396*d83cc019SAndroid Build Coastguard Worker 					    format.a_off);
1397*d83cc019SAndroid Build Coastguard Worker 		int a_id = format.first_a + j;
1398*d83cc019SAndroid Build Coastguard Worker 		uint32_t delta = a1[j] - a0[j];
1399*d83cc019SAndroid Build Coastguard Worker 
1400*d83cc019SAndroid Build Coastguard Worker 		if (undefined_a_counters[a_id])
1401*d83cc019SAndroid Build Coastguard Worker 			continue;
1402*d83cc019SAndroid Build Coastguard Worker 
1403*d83cc019SAndroid Build Coastguard Worker 		igt_debug("A%d: 1st = %"PRIu32", 2nd = %"PRIu32", delta = %"PRIu32"\n",
1404*d83cc019SAndroid Build Coastguard Worker 			  a_id, a0[j], a1[j], delta);
1405*d83cc019SAndroid Build Coastguard Worker 	}
1406*d83cc019SAndroid Build Coastguard Worker 
1407*d83cc019SAndroid Build Coastguard Worker 	for (int j = 0; j < format.n_b; j++) {
1408*d83cc019SAndroid Build Coastguard Worker 		uint32_t *b0 = (uint32_t *)(((uint8_t *)oa_report0) +
1409*d83cc019SAndroid Build Coastguard Worker 					    format.b_off);
1410*d83cc019SAndroid Build Coastguard Worker 		uint32_t *b1 = (uint32_t *)(((uint8_t *)oa_report1) +
1411*d83cc019SAndroid Build Coastguard Worker 					    format.b_off);
1412*d83cc019SAndroid Build Coastguard Worker 		uint32_t delta = b1[j] - b0[j];
1413*d83cc019SAndroid Build Coastguard Worker 
1414*d83cc019SAndroid Build Coastguard Worker 		igt_debug("B%d: 1st = %"PRIu32", 2nd = %"PRIu32", delta = %"PRIu32"\n",
1415*d83cc019SAndroid Build Coastguard Worker 			  j, b0[j], b1[j], delta);
1416*d83cc019SAndroid Build Coastguard Worker 	}
1417*d83cc019SAndroid Build Coastguard Worker 
1418*d83cc019SAndroid Build Coastguard Worker 	for (int j = 0; j < format.n_c; j++) {
1419*d83cc019SAndroid Build Coastguard Worker 		uint32_t *c0 = (uint32_t *)(((uint8_t *)oa_report0) +
1420*d83cc019SAndroid Build Coastguard Worker 					    format.c_off);
1421*d83cc019SAndroid Build Coastguard Worker 		uint32_t *c1 = (uint32_t *)(((uint8_t *)oa_report1) +
1422*d83cc019SAndroid Build Coastguard Worker 					    format.c_off);
1423*d83cc019SAndroid Build Coastguard Worker 		uint32_t delta = c1[j] - c0[j];
1424*d83cc019SAndroid Build Coastguard Worker 
1425*d83cc019SAndroid Build Coastguard Worker 		igt_debug("C%d: 1st = %"PRIu32", 2nd = %"PRIu32", delta = %"PRIu32"\n",
1426*d83cc019SAndroid Build Coastguard Worker 			  j, c0[j], c1[j], delta);
1427*d83cc019SAndroid Build Coastguard Worker 	}
1428*d83cc019SAndroid Build Coastguard Worker }
1429*d83cc019SAndroid Build Coastguard Worker 
1430*d83cc019SAndroid Build Coastguard Worker /* Debug function, only useful when reports don't make sense. */
1431*d83cc019SAndroid Build Coastguard Worker #if 0
1432*d83cc019SAndroid Build Coastguard Worker static void
1433*d83cc019SAndroid Build Coastguard Worker print_report(uint32_t *report, int fmt)
1434*d83cc019SAndroid Build Coastguard Worker {
1435*d83cc019SAndroid Build Coastguard Worker 	struct oa_format format = get_oa_format(fmt);
1436*d83cc019SAndroid Build Coastguard Worker 
1437*d83cc019SAndroid Build Coastguard Worker 	igt_debug("TIMESTAMP: %"PRIu32"\n", report[1]);
1438*d83cc019SAndroid Build Coastguard Worker 
1439*d83cc019SAndroid Build Coastguard Worker 	if (IS_HASWELL(devid) && format.n_c == 0) {
1440*d83cc019SAndroid Build Coastguard Worker 		igt_debug("CLOCK = N/A\n");
1441*d83cc019SAndroid Build Coastguard Worker 	} else {
1442*d83cc019SAndroid Build Coastguard Worker 		uint32_t clock = read_report_ticks(report, fmt);
1443*d83cc019SAndroid Build Coastguard Worker 
1444*d83cc019SAndroid Build Coastguard Worker 		igt_debug("CLOCK: %"PRIu32"\n", clock);
1445*d83cc019SAndroid Build Coastguard Worker 	}
1446*d83cc019SAndroid Build Coastguard Worker 
1447*d83cc019SAndroid Build Coastguard Worker 	if (intel_gen(devid) >= 8) {
1448*d83cc019SAndroid Build Coastguard Worker 		uint32_t slice_freq, unslice_freq;
1449*d83cc019SAndroid Build Coastguard Worker 		const char *reason = gen8_read_report_reason(report);
1450*d83cc019SAndroid Build Coastguard Worker 
1451*d83cc019SAndroid Build Coastguard Worker 		gen8_read_report_clock_ratios(report, &slice_freq, &unslice_freq);
1452*d83cc019SAndroid Build Coastguard Worker 
1453*d83cc019SAndroid Build Coastguard Worker 		igt_debug("SLICE CLK: %umhz\n", slice_freq);
1454*d83cc019SAndroid Build Coastguard Worker 		igt_debug("UNSLICE CLK: %umhz\n", unslice_freq);
1455*d83cc019SAndroid Build Coastguard Worker 		igt_debug("REASON: \"%s\"\n", reason);
1456*d83cc019SAndroid Build Coastguard Worker 		igt_debug("CTX ID: %"PRIu32"/%"PRIx32"\n", report[2], report[2]);
1457*d83cc019SAndroid Build Coastguard Worker 	}
1458*d83cc019SAndroid Build Coastguard Worker 
1459*d83cc019SAndroid Build Coastguard Worker 	/* Gen8+ has some 40bit A counters... */
1460*d83cc019SAndroid Build Coastguard Worker 	for (int j = 0; j < format.n_a40; j++) {
1461*d83cc019SAndroid Build Coastguard Worker 		uint64_t value = gen8_read_40bit_a_counter(report, fmt, j);
1462*d83cc019SAndroid Build Coastguard Worker 
1463*d83cc019SAndroid Build Coastguard Worker 		if (undefined_a_counters[j])
1464*d83cc019SAndroid Build Coastguard Worker 			continue;
1465*d83cc019SAndroid Build Coastguard Worker 
1466*d83cc019SAndroid Build Coastguard Worker 		igt_debug("A%d: %"PRIu64"\n", j, value);
1467*d83cc019SAndroid Build Coastguard Worker 	}
1468*d83cc019SAndroid Build Coastguard Worker 
1469*d83cc019SAndroid Build Coastguard Worker 	for (int j = 0; j < format.n_a; j++) {
1470*d83cc019SAndroid Build Coastguard Worker 		uint32_t *a = (uint32_t *)(((uint8_t *)report) +
1471*d83cc019SAndroid Build Coastguard Worker 					   format.a_off);
1472*d83cc019SAndroid Build Coastguard Worker 		int a_id = format.first_a + j;
1473*d83cc019SAndroid Build Coastguard Worker 
1474*d83cc019SAndroid Build Coastguard Worker 		if (undefined_a_counters[a_id])
1475*d83cc019SAndroid Build Coastguard Worker 			continue;
1476*d83cc019SAndroid Build Coastguard Worker 
1477*d83cc019SAndroid Build Coastguard Worker 		igt_debug("A%d: %"PRIu32"\n", a_id, a[j]);
1478*d83cc019SAndroid Build Coastguard Worker 	}
1479*d83cc019SAndroid Build Coastguard Worker 
1480*d83cc019SAndroid Build Coastguard Worker 	for (int j = 0; j < format.n_b; j++) {
1481*d83cc019SAndroid Build Coastguard Worker 		uint32_t *b = (uint32_t *)(((uint8_t *)report) +
1482*d83cc019SAndroid Build Coastguard Worker 					   format.b_off);
1483*d83cc019SAndroid Build Coastguard Worker 
1484*d83cc019SAndroid Build Coastguard Worker 		igt_debug("B%d: %"PRIu32"\n", j, b[j]);
1485*d83cc019SAndroid Build Coastguard Worker 	}
1486*d83cc019SAndroid Build Coastguard Worker 
1487*d83cc019SAndroid Build Coastguard Worker 	for (int j = 0; j < format.n_c; j++) {
1488*d83cc019SAndroid Build Coastguard Worker 		uint32_t *c = (uint32_t *)(((uint8_t *)report) +
1489*d83cc019SAndroid Build Coastguard Worker 					   format.c_off);
1490*d83cc019SAndroid Build Coastguard Worker 
1491*d83cc019SAndroid Build Coastguard Worker 		igt_debug("C%d: %"PRIu32"\n", j, c[j]);
1492*d83cc019SAndroid Build Coastguard Worker 	}
1493*d83cc019SAndroid Build Coastguard Worker }
1494*d83cc019SAndroid Build Coastguard Worker #endif
1495*d83cc019SAndroid Build Coastguard Worker 
1496*d83cc019SAndroid Build Coastguard Worker static void
test_oa_formats(void)1497*d83cc019SAndroid Build Coastguard Worker test_oa_formats(void)
1498*d83cc019SAndroid Build Coastguard Worker {
1499*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; i < I915_OA_FORMAT_MAX; i++) {
1500*d83cc019SAndroid Build Coastguard Worker 		struct oa_format format = get_oa_format(i);
1501*d83cc019SAndroid Build Coastguard Worker 		uint32_t oa_report0[64];
1502*d83cc019SAndroid Build Coastguard Worker 		uint32_t oa_report1[64];
1503*d83cc019SAndroid Build Coastguard Worker 
1504*d83cc019SAndroid Build Coastguard Worker 		if (!format.name) /* sparse, indexed by ID */
1505*d83cc019SAndroid Build Coastguard Worker 			continue;
1506*d83cc019SAndroid Build Coastguard Worker 
1507*d83cc019SAndroid Build Coastguard Worker 		igt_debug("Checking OA format %s\n", format.name);
1508*d83cc019SAndroid Build Coastguard Worker 
1509*d83cc019SAndroid Build Coastguard Worker 		open_and_read_2_oa_reports(i,
1510*d83cc019SAndroid Build Coastguard Worker 					   oa_exp_1_millisec,
1511*d83cc019SAndroid Build Coastguard Worker 					   oa_report0,
1512*d83cc019SAndroid Build Coastguard Worker 					   oa_report1,
1513*d83cc019SAndroid Build Coastguard Worker 					   false); /* timer reports only */
1514*d83cc019SAndroid Build Coastguard Worker 
1515*d83cc019SAndroid Build Coastguard Worker 		print_reports(oa_report0, oa_report1, i);
1516*d83cc019SAndroid Build Coastguard Worker 		sanity_check_reports(oa_report0, oa_report1, i);
1517*d83cc019SAndroid Build Coastguard Worker 	}
1518*d83cc019SAndroid Build Coastguard Worker }
1519*d83cc019SAndroid Build Coastguard Worker 
1520*d83cc019SAndroid Build Coastguard Worker 
1521*d83cc019SAndroid Build Coastguard Worker enum load {
1522*d83cc019SAndroid Build Coastguard Worker 	LOW,
1523*d83cc019SAndroid Build Coastguard Worker 	HIGH
1524*d83cc019SAndroid Build Coastguard Worker };
1525*d83cc019SAndroid Build Coastguard Worker 
1526*d83cc019SAndroid Build Coastguard Worker #define LOAD_HELPER_PAUSE_USEC 500
1527*d83cc019SAndroid Build Coastguard Worker 
1528*d83cc019SAndroid Build Coastguard Worker static struct load_helper {
1529*d83cc019SAndroid Build Coastguard Worker 	int devid;
1530*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bufmgr *bufmgr;
1531*d83cc019SAndroid Build Coastguard Worker 	drm_intel_context *context;
1532*d83cc019SAndroid Build Coastguard Worker 	uint32_t context_id;
1533*d83cc019SAndroid Build Coastguard Worker 	struct intel_batchbuffer *batch;
1534*d83cc019SAndroid Build Coastguard Worker 	enum load load;
1535*d83cc019SAndroid Build Coastguard Worker 	bool exit;
1536*d83cc019SAndroid Build Coastguard Worker 	struct igt_helper_process igt_proc;
1537*d83cc019SAndroid Build Coastguard Worker 	struct igt_buf src, dst;
1538*d83cc019SAndroid Build Coastguard Worker } lh = { 0, };
1539*d83cc019SAndroid Build Coastguard Worker 
load_helper_signal_handler(int sig)1540*d83cc019SAndroid Build Coastguard Worker static void load_helper_signal_handler(int sig)
1541*d83cc019SAndroid Build Coastguard Worker {
1542*d83cc019SAndroid Build Coastguard Worker 	if (sig == SIGUSR2)
1543*d83cc019SAndroid Build Coastguard Worker 		lh.load = lh.load == LOW ? HIGH : LOW;
1544*d83cc019SAndroid Build Coastguard Worker 	else
1545*d83cc019SAndroid Build Coastguard Worker 		lh.exit = true;
1546*d83cc019SAndroid Build Coastguard Worker }
1547*d83cc019SAndroid Build Coastguard Worker 
load_helper_set_load(enum load load)1548*d83cc019SAndroid Build Coastguard Worker static void load_helper_set_load(enum load load)
1549*d83cc019SAndroid Build Coastguard Worker {
1550*d83cc019SAndroid Build Coastguard Worker 	igt_assert(lh.igt_proc.running);
1551*d83cc019SAndroid Build Coastguard Worker 
1552*d83cc019SAndroid Build Coastguard Worker 	if (lh.load == load)
1553*d83cc019SAndroid Build Coastguard Worker 		return;
1554*d83cc019SAndroid Build Coastguard Worker 
1555*d83cc019SAndroid Build Coastguard Worker 	lh.load = load;
1556*d83cc019SAndroid Build Coastguard Worker 	kill(lh.igt_proc.pid, SIGUSR2);
1557*d83cc019SAndroid Build Coastguard Worker }
1558*d83cc019SAndroid Build Coastguard Worker 
load_helper_run(enum load load)1559*d83cc019SAndroid Build Coastguard Worker static void load_helper_run(enum load load)
1560*d83cc019SAndroid Build Coastguard Worker {
1561*d83cc019SAndroid Build Coastguard Worker 	/*
1562*d83cc019SAndroid Build Coastguard Worker 	 * FIXME fork helpers won't get cleaned up when started from within a
1563*d83cc019SAndroid Build Coastguard Worker 	 * subtest, so handle the case where it sticks around a bit too long.
1564*d83cc019SAndroid Build Coastguard Worker 	 */
1565*d83cc019SAndroid Build Coastguard Worker 	if (lh.igt_proc.running) {
1566*d83cc019SAndroid Build Coastguard Worker 		load_helper_set_load(load);
1567*d83cc019SAndroid Build Coastguard Worker 		return;
1568*d83cc019SAndroid Build Coastguard Worker 	}
1569*d83cc019SAndroid Build Coastguard Worker 
1570*d83cc019SAndroid Build Coastguard Worker 	lh.load = load;
1571*d83cc019SAndroid Build Coastguard Worker 
1572*d83cc019SAndroid Build Coastguard Worker 	igt_fork_helper(&lh.igt_proc) {
1573*d83cc019SAndroid Build Coastguard Worker 		signal(SIGUSR1, load_helper_signal_handler);
1574*d83cc019SAndroid Build Coastguard Worker 		signal(SIGUSR2, load_helper_signal_handler);
1575*d83cc019SAndroid Build Coastguard Worker 
1576*d83cc019SAndroid Build Coastguard Worker 		while (!lh.exit) {
1577*d83cc019SAndroid Build Coastguard Worker 			int ret;
1578*d83cc019SAndroid Build Coastguard Worker 
1579*d83cc019SAndroid Build Coastguard Worker 			render_copy(lh.batch,
1580*d83cc019SAndroid Build Coastguard Worker 				    lh.context,
1581*d83cc019SAndroid Build Coastguard Worker 				    &lh.src, 0, 0, 1920, 1080,
1582*d83cc019SAndroid Build Coastguard Worker 				    &lh.dst, 0, 0);
1583*d83cc019SAndroid Build Coastguard Worker 
1584*d83cc019SAndroid Build Coastguard Worker 			intel_batchbuffer_flush_with_context(lh.batch,
1585*d83cc019SAndroid Build Coastguard Worker 							     lh.context);
1586*d83cc019SAndroid Build Coastguard Worker 
1587*d83cc019SAndroid Build Coastguard Worker 			ret = drm_intel_gem_context_get_id(lh.context,
1588*d83cc019SAndroid Build Coastguard Worker 							   &lh.context_id);
1589*d83cc019SAndroid Build Coastguard Worker 			igt_assert_eq(ret, 0);
1590*d83cc019SAndroid Build Coastguard Worker 
1591*d83cc019SAndroid Build Coastguard Worker 			drm_intel_bo_wait_rendering(lh.dst.bo);
1592*d83cc019SAndroid Build Coastguard Worker 
1593*d83cc019SAndroid Build Coastguard Worker 			/* Lower the load by pausing after every submitted
1594*d83cc019SAndroid Build Coastguard Worker 			 * write. */
1595*d83cc019SAndroid Build Coastguard Worker 			if (lh.load == LOW)
1596*d83cc019SAndroid Build Coastguard Worker 				usleep(LOAD_HELPER_PAUSE_USEC);
1597*d83cc019SAndroid Build Coastguard Worker 		}
1598*d83cc019SAndroid Build Coastguard Worker 	}
1599*d83cc019SAndroid Build Coastguard Worker }
1600*d83cc019SAndroid Build Coastguard Worker 
load_helper_stop(void)1601*d83cc019SAndroid Build Coastguard Worker static void load_helper_stop(void)
1602*d83cc019SAndroid Build Coastguard Worker {
1603*d83cc019SAndroid Build Coastguard Worker 	kill(lh.igt_proc.pid, SIGUSR1);
1604*d83cc019SAndroid Build Coastguard Worker 	igt_assert(igt_wait_helper(&lh.igt_proc) == 0);
1605*d83cc019SAndroid Build Coastguard Worker }
1606*d83cc019SAndroid Build Coastguard Worker 
load_helper_init(void)1607*d83cc019SAndroid Build Coastguard Worker static void load_helper_init(void)
1608*d83cc019SAndroid Build Coastguard Worker {
1609*d83cc019SAndroid Build Coastguard Worker 	int ret;
1610*d83cc019SAndroid Build Coastguard Worker 
1611*d83cc019SAndroid Build Coastguard Worker 	lh.devid = intel_get_drm_devid(drm_fd);
1612*d83cc019SAndroid Build Coastguard Worker 
1613*d83cc019SAndroid Build Coastguard Worker 	/* MI_STORE_DATA can only use GTT address on gen4+/g33 and needs
1614*d83cc019SAndroid Build Coastguard Worker 	 * snoopable mem on pre-gen6. Hence load-helper only works on gen6+, but
1615*d83cc019SAndroid Build Coastguard Worker 	 * that's also all we care about for the rps testcase*/
1616*d83cc019SAndroid Build Coastguard Worker 	igt_assert(intel_gen(lh.devid) >= 6);
1617*d83cc019SAndroid Build Coastguard Worker 	lh.bufmgr = drm_intel_bufmgr_gem_init(drm_fd, 4096);
1618*d83cc019SAndroid Build Coastguard Worker 	igt_assert(lh.bufmgr);
1619*d83cc019SAndroid Build Coastguard Worker 
1620*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bufmgr_gem_enable_reuse(lh.bufmgr);
1621*d83cc019SAndroid Build Coastguard Worker 
1622*d83cc019SAndroid Build Coastguard Worker 	lh.context = drm_intel_gem_context_create(lh.bufmgr);
1623*d83cc019SAndroid Build Coastguard Worker 	igt_assert(lh.context);
1624*d83cc019SAndroid Build Coastguard Worker 
1625*d83cc019SAndroid Build Coastguard Worker 	lh.context_id = 0xffffffff;
1626*d83cc019SAndroid Build Coastguard Worker 	ret = drm_intel_gem_context_get_id(lh.context, &lh.context_id);
1627*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(ret, 0);
1628*d83cc019SAndroid Build Coastguard Worker 	igt_assert_neq(lh.context_id, 0xffffffff);
1629*d83cc019SAndroid Build Coastguard Worker 
1630*d83cc019SAndroid Build Coastguard Worker 	lh.batch = intel_batchbuffer_alloc(lh.bufmgr, lh.devid);
1631*d83cc019SAndroid Build Coastguard Worker 	igt_assert(lh.batch);
1632*d83cc019SAndroid Build Coastguard Worker 
1633*d83cc019SAndroid Build Coastguard Worker 	scratch_buf_init(lh.bufmgr, &lh.dst, 1920, 1080, 0);
1634*d83cc019SAndroid Build Coastguard Worker 	scratch_buf_init(lh.bufmgr, &lh.src, 1920, 1080, 0);
1635*d83cc019SAndroid Build Coastguard Worker }
1636*d83cc019SAndroid Build Coastguard Worker 
load_helper_fini(void)1637*d83cc019SAndroid Build Coastguard Worker static void load_helper_fini(void)
1638*d83cc019SAndroid Build Coastguard Worker {
1639*d83cc019SAndroid Build Coastguard Worker 	if (lh.igt_proc.running)
1640*d83cc019SAndroid Build Coastguard Worker 		load_helper_stop();
1641*d83cc019SAndroid Build Coastguard Worker 
1642*d83cc019SAndroid Build Coastguard Worker 	if (lh.src.bo)
1643*d83cc019SAndroid Build Coastguard Worker 		drm_intel_bo_unreference(lh.src.bo);
1644*d83cc019SAndroid Build Coastguard Worker 	if (lh.dst.bo)
1645*d83cc019SAndroid Build Coastguard Worker 		drm_intel_bo_unreference(lh.dst.bo);
1646*d83cc019SAndroid Build Coastguard Worker 
1647*d83cc019SAndroid Build Coastguard Worker 	if (lh.batch)
1648*d83cc019SAndroid Build Coastguard Worker 		intel_batchbuffer_free(lh.batch);
1649*d83cc019SAndroid Build Coastguard Worker 
1650*d83cc019SAndroid Build Coastguard Worker 	if (lh.context)
1651*d83cc019SAndroid Build Coastguard Worker 		drm_intel_gem_context_destroy(lh.context);
1652*d83cc019SAndroid Build Coastguard Worker 
1653*d83cc019SAndroid Build Coastguard Worker 	if (lh.bufmgr)
1654*d83cc019SAndroid Build Coastguard Worker 		drm_intel_bufmgr_destroy(lh.bufmgr);
1655*d83cc019SAndroid Build Coastguard Worker }
1656*d83cc019SAndroid Build Coastguard Worker 
expected_report_timing_delta(uint32_t delta,uint32_t expected_delta)1657*d83cc019SAndroid Build Coastguard Worker static bool expected_report_timing_delta(uint32_t delta, uint32_t expected_delta)
1658*d83cc019SAndroid Build Coastguard Worker {
1659*d83cc019SAndroid Build Coastguard Worker 	/*
1660*d83cc019SAndroid Build Coastguard Worker 	 * On ICL, the OA unit appears to be a bit more relaxed about
1661*d83cc019SAndroid Build Coastguard Worker 	 * its timing for emitting OA reports (often missing the
1662*d83cc019SAndroid Build Coastguard Worker 	 * deadline by 1 timestamp).
1663*d83cc019SAndroid Build Coastguard Worker 	 */
1664*d83cc019SAndroid Build Coastguard Worker 	if (IS_ICELAKE(devid))
1665*d83cc019SAndroid Build Coastguard Worker 		return delta <= (expected_delta + 3);
1666*d83cc019SAndroid Build Coastguard Worker 	else
1667*d83cc019SAndroid Build Coastguard Worker 		return delta <= expected_delta;
1668*d83cc019SAndroid Build Coastguard Worker }
1669*d83cc019SAndroid Build Coastguard Worker 
1670*d83cc019SAndroid Build Coastguard Worker static void
test_oa_exponents(void)1671*d83cc019SAndroid Build Coastguard Worker test_oa_exponents(void)
1672*d83cc019SAndroid Build Coastguard Worker {
1673*d83cc019SAndroid Build Coastguard Worker 	load_helper_init();
1674*d83cc019SAndroid Build Coastguard Worker 	load_helper_run(HIGH);
1675*d83cc019SAndroid Build Coastguard Worker 
1676*d83cc019SAndroid Build Coastguard Worker 	/* It's asking a lot to sample with a 160 nanosecond period and the
1677*d83cc019SAndroid Build Coastguard Worker 	 * test can fail due to buffer overflows if it wasn't possible to
1678*d83cc019SAndroid Build Coastguard Worker 	 * keep up, so we don't start from an exponent of zero...
1679*d83cc019SAndroid Build Coastguard Worker 	 */
1680*d83cc019SAndroid Build Coastguard Worker 	for (int exponent = 5; exponent < 20; exponent++) {
1681*d83cc019SAndroid Build Coastguard Worker 		uint64_t properties[] = {
1682*d83cc019SAndroid Build Coastguard Worker 			/* Include OA reports in samples */
1683*d83cc019SAndroid Build Coastguard Worker 			DRM_I915_PERF_PROP_SAMPLE_OA, true,
1684*d83cc019SAndroid Build Coastguard Worker 
1685*d83cc019SAndroid Build Coastguard Worker 			/* OA unit configuration */
1686*d83cc019SAndroid Build Coastguard Worker 			DRM_I915_PERF_PROP_OA_METRICS_SET, test_metric_set_id,
1687*d83cc019SAndroid Build Coastguard Worker 			DRM_I915_PERF_PROP_OA_FORMAT, test_oa_format,
1688*d83cc019SAndroid Build Coastguard Worker 			DRM_I915_PERF_PROP_OA_EXPONENT, exponent,
1689*d83cc019SAndroid Build Coastguard Worker 		};
1690*d83cc019SAndroid Build Coastguard Worker 		struct drm_i915_perf_open_param param = {
1691*d83cc019SAndroid Build Coastguard Worker 			.flags = I915_PERF_FLAG_FD_CLOEXEC,
1692*d83cc019SAndroid Build Coastguard Worker 			.num_properties = ARRAY_SIZE(properties) / 2,
1693*d83cc019SAndroid Build Coastguard Worker 			.properties_ptr = to_user_pointer(properties),
1694*d83cc019SAndroid Build Coastguard Worker 		};
1695*d83cc019SAndroid Build Coastguard Worker 		uint64_t expected_timestamp_delta = 2ULL << exponent;
1696*d83cc019SAndroid Build Coastguard Worker 		size_t format_size = get_oa_format(test_oa_format).size;
1697*d83cc019SAndroid Build Coastguard Worker 		size_t sample_size = (sizeof(struct drm_i915_perf_record_header) +
1698*d83cc019SAndroid Build Coastguard Worker 				      format_size);
1699*d83cc019SAndroid Build Coastguard Worker 		int max_reports = MAX_OA_BUF_SIZE / format_size;
1700*d83cc019SAndroid Build Coastguard Worker 		int buf_size = sample_size * max_reports * 1.5;
1701*d83cc019SAndroid Build Coastguard Worker 		uint8_t *buf = calloc(1, buf_size);
1702*d83cc019SAndroid Build Coastguard Worker 		int ret, n_timer_reports = 0;
1703*d83cc019SAndroid Build Coastguard Worker 		uint32_t matches = 0;
1704*d83cc019SAndroid Build Coastguard Worker 		struct {
1705*d83cc019SAndroid Build Coastguard Worker 			uint32_t report[64];
1706*d83cc019SAndroid Build Coastguard Worker 		} timer_reports[30];
1707*d83cc019SAndroid Build Coastguard Worker 
1708*d83cc019SAndroid Build Coastguard Worker 		igt_debug("testing OA exponent %d,"
1709*d83cc019SAndroid Build Coastguard Worker 			  " expected ts delta = %"PRIu64" (%"PRIu64"ns/%.2fus/%.2fms)\n",
1710*d83cc019SAndroid Build Coastguard Worker 			  exponent, expected_timestamp_delta,
1711*d83cc019SAndroid Build Coastguard Worker 			  oa_exponent_to_ns(exponent),
1712*d83cc019SAndroid Build Coastguard Worker 			  oa_exponent_to_ns(exponent) / 1000.0,
1713*d83cc019SAndroid Build Coastguard Worker 			  oa_exponent_to_ns(exponent) / (1000.0 * 1000.0));
1714*d83cc019SAndroid Build Coastguard Worker 
1715*d83cc019SAndroid Build Coastguard Worker 		stream_fd = __perf_open(drm_fd, &param, true /* prevent_pm */);
1716*d83cc019SAndroid Build Coastguard Worker 
1717*d83cc019SAndroid Build Coastguard Worker 		while (n_timer_reports < ARRAY_SIZE(timer_reports)) {
1718*d83cc019SAndroid Build Coastguard Worker 			struct drm_i915_perf_record_header *header;
1719*d83cc019SAndroid Build Coastguard Worker 
1720*d83cc019SAndroid Build Coastguard Worker 			while ((ret = read(stream_fd, buf, buf_size)) < 0 &&
1721*d83cc019SAndroid Build Coastguard Worker 			       errno == EINTR)
1722*d83cc019SAndroid Build Coastguard Worker 				;
1723*d83cc019SAndroid Build Coastguard Worker 
1724*d83cc019SAndroid Build Coastguard Worker 			/* igt_debug(" > read %i bytes\n", ret); */
1725*d83cc019SAndroid Build Coastguard Worker 
1726*d83cc019SAndroid Build Coastguard Worker 			/* We should never have no data. */
1727*d83cc019SAndroid Build Coastguard Worker 			igt_assert(ret > 0);
1728*d83cc019SAndroid Build Coastguard Worker 
1729*d83cc019SAndroid Build Coastguard Worker 			for (int offset = 0;
1730*d83cc019SAndroid Build Coastguard Worker 			     offset < ret && n_timer_reports < ARRAY_SIZE(timer_reports);
1731*d83cc019SAndroid Build Coastguard Worker 			     offset += header->size) {
1732*d83cc019SAndroid Build Coastguard Worker 				uint32_t *report;
1733*d83cc019SAndroid Build Coastguard Worker 
1734*d83cc019SAndroid Build Coastguard Worker 				header = (void *)(buf + offset);
1735*d83cc019SAndroid Build Coastguard Worker 
1736*d83cc019SAndroid Build Coastguard Worker 				if (header->type == DRM_I915_PERF_RECORD_OA_BUFFER_LOST) {
1737*d83cc019SAndroid Build Coastguard Worker 					igt_assert(!"reached");
1738*d83cc019SAndroid Build Coastguard Worker 					break;
1739*d83cc019SAndroid Build Coastguard Worker 				}
1740*d83cc019SAndroid Build Coastguard Worker 
1741*d83cc019SAndroid Build Coastguard Worker 				if (header->type == DRM_I915_PERF_RECORD_OA_REPORT_LOST)
1742*d83cc019SAndroid Build Coastguard Worker 					igt_debug("report loss\n");
1743*d83cc019SAndroid Build Coastguard Worker 
1744*d83cc019SAndroid Build Coastguard Worker 				if (header->type != DRM_I915_PERF_RECORD_SAMPLE)
1745*d83cc019SAndroid Build Coastguard Worker 					continue;
1746*d83cc019SAndroid Build Coastguard Worker 
1747*d83cc019SAndroid Build Coastguard Worker 				report = (void *)(header + 1);
1748*d83cc019SAndroid Build Coastguard Worker 
1749*d83cc019SAndroid Build Coastguard Worker 				if (!oa_report_is_periodic(exponent, report))
1750*d83cc019SAndroid Build Coastguard Worker 					continue;
1751*d83cc019SAndroid Build Coastguard Worker 
1752*d83cc019SAndroid Build Coastguard Worker 				memcpy(timer_reports[n_timer_reports].report, report,
1753*d83cc019SAndroid Build Coastguard Worker 				       sizeof(timer_reports[n_timer_reports].report));
1754*d83cc019SAndroid Build Coastguard Worker 				n_timer_reports++;
1755*d83cc019SAndroid Build Coastguard Worker 			}
1756*d83cc019SAndroid Build Coastguard Worker 		}
1757*d83cc019SAndroid Build Coastguard Worker 
1758*d83cc019SAndroid Build Coastguard Worker 		__perf_close(stream_fd);
1759*d83cc019SAndroid Build Coastguard Worker 
1760*d83cc019SAndroid Build Coastguard Worker 		igt_debug("report%04i ts=%08x hw_id=0x%08x\n", 0,
1761*d83cc019SAndroid Build Coastguard Worker 			  timer_reports[0].report[1],
1762*d83cc019SAndroid Build Coastguard Worker 			  oa_report_get_ctx_id(timer_reports[0].report));
1763*d83cc019SAndroid Build Coastguard Worker 		for (int i = 1; i < n_timer_reports; i++) {
1764*d83cc019SAndroid Build Coastguard Worker 			uint32_t delta =
1765*d83cc019SAndroid Build Coastguard Worker 				timer_reports[i].report[1] - timer_reports[i - 1].report[1];
1766*d83cc019SAndroid Build Coastguard Worker 
1767*d83cc019SAndroid Build Coastguard Worker 			igt_debug("report%04i ts=%08x hw_id=0x%08x delta=%u %s\n", i,
1768*d83cc019SAndroid Build Coastguard Worker 				  timer_reports[i].report[1],
1769*d83cc019SAndroid Build Coastguard Worker 				  oa_report_get_ctx_id(timer_reports[i].report),
1770*d83cc019SAndroid Build Coastguard Worker 				  delta, expected_report_timing_delta(delta,
1771*d83cc019SAndroid Build Coastguard Worker 								      expected_timestamp_delta) ? "" : "******");
1772*d83cc019SAndroid Build Coastguard Worker 
1773*d83cc019SAndroid Build Coastguard Worker 			matches += expected_report_timing_delta(delta,expected_timestamp_delta);
1774*d83cc019SAndroid Build Coastguard Worker 		}
1775*d83cc019SAndroid Build Coastguard Worker 
1776*d83cc019SAndroid Build Coastguard Worker 		igt_debug("matches=%u/%u\n", matches, n_timer_reports - 1);
1777*d83cc019SAndroid Build Coastguard Worker 
1778*d83cc019SAndroid Build Coastguard Worker 		/* Allow for a couple of errors. */
1779*d83cc019SAndroid Build Coastguard Worker 		igt_assert_lte(n_timer_reports - 3, matches);
1780*d83cc019SAndroid Build Coastguard Worker 	}
1781*d83cc019SAndroid Build Coastguard Worker 
1782*d83cc019SAndroid Build Coastguard Worker 	load_helper_stop();
1783*d83cc019SAndroid Build Coastguard Worker 	load_helper_fini();
1784*d83cc019SAndroid Build Coastguard Worker }
1785*d83cc019SAndroid Build Coastguard Worker 
1786*d83cc019SAndroid Build Coastguard Worker /* The OA exponent selects a timestamp counter bit to trigger reports on.
1787*d83cc019SAndroid Build Coastguard Worker  *
1788*d83cc019SAndroid Build Coastguard Worker  * With a 64bit timestamp and least significant bit approx == 80ns then the MSB
1789*d83cc019SAndroid Build Coastguard Worker  * equates to > 40 thousand years and isn't exposed via the i915 perf interface.
1790*d83cc019SAndroid Build Coastguard Worker  *
1791*d83cc019SAndroid Build Coastguard Worker  * The max exponent exposed is expected to be 31, which is still a fairly
1792*d83cc019SAndroid Build Coastguard Worker  * ridiculous period (>5min) but is the maximum exponent where it's still
1793*d83cc019SAndroid Build Coastguard Worker  * possible to use periodic sampling as a means for tracking the overflow of
1794*d83cc019SAndroid Build Coastguard Worker  * 32bit OA report timestamps.
1795*d83cc019SAndroid Build Coastguard Worker  */
1796*d83cc019SAndroid Build Coastguard Worker static void
test_invalid_oa_exponent(void)1797*d83cc019SAndroid Build Coastguard Worker test_invalid_oa_exponent(void)
1798*d83cc019SAndroid Build Coastguard Worker {
1799*d83cc019SAndroid Build Coastguard Worker 	uint64_t properties[] = {
1800*d83cc019SAndroid Build Coastguard Worker 		/* Include OA reports in samples */
1801*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_SAMPLE_OA, true,
1802*d83cc019SAndroid Build Coastguard Worker 
1803*d83cc019SAndroid Build Coastguard Worker 		/* OA unit configuration */
1804*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_METRICS_SET, test_metric_set_id,
1805*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_FORMAT, test_oa_format,
1806*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_EXPONENT, 31, /* maximum exponent expected
1807*d83cc019SAndroid Build Coastguard Worker 						       to be accepted */
1808*d83cc019SAndroid Build Coastguard Worker 	};
1809*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_perf_open_param param = {
1810*d83cc019SAndroid Build Coastguard Worker 		.flags = I915_PERF_FLAG_FD_CLOEXEC,
1811*d83cc019SAndroid Build Coastguard Worker 		.num_properties = sizeof(properties) / 16,
1812*d83cc019SAndroid Build Coastguard Worker 		.properties_ptr = to_user_pointer(properties),
1813*d83cc019SAndroid Build Coastguard Worker 	};
1814*d83cc019SAndroid Build Coastguard Worker 
1815*d83cc019SAndroid Build Coastguard Worker 	stream_fd = __perf_open(drm_fd, &param, false);
1816*d83cc019SAndroid Build Coastguard Worker 
1817*d83cc019SAndroid Build Coastguard Worker 	__perf_close(stream_fd);
1818*d83cc019SAndroid Build Coastguard Worker 
1819*d83cc019SAndroid Build Coastguard Worker 	for (int i = 32; i < 65; i++) {
1820*d83cc019SAndroid Build Coastguard Worker 		properties[7] = i;
1821*d83cc019SAndroid Build Coastguard Worker 		do_ioctl_err(drm_fd, DRM_IOCTL_I915_PERF_OPEN, &param, EINVAL);
1822*d83cc019SAndroid Build Coastguard Worker 	}
1823*d83cc019SAndroid Build Coastguard Worker }
1824*d83cc019SAndroid Build Coastguard Worker 
1825*d83cc019SAndroid Build Coastguard Worker /* The lowest periodic sampling exponent equates to a period of 160 nanoseconds
1826*d83cc019SAndroid Build Coastguard Worker  * or a frequency of 6.25MHz which is only possible to request as root by
1827*d83cc019SAndroid Build Coastguard Worker  * default. By default the maximum OA sampling rate is 100KHz
1828*d83cc019SAndroid Build Coastguard Worker  */
1829*d83cc019SAndroid Build Coastguard Worker static void
test_low_oa_exponent_permissions(void)1830*d83cc019SAndroid Build Coastguard Worker test_low_oa_exponent_permissions(void)
1831*d83cc019SAndroid Build Coastguard Worker {
1832*d83cc019SAndroid Build Coastguard Worker 	int max_freq = read_u64_file("/proc/sys/dev/i915/oa_max_sample_rate");
1833*d83cc019SAndroid Build Coastguard Worker 	int bad_exponent = max_oa_exponent_for_freq_gt(max_freq);
1834*d83cc019SAndroid Build Coastguard Worker 	int ok_exponent = bad_exponent + 1;
1835*d83cc019SAndroid Build Coastguard Worker 	uint64_t properties[] = {
1836*d83cc019SAndroid Build Coastguard Worker 		/* Include OA reports in samples */
1837*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_SAMPLE_OA, true,
1838*d83cc019SAndroid Build Coastguard Worker 
1839*d83cc019SAndroid Build Coastguard Worker 		/* OA unit configuration */
1840*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_METRICS_SET, test_metric_set_id,
1841*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_FORMAT, test_oa_format,
1842*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_EXPONENT, bad_exponent,
1843*d83cc019SAndroid Build Coastguard Worker 	};
1844*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_perf_open_param param = {
1845*d83cc019SAndroid Build Coastguard Worker 		.flags = I915_PERF_FLAG_FD_CLOEXEC,
1846*d83cc019SAndroid Build Coastguard Worker 		.num_properties = sizeof(properties) / 16,
1847*d83cc019SAndroid Build Coastguard Worker 		.properties_ptr = to_user_pointer(properties),
1848*d83cc019SAndroid Build Coastguard Worker 	};
1849*d83cc019SAndroid Build Coastguard Worker 	uint64_t oa_period, oa_freq;
1850*d83cc019SAndroid Build Coastguard Worker 
1851*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(max_freq, 100000);
1852*d83cc019SAndroid Build Coastguard Worker 
1853*d83cc019SAndroid Build Coastguard Worker 	/* Avoid EACCES errors opening a stream without CAP_SYS_ADMIN */
1854*d83cc019SAndroid Build Coastguard Worker 	write_u64_file("/proc/sys/dev/i915/perf_stream_paranoid", 0);
1855*d83cc019SAndroid Build Coastguard Worker 
1856*d83cc019SAndroid Build Coastguard Worker 	igt_fork(child, 1) {
1857*d83cc019SAndroid Build Coastguard Worker 		igt_drop_root();
1858*d83cc019SAndroid Build Coastguard Worker 
1859*d83cc019SAndroid Build Coastguard Worker 		do_ioctl_err(drm_fd, DRM_IOCTL_I915_PERF_OPEN, &param, EACCES);
1860*d83cc019SAndroid Build Coastguard Worker 	}
1861*d83cc019SAndroid Build Coastguard Worker 
1862*d83cc019SAndroid Build Coastguard Worker 	igt_waitchildren();
1863*d83cc019SAndroid Build Coastguard Worker 
1864*d83cc019SAndroid Build Coastguard Worker 	properties[7] = ok_exponent;
1865*d83cc019SAndroid Build Coastguard Worker 
1866*d83cc019SAndroid Build Coastguard Worker 	igt_fork(child, 1) {
1867*d83cc019SAndroid Build Coastguard Worker 		igt_drop_root();
1868*d83cc019SAndroid Build Coastguard Worker 
1869*d83cc019SAndroid Build Coastguard Worker 		stream_fd = __perf_open(drm_fd, &param, false);
1870*d83cc019SAndroid Build Coastguard Worker 		__perf_close(stream_fd);
1871*d83cc019SAndroid Build Coastguard Worker 	}
1872*d83cc019SAndroid Build Coastguard Worker 
1873*d83cc019SAndroid Build Coastguard Worker 	igt_waitchildren();
1874*d83cc019SAndroid Build Coastguard Worker 
1875*d83cc019SAndroid Build Coastguard Worker 	oa_period = timebase_scale(2 << ok_exponent);
1876*d83cc019SAndroid Build Coastguard Worker 	oa_freq = NSEC_PER_SEC / oa_period;
1877*d83cc019SAndroid Build Coastguard Worker 	write_u64_file("/proc/sys/dev/i915/oa_max_sample_rate", oa_freq - 100);
1878*d83cc019SAndroid Build Coastguard Worker 
1879*d83cc019SAndroid Build Coastguard Worker 	igt_fork(child, 1) {
1880*d83cc019SAndroid Build Coastguard Worker 		igt_drop_root();
1881*d83cc019SAndroid Build Coastguard Worker 
1882*d83cc019SAndroid Build Coastguard Worker 		do_ioctl_err(drm_fd, DRM_IOCTL_I915_PERF_OPEN, &param, EACCES);
1883*d83cc019SAndroid Build Coastguard Worker 	}
1884*d83cc019SAndroid Build Coastguard Worker 
1885*d83cc019SAndroid Build Coastguard Worker 	igt_waitchildren();
1886*d83cc019SAndroid Build Coastguard Worker 
1887*d83cc019SAndroid Build Coastguard Worker 	/* restore the defaults */
1888*d83cc019SAndroid Build Coastguard Worker 	write_u64_file("/proc/sys/dev/i915/oa_max_sample_rate", 100000);
1889*d83cc019SAndroid Build Coastguard Worker 	write_u64_file("/proc/sys/dev/i915/perf_stream_paranoid", 1);
1890*d83cc019SAndroid Build Coastguard Worker }
1891*d83cc019SAndroid Build Coastguard Worker 
1892*d83cc019SAndroid Build Coastguard Worker static void
test_per_context_mode_unprivileged(void)1893*d83cc019SAndroid Build Coastguard Worker test_per_context_mode_unprivileged(void)
1894*d83cc019SAndroid Build Coastguard Worker {
1895*d83cc019SAndroid Build Coastguard Worker 	uint64_t properties[] = {
1896*d83cc019SAndroid Build Coastguard Worker 		/* Single context sampling */
1897*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_CTX_HANDLE, UINT64_MAX, /* updated below */
1898*d83cc019SAndroid Build Coastguard Worker 
1899*d83cc019SAndroid Build Coastguard Worker 		/* Include OA reports in samples */
1900*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_SAMPLE_OA, true,
1901*d83cc019SAndroid Build Coastguard Worker 
1902*d83cc019SAndroid Build Coastguard Worker 		/* OA unit configuration */
1903*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_METRICS_SET, test_metric_set_id,
1904*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_FORMAT, test_oa_format,
1905*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_EXPONENT, oa_exp_1_millisec,
1906*d83cc019SAndroid Build Coastguard Worker 	};
1907*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_perf_open_param param = {
1908*d83cc019SAndroid Build Coastguard Worker 		.flags = I915_PERF_FLAG_FD_CLOEXEC,
1909*d83cc019SAndroid Build Coastguard Worker 		.num_properties = sizeof(properties) / 16,
1910*d83cc019SAndroid Build Coastguard Worker 		.properties_ptr = to_user_pointer(properties),
1911*d83cc019SAndroid Build Coastguard Worker 	};
1912*d83cc019SAndroid Build Coastguard Worker 
1913*d83cc019SAndroid Build Coastguard Worker 	/* should be default, but just to be sure... */
1914*d83cc019SAndroid Build Coastguard Worker 	write_u64_file("/proc/sys/dev/i915/perf_stream_paranoid", 1);
1915*d83cc019SAndroid Build Coastguard Worker 
1916*d83cc019SAndroid Build Coastguard Worker 	igt_fork(child, 1) {
1917*d83cc019SAndroid Build Coastguard Worker 		drm_intel_context *context;
1918*d83cc019SAndroid Build Coastguard Worker 		drm_intel_bufmgr *bufmgr;
1919*d83cc019SAndroid Build Coastguard Worker 		uint32_t ctx_id = 0xffffffff; /* invalid id */
1920*d83cc019SAndroid Build Coastguard Worker 		int ret;
1921*d83cc019SAndroid Build Coastguard Worker 
1922*d83cc019SAndroid Build Coastguard Worker 		igt_drop_root();
1923*d83cc019SAndroid Build Coastguard Worker 
1924*d83cc019SAndroid Build Coastguard Worker 		bufmgr = drm_intel_bufmgr_gem_init(drm_fd, 4096);
1925*d83cc019SAndroid Build Coastguard Worker 		context = drm_intel_gem_context_create(bufmgr);
1926*d83cc019SAndroid Build Coastguard Worker 
1927*d83cc019SAndroid Build Coastguard Worker 		igt_assert(context);
1928*d83cc019SAndroid Build Coastguard Worker 
1929*d83cc019SAndroid Build Coastguard Worker 		ret = drm_intel_gem_context_get_id(context, &ctx_id);
1930*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(ret, 0);
1931*d83cc019SAndroid Build Coastguard Worker 		igt_assert_neq(ctx_id, 0xffffffff);
1932*d83cc019SAndroid Build Coastguard Worker 
1933*d83cc019SAndroid Build Coastguard Worker 		properties[1] = ctx_id;
1934*d83cc019SAndroid Build Coastguard Worker 
1935*d83cc019SAndroid Build Coastguard Worker 		stream_fd = __perf_open(drm_fd, &param, false);
1936*d83cc019SAndroid Build Coastguard Worker 		__perf_close(stream_fd);
1937*d83cc019SAndroid Build Coastguard Worker 
1938*d83cc019SAndroid Build Coastguard Worker 		drm_intel_gem_context_destroy(context);
1939*d83cc019SAndroid Build Coastguard Worker 		drm_intel_bufmgr_destroy(bufmgr);
1940*d83cc019SAndroid Build Coastguard Worker 	}
1941*d83cc019SAndroid Build Coastguard Worker 
1942*d83cc019SAndroid Build Coastguard Worker 	igt_waitchildren();
1943*d83cc019SAndroid Build Coastguard Worker }
1944*d83cc019SAndroid Build Coastguard Worker 
1945*d83cc019SAndroid Build Coastguard Worker static int64_t
get_time(void)1946*d83cc019SAndroid Build Coastguard Worker get_time(void)
1947*d83cc019SAndroid Build Coastguard Worker {
1948*d83cc019SAndroid Build Coastguard Worker 	struct timespec ts;
1949*d83cc019SAndroid Build Coastguard Worker 
1950*d83cc019SAndroid Build Coastguard Worker 	clock_gettime(CLOCK_MONOTONIC, &ts);
1951*d83cc019SAndroid Build Coastguard Worker 
1952*d83cc019SAndroid Build Coastguard Worker 	return ts.tv_sec * 1000000000 + ts.tv_nsec;
1953*d83cc019SAndroid Build Coastguard Worker }
1954*d83cc019SAndroid Build Coastguard Worker 
1955*d83cc019SAndroid Build Coastguard Worker /* Note: The interface doesn't currently provide strict guarantees or control
1956*d83cc019SAndroid Build Coastguard Worker  * over the upper bound for how long it might take for a POLLIN event after
1957*d83cc019SAndroid Build Coastguard Worker  * some OA report is written by the OA unit.
1958*d83cc019SAndroid Build Coastguard Worker  *
1959*d83cc019SAndroid Build Coastguard Worker  * The plan is to add a property later that gives some control over the maximum
1960*d83cc019SAndroid Build Coastguard Worker  * latency, but for now we expect it is tuned for a fairly low latency
1961*d83cc019SAndroid Build Coastguard Worker  * suitable for applications wanting to provide live feedback for captured
1962*d83cc019SAndroid Build Coastguard Worker  * metrics.
1963*d83cc019SAndroid Build Coastguard Worker  *
1964*d83cc019SAndroid Build Coastguard Worker  * At the time of writing this test the driver was using a fixed 200Hz hrtimer
1965*d83cc019SAndroid Build Coastguard Worker  * regardless of the OA sampling exponent.
1966*d83cc019SAndroid Build Coastguard Worker  *
1967*d83cc019SAndroid Build Coastguard Worker  * There is no lower bound since a stream configured for periodic sampling may
1968*d83cc019SAndroid Build Coastguard Worker  * still contain other automatically triggered reports.
1969*d83cc019SAndroid Build Coastguard Worker  *
1970*d83cc019SAndroid Build Coastguard Worker  * What we try and check for here is that blocking reads don't return EAGAIN
1971*d83cc019SAndroid Build Coastguard Worker  * and that we aren't spending any significant time burning the cpu in
1972*d83cc019SAndroid Build Coastguard Worker  * kernelspace.
1973*d83cc019SAndroid Build Coastguard Worker  */
1974*d83cc019SAndroid Build Coastguard Worker static void
test_blocking(void)1975*d83cc019SAndroid Build Coastguard Worker test_blocking(void)
1976*d83cc019SAndroid Build Coastguard Worker {
1977*d83cc019SAndroid Build Coastguard Worker 	/* ~40 milliseconds
1978*d83cc019SAndroid Build Coastguard Worker 	 *
1979*d83cc019SAndroid Build Coastguard Worker 	 * Having a period somewhat > sysconf(_SC_CLK_TCK) helps to stop
1980*d83cc019SAndroid Build Coastguard Worker 	 * scheduling (liable to kick in when we make blocking poll()s/reads)
1981*d83cc019SAndroid Build Coastguard Worker 	 * from interfering with the test.
1982*d83cc019SAndroid Build Coastguard Worker 	 */
1983*d83cc019SAndroid Build Coastguard Worker 	int oa_exponent = max_oa_exponent_for_period_lte(40000000);
1984*d83cc019SAndroid Build Coastguard Worker 	uint64_t oa_period = oa_exponent_to_ns(oa_exponent);
1985*d83cc019SAndroid Build Coastguard Worker 	uint64_t properties[] = {
1986*d83cc019SAndroid Build Coastguard Worker 		/* Include OA reports in samples */
1987*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_SAMPLE_OA, true,
1988*d83cc019SAndroid Build Coastguard Worker 
1989*d83cc019SAndroid Build Coastguard Worker 		/* OA unit configuration */
1990*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_METRICS_SET, test_metric_set_id,
1991*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_FORMAT, test_oa_format,
1992*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_EXPONENT, oa_exponent,
1993*d83cc019SAndroid Build Coastguard Worker 	};
1994*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_perf_open_param param = {
1995*d83cc019SAndroid Build Coastguard Worker 		.flags = I915_PERF_FLAG_FD_CLOEXEC |
1996*d83cc019SAndroid Build Coastguard Worker 			I915_PERF_FLAG_DISABLED,
1997*d83cc019SAndroid Build Coastguard Worker 		.num_properties = sizeof(properties) / 16,
1998*d83cc019SAndroid Build Coastguard Worker 		.properties_ptr = to_user_pointer(properties),
1999*d83cc019SAndroid Build Coastguard Worker 	};
2000*d83cc019SAndroid Build Coastguard Worker 	uint8_t buf[1024 * 1024];
2001*d83cc019SAndroid Build Coastguard Worker 	struct tms start_times;
2002*d83cc019SAndroid Build Coastguard Worker 	struct tms end_times;
2003*d83cc019SAndroid Build Coastguard Worker 	int64_t user_ns, kernel_ns;
2004*d83cc019SAndroid Build Coastguard Worker 	int64_t tick_ns = 1000000000 / sysconf(_SC_CLK_TCK);
2005*d83cc019SAndroid Build Coastguard Worker 	int64_t test_duration_ns = tick_ns * 1000;
2006*d83cc019SAndroid Build Coastguard Worker 
2007*d83cc019SAndroid Build Coastguard Worker 	int max_iterations = (test_duration_ns / oa_period) + 2;
2008*d83cc019SAndroid Build Coastguard Worker 	int n_extra_iterations = 0;
2009*d83cc019SAndroid Build Coastguard Worker 
2010*d83cc019SAndroid Build Coastguard Worker 	/* It's a bit tricky to put a lower limit here, but we expect a
2011*d83cc019SAndroid Build Coastguard Worker 	 * relatively low latency for seeing reports, while we don't currently
2012*d83cc019SAndroid Build Coastguard Worker 	 * give any control over this in the api.
2013*d83cc019SAndroid Build Coastguard Worker 	 *
2014*d83cc019SAndroid Build Coastguard Worker 	 * We assume a maximum latency of 6 millisecond to deliver a POLLIN and
2015*d83cc019SAndroid Build Coastguard Worker 	 * read() after a new sample is written (46ms per iteration) considering
2016*d83cc019SAndroid Build Coastguard Worker 	 * the knowledge that that the driver uses a 200Hz hrtimer (5ms period)
2017*d83cc019SAndroid Build Coastguard Worker 	 * to check for data and giving some time to read().
2018*d83cc019SAndroid Build Coastguard Worker 	 */
2019*d83cc019SAndroid Build Coastguard Worker 	int min_iterations = (test_duration_ns / (oa_period + 6000000ull));
2020*d83cc019SAndroid Build Coastguard Worker 
2021*d83cc019SAndroid Build Coastguard Worker 	int64_t start, end;
2022*d83cc019SAndroid Build Coastguard Worker 	int n = 0;
2023*d83cc019SAndroid Build Coastguard Worker 
2024*d83cc019SAndroid Build Coastguard Worker 	stream_fd = __perf_open(drm_fd, &param, true /* prevent_pm */);
2025*d83cc019SAndroid Build Coastguard Worker 
2026*d83cc019SAndroid Build Coastguard Worker 	times(&start_times);
2027*d83cc019SAndroid Build Coastguard Worker 
2028*d83cc019SAndroid Build Coastguard Worker 	igt_debug("tick length = %dns, test duration = %"PRIu64"ns, min iter. = %d,"
2029*d83cc019SAndroid Build Coastguard Worker 		  " estimated max iter. = %d, oa_period = %"PRIu64"ns\n",
2030*d83cc019SAndroid Build Coastguard Worker 		  (int)tick_ns, test_duration_ns,
2031*d83cc019SAndroid Build Coastguard Worker 		  min_iterations, max_iterations, oa_period);
2032*d83cc019SAndroid Build Coastguard Worker 
2033*d83cc019SAndroid Build Coastguard Worker 	/* In the loop we perform blocking polls while the HW is sampling at
2034*d83cc019SAndroid Build Coastguard Worker 	 * ~25Hz, with the expectation that we spend most of our time blocked
2035*d83cc019SAndroid Build Coastguard Worker 	 * in the kernel, and shouldn't be burning cpu cycles in the kernel in
2036*d83cc019SAndroid Build Coastguard Worker 	 * association with this process (verified by looking at stime before
2037*d83cc019SAndroid Build Coastguard Worker 	 * and after loop).
2038*d83cc019SAndroid Build Coastguard Worker 	 *
2039*d83cc019SAndroid Build Coastguard Worker 	 * We're looking to assert that less than 1% of the test duration is
2040*d83cc019SAndroid Build Coastguard Worker 	 * spent in the kernel dealing with polling and read()ing.
2041*d83cc019SAndroid Build Coastguard Worker 	 *
2042*d83cc019SAndroid Build Coastguard Worker 	 * The test runs for a relatively long time considering the very low
2043*d83cc019SAndroid Build Coastguard Worker 	 * resolution of stime in ticks of typically 10 milliseconds. Since we
2044*d83cc019SAndroid Build Coastguard Worker 	 * don't know the fractional part of tick values we read from userspace
2045*d83cc019SAndroid Build Coastguard Worker 	 * so our minimum threshold needs to be >= one tick since any
2046*d83cc019SAndroid Build Coastguard Worker 	 * measurement might really be +- tick_ns (assuming we effectively get
2047*d83cc019SAndroid Build Coastguard Worker 	 * floor(real_stime)).
2048*d83cc019SAndroid Build Coastguard Worker 	 *
2049*d83cc019SAndroid Build Coastguard Worker 	 * We Loop for 1000 x tick_ns so one tick corresponds to 0.1%
2050*d83cc019SAndroid Build Coastguard Worker 	 *
2051*d83cc019SAndroid Build Coastguard Worker 	 * Also enable the stream just before poll/read to minimize
2052*d83cc019SAndroid Build Coastguard Worker 	 * the error delta.
2053*d83cc019SAndroid Build Coastguard Worker 	 */
2054*d83cc019SAndroid Build Coastguard Worker 	start = get_time();
2055*d83cc019SAndroid Build Coastguard Worker 	do_ioctl(stream_fd, I915_PERF_IOCTL_ENABLE, 0);
2056*d83cc019SAndroid Build Coastguard Worker 	for (/* nop */; ((end = get_time()) - start) < test_duration_ns; /* nop */) {
2057*d83cc019SAndroid Build Coastguard Worker 		struct drm_i915_perf_record_header *header;
2058*d83cc019SAndroid Build Coastguard Worker 		bool timer_report_read = false;
2059*d83cc019SAndroid Build Coastguard Worker 		bool non_timer_report_read = false;
2060*d83cc019SAndroid Build Coastguard Worker 		int ret;
2061*d83cc019SAndroid Build Coastguard Worker 
2062*d83cc019SAndroid Build Coastguard Worker 		while ((ret = read(stream_fd, buf, sizeof(buf))) < 0 &&
2063*d83cc019SAndroid Build Coastguard Worker 		       errno == EINTR)
2064*d83cc019SAndroid Build Coastguard Worker 			;
2065*d83cc019SAndroid Build Coastguard Worker 
2066*d83cc019SAndroid Build Coastguard Worker 		igt_assert(ret > 0);
2067*d83cc019SAndroid Build Coastguard Worker 
2068*d83cc019SAndroid Build Coastguard Worker 		/* For Haswell reports don't contain a well defined reason
2069*d83cc019SAndroid Build Coastguard Worker 		 * field we so assume all reports to be 'periodic'. For gen8+
2070*d83cc019SAndroid Build Coastguard Worker 		 * we want to to consider that the HW automatically writes some
2071*d83cc019SAndroid Build Coastguard Worker 		 * non periodic reports (e.g. on context switch) which might
2072*d83cc019SAndroid Build Coastguard Worker 		 * lead to more successful read()s than expected due to
2073*d83cc019SAndroid Build Coastguard Worker 		 * periodic sampling and we don't want these extra reads to
2074*d83cc019SAndroid Build Coastguard Worker 		 * cause the test to fail...
2075*d83cc019SAndroid Build Coastguard Worker 		 */
2076*d83cc019SAndroid Build Coastguard Worker 		if (intel_gen(devid) >= 8) {
2077*d83cc019SAndroid Build Coastguard Worker 			for (int offset = 0; offset < ret; offset += header->size) {
2078*d83cc019SAndroid Build Coastguard Worker 				header = (void *)(buf + offset);
2079*d83cc019SAndroid Build Coastguard Worker 
2080*d83cc019SAndroid Build Coastguard Worker 				if (header->type == DRM_I915_PERF_RECORD_SAMPLE) {
2081*d83cc019SAndroid Build Coastguard Worker 					uint32_t *report = (void *)(header + 1);
2082*d83cc019SAndroid Build Coastguard Worker 
2083*d83cc019SAndroid Build Coastguard Worker 					if (oa_report_is_periodic(oa_exponent,
2084*d83cc019SAndroid Build Coastguard Worker 								  report))
2085*d83cc019SAndroid Build Coastguard Worker 						timer_report_read = true;
2086*d83cc019SAndroid Build Coastguard Worker 					else
2087*d83cc019SAndroid Build Coastguard Worker 						non_timer_report_read = true;
2088*d83cc019SAndroid Build Coastguard Worker 				}
2089*d83cc019SAndroid Build Coastguard Worker 			}
2090*d83cc019SAndroid Build Coastguard Worker 		}
2091*d83cc019SAndroid Build Coastguard Worker 
2092*d83cc019SAndroid Build Coastguard Worker 		if (non_timer_report_read && !timer_report_read)
2093*d83cc019SAndroid Build Coastguard Worker 			n_extra_iterations++;
2094*d83cc019SAndroid Build Coastguard Worker 
2095*d83cc019SAndroid Build Coastguard Worker 		n++;
2096*d83cc019SAndroid Build Coastguard Worker 	}
2097*d83cc019SAndroid Build Coastguard Worker 
2098*d83cc019SAndroid Build Coastguard Worker 	times(&end_times);
2099*d83cc019SAndroid Build Coastguard Worker 
2100*d83cc019SAndroid Build Coastguard Worker 	/* Using nanosecond units is fairly silly here, given the tick in-
2101*d83cc019SAndroid Build Coastguard Worker 	 * precision - ah well, it's consistent with the get_time() units.
2102*d83cc019SAndroid Build Coastguard Worker 	 */
2103*d83cc019SAndroid Build Coastguard Worker 	user_ns = (end_times.tms_utime - start_times.tms_utime) * tick_ns;
2104*d83cc019SAndroid Build Coastguard Worker 	kernel_ns = (end_times.tms_stime - start_times.tms_stime) * tick_ns;
2105*d83cc019SAndroid Build Coastguard Worker 
2106*d83cc019SAndroid Build Coastguard Worker 	igt_debug("%d blocking reads during test with ~25Hz OA sampling (expect no more than %d)\n",
2107*d83cc019SAndroid Build Coastguard Worker 		  n, max_iterations);
2108*d83cc019SAndroid Build Coastguard Worker 	igt_debug("%d extra iterations seen, not related to periodic sampling (e.g. context switches)\n",
2109*d83cc019SAndroid Build Coastguard Worker 		  n_extra_iterations);
2110*d83cc019SAndroid Build Coastguard Worker 	igt_debug("time in userspace = %"PRIu64"ns (+-%dns) (start utime = %d, end = %d)\n",
2111*d83cc019SAndroid Build Coastguard Worker 		  user_ns, (int)tick_ns,
2112*d83cc019SAndroid Build Coastguard Worker 		  (int)start_times.tms_utime, (int)end_times.tms_utime);
2113*d83cc019SAndroid Build Coastguard Worker 	igt_debug("time in kernelspace = %"PRIu64"ns (+-%dns) (start stime = %d, end = %d)\n",
2114*d83cc019SAndroid Build Coastguard Worker 		  kernel_ns, (int)tick_ns,
2115*d83cc019SAndroid Build Coastguard Worker 		  (int)start_times.tms_stime, (int)end_times.tms_stime);
2116*d83cc019SAndroid Build Coastguard Worker 
2117*d83cc019SAndroid Build Coastguard Worker 	/* With completely broken blocking (but also not returning an error) we
2118*d83cc019SAndroid Build Coastguard Worker 	 * could end up with an open loop,
2119*d83cc019SAndroid Build Coastguard Worker 	 */
2120*d83cc019SAndroid Build Coastguard Worker 	igt_assert(n <= (max_iterations + n_extra_iterations));
2121*d83cc019SAndroid Build Coastguard Worker 
2122*d83cc019SAndroid Build Coastguard Worker 	/* Make sure the driver is reporting new samples with a reasonably
2123*d83cc019SAndroid Build Coastguard Worker 	 * low latency...
2124*d83cc019SAndroid Build Coastguard Worker 	 */
2125*d83cc019SAndroid Build Coastguard Worker 	igt_assert(n > (min_iterations + n_extra_iterations));
2126*d83cc019SAndroid Build Coastguard Worker 
2127*d83cc019SAndroid Build Coastguard Worker 	igt_assert(kernel_ns <= (test_duration_ns / 100ull));
2128*d83cc019SAndroid Build Coastguard Worker 
2129*d83cc019SAndroid Build Coastguard Worker 	__perf_close(stream_fd);
2130*d83cc019SAndroid Build Coastguard Worker }
2131*d83cc019SAndroid Build Coastguard Worker 
2132*d83cc019SAndroid Build Coastguard Worker static void
test_polling(void)2133*d83cc019SAndroid Build Coastguard Worker test_polling(void)
2134*d83cc019SAndroid Build Coastguard Worker {
2135*d83cc019SAndroid Build Coastguard Worker 	/* ~40 milliseconds
2136*d83cc019SAndroid Build Coastguard Worker 	 *
2137*d83cc019SAndroid Build Coastguard Worker 	 * Having a period somewhat > sysconf(_SC_CLK_TCK) helps to stop
2138*d83cc019SAndroid Build Coastguard Worker 	 * scheduling (liable to kick in when we make blocking poll()s/reads)
2139*d83cc019SAndroid Build Coastguard Worker 	 * from interfering with the test.
2140*d83cc019SAndroid Build Coastguard Worker 	 */
2141*d83cc019SAndroid Build Coastguard Worker 	int oa_exponent = max_oa_exponent_for_period_lte(40000000);
2142*d83cc019SAndroid Build Coastguard Worker 	uint64_t oa_period = oa_exponent_to_ns(oa_exponent);
2143*d83cc019SAndroid Build Coastguard Worker 	uint64_t properties[] = {
2144*d83cc019SAndroid Build Coastguard Worker 		/* Include OA reports in samples */
2145*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_SAMPLE_OA, true,
2146*d83cc019SAndroid Build Coastguard Worker 
2147*d83cc019SAndroid Build Coastguard Worker 		/* OA unit configuration */
2148*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_METRICS_SET, test_metric_set_id,
2149*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_FORMAT, test_oa_format,
2150*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_EXPONENT, oa_exponent,
2151*d83cc019SAndroid Build Coastguard Worker 	};
2152*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_perf_open_param param = {
2153*d83cc019SAndroid Build Coastguard Worker 		.flags = I915_PERF_FLAG_FD_CLOEXEC |
2154*d83cc019SAndroid Build Coastguard Worker 			I915_PERF_FLAG_DISABLED |
2155*d83cc019SAndroid Build Coastguard Worker 			I915_PERF_FLAG_FD_NONBLOCK,
2156*d83cc019SAndroid Build Coastguard Worker 		.num_properties = sizeof(properties) / 16,
2157*d83cc019SAndroid Build Coastguard Worker 		.properties_ptr = to_user_pointer(properties),
2158*d83cc019SAndroid Build Coastguard Worker 	};
2159*d83cc019SAndroid Build Coastguard Worker 	uint8_t buf[1024 * 1024];
2160*d83cc019SAndroid Build Coastguard Worker 	struct tms start_times;
2161*d83cc019SAndroid Build Coastguard Worker 	struct tms end_times;
2162*d83cc019SAndroid Build Coastguard Worker 	int64_t user_ns, kernel_ns;
2163*d83cc019SAndroid Build Coastguard Worker 	int64_t tick_ns = 1000000000 / sysconf(_SC_CLK_TCK);
2164*d83cc019SAndroid Build Coastguard Worker 	int64_t test_duration_ns = tick_ns * 1000;
2165*d83cc019SAndroid Build Coastguard Worker 
2166*d83cc019SAndroid Build Coastguard Worker 	int max_iterations = (test_duration_ns / oa_period) + 2;
2167*d83cc019SAndroid Build Coastguard Worker 	int n_extra_iterations = 0;
2168*d83cc019SAndroid Build Coastguard Worker 
2169*d83cc019SAndroid Build Coastguard Worker 	/* It's a bit tricky to put a lower limit here, but we expect a
2170*d83cc019SAndroid Build Coastguard Worker 	 * relatively low latency for seeing reports, while we don't currently
2171*d83cc019SAndroid Build Coastguard Worker 	 * give any control over this in the api.
2172*d83cc019SAndroid Build Coastguard Worker 	 *
2173*d83cc019SAndroid Build Coastguard Worker 	 * We assume a maximum latency of 6 millisecond to deliver a POLLIN and
2174*d83cc019SAndroid Build Coastguard Worker 	 * read() after a new sample is written (46ms per iteration) considering
2175*d83cc019SAndroid Build Coastguard Worker 	 * the knowledge that that the driver uses a 200Hz hrtimer (5ms period)
2176*d83cc019SAndroid Build Coastguard Worker 	 * to check for data and giving some time to read().
2177*d83cc019SAndroid Build Coastguard Worker 	 */
2178*d83cc019SAndroid Build Coastguard Worker 	int min_iterations = (test_duration_ns / (oa_period + 6000000ull));
2179*d83cc019SAndroid Build Coastguard Worker 	int64_t start, end;
2180*d83cc019SAndroid Build Coastguard Worker 	int n = 0;
2181*d83cc019SAndroid Build Coastguard Worker 
2182*d83cc019SAndroid Build Coastguard Worker 	stream_fd = __perf_open(drm_fd, &param, true /* prevent_pm */);
2183*d83cc019SAndroid Build Coastguard Worker 
2184*d83cc019SAndroid Build Coastguard Worker 	times(&start_times);
2185*d83cc019SAndroid Build Coastguard Worker 
2186*d83cc019SAndroid Build Coastguard Worker 	igt_debug("tick length = %dns, test duration = %"PRIu64"ns, min iter. = %d, max iter. = %d\n",
2187*d83cc019SAndroid Build Coastguard Worker 		  (int)tick_ns, test_duration_ns,
2188*d83cc019SAndroid Build Coastguard Worker 		  min_iterations, max_iterations);
2189*d83cc019SAndroid Build Coastguard Worker 
2190*d83cc019SAndroid Build Coastguard Worker 	/* In the loop we perform blocking polls while the HW is sampling at
2191*d83cc019SAndroid Build Coastguard Worker 	 * ~25Hz, with the expectation that we spend most of our time blocked
2192*d83cc019SAndroid Build Coastguard Worker 	 * in the kernel, and shouldn't be burning cpu cycles in the kernel in
2193*d83cc019SAndroid Build Coastguard Worker 	 * association with this process (verified by looking at stime before
2194*d83cc019SAndroid Build Coastguard Worker 	 * and after loop).
2195*d83cc019SAndroid Build Coastguard Worker 	 *
2196*d83cc019SAndroid Build Coastguard Worker 	 * We're looking to assert that less than 1% of the test duration is
2197*d83cc019SAndroid Build Coastguard Worker 	 * spent in the kernel dealing with polling and read()ing.
2198*d83cc019SAndroid Build Coastguard Worker 	 *
2199*d83cc019SAndroid Build Coastguard Worker 	 * The test runs for a relatively long time considering the very low
2200*d83cc019SAndroid Build Coastguard Worker 	 * resolution of stime in ticks of typically 10 milliseconds. Since we
2201*d83cc019SAndroid Build Coastguard Worker 	 * don't know the fractional part of tick values we read from userspace
2202*d83cc019SAndroid Build Coastguard Worker 	 * so our minimum threshold needs to be >= one tick since any
2203*d83cc019SAndroid Build Coastguard Worker 	 * measurement might really be +- tick_ns (assuming we effectively get
2204*d83cc019SAndroid Build Coastguard Worker 	 * floor(real_stime)).
2205*d83cc019SAndroid Build Coastguard Worker 	 *
2206*d83cc019SAndroid Build Coastguard Worker 	 * We Loop for 1000 x tick_ns so one tick corresponds to 0.1%
2207*d83cc019SAndroid Build Coastguard Worker 	 *
2208*d83cc019SAndroid Build Coastguard Worker 	 * Also enable the stream just before poll/read to minimize
2209*d83cc019SAndroid Build Coastguard Worker 	 * the error delta.
2210*d83cc019SAndroid Build Coastguard Worker 	 */
2211*d83cc019SAndroid Build Coastguard Worker 	start = get_time();
2212*d83cc019SAndroid Build Coastguard Worker 	do_ioctl(stream_fd, I915_PERF_IOCTL_ENABLE, 0);
2213*d83cc019SAndroid Build Coastguard Worker 	for (/* nop */; ((end = get_time()) - start) < test_duration_ns; /* nop */) {
2214*d83cc019SAndroid Build Coastguard Worker 		struct pollfd pollfd = { .fd = stream_fd, .events = POLLIN };
2215*d83cc019SAndroid Build Coastguard Worker 		struct drm_i915_perf_record_header *header;
2216*d83cc019SAndroid Build Coastguard Worker 		bool timer_report_read = false;
2217*d83cc019SAndroid Build Coastguard Worker 		bool non_timer_report_read = false;
2218*d83cc019SAndroid Build Coastguard Worker 		int ret;
2219*d83cc019SAndroid Build Coastguard Worker 
2220*d83cc019SAndroid Build Coastguard Worker 		while ((ret = poll(&pollfd, 1, -1)) < 0 &&
2221*d83cc019SAndroid Build Coastguard Worker 		       errno == EINTR)
2222*d83cc019SAndroid Build Coastguard Worker 			;
2223*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(ret, 1);
2224*d83cc019SAndroid Build Coastguard Worker 		igt_assert(pollfd.revents & POLLIN);
2225*d83cc019SAndroid Build Coastguard Worker 
2226*d83cc019SAndroid Build Coastguard Worker 		while ((ret = read(stream_fd, buf, sizeof(buf))) < 0 &&
2227*d83cc019SAndroid Build Coastguard Worker 		       errno == EINTR)
2228*d83cc019SAndroid Build Coastguard Worker 			;
2229*d83cc019SAndroid Build Coastguard Worker 
2230*d83cc019SAndroid Build Coastguard Worker 		/* Don't expect to see EAGAIN if we've had a POLLIN event
2231*d83cc019SAndroid Build Coastguard Worker 		 *
2232*d83cc019SAndroid Build Coastguard Worker 		 * XXX: actually this is technically overly strict since we do
2233*d83cc019SAndroid Build Coastguard Worker 		 * knowingly allow false positive POLLIN events. At least in
2234*d83cc019SAndroid Build Coastguard Worker 		 * the future when supporting context filtering of metrics for
2235*d83cc019SAndroid Build Coastguard Worker 		 * Gen8+ handled in the kernel then POLLIN events may be
2236*d83cc019SAndroid Build Coastguard Worker 		 * delivered when we know there are pending reports to process
2237*d83cc019SAndroid Build Coastguard Worker 		 * but before we've done any filtering to know for certain that
2238*d83cc019SAndroid Build Coastguard Worker 		 * any reports are destined to be copied to userspace.
2239*d83cc019SAndroid Build Coastguard Worker 		 *
2240*d83cc019SAndroid Build Coastguard Worker 		 * Still, for now it's a reasonable sanity check.
2241*d83cc019SAndroid Build Coastguard Worker 		 */
2242*d83cc019SAndroid Build Coastguard Worker 		if (ret < 0)
2243*d83cc019SAndroid Build Coastguard Worker 			igt_debug("Unexpected error when reading after poll = %d\n", errno);
2244*d83cc019SAndroid Build Coastguard Worker 		igt_assert_neq(ret, -1);
2245*d83cc019SAndroid Build Coastguard Worker 
2246*d83cc019SAndroid Build Coastguard Worker 		/* For Haswell reports don't contain a well defined reason
2247*d83cc019SAndroid Build Coastguard Worker 		 * field we so assume all reports to be 'periodic'. For gen8+
2248*d83cc019SAndroid Build Coastguard Worker 		 * we want to to consider that the HW automatically writes some
2249*d83cc019SAndroid Build Coastguard Worker 		 * non periodic reports (e.g. on context switch) which might
2250*d83cc019SAndroid Build Coastguard Worker 		 * lead to more successful read()s than expected due to
2251*d83cc019SAndroid Build Coastguard Worker 		 * periodic sampling and we don't want these extra reads to
2252*d83cc019SAndroid Build Coastguard Worker 		 * cause the test to fail...
2253*d83cc019SAndroid Build Coastguard Worker 		 */
2254*d83cc019SAndroid Build Coastguard Worker 		if (intel_gen(devid) >= 8) {
2255*d83cc019SAndroid Build Coastguard Worker 			for (int offset = 0; offset < ret; offset += header->size) {
2256*d83cc019SAndroid Build Coastguard Worker 				header = (void *)(buf + offset);
2257*d83cc019SAndroid Build Coastguard Worker 
2258*d83cc019SAndroid Build Coastguard Worker 				if (header->type == DRM_I915_PERF_RECORD_SAMPLE) {
2259*d83cc019SAndroid Build Coastguard Worker 					uint32_t *report = (void *)(header + 1);
2260*d83cc019SAndroid Build Coastguard Worker 
2261*d83cc019SAndroid Build Coastguard Worker 					if (oa_report_is_periodic(oa_exponent, report))
2262*d83cc019SAndroid Build Coastguard Worker 						timer_report_read = true;
2263*d83cc019SAndroid Build Coastguard Worker 					else
2264*d83cc019SAndroid Build Coastguard Worker 						non_timer_report_read = true;
2265*d83cc019SAndroid Build Coastguard Worker 				}
2266*d83cc019SAndroid Build Coastguard Worker 			}
2267*d83cc019SAndroid Build Coastguard Worker 		}
2268*d83cc019SAndroid Build Coastguard Worker 
2269*d83cc019SAndroid Build Coastguard Worker 		if (non_timer_report_read && !timer_report_read)
2270*d83cc019SAndroid Build Coastguard Worker 			n_extra_iterations++;
2271*d83cc019SAndroid Build Coastguard Worker 
2272*d83cc019SAndroid Build Coastguard Worker 		/* At this point, after consuming pending reports (and hoping
2273*d83cc019SAndroid Build Coastguard Worker 		 * the scheduler hasn't stopped us for too long we now
2274*d83cc019SAndroid Build Coastguard Worker 		 * expect EAGAIN on read.
2275*d83cc019SAndroid Build Coastguard Worker 		 */
2276*d83cc019SAndroid Build Coastguard Worker 		while ((ret = read(stream_fd, buf, sizeof(buf))) < 0 &&
2277*d83cc019SAndroid Build Coastguard Worker 		       errno == EINTR)
2278*d83cc019SAndroid Build Coastguard Worker 			;
2279*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(ret, -1);
2280*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(errno, EAGAIN);
2281*d83cc019SAndroid Build Coastguard Worker 
2282*d83cc019SAndroid Build Coastguard Worker 		n++;
2283*d83cc019SAndroid Build Coastguard Worker 	}
2284*d83cc019SAndroid Build Coastguard Worker 
2285*d83cc019SAndroid Build Coastguard Worker 	times(&end_times);
2286*d83cc019SAndroid Build Coastguard Worker 
2287*d83cc019SAndroid Build Coastguard Worker 	/* Using nanosecond units is fairly silly here, given the tick in-
2288*d83cc019SAndroid Build Coastguard Worker 	 * precision - ah well, it's consistent with the get_time() units.
2289*d83cc019SAndroid Build Coastguard Worker 	 */
2290*d83cc019SAndroid Build Coastguard Worker 	user_ns = (end_times.tms_utime - start_times.tms_utime) * tick_ns;
2291*d83cc019SAndroid Build Coastguard Worker 	kernel_ns = (end_times.tms_stime - start_times.tms_stime) * tick_ns;
2292*d83cc019SAndroid Build Coastguard Worker 
2293*d83cc019SAndroid Build Coastguard Worker 	igt_debug("%d blocking reads during test with ~25Hz OA sampling (expect no more than %d)\n",
2294*d83cc019SAndroid Build Coastguard Worker 		  n, max_iterations);
2295*d83cc019SAndroid Build Coastguard Worker 	igt_debug("%d extra iterations seen, not related to periodic sampling (e.g. context switches)\n",
2296*d83cc019SAndroid Build Coastguard Worker 		  n_extra_iterations);
2297*d83cc019SAndroid Build Coastguard Worker 	igt_debug("time in userspace = %"PRIu64"ns (+-%dns) (start utime = %d, end = %d)\n",
2298*d83cc019SAndroid Build Coastguard Worker 		  user_ns, (int)tick_ns,
2299*d83cc019SAndroid Build Coastguard Worker 		  (int)start_times.tms_utime, (int)end_times.tms_utime);
2300*d83cc019SAndroid Build Coastguard Worker 	igt_debug("time in kernelspace = %"PRIu64"ns (+-%dns) (start stime = %d, end = %d)\n",
2301*d83cc019SAndroid Build Coastguard Worker 		  kernel_ns, (int)tick_ns,
2302*d83cc019SAndroid Build Coastguard Worker 		  (int)start_times.tms_stime, (int)end_times.tms_stime);
2303*d83cc019SAndroid Build Coastguard Worker 
2304*d83cc019SAndroid Build Coastguard Worker 	/* With completely broken blocking while polling (but still somehow
2305*d83cc019SAndroid Build Coastguard Worker 	 * reporting a POLLIN event) we could end up with an open loop.
2306*d83cc019SAndroid Build Coastguard Worker 	 */
2307*d83cc019SAndroid Build Coastguard Worker 	igt_assert(n <= (max_iterations + n_extra_iterations));
2308*d83cc019SAndroid Build Coastguard Worker 
2309*d83cc019SAndroid Build Coastguard Worker 	/* Make sure the driver is reporting new samples with a reasonably
2310*d83cc019SAndroid Build Coastguard Worker 	 * low latency...
2311*d83cc019SAndroid Build Coastguard Worker 	 */
2312*d83cc019SAndroid Build Coastguard Worker 	igt_assert(n > (min_iterations + n_extra_iterations));
2313*d83cc019SAndroid Build Coastguard Worker 
2314*d83cc019SAndroid Build Coastguard Worker 	igt_assert(kernel_ns <= (test_duration_ns / 100ull));
2315*d83cc019SAndroid Build Coastguard Worker 
2316*d83cc019SAndroid Build Coastguard Worker 	__perf_close(stream_fd);
2317*d83cc019SAndroid Build Coastguard Worker }
2318*d83cc019SAndroid Build Coastguard Worker 
2319*d83cc019SAndroid Build Coastguard Worker static void
test_buffer_fill(void)2320*d83cc019SAndroid Build Coastguard Worker test_buffer_fill(void)
2321*d83cc019SAndroid Build Coastguard Worker {
2322*d83cc019SAndroid Build Coastguard Worker 	/* ~5 micro second period */
2323*d83cc019SAndroid Build Coastguard Worker 	int oa_exponent = max_oa_exponent_for_period_lte(5000);
2324*d83cc019SAndroid Build Coastguard Worker 	uint64_t oa_period = oa_exponent_to_ns(oa_exponent);
2325*d83cc019SAndroid Build Coastguard Worker 	uint64_t properties[] = {
2326*d83cc019SAndroid Build Coastguard Worker 		/* Include OA reports in samples */
2327*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_SAMPLE_OA, true,
2328*d83cc019SAndroid Build Coastguard Worker 
2329*d83cc019SAndroid Build Coastguard Worker 		/* OA unit configuration */
2330*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_METRICS_SET, test_metric_set_id,
2331*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_FORMAT, test_oa_format,
2332*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_EXPONENT, oa_exponent,
2333*d83cc019SAndroid Build Coastguard Worker 	};
2334*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_perf_open_param param = {
2335*d83cc019SAndroid Build Coastguard Worker 		.flags = I915_PERF_FLAG_FD_CLOEXEC,
2336*d83cc019SAndroid Build Coastguard Worker 		.num_properties = sizeof(properties) / 16,
2337*d83cc019SAndroid Build Coastguard Worker 		.properties_ptr = to_user_pointer(properties),
2338*d83cc019SAndroid Build Coastguard Worker 	};
2339*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_perf_record_header *header;
2340*d83cc019SAndroid Build Coastguard Worker 	int buf_size = 65536 * (256 + sizeof(struct drm_i915_perf_record_header));
2341*d83cc019SAndroid Build Coastguard Worker 	uint8_t *buf = malloc(buf_size);
2342*d83cc019SAndroid Build Coastguard Worker 	int len;
2343*d83cc019SAndroid Build Coastguard Worker 	size_t oa_buf_size = MAX_OA_BUF_SIZE;
2344*d83cc019SAndroid Build Coastguard Worker 	size_t report_size = get_oa_format(test_oa_format).size;
2345*d83cc019SAndroid Build Coastguard Worker 	int n_full_oa_reports = oa_buf_size / report_size;
2346*d83cc019SAndroid Build Coastguard Worker 	uint64_t fill_duration = n_full_oa_reports * oa_period;
2347*d83cc019SAndroid Build Coastguard Worker 
2348*d83cc019SAndroid Build Coastguard Worker 	igt_assert(fill_duration < 1000000000);
2349*d83cc019SAndroid Build Coastguard Worker 
2350*d83cc019SAndroid Build Coastguard Worker 	stream_fd = __perf_open(drm_fd, &param, true /* prevent_pm */);
2351*d83cc019SAndroid Build Coastguard Worker 
2352*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; i < 5; i++) {
2353*d83cc019SAndroid Build Coastguard Worker 		bool overflow_seen;
2354*d83cc019SAndroid Build Coastguard Worker 		uint32_t n_periodic_reports;
2355*d83cc019SAndroid Build Coastguard Worker 		uint32_t first_timestamp = 0, last_timestamp = 0;
2356*d83cc019SAndroid Build Coastguard Worker 		uint32_t last_periodic_report[64];
2357*d83cc019SAndroid Build Coastguard Worker 
2358*d83cc019SAndroid Build Coastguard Worker 		do_ioctl(stream_fd, I915_PERF_IOCTL_ENABLE, 0);
2359*d83cc019SAndroid Build Coastguard Worker 
2360*d83cc019SAndroid Build Coastguard Worker 		nanosleep(&(struct timespec){ .tv_sec = 0,
2361*d83cc019SAndroid Build Coastguard Worker 					      .tv_nsec = fill_duration * 1.25 },
2362*d83cc019SAndroid Build Coastguard Worker 			  NULL);
2363*d83cc019SAndroid Build Coastguard Worker 
2364*d83cc019SAndroid Build Coastguard Worker 		while ((len = read(stream_fd, buf, buf_size)) == -1 && errno == EINTR)
2365*d83cc019SAndroid Build Coastguard Worker 			;
2366*d83cc019SAndroid Build Coastguard Worker 
2367*d83cc019SAndroid Build Coastguard Worker 		igt_assert_neq(len, -1);
2368*d83cc019SAndroid Build Coastguard Worker 
2369*d83cc019SAndroid Build Coastguard Worker 		overflow_seen = false;
2370*d83cc019SAndroid Build Coastguard Worker 		for (int offset = 0; offset < len; offset += header->size) {
2371*d83cc019SAndroid Build Coastguard Worker 			header = (void *)(buf + offset);
2372*d83cc019SAndroid Build Coastguard Worker 
2373*d83cc019SAndroid Build Coastguard Worker 			if (header->type == DRM_I915_PERF_RECORD_OA_BUFFER_LOST)
2374*d83cc019SAndroid Build Coastguard Worker 				overflow_seen = true;
2375*d83cc019SAndroid Build Coastguard Worker 		}
2376*d83cc019SAndroid Build Coastguard Worker 
2377*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(overflow_seen, true);
2378*d83cc019SAndroid Build Coastguard Worker 
2379*d83cc019SAndroid Build Coastguard Worker 		do_ioctl(stream_fd, I915_PERF_IOCTL_DISABLE, 0);
2380*d83cc019SAndroid Build Coastguard Worker 
2381*d83cc019SAndroid Build Coastguard Worker 		igt_debug("fill_duration = %"PRIu64"ns, oa_exponent = %u\n",
2382*d83cc019SAndroid Build Coastguard Worker 			  fill_duration, oa_exponent);
2383*d83cc019SAndroid Build Coastguard Worker 
2384*d83cc019SAndroid Build Coastguard Worker 		do_ioctl(stream_fd, I915_PERF_IOCTL_ENABLE, 0);
2385*d83cc019SAndroid Build Coastguard Worker 
2386*d83cc019SAndroid Build Coastguard Worker 		nanosleep(&(struct timespec){ .tv_sec = 0,
2387*d83cc019SAndroid Build Coastguard Worker 					.tv_nsec = fill_duration / 2 },
2388*d83cc019SAndroid Build Coastguard Worker 			NULL);
2389*d83cc019SAndroid Build Coastguard Worker 
2390*d83cc019SAndroid Build Coastguard Worker 		n_periodic_reports = 0;
2391*d83cc019SAndroid Build Coastguard Worker 
2392*d83cc019SAndroid Build Coastguard Worker 		/* Because of the race condition between notification of new
2393*d83cc019SAndroid Build Coastguard Worker 		 * reports and reports landing in memory, we need to rely on
2394*d83cc019SAndroid Build Coastguard Worker 		 * timestamps to figure whether we've read enough of them.
2395*d83cc019SAndroid Build Coastguard Worker 		 */
2396*d83cc019SAndroid Build Coastguard Worker 		while (((last_timestamp - first_timestamp) * oa_period) < (fill_duration / 2)) {
2397*d83cc019SAndroid Build Coastguard Worker 
2398*d83cc019SAndroid Build Coastguard Worker 			igt_debug("dts=%u elapsed=%"PRIu64" duration=%"PRIu64"\n",
2399*d83cc019SAndroid Build Coastguard Worker 				  last_timestamp - first_timestamp,
2400*d83cc019SAndroid Build Coastguard Worker 				  (last_timestamp - first_timestamp) * oa_period,
2401*d83cc019SAndroid Build Coastguard Worker 				  fill_duration / 2);
2402*d83cc019SAndroid Build Coastguard Worker 
2403*d83cc019SAndroid Build Coastguard Worker 			while ((len = read(stream_fd, buf, buf_size)) == -1 && errno == EINTR)
2404*d83cc019SAndroid Build Coastguard Worker 				;
2405*d83cc019SAndroid Build Coastguard Worker 
2406*d83cc019SAndroid Build Coastguard Worker 			igt_assert_neq(len, -1);
2407*d83cc019SAndroid Build Coastguard Worker 
2408*d83cc019SAndroid Build Coastguard Worker 			for (int offset = 0; offset < len; offset += header->size) {
2409*d83cc019SAndroid Build Coastguard Worker 				uint32_t *report;
2410*d83cc019SAndroid Build Coastguard Worker 
2411*d83cc019SAndroid Build Coastguard Worker 				header = (void *) (buf + offset);
2412*d83cc019SAndroid Build Coastguard Worker 				report = (void *) (header + 1);
2413*d83cc019SAndroid Build Coastguard Worker 
2414*d83cc019SAndroid Build Coastguard Worker 				switch (header->type) {
2415*d83cc019SAndroid Build Coastguard Worker 				case DRM_I915_PERF_RECORD_OA_REPORT_LOST:
2416*d83cc019SAndroid Build Coastguard Worker 					igt_debug("report loss, trying again\n");
2417*d83cc019SAndroid Build Coastguard Worker 					break;
2418*d83cc019SAndroid Build Coastguard Worker 				case DRM_I915_PERF_RECORD_SAMPLE:
2419*d83cc019SAndroid Build Coastguard Worker 					igt_debug(" > report ts=%u"
2420*d83cc019SAndroid Build Coastguard Worker 						  " ts_delta_last_periodic=%8u is_timer=%i ctx_id=%8x nb_periodic=%u\n",
2421*d83cc019SAndroid Build Coastguard Worker 						  report[1],
2422*d83cc019SAndroid Build Coastguard Worker 						  n_periodic_reports > 0 ? report[1] - last_periodic_report[1] : 0,
2423*d83cc019SAndroid Build Coastguard Worker 						  oa_report_is_periodic(oa_exponent, report),
2424*d83cc019SAndroid Build Coastguard Worker 						  oa_report_get_ctx_id(report),
2425*d83cc019SAndroid Build Coastguard Worker 						  n_periodic_reports);
2426*d83cc019SAndroid Build Coastguard Worker 
2427*d83cc019SAndroid Build Coastguard Worker 					if (first_timestamp == 0)
2428*d83cc019SAndroid Build Coastguard Worker 						first_timestamp = report[1];
2429*d83cc019SAndroid Build Coastguard Worker 					last_timestamp = report[1];
2430*d83cc019SAndroid Build Coastguard Worker 
2431*d83cc019SAndroid Build Coastguard Worker 					if (oa_report_is_periodic(oa_exponent, report)) {
2432*d83cc019SAndroid Build Coastguard Worker 						memcpy(last_periodic_report, report,
2433*d83cc019SAndroid Build Coastguard Worker 						       sizeof(last_periodic_report));
2434*d83cc019SAndroid Build Coastguard Worker 						n_periodic_reports++;
2435*d83cc019SAndroid Build Coastguard Worker 					}
2436*d83cc019SAndroid Build Coastguard Worker 					break;
2437*d83cc019SAndroid Build Coastguard Worker 				case DRM_I915_PERF_RECORD_OA_BUFFER_LOST:
2438*d83cc019SAndroid Build Coastguard Worker 					igt_assert(!"unexpected overflow");
2439*d83cc019SAndroid Build Coastguard Worker 					break;
2440*d83cc019SAndroid Build Coastguard Worker 				}
2441*d83cc019SAndroid Build Coastguard Worker 			}
2442*d83cc019SAndroid Build Coastguard Worker 		}
2443*d83cc019SAndroid Build Coastguard Worker 
2444*d83cc019SAndroid Build Coastguard Worker 		do_ioctl(stream_fd, I915_PERF_IOCTL_DISABLE, 0);
2445*d83cc019SAndroid Build Coastguard Worker 
2446*d83cc019SAndroid Build Coastguard Worker 		igt_debug("%f < %zu < %f\n",
2447*d83cc019SAndroid Build Coastguard Worker 			  report_size * n_full_oa_reports * 0.45,
2448*d83cc019SAndroid Build Coastguard Worker 			  n_periodic_reports * report_size,
2449*d83cc019SAndroid Build Coastguard Worker 			  report_size * n_full_oa_reports * 0.55);
2450*d83cc019SAndroid Build Coastguard Worker 
2451*d83cc019SAndroid Build Coastguard Worker 		igt_assert(n_periodic_reports * report_size >
2452*d83cc019SAndroid Build Coastguard Worker 			   report_size * n_full_oa_reports * 0.45);
2453*d83cc019SAndroid Build Coastguard Worker 		igt_assert(n_periodic_reports * report_size <
2454*d83cc019SAndroid Build Coastguard Worker 			   report_size * n_full_oa_reports * 0.55);
2455*d83cc019SAndroid Build Coastguard Worker 	}
2456*d83cc019SAndroid Build Coastguard Worker 
2457*d83cc019SAndroid Build Coastguard Worker 	free(buf);
2458*d83cc019SAndroid Build Coastguard Worker 
2459*d83cc019SAndroid Build Coastguard Worker 	__perf_close(stream_fd);
2460*d83cc019SAndroid Build Coastguard Worker }
2461*d83cc019SAndroid Build Coastguard Worker 
2462*d83cc019SAndroid Build Coastguard Worker static void
test_enable_disable(void)2463*d83cc019SAndroid Build Coastguard Worker test_enable_disable(void)
2464*d83cc019SAndroid Build Coastguard Worker {
2465*d83cc019SAndroid Build Coastguard Worker 	/* ~5 micro second period */
2466*d83cc019SAndroid Build Coastguard Worker 	int oa_exponent = max_oa_exponent_for_period_lte(5000);
2467*d83cc019SAndroid Build Coastguard Worker 	uint64_t oa_period = oa_exponent_to_ns(oa_exponent);
2468*d83cc019SAndroid Build Coastguard Worker 	uint64_t properties[] = {
2469*d83cc019SAndroid Build Coastguard Worker 		/* Include OA reports in samples */
2470*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_SAMPLE_OA, true,
2471*d83cc019SAndroid Build Coastguard Worker 
2472*d83cc019SAndroid Build Coastguard Worker 		/* OA unit configuration */
2473*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_METRICS_SET, test_metric_set_id,
2474*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_FORMAT, test_oa_format,
2475*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_EXPONENT, oa_exponent,
2476*d83cc019SAndroid Build Coastguard Worker 	};
2477*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_perf_open_param param = {
2478*d83cc019SAndroid Build Coastguard Worker 		.flags = I915_PERF_FLAG_FD_CLOEXEC |
2479*d83cc019SAndroid Build Coastguard Worker 			 I915_PERF_FLAG_DISABLED, /* Verify we start disabled */
2480*d83cc019SAndroid Build Coastguard Worker 		.num_properties = sizeof(properties) / 16,
2481*d83cc019SAndroid Build Coastguard Worker 		.properties_ptr = to_user_pointer(properties),
2482*d83cc019SAndroid Build Coastguard Worker 	};
2483*d83cc019SAndroid Build Coastguard Worker 	int buf_size = 65536 * (256 + sizeof(struct drm_i915_perf_record_header));
2484*d83cc019SAndroid Build Coastguard Worker 	uint8_t *buf = malloc(buf_size);
2485*d83cc019SAndroid Build Coastguard Worker 	size_t oa_buf_size = MAX_OA_BUF_SIZE;
2486*d83cc019SAndroid Build Coastguard Worker 	size_t report_size = get_oa_format(test_oa_format).size;
2487*d83cc019SAndroid Build Coastguard Worker 	int n_full_oa_reports = oa_buf_size / report_size;
2488*d83cc019SAndroid Build Coastguard Worker 	uint64_t fill_duration = n_full_oa_reports * oa_period;
2489*d83cc019SAndroid Build Coastguard Worker 
2490*d83cc019SAndroid Build Coastguard Worker 	load_helper_init();
2491*d83cc019SAndroid Build Coastguard Worker 	load_helper_run(HIGH);
2492*d83cc019SAndroid Build Coastguard Worker 
2493*d83cc019SAndroid Build Coastguard Worker 	stream_fd = __perf_open(drm_fd, &param, true /* prevent_pm */);
2494*d83cc019SAndroid Build Coastguard Worker 
2495*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; i < 5; i++) {
2496*d83cc019SAndroid Build Coastguard Worker 		int len;
2497*d83cc019SAndroid Build Coastguard Worker 		uint32_t n_periodic_reports;
2498*d83cc019SAndroid Build Coastguard Worker 		struct drm_i915_perf_record_header *header;
2499*d83cc019SAndroid Build Coastguard Worker 		uint32_t first_timestamp = 0, last_timestamp = 0;
2500*d83cc019SAndroid Build Coastguard Worker 		uint32_t last_periodic_report[64];
2501*d83cc019SAndroid Build Coastguard Worker 
2502*d83cc019SAndroid Build Coastguard Worker 		/* Giving enough time for an overflow might help catch whether
2503*d83cc019SAndroid Build Coastguard Worker 		 * the OA unit has been enabled even if the driver might at
2504*d83cc019SAndroid Build Coastguard Worker 		 * least avoid copying reports while disabled.
2505*d83cc019SAndroid Build Coastguard Worker 		 */
2506*d83cc019SAndroid Build Coastguard Worker 		nanosleep(&(struct timespec){ .tv_sec = 0,
2507*d83cc019SAndroid Build Coastguard Worker 					      .tv_nsec = fill_duration * 1.25 },
2508*d83cc019SAndroid Build Coastguard Worker 			  NULL);
2509*d83cc019SAndroid Build Coastguard Worker 
2510*d83cc019SAndroid Build Coastguard Worker 		while ((len = read(stream_fd, buf, buf_size)) == -1 && errno == EINTR)
2511*d83cc019SAndroid Build Coastguard Worker 			;
2512*d83cc019SAndroid Build Coastguard Worker 
2513*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(len, -1);
2514*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(errno, EIO);
2515*d83cc019SAndroid Build Coastguard Worker 
2516*d83cc019SAndroid Build Coastguard Worker 		do_ioctl(stream_fd, I915_PERF_IOCTL_ENABLE, 0);
2517*d83cc019SAndroid Build Coastguard Worker 
2518*d83cc019SAndroid Build Coastguard Worker 		nanosleep(&(struct timespec){ .tv_sec = 0,
2519*d83cc019SAndroid Build Coastguard Worker 					      .tv_nsec = fill_duration / 2 },
2520*d83cc019SAndroid Build Coastguard Worker 			NULL);
2521*d83cc019SAndroid Build Coastguard Worker 
2522*d83cc019SAndroid Build Coastguard Worker 		n_periodic_reports = 0;
2523*d83cc019SAndroid Build Coastguard Worker 
2524*d83cc019SAndroid Build Coastguard Worker 		/* Because of the race condition between notification of new
2525*d83cc019SAndroid Build Coastguard Worker 		 * reports and reports landing in memory, we need to rely on
2526*d83cc019SAndroid Build Coastguard Worker 		 * timestamps to figure whether we've read enough of them.
2527*d83cc019SAndroid Build Coastguard Worker 		 */
2528*d83cc019SAndroid Build Coastguard Worker 		while (((last_timestamp - first_timestamp) * oa_period) < (fill_duration / 2)) {
2529*d83cc019SAndroid Build Coastguard Worker 
2530*d83cc019SAndroid Build Coastguard Worker 			while ((len = read(stream_fd, buf, buf_size)) == -1 && errno == EINTR)
2531*d83cc019SAndroid Build Coastguard Worker 				;
2532*d83cc019SAndroid Build Coastguard Worker 
2533*d83cc019SAndroid Build Coastguard Worker 			igt_assert_neq(len, -1);
2534*d83cc019SAndroid Build Coastguard Worker 
2535*d83cc019SAndroid Build Coastguard Worker 			for (int offset = 0; offset < len; offset += header->size) {
2536*d83cc019SAndroid Build Coastguard Worker 				uint32_t *report;
2537*d83cc019SAndroid Build Coastguard Worker 
2538*d83cc019SAndroid Build Coastguard Worker 				header = (void *) (buf + offset);
2539*d83cc019SAndroid Build Coastguard Worker 				report = (void *) (header + 1);
2540*d83cc019SAndroid Build Coastguard Worker 
2541*d83cc019SAndroid Build Coastguard Worker 				switch (header->type) {
2542*d83cc019SAndroid Build Coastguard Worker 				case DRM_I915_PERF_RECORD_OA_REPORT_LOST:
2543*d83cc019SAndroid Build Coastguard Worker 					break;
2544*d83cc019SAndroid Build Coastguard Worker 				case DRM_I915_PERF_RECORD_SAMPLE:
2545*d83cc019SAndroid Build Coastguard Worker 					if (first_timestamp == 0)
2546*d83cc019SAndroid Build Coastguard Worker 						first_timestamp = report[1];
2547*d83cc019SAndroid Build Coastguard Worker 					last_timestamp = report[1];
2548*d83cc019SAndroid Build Coastguard Worker 
2549*d83cc019SAndroid Build Coastguard Worker 					igt_debug(" > report ts=%8x"
2550*d83cc019SAndroid Build Coastguard Worker 						  " ts_delta_last_periodic=%s%8u"
2551*d83cc019SAndroid Build Coastguard Worker 						  " is_timer=%i ctx_id=0x%8x\n",
2552*d83cc019SAndroid Build Coastguard Worker 						  report[1],
2553*d83cc019SAndroid Build Coastguard Worker 						  oa_report_is_periodic(oa_exponent, report) ? " " : "*",
2554*d83cc019SAndroid Build Coastguard Worker 						  n_periodic_reports > 0 ? (report[1] - last_periodic_report[1]) : 0,
2555*d83cc019SAndroid Build Coastguard Worker 						  oa_report_is_periodic(oa_exponent, report),
2556*d83cc019SAndroid Build Coastguard Worker 						  oa_report_get_ctx_id(report));
2557*d83cc019SAndroid Build Coastguard Worker 
2558*d83cc019SAndroid Build Coastguard Worker 					if (oa_report_is_periodic(oa_exponent, report)) {
2559*d83cc019SAndroid Build Coastguard Worker 						memcpy(last_periodic_report, report,
2560*d83cc019SAndroid Build Coastguard Worker 						       sizeof(last_periodic_report));
2561*d83cc019SAndroid Build Coastguard Worker 
2562*d83cc019SAndroid Build Coastguard Worker 						/* We want to measure only the
2563*d83cc019SAndroid Build Coastguard Worker 						 * periodic reports, ctx-switch
2564*d83cc019SAndroid Build Coastguard Worker 						 * might inflate the content of
2565*d83cc019SAndroid Build Coastguard Worker 						 * the buffer and skew or
2566*d83cc019SAndroid Build Coastguard Worker 						 * measurement.
2567*d83cc019SAndroid Build Coastguard Worker 						 */
2568*d83cc019SAndroid Build Coastguard Worker 						n_periodic_reports++;
2569*d83cc019SAndroid Build Coastguard Worker 					}
2570*d83cc019SAndroid Build Coastguard Worker 					break;
2571*d83cc019SAndroid Build Coastguard Worker 				case DRM_I915_PERF_RECORD_OA_BUFFER_LOST:
2572*d83cc019SAndroid Build Coastguard Worker 					igt_assert(!"unexpected overflow");
2573*d83cc019SAndroid Build Coastguard Worker 					break;
2574*d83cc019SAndroid Build Coastguard Worker 				}
2575*d83cc019SAndroid Build Coastguard Worker 			}
2576*d83cc019SAndroid Build Coastguard Worker 
2577*d83cc019SAndroid Build Coastguard Worker 		}
2578*d83cc019SAndroid Build Coastguard Worker 
2579*d83cc019SAndroid Build Coastguard Worker 		do_ioctl(stream_fd, I915_PERF_IOCTL_DISABLE, 0);
2580*d83cc019SAndroid Build Coastguard Worker 
2581*d83cc019SAndroid Build Coastguard Worker 		igt_debug("%f < %zu < %f\n",
2582*d83cc019SAndroid Build Coastguard Worker 			  report_size * n_full_oa_reports * 0.45,
2583*d83cc019SAndroid Build Coastguard Worker 			  n_periodic_reports * report_size,
2584*d83cc019SAndroid Build Coastguard Worker 			  report_size * n_full_oa_reports * 0.55);
2585*d83cc019SAndroid Build Coastguard Worker 
2586*d83cc019SAndroid Build Coastguard Worker 		igt_assert((n_periodic_reports * report_size) >
2587*d83cc019SAndroid Build Coastguard Worker 			   (report_size * n_full_oa_reports * 0.45));
2588*d83cc019SAndroid Build Coastguard Worker 		igt_assert((n_periodic_reports * report_size) <
2589*d83cc019SAndroid Build Coastguard Worker 			   report_size * n_full_oa_reports * 0.55);
2590*d83cc019SAndroid Build Coastguard Worker 
2591*d83cc019SAndroid Build Coastguard Worker 
2592*d83cc019SAndroid Build Coastguard Worker 		/* It's considered an error to read a stream while it's disabled
2593*d83cc019SAndroid Build Coastguard Worker 		 * since it would block indefinitely...
2594*d83cc019SAndroid Build Coastguard Worker 		 */
2595*d83cc019SAndroid Build Coastguard Worker 		len = read(stream_fd, buf, buf_size);
2596*d83cc019SAndroid Build Coastguard Worker 
2597*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(len, -1);
2598*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(errno, EIO);
2599*d83cc019SAndroid Build Coastguard Worker 	}
2600*d83cc019SAndroid Build Coastguard Worker 
2601*d83cc019SAndroid Build Coastguard Worker 	free(buf);
2602*d83cc019SAndroid Build Coastguard Worker 
2603*d83cc019SAndroid Build Coastguard Worker 	__perf_close(stream_fd);
2604*d83cc019SAndroid Build Coastguard Worker 
2605*d83cc019SAndroid Build Coastguard Worker 	load_helper_stop();
2606*d83cc019SAndroid Build Coastguard Worker 	load_helper_fini();
2607*d83cc019SAndroid Build Coastguard Worker }
2608*d83cc019SAndroid Build Coastguard Worker 
2609*d83cc019SAndroid Build Coastguard Worker static void
test_short_reads(void)2610*d83cc019SAndroid Build Coastguard Worker test_short_reads(void)
2611*d83cc019SAndroid Build Coastguard Worker {
2612*d83cc019SAndroid Build Coastguard Worker 	int oa_exponent = max_oa_exponent_for_period_lte(5000);
2613*d83cc019SAndroid Build Coastguard Worker 	uint64_t properties[] = {
2614*d83cc019SAndroid Build Coastguard Worker 		/* Include OA reports in samples */
2615*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_SAMPLE_OA, true,
2616*d83cc019SAndroid Build Coastguard Worker 
2617*d83cc019SAndroid Build Coastguard Worker 		/* OA unit configuration */
2618*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_METRICS_SET, test_metric_set_id,
2619*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_FORMAT, test_oa_format,
2620*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_EXPONENT, oa_exponent,
2621*d83cc019SAndroid Build Coastguard Worker 	};
2622*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_perf_open_param param = {
2623*d83cc019SAndroid Build Coastguard Worker 		.flags = I915_PERF_FLAG_FD_CLOEXEC,
2624*d83cc019SAndroid Build Coastguard Worker 		.num_properties = sizeof(properties) / 16,
2625*d83cc019SAndroid Build Coastguard Worker 		.properties_ptr = to_user_pointer(properties),
2626*d83cc019SAndroid Build Coastguard Worker 	};
2627*d83cc019SAndroid Build Coastguard Worker 	size_t record_size = 256 + sizeof(struct drm_i915_perf_record_header);
2628*d83cc019SAndroid Build Coastguard Worker 	size_t page_size = sysconf(_SC_PAGE_SIZE);
2629*d83cc019SAndroid Build Coastguard Worker 	int zero_fd = open("/dev/zero", O_RDWR|O_CLOEXEC);
2630*d83cc019SAndroid Build Coastguard Worker 	uint8_t *pages = mmap(NULL, page_size * 2,
2631*d83cc019SAndroid Build Coastguard Worker 			      PROT_READ|PROT_WRITE, MAP_PRIVATE, zero_fd, 0);
2632*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_perf_record_header *header;
2633*d83cc019SAndroid Build Coastguard Worker 	int ret;
2634*d83cc019SAndroid Build Coastguard Worker 
2635*d83cc019SAndroid Build Coastguard Worker 	igt_assert_neq(zero_fd, -1);
2636*d83cc019SAndroid Build Coastguard Worker 	close(zero_fd);
2637*d83cc019SAndroid Build Coastguard Worker 	zero_fd = -1;
2638*d83cc019SAndroid Build Coastguard Worker 
2639*d83cc019SAndroid Build Coastguard Worker 	igt_assert(pages);
2640*d83cc019SAndroid Build Coastguard Worker 
2641*d83cc019SAndroid Build Coastguard Worker 	ret = mprotect(pages + page_size, page_size, PROT_NONE);
2642*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(ret, 0);
2643*d83cc019SAndroid Build Coastguard Worker 
2644*d83cc019SAndroid Build Coastguard Worker 	stream_fd = __perf_open(drm_fd, &param, false);
2645*d83cc019SAndroid Build Coastguard Worker 
2646*d83cc019SAndroid Build Coastguard Worker 	nanosleep(&(struct timespec){ .tv_sec = 0, .tv_nsec = 5000000 }, NULL);
2647*d83cc019SAndroid Build Coastguard Worker 
2648*d83cc019SAndroid Build Coastguard Worker 	/* At this point there should be lots of pending reports to read */
2649*d83cc019SAndroid Build Coastguard Worker 
2650*d83cc019SAndroid Build Coastguard Worker 	/* A read that can return at least one record should result in a short
2651*d83cc019SAndroid Build Coastguard Worker 	 * read not an EFAULT if the buffer is smaller than the requested read
2652*d83cc019SAndroid Build Coastguard Worker 	 * size...
2653*d83cc019SAndroid Build Coastguard Worker 	 *
2654*d83cc019SAndroid Build Coastguard Worker 	 * Expect to see a sample record here, but at least skip over any
2655*d83cc019SAndroid Build Coastguard Worker 	 * _RECORD_LOST notifications.
2656*d83cc019SAndroid Build Coastguard Worker 	 */
2657*d83cc019SAndroid Build Coastguard Worker 	do {
2658*d83cc019SAndroid Build Coastguard Worker 		header = (void *)(pages + page_size - record_size);
2659*d83cc019SAndroid Build Coastguard Worker 		ret = read(stream_fd,
2660*d83cc019SAndroid Build Coastguard Worker 			   header,
2661*d83cc019SAndroid Build Coastguard Worker 			   page_size);
2662*d83cc019SAndroid Build Coastguard Worker 		igt_assert(ret > 0);
2663*d83cc019SAndroid Build Coastguard Worker 	} while (header->type == DRM_I915_PERF_RECORD_OA_REPORT_LOST);
2664*d83cc019SAndroid Build Coastguard Worker 
2665*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(ret, record_size);
2666*d83cc019SAndroid Build Coastguard Worker 
2667*d83cc019SAndroid Build Coastguard Worker 	/* A read that can't return a single record because it would result
2668*d83cc019SAndroid Build Coastguard Worker 	 * in a fault on buffer overrun should result in an EFAULT error...
2669*d83cc019SAndroid Build Coastguard Worker 	 */
2670*d83cc019SAndroid Build Coastguard Worker 	ret = read(stream_fd, pages + page_size - 16, page_size);
2671*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(ret, -1);
2672*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(errno, EFAULT);
2673*d83cc019SAndroid Build Coastguard Worker 
2674*d83cc019SAndroid Build Coastguard Worker 	/* A read that can't return a single record because the buffer is too
2675*d83cc019SAndroid Build Coastguard Worker 	 * small should result in an ENOSPC error..
2676*d83cc019SAndroid Build Coastguard Worker 	 *
2677*d83cc019SAndroid Build Coastguard Worker 	 * Again, skip over _RECORD_LOST records (smaller than record_size/2)
2678*d83cc019SAndroid Build Coastguard Worker 	 */
2679*d83cc019SAndroid Build Coastguard Worker 	do {
2680*d83cc019SAndroid Build Coastguard Worker 		header = (void *)(pages + page_size - record_size / 2);
2681*d83cc019SAndroid Build Coastguard Worker 		ret = read(stream_fd,
2682*d83cc019SAndroid Build Coastguard Worker 			   header,
2683*d83cc019SAndroid Build Coastguard Worker 			   record_size / 2);
2684*d83cc019SAndroid Build Coastguard Worker 	} while (ret > 0 && header->type == DRM_I915_PERF_RECORD_OA_REPORT_LOST);
2685*d83cc019SAndroid Build Coastguard Worker 
2686*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(ret, -1);
2687*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(errno, ENOSPC);
2688*d83cc019SAndroid Build Coastguard Worker 
2689*d83cc019SAndroid Build Coastguard Worker 	__perf_close(stream_fd);
2690*d83cc019SAndroid Build Coastguard Worker 
2691*d83cc019SAndroid Build Coastguard Worker 	munmap(pages, page_size * 2);
2692*d83cc019SAndroid Build Coastguard Worker }
2693*d83cc019SAndroid Build Coastguard Worker 
2694*d83cc019SAndroid Build Coastguard Worker static void
test_non_sampling_read_error(void)2695*d83cc019SAndroid Build Coastguard Worker test_non_sampling_read_error(void)
2696*d83cc019SAndroid Build Coastguard Worker {
2697*d83cc019SAndroid Build Coastguard Worker 	uint64_t properties[] = {
2698*d83cc019SAndroid Build Coastguard Worker 		/* XXX: even without periodic sampling we have to
2699*d83cc019SAndroid Build Coastguard Worker 		 * specify at least one sample layout property...
2700*d83cc019SAndroid Build Coastguard Worker 		 */
2701*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_SAMPLE_OA, true,
2702*d83cc019SAndroid Build Coastguard Worker 
2703*d83cc019SAndroid Build Coastguard Worker 		/* OA unit configuration */
2704*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_METRICS_SET, test_metric_set_id,
2705*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_FORMAT, test_oa_format,
2706*d83cc019SAndroid Build Coastguard Worker 
2707*d83cc019SAndroid Build Coastguard Worker 		/* XXX: no sampling exponent */
2708*d83cc019SAndroid Build Coastguard Worker 	};
2709*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_perf_open_param param = {
2710*d83cc019SAndroid Build Coastguard Worker 		.flags = I915_PERF_FLAG_FD_CLOEXEC,
2711*d83cc019SAndroid Build Coastguard Worker 		.num_properties = sizeof(properties) / 16,
2712*d83cc019SAndroid Build Coastguard Worker 		.properties_ptr = to_user_pointer(properties),
2713*d83cc019SAndroid Build Coastguard Worker 	};
2714*d83cc019SAndroid Build Coastguard Worker 	int ret;
2715*d83cc019SAndroid Build Coastguard Worker 	uint8_t buf[1024];
2716*d83cc019SAndroid Build Coastguard Worker 
2717*d83cc019SAndroid Build Coastguard Worker 	stream_fd = __perf_open(drm_fd, &param, false);
2718*d83cc019SAndroid Build Coastguard Worker 
2719*d83cc019SAndroid Build Coastguard Worker 	ret = read(stream_fd, buf, sizeof(buf));
2720*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(ret, -1);
2721*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(errno, EIO);
2722*d83cc019SAndroid Build Coastguard Worker 
2723*d83cc019SAndroid Build Coastguard Worker 	__perf_close(stream_fd);
2724*d83cc019SAndroid Build Coastguard Worker }
2725*d83cc019SAndroid Build Coastguard Worker 
2726*d83cc019SAndroid Build Coastguard Worker /* Check that attempts to read from a stream while it is disable will return
2727*d83cc019SAndroid Build Coastguard Worker  * EIO instead of blocking indefinitely.
2728*d83cc019SAndroid Build Coastguard Worker  */
2729*d83cc019SAndroid Build Coastguard Worker static void
test_disabled_read_error(void)2730*d83cc019SAndroid Build Coastguard Worker test_disabled_read_error(void)
2731*d83cc019SAndroid Build Coastguard Worker {
2732*d83cc019SAndroid Build Coastguard Worker 	int oa_exponent = 5; /* 5 micro seconds */
2733*d83cc019SAndroid Build Coastguard Worker 	uint64_t properties[] = {
2734*d83cc019SAndroid Build Coastguard Worker 		/* XXX: even without periodic sampling we have to
2735*d83cc019SAndroid Build Coastguard Worker 		 * specify at least one sample layout property...
2736*d83cc019SAndroid Build Coastguard Worker 		 */
2737*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_SAMPLE_OA, true,
2738*d83cc019SAndroid Build Coastguard Worker 
2739*d83cc019SAndroid Build Coastguard Worker 		/* OA unit configuration */
2740*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_METRICS_SET, test_metric_set_id,
2741*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_FORMAT, test_oa_format,
2742*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_EXPONENT, oa_exponent,
2743*d83cc019SAndroid Build Coastguard Worker 	};
2744*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_perf_open_param param = {
2745*d83cc019SAndroid Build Coastguard Worker 		.flags = I915_PERF_FLAG_FD_CLOEXEC |
2746*d83cc019SAndroid Build Coastguard Worker 			 I915_PERF_FLAG_DISABLED, /* XXX: open disabled */
2747*d83cc019SAndroid Build Coastguard Worker 		.num_properties = sizeof(properties) / 16,
2748*d83cc019SAndroid Build Coastguard Worker 		.properties_ptr = to_user_pointer(properties),
2749*d83cc019SAndroid Build Coastguard Worker 	};
2750*d83cc019SAndroid Build Coastguard Worker 	uint32_t oa_report0[64];
2751*d83cc019SAndroid Build Coastguard Worker 	uint32_t oa_report1[64];
2752*d83cc019SAndroid Build Coastguard Worker 	uint32_t buf[128] = { 0 };
2753*d83cc019SAndroid Build Coastguard Worker 	int ret;
2754*d83cc019SAndroid Build Coastguard Worker 
2755*d83cc019SAndroid Build Coastguard Worker 	stream_fd = __perf_open(drm_fd, &param, false);
2756*d83cc019SAndroid Build Coastguard Worker 
2757*d83cc019SAndroid Build Coastguard Worker 	ret = read(stream_fd, buf, sizeof(buf));
2758*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(ret, -1);
2759*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(errno, EIO);
2760*d83cc019SAndroid Build Coastguard Worker 
2761*d83cc019SAndroid Build Coastguard Worker 	__perf_close(stream_fd);
2762*d83cc019SAndroid Build Coastguard Worker 
2763*d83cc019SAndroid Build Coastguard Worker 
2764*d83cc019SAndroid Build Coastguard Worker 	param.flags &= ~I915_PERF_FLAG_DISABLED;
2765*d83cc019SAndroid Build Coastguard Worker 	stream_fd = __perf_open(drm_fd, &param, false);
2766*d83cc019SAndroid Build Coastguard Worker 
2767*d83cc019SAndroid Build Coastguard Worker 	read_2_oa_reports(test_oa_format,
2768*d83cc019SAndroid Build Coastguard Worker 			  oa_exponent,
2769*d83cc019SAndroid Build Coastguard Worker 			  oa_report0,
2770*d83cc019SAndroid Build Coastguard Worker 			  oa_report1,
2771*d83cc019SAndroid Build Coastguard Worker 			  false); /* not just timer reports */
2772*d83cc019SAndroid Build Coastguard Worker 
2773*d83cc019SAndroid Build Coastguard Worker 	do_ioctl(stream_fd, I915_PERF_IOCTL_DISABLE, 0);
2774*d83cc019SAndroid Build Coastguard Worker 
2775*d83cc019SAndroid Build Coastguard Worker 	ret = read(stream_fd, buf, sizeof(buf));
2776*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(ret, -1);
2777*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(errno, EIO);
2778*d83cc019SAndroid Build Coastguard Worker 
2779*d83cc019SAndroid Build Coastguard Worker 	do_ioctl(stream_fd, I915_PERF_IOCTL_ENABLE, 0);
2780*d83cc019SAndroid Build Coastguard Worker 
2781*d83cc019SAndroid Build Coastguard Worker 	read_2_oa_reports(test_oa_format,
2782*d83cc019SAndroid Build Coastguard Worker 			  oa_exponent,
2783*d83cc019SAndroid Build Coastguard Worker 			  oa_report0,
2784*d83cc019SAndroid Build Coastguard Worker 			  oa_report1,
2785*d83cc019SAndroid Build Coastguard Worker 			  false); /* not just timer reports */
2786*d83cc019SAndroid Build Coastguard Worker 
2787*d83cc019SAndroid Build Coastguard Worker 	__perf_close(stream_fd);
2788*d83cc019SAndroid Build Coastguard Worker }
2789*d83cc019SAndroid Build Coastguard Worker 
2790*d83cc019SAndroid Build Coastguard Worker static void
test_mi_rpc(void)2791*d83cc019SAndroid Build Coastguard Worker test_mi_rpc(void)
2792*d83cc019SAndroid Build Coastguard Worker {
2793*d83cc019SAndroid Build Coastguard Worker 	uint64_t properties[] = {
2794*d83cc019SAndroid Build Coastguard Worker 		/* Note: we have to specify at least one sample property even
2795*d83cc019SAndroid Build Coastguard Worker 		 * though we aren't interested in samples in this case.
2796*d83cc019SAndroid Build Coastguard Worker 		 */
2797*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_SAMPLE_OA, true,
2798*d83cc019SAndroid Build Coastguard Worker 
2799*d83cc019SAndroid Build Coastguard Worker 		/* OA unit configuration */
2800*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_METRICS_SET, test_metric_set_id,
2801*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_FORMAT, test_oa_format,
2802*d83cc019SAndroid Build Coastguard Worker 
2803*d83cc019SAndroid Build Coastguard Worker 		/* Note: no OA exponent specified in this case */
2804*d83cc019SAndroid Build Coastguard Worker 	};
2805*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_perf_open_param param = {
2806*d83cc019SAndroid Build Coastguard Worker 		.flags = I915_PERF_FLAG_FD_CLOEXEC,
2807*d83cc019SAndroid Build Coastguard Worker 		.num_properties = sizeof(properties) / 16,
2808*d83cc019SAndroid Build Coastguard Worker 		.properties_ptr = to_user_pointer(properties),
2809*d83cc019SAndroid Build Coastguard Worker 	};
2810*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bufmgr *bufmgr = drm_intel_bufmgr_gem_init(drm_fd, 4096);
2811*d83cc019SAndroid Build Coastguard Worker 	drm_intel_context *context;
2812*d83cc019SAndroid Build Coastguard Worker 	struct intel_batchbuffer *batch;
2813*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bo *bo;
2814*d83cc019SAndroid Build Coastguard Worker 	uint32_t *report32;
2815*d83cc019SAndroid Build Coastguard Worker 	int ret;
2816*d83cc019SAndroid Build Coastguard Worker 
2817*d83cc019SAndroid Build Coastguard Worker 	stream_fd = __perf_open(drm_fd, &param, false);
2818*d83cc019SAndroid Build Coastguard Worker 
2819*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bufmgr_gem_enable_reuse(bufmgr);
2820*d83cc019SAndroid Build Coastguard Worker 
2821*d83cc019SAndroid Build Coastguard Worker 	context = drm_intel_gem_context_create(bufmgr);
2822*d83cc019SAndroid Build Coastguard Worker 	igt_assert(context);
2823*d83cc019SAndroid Build Coastguard Worker 
2824*d83cc019SAndroid Build Coastguard Worker 	batch = intel_batchbuffer_alloc(bufmgr, devid);
2825*d83cc019SAndroid Build Coastguard Worker 
2826*d83cc019SAndroid Build Coastguard Worker 	bo = drm_intel_bo_alloc(bufmgr, "mi_rpc dest bo", 4096, 64);
2827*d83cc019SAndroid Build Coastguard Worker 
2828*d83cc019SAndroid Build Coastguard Worker 	ret = drm_intel_bo_map(bo, true);
2829*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(ret, 0);
2830*d83cc019SAndroid Build Coastguard Worker 
2831*d83cc019SAndroid Build Coastguard Worker 	memset(bo->virtual, 0x80, 4096);
2832*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bo_unmap(bo);
2833*d83cc019SAndroid Build Coastguard Worker 
2834*d83cc019SAndroid Build Coastguard Worker 	emit_report_perf_count(batch,
2835*d83cc019SAndroid Build Coastguard Worker 			       bo, /* dst */
2836*d83cc019SAndroid Build Coastguard Worker 			       0, /* dst offset in bytes */
2837*d83cc019SAndroid Build Coastguard Worker 			       0xdeadbeef); /* report ID */
2838*d83cc019SAndroid Build Coastguard Worker 
2839*d83cc019SAndroid Build Coastguard Worker 	intel_batchbuffer_flush_with_context(batch, context);
2840*d83cc019SAndroid Build Coastguard Worker 
2841*d83cc019SAndroid Build Coastguard Worker 	ret = drm_intel_bo_map(bo, false /* write enable */);
2842*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(ret, 0);
2843*d83cc019SAndroid Build Coastguard Worker 
2844*d83cc019SAndroid Build Coastguard Worker 	report32 = bo->virtual;
2845*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(report32[0], 0xdeadbeef); /* report ID */
2846*d83cc019SAndroid Build Coastguard Worker 	igt_assert_neq(report32[1], 0); /* timestamp */
2847*d83cc019SAndroid Build Coastguard Worker 
2848*d83cc019SAndroid Build Coastguard Worker 	igt_assert_neq(report32[63], 0x80808080); /* end of report */
2849*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(report32[64], 0x80808080); /* after 256 byte report */
2850*d83cc019SAndroid Build Coastguard Worker 
2851*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bo_unmap(bo);
2852*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bo_unreference(bo);
2853*d83cc019SAndroid Build Coastguard Worker 	intel_batchbuffer_free(batch);
2854*d83cc019SAndroid Build Coastguard Worker 	drm_intel_gem_context_destroy(context);
2855*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bufmgr_destroy(bufmgr);
2856*d83cc019SAndroid Build Coastguard Worker 	__perf_close(stream_fd);
2857*d83cc019SAndroid Build Coastguard Worker }
2858*d83cc019SAndroid Build Coastguard Worker 
2859*d83cc019SAndroid Build Coastguard Worker static void
emit_stall_timestamp_and_rpc(struct intel_batchbuffer * batch,drm_intel_bo * dst,int timestamp_offset,int report_dst_offset,uint32_t report_id)2860*d83cc019SAndroid Build Coastguard Worker emit_stall_timestamp_and_rpc(struct intel_batchbuffer *batch,
2861*d83cc019SAndroid Build Coastguard Worker 			     drm_intel_bo *dst,
2862*d83cc019SAndroid Build Coastguard Worker 			     int timestamp_offset,
2863*d83cc019SAndroid Build Coastguard Worker 			     int report_dst_offset,
2864*d83cc019SAndroid Build Coastguard Worker 			     uint32_t report_id)
2865*d83cc019SAndroid Build Coastguard Worker {
2866*d83cc019SAndroid Build Coastguard Worker 	uint32_t pipe_ctl_flags = (PIPE_CONTROL_CS_STALL |
2867*d83cc019SAndroid Build Coastguard Worker 				   PIPE_CONTROL_RENDER_TARGET_FLUSH |
2868*d83cc019SAndroid Build Coastguard Worker 				   PIPE_CONTROL_WRITE_TIMESTAMP);
2869*d83cc019SAndroid Build Coastguard Worker 
2870*d83cc019SAndroid Build Coastguard Worker 	if (intel_gen(devid) >= 8) {
2871*d83cc019SAndroid Build Coastguard Worker 		BEGIN_BATCH(5, 1);
2872*d83cc019SAndroid Build Coastguard Worker 		OUT_BATCH(GFX_OP_PIPE_CONTROL | (6 - 2));
2873*d83cc019SAndroid Build Coastguard Worker 		OUT_BATCH(pipe_ctl_flags);
2874*d83cc019SAndroid Build Coastguard Worker 		OUT_RELOC(dst, I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
2875*d83cc019SAndroid Build Coastguard Worker 			  timestamp_offset);
2876*d83cc019SAndroid Build Coastguard Worker 		OUT_BATCH(0); /* imm lower */
2877*d83cc019SAndroid Build Coastguard Worker 		OUT_BATCH(0); /* imm upper */
2878*d83cc019SAndroid Build Coastguard Worker 		ADVANCE_BATCH();
2879*d83cc019SAndroid Build Coastguard Worker 	} else {
2880*d83cc019SAndroid Build Coastguard Worker 		BEGIN_BATCH(5, 1);
2881*d83cc019SAndroid Build Coastguard Worker 		OUT_BATCH(GFX_OP_PIPE_CONTROL | (5 - 2));
2882*d83cc019SAndroid Build Coastguard Worker 		OUT_BATCH(pipe_ctl_flags);
2883*d83cc019SAndroid Build Coastguard Worker 		OUT_RELOC(dst, I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
2884*d83cc019SAndroid Build Coastguard Worker 			  timestamp_offset);
2885*d83cc019SAndroid Build Coastguard Worker 		OUT_BATCH(0); /* imm lower */
2886*d83cc019SAndroid Build Coastguard Worker 		OUT_BATCH(0); /* imm upper */
2887*d83cc019SAndroid Build Coastguard Worker 		ADVANCE_BATCH();
2888*d83cc019SAndroid Build Coastguard Worker 	}
2889*d83cc019SAndroid Build Coastguard Worker 
2890*d83cc019SAndroid Build Coastguard Worker 	emit_report_perf_count(batch, dst, report_dst_offset, report_id);
2891*d83cc019SAndroid Build Coastguard Worker }
2892*d83cc019SAndroid Build Coastguard Worker 
2893*d83cc019SAndroid Build Coastguard Worker /* Tests the INTEL_performance_query use case where an unprivileged process
2894*d83cc019SAndroid Build Coastguard Worker  * should be able to configure the OA unit for per-context metrics (for a
2895*d83cc019SAndroid Build Coastguard Worker  * context associated with that process' drm file descriptor) and the counters
2896*d83cc019SAndroid Build Coastguard Worker  * should only relate to that specific context.
2897*d83cc019SAndroid Build Coastguard Worker  *
2898*d83cc019SAndroid Build Coastguard Worker  * Unfortunately only Haswell limits the progression of OA counters for a
2899*d83cc019SAndroid Build Coastguard Worker  * single context and so this unit test is Haswell specific. For Gen8+ although
2900*d83cc019SAndroid Build Coastguard Worker  * reports read via i915 perf can be filtered for a single context the counters
2901*d83cc019SAndroid Build Coastguard Worker  * themselves always progress as global/system-wide counters affected by all
2902*d83cc019SAndroid Build Coastguard Worker  * contexts.
2903*d83cc019SAndroid Build Coastguard Worker  */
2904*d83cc019SAndroid Build Coastguard Worker static void
hsw_test_single_ctx_counters(void)2905*d83cc019SAndroid Build Coastguard Worker hsw_test_single_ctx_counters(void)
2906*d83cc019SAndroid Build Coastguard Worker {
2907*d83cc019SAndroid Build Coastguard Worker 	uint64_t properties[] = {
2908*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_CTX_HANDLE, UINT64_MAX, /* updated below */
2909*d83cc019SAndroid Build Coastguard Worker 
2910*d83cc019SAndroid Build Coastguard Worker 		/* Note: we have to specify at least one sample property even
2911*d83cc019SAndroid Build Coastguard Worker 		 * though we aren't interested in samples in this case
2912*d83cc019SAndroid Build Coastguard Worker 		 */
2913*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_SAMPLE_OA, true,
2914*d83cc019SAndroid Build Coastguard Worker 
2915*d83cc019SAndroid Build Coastguard Worker 		/* OA unit configuration */
2916*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_METRICS_SET, test_metric_set_id,
2917*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_FORMAT, test_oa_format,
2918*d83cc019SAndroid Build Coastguard Worker 
2919*d83cc019SAndroid Build Coastguard Worker 		/* Note: no OA exponent specified in this case */
2920*d83cc019SAndroid Build Coastguard Worker 	};
2921*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_perf_open_param param = {
2922*d83cc019SAndroid Build Coastguard Worker 		.flags = I915_PERF_FLAG_FD_CLOEXEC,
2923*d83cc019SAndroid Build Coastguard Worker 		.num_properties = sizeof(properties) / 16,
2924*d83cc019SAndroid Build Coastguard Worker 		.properties_ptr = to_user_pointer(properties),
2925*d83cc019SAndroid Build Coastguard Worker 	};
2926*d83cc019SAndroid Build Coastguard Worker 
2927*d83cc019SAndroid Build Coastguard Worker 	/* should be default, but just to be sure... */
2928*d83cc019SAndroid Build Coastguard Worker 	write_u64_file("/proc/sys/dev/i915/perf_stream_paranoid", 1);
2929*d83cc019SAndroid Build Coastguard Worker 
2930*d83cc019SAndroid Build Coastguard Worker 	igt_fork(child, 1) {
2931*d83cc019SAndroid Build Coastguard Worker 		drm_intel_bufmgr *bufmgr;
2932*d83cc019SAndroid Build Coastguard Worker 		drm_intel_context *context0, *context1;
2933*d83cc019SAndroid Build Coastguard Worker 		struct intel_batchbuffer *batch;
2934*d83cc019SAndroid Build Coastguard Worker 		struct igt_buf src[3], dst[3];
2935*d83cc019SAndroid Build Coastguard Worker 		drm_intel_bo *bo;
2936*d83cc019SAndroid Build Coastguard Worker 		uint32_t *report0_32, *report1_32;
2937*d83cc019SAndroid Build Coastguard Worker 		uint64_t timestamp0_64, timestamp1_64;
2938*d83cc019SAndroid Build Coastguard Worker 		uint32_t delta_ts64, delta_oa32;
2939*d83cc019SAndroid Build Coastguard Worker 		uint64_t delta_ts64_ns, delta_oa32_ns;
2940*d83cc019SAndroid Build Coastguard Worker 		uint32_t delta_delta;
2941*d83cc019SAndroid Build Coastguard Worker 		int n_samples_written;
2942*d83cc019SAndroid Build Coastguard Worker 		int width = 800;
2943*d83cc019SAndroid Build Coastguard Worker 		int height = 600;
2944*d83cc019SAndroid Build Coastguard Worker 		uint32_t ctx_id = 0xffffffff; /* invalid id */
2945*d83cc019SAndroid Build Coastguard Worker 		int ret;
2946*d83cc019SAndroid Build Coastguard Worker 
2947*d83cc019SAndroid Build Coastguard Worker 		igt_drop_root();
2948*d83cc019SAndroid Build Coastguard Worker 
2949*d83cc019SAndroid Build Coastguard Worker 		bufmgr = drm_intel_bufmgr_gem_init(drm_fd, 4096);
2950*d83cc019SAndroid Build Coastguard Worker 		drm_intel_bufmgr_gem_enable_reuse(bufmgr);
2951*d83cc019SAndroid Build Coastguard Worker 
2952*d83cc019SAndroid Build Coastguard Worker 		for (int i = 0; i < ARRAY_SIZE(src); i++) {
2953*d83cc019SAndroid Build Coastguard Worker 			scratch_buf_init(bufmgr, &src[i], width, height, 0xff0000ff);
2954*d83cc019SAndroid Build Coastguard Worker 			scratch_buf_init(bufmgr, &dst[i], width, height, 0x00ff00ff);
2955*d83cc019SAndroid Build Coastguard Worker 		}
2956*d83cc019SAndroid Build Coastguard Worker 
2957*d83cc019SAndroid Build Coastguard Worker 		batch = intel_batchbuffer_alloc(bufmgr, devid);
2958*d83cc019SAndroid Build Coastguard Worker 
2959*d83cc019SAndroid Build Coastguard Worker 		context0 = drm_intel_gem_context_create(bufmgr);
2960*d83cc019SAndroid Build Coastguard Worker 		igt_assert(context0);
2961*d83cc019SAndroid Build Coastguard Worker 
2962*d83cc019SAndroid Build Coastguard Worker 		context1 = drm_intel_gem_context_create(bufmgr);
2963*d83cc019SAndroid Build Coastguard Worker 		igt_assert(context1);
2964*d83cc019SAndroid Build Coastguard Worker 
2965*d83cc019SAndroid Build Coastguard Worker 		igt_debug("submitting warm up render_copy\n");
2966*d83cc019SAndroid Build Coastguard Worker 
2967*d83cc019SAndroid Build Coastguard Worker 		/* Submit some early, unmeasured, work to the context we want
2968*d83cc019SAndroid Build Coastguard Worker 		 * to measure to try and catch issues with i915-perf
2969*d83cc019SAndroid Build Coastguard Worker 		 * initializing the HW context ID for filtering.
2970*d83cc019SAndroid Build Coastguard Worker 		 *
2971*d83cc019SAndroid Build Coastguard Worker 		 * We do this because i915-perf single context filtering had
2972*d83cc019SAndroid Build Coastguard Worker 		 * previously only relied on a hook into context pinning to
2973*d83cc019SAndroid Build Coastguard Worker 		 * initialize the HW context ID, instead of also trying to
2974*d83cc019SAndroid Build Coastguard Worker 		 * determine the HW ID while opening the stream, in case it
2975*d83cc019SAndroid Build Coastguard Worker 		 * has already been pinned.
2976*d83cc019SAndroid Build Coastguard Worker 		 *
2977*d83cc019SAndroid Build Coastguard Worker 		 * This wasn't noticed by the previous unit test because we
2978*d83cc019SAndroid Build Coastguard Worker 		 * were opening the stream while the context hadn't been
2979*d83cc019SAndroid Build Coastguard Worker 		 * touched or pinned yet and so it worked out correctly to wait
2980*d83cc019SAndroid Build Coastguard Worker 		 * for the pinning hook.
2981*d83cc019SAndroid Build Coastguard Worker 		 *
2982*d83cc019SAndroid Build Coastguard Worker 		 * Now a buggy version of i915-perf will fail to measure
2983*d83cc019SAndroid Build Coastguard Worker 		 * anything for context0 once this initial render_copy() ends
2984*d83cc019SAndroid Build Coastguard Worker 		 * up pinning the context since there won't ever be a pinning
2985*d83cc019SAndroid Build Coastguard Worker 		 * hook callback.
2986*d83cc019SAndroid Build Coastguard Worker 		 */
2987*d83cc019SAndroid Build Coastguard Worker 		render_copy(batch,
2988*d83cc019SAndroid Build Coastguard Worker 			    context0,
2989*d83cc019SAndroid Build Coastguard Worker 			    &src[0], 0, 0, width, height,
2990*d83cc019SAndroid Build Coastguard Worker 			    &dst[0], 0, 0);
2991*d83cc019SAndroid Build Coastguard Worker 
2992*d83cc019SAndroid Build Coastguard Worker 		ret = drm_intel_gem_context_get_id(context0, &ctx_id);
2993*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(ret, 0);
2994*d83cc019SAndroid Build Coastguard Worker 		igt_assert_neq(ctx_id, 0xffffffff);
2995*d83cc019SAndroid Build Coastguard Worker 		properties[1] = ctx_id;
2996*d83cc019SAndroid Build Coastguard Worker 
2997*d83cc019SAndroid Build Coastguard Worker 		intel_batchbuffer_flush_with_context(batch, context0);
2998*d83cc019SAndroid Build Coastguard Worker 
2999*d83cc019SAndroid Build Coastguard Worker 		scratch_buf_memset(src[0].bo, width, height, 0xff0000ff);
3000*d83cc019SAndroid Build Coastguard Worker 		scratch_buf_memset(dst[0].bo, width, height, 0x00ff00ff);
3001*d83cc019SAndroid Build Coastguard Worker 
3002*d83cc019SAndroid Build Coastguard Worker 		igt_debug("opening i915-perf stream\n");
3003*d83cc019SAndroid Build Coastguard Worker 		stream_fd = __perf_open(drm_fd, &param, false);
3004*d83cc019SAndroid Build Coastguard Worker 
3005*d83cc019SAndroid Build Coastguard Worker 		bo = drm_intel_bo_alloc(bufmgr, "mi_rpc dest bo", 4096, 64);
3006*d83cc019SAndroid Build Coastguard Worker 
3007*d83cc019SAndroid Build Coastguard Worker 		ret = drm_intel_bo_map(bo, true /* write enable */);
3008*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(ret, 0);
3009*d83cc019SAndroid Build Coastguard Worker 
3010*d83cc019SAndroid Build Coastguard Worker 		memset(bo->virtual, 0x80, 4096);
3011*d83cc019SAndroid Build Coastguard Worker 		drm_intel_bo_unmap(bo);
3012*d83cc019SAndroid Build Coastguard Worker 
3013*d83cc019SAndroid Build Coastguard Worker 		emit_stall_timestamp_and_rpc(batch,
3014*d83cc019SAndroid Build Coastguard Worker 					     bo,
3015*d83cc019SAndroid Build Coastguard Worker 					     512 /* timestamp offset */,
3016*d83cc019SAndroid Build Coastguard Worker 					     0, /* report dst offset */
3017*d83cc019SAndroid Build Coastguard Worker 					     0xdeadbeef); /* report id */
3018*d83cc019SAndroid Build Coastguard Worker 
3019*d83cc019SAndroid Build Coastguard Worker 		/* Explicitly flush here (even though the render_copy() call
3020*d83cc019SAndroid Build Coastguard Worker 		 * will itself flush before/after the copy) to clarify that
3021*d83cc019SAndroid Build Coastguard Worker 		 * that the PIPE_CONTROL + MI_RPC commands will be in a
3022*d83cc019SAndroid Build Coastguard Worker 		 * separate batch from the copy.
3023*d83cc019SAndroid Build Coastguard Worker 		 */
3024*d83cc019SAndroid Build Coastguard Worker 		intel_batchbuffer_flush_with_context(batch, context0);
3025*d83cc019SAndroid Build Coastguard Worker 
3026*d83cc019SAndroid Build Coastguard Worker 		render_copy(batch,
3027*d83cc019SAndroid Build Coastguard Worker 			    context0,
3028*d83cc019SAndroid Build Coastguard Worker 			    &src[0], 0, 0, width, height,
3029*d83cc019SAndroid Build Coastguard Worker 			    &dst[0], 0, 0);
3030*d83cc019SAndroid Build Coastguard Worker 
3031*d83cc019SAndroid Build Coastguard Worker 		/* Another redundant flush to clarify batch bo is free to reuse */
3032*d83cc019SAndroid Build Coastguard Worker 		intel_batchbuffer_flush_with_context(batch, context0);
3033*d83cc019SAndroid Build Coastguard Worker 
3034*d83cc019SAndroid Build Coastguard Worker 		/* submit two copies on the other context to avoid a false
3035*d83cc019SAndroid Build Coastguard Worker 		 * positive in case the driver somehow ended up filtering for
3036*d83cc019SAndroid Build Coastguard Worker 		 * context1
3037*d83cc019SAndroid Build Coastguard Worker 		 */
3038*d83cc019SAndroid Build Coastguard Worker 		render_copy(batch,
3039*d83cc019SAndroid Build Coastguard Worker 			    context1,
3040*d83cc019SAndroid Build Coastguard Worker 			    &src[1], 0, 0, width, height,
3041*d83cc019SAndroid Build Coastguard Worker 			    &dst[1], 0, 0);
3042*d83cc019SAndroid Build Coastguard Worker 
3043*d83cc019SAndroid Build Coastguard Worker 		render_copy(batch,
3044*d83cc019SAndroid Build Coastguard Worker 			    context1,
3045*d83cc019SAndroid Build Coastguard Worker 			    &src[2], 0, 0, width, height,
3046*d83cc019SAndroid Build Coastguard Worker 			    &dst[2], 0, 0);
3047*d83cc019SAndroid Build Coastguard Worker 
3048*d83cc019SAndroid Build Coastguard Worker 		/* And another */
3049*d83cc019SAndroid Build Coastguard Worker 		intel_batchbuffer_flush_with_context(batch, context1);
3050*d83cc019SAndroid Build Coastguard Worker 
3051*d83cc019SAndroid Build Coastguard Worker 		emit_stall_timestamp_and_rpc(batch,
3052*d83cc019SAndroid Build Coastguard Worker 					     bo,
3053*d83cc019SAndroid Build Coastguard Worker 					     520 /* timestamp offset */,
3054*d83cc019SAndroid Build Coastguard Worker 					     256, /* report dst offset */
3055*d83cc019SAndroid Build Coastguard Worker 					     0xbeefbeef); /* report id */
3056*d83cc019SAndroid Build Coastguard Worker 
3057*d83cc019SAndroid Build Coastguard Worker 		intel_batchbuffer_flush_with_context(batch, context0);
3058*d83cc019SAndroid Build Coastguard Worker 
3059*d83cc019SAndroid Build Coastguard Worker 		ret = drm_intel_bo_map(bo, false /* write enable */);
3060*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(ret, 0);
3061*d83cc019SAndroid Build Coastguard Worker 
3062*d83cc019SAndroid Build Coastguard Worker 		report0_32 = bo->virtual;
3063*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(report0_32[0], 0xdeadbeef); /* report ID */
3064*d83cc019SAndroid Build Coastguard Worker 		igt_assert_neq(report0_32[1], 0); /* timestamp */
3065*d83cc019SAndroid Build Coastguard Worker 
3066*d83cc019SAndroid Build Coastguard Worker 		report1_32 = report0_32 + 64;
3067*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(report1_32[0], 0xbeefbeef); /* report ID */
3068*d83cc019SAndroid Build Coastguard Worker 		igt_assert_neq(report1_32[1], 0); /* timestamp */
3069*d83cc019SAndroid Build Coastguard Worker 
3070*d83cc019SAndroid Build Coastguard Worker 		print_reports(report0_32, report1_32,
3071*d83cc019SAndroid Build Coastguard Worker 			      lookup_format(test_oa_format));
3072*d83cc019SAndroid Build Coastguard Worker 
3073*d83cc019SAndroid Build Coastguard Worker 		/* A40 == N samples written to all render targets */
3074*d83cc019SAndroid Build Coastguard Worker 		n_samples_written = report1_32[43] - report0_32[43];
3075*d83cc019SAndroid Build Coastguard Worker 
3076*d83cc019SAndroid Build Coastguard Worker 		igt_debug("n samples written = %d\n", n_samples_written);
3077*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(n_samples_written, width * height);
3078*d83cc019SAndroid Build Coastguard Worker 
3079*d83cc019SAndroid Build Coastguard Worker 		igt_debug("timestamp32 0 = %u\n", report0_32[1]);
3080*d83cc019SAndroid Build Coastguard Worker 		igt_debug("timestamp32 1 = %u\n", report1_32[1]);
3081*d83cc019SAndroid Build Coastguard Worker 
3082*d83cc019SAndroid Build Coastguard Worker 		timestamp0_64 = *(uint64_t *)(((uint8_t *)bo->virtual) + 512);
3083*d83cc019SAndroid Build Coastguard Worker 		timestamp1_64 = *(uint64_t *)(((uint8_t *)bo->virtual) + 520);
3084*d83cc019SAndroid Build Coastguard Worker 
3085*d83cc019SAndroid Build Coastguard Worker 		igt_debug("timestamp64 0 = %"PRIu64"\n", timestamp0_64);
3086*d83cc019SAndroid Build Coastguard Worker 		igt_debug("timestamp64 1 = %"PRIu64"\n", timestamp1_64);
3087*d83cc019SAndroid Build Coastguard Worker 
3088*d83cc019SAndroid Build Coastguard Worker 		delta_ts64 = timestamp1_64 - timestamp0_64;
3089*d83cc019SAndroid Build Coastguard Worker 		delta_oa32 = report1_32[1] - report0_32[1];
3090*d83cc019SAndroid Build Coastguard Worker 
3091*d83cc019SAndroid Build Coastguard Worker 		/* sanity check that we can pass the delta to timebase_scale */
3092*d83cc019SAndroid Build Coastguard Worker 		igt_assert(delta_ts64 < UINT32_MAX);
3093*d83cc019SAndroid Build Coastguard Worker 		delta_oa32_ns = timebase_scale(delta_oa32);
3094*d83cc019SAndroid Build Coastguard Worker 		delta_ts64_ns = timebase_scale(delta_ts64);
3095*d83cc019SAndroid Build Coastguard Worker 
3096*d83cc019SAndroid Build Coastguard Worker 		igt_debug("ts32 delta = %u, = %uns\n",
3097*d83cc019SAndroid Build Coastguard Worker 			  delta_oa32, (unsigned)delta_oa32_ns);
3098*d83cc019SAndroid Build Coastguard Worker 		igt_debug("ts64 delta = %u, = %uns\n",
3099*d83cc019SAndroid Build Coastguard Worker 			  delta_ts64, (unsigned)delta_ts64_ns);
3100*d83cc019SAndroid Build Coastguard Worker 
3101*d83cc019SAndroid Build Coastguard Worker 		/* The delta as calculated via the PIPE_CONTROL timestamp or
3102*d83cc019SAndroid Build Coastguard Worker 		 * the OA report timestamps should be almost identical but
3103*d83cc019SAndroid Build Coastguard Worker 		 * allow a 320 nanoseconds margin.
3104*d83cc019SAndroid Build Coastguard Worker 		 */
3105*d83cc019SAndroid Build Coastguard Worker 		delta_delta = delta_ts64_ns > delta_oa32_ns ?
3106*d83cc019SAndroid Build Coastguard Worker 			(delta_ts64_ns - delta_oa32_ns) :
3107*d83cc019SAndroid Build Coastguard Worker 			(delta_oa32_ns - delta_ts64_ns);
3108*d83cc019SAndroid Build Coastguard Worker 		igt_assert(delta_delta <= 320);
3109*d83cc019SAndroid Build Coastguard Worker 
3110*d83cc019SAndroid Build Coastguard Worker 		for (int i = 0; i < ARRAY_SIZE(src); i++) {
3111*d83cc019SAndroid Build Coastguard Worker 			drm_intel_bo_unreference(src[i].bo);
3112*d83cc019SAndroid Build Coastguard Worker 			drm_intel_bo_unreference(dst[i].bo);
3113*d83cc019SAndroid Build Coastguard Worker 		}
3114*d83cc019SAndroid Build Coastguard Worker 
3115*d83cc019SAndroid Build Coastguard Worker 		drm_intel_bo_unmap(bo);
3116*d83cc019SAndroid Build Coastguard Worker 		drm_intel_bo_unreference(bo);
3117*d83cc019SAndroid Build Coastguard Worker 		intel_batchbuffer_free(batch);
3118*d83cc019SAndroid Build Coastguard Worker 		drm_intel_gem_context_destroy(context0);
3119*d83cc019SAndroid Build Coastguard Worker 		drm_intel_gem_context_destroy(context1);
3120*d83cc019SAndroid Build Coastguard Worker 		drm_intel_bufmgr_destroy(bufmgr);
3121*d83cc019SAndroid Build Coastguard Worker 		__perf_close(stream_fd);
3122*d83cc019SAndroid Build Coastguard Worker 	}
3123*d83cc019SAndroid Build Coastguard Worker 
3124*d83cc019SAndroid Build Coastguard Worker 	igt_waitchildren();
3125*d83cc019SAndroid Build Coastguard Worker }
3126*d83cc019SAndroid Build Coastguard Worker 
3127*d83cc019SAndroid Build Coastguard Worker /* Tests the INTEL_performance_query use case where an unprivileged process
3128*d83cc019SAndroid Build Coastguard Worker  * should be able to configure the OA unit for per-context metrics (for a
3129*d83cc019SAndroid Build Coastguard Worker  * context associated with that process' drm file descriptor) and the counters
3130*d83cc019SAndroid Build Coastguard Worker  * should only relate to that specific context.
3131*d83cc019SAndroid Build Coastguard Worker  *
3132*d83cc019SAndroid Build Coastguard Worker  * For Gen8+ although reports read via i915 perf can be filtered for a single
3133*d83cc019SAndroid Build Coastguard Worker  * context the counters themselves always progress as global/system-wide
3134*d83cc019SAndroid Build Coastguard Worker  * counters affected by all contexts. To support the INTEL_performance_query
3135*d83cc019SAndroid Build Coastguard Worker  * use case on Gen8+ it's necessary to combine OABUFFER and
3136*d83cc019SAndroid Build Coastguard Worker  * MI_REPORT_PERF_COUNT reports so that counter normalisation can take into
3137*d83cc019SAndroid Build Coastguard Worker  * account context-switch reports and factor out any counter progression not
3138*d83cc019SAndroid Build Coastguard Worker  * associated with the current context.
3139*d83cc019SAndroid Build Coastguard Worker  */
3140*d83cc019SAndroid Build Coastguard Worker static void
gen8_test_single_ctx_render_target_writes_a_counter(void)3141*d83cc019SAndroid Build Coastguard Worker gen8_test_single_ctx_render_target_writes_a_counter(void)
3142*d83cc019SAndroid Build Coastguard Worker {
3143*d83cc019SAndroid Build Coastguard Worker 	int oa_exponent = max_oa_exponent_for_period_lte(1000000);
3144*d83cc019SAndroid Build Coastguard Worker 	uint64_t properties[] = {
3145*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_CTX_HANDLE, UINT64_MAX, /* updated below */
3146*d83cc019SAndroid Build Coastguard Worker 
3147*d83cc019SAndroid Build Coastguard Worker 		/* Note: we have to specify at least one sample property even
3148*d83cc019SAndroid Build Coastguard Worker 		 * though we aren't interested in samples in this case
3149*d83cc019SAndroid Build Coastguard Worker 		 */
3150*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_SAMPLE_OA, true,
3151*d83cc019SAndroid Build Coastguard Worker 
3152*d83cc019SAndroid Build Coastguard Worker 		/* OA unit configuration */
3153*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_METRICS_SET, test_metric_set_id,
3154*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_FORMAT, test_oa_format,
3155*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_EXPONENT, oa_exponent,
3156*d83cc019SAndroid Build Coastguard Worker 
3157*d83cc019SAndroid Build Coastguard Worker 		/* Note: no OA exponent specified in this case */
3158*d83cc019SAndroid Build Coastguard Worker 	};
3159*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_perf_open_param param = {
3160*d83cc019SAndroid Build Coastguard Worker 		.flags = I915_PERF_FLAG_FD_CLOEXEC,
3161*d83cc019SAndroid Build Coastguard Worker 		.num_properties = ARRAY_SIZE(properties) / 2,
3162*d83cc019SAndroid Build Coastguard Worker 		.properties_ptr = to_user_pointer(properties),
3163*d83cc019SAndroid Build Coastguard Worker 	};
3164*d83cc019SAndroid Build Coastguard Worker 	size_t format_size = get_oa_format(test_oa_format).size;
3165*d83cc019SAndroid Build Coastguard Worker 	size_t sample_size = (sizeof(struct drm_i915_perf_record_header) +
3166*d83cc019SAndroid Build Coastguard Worker 			      format_size);
3167*d83cc019SAndroid Build Coastguard Worker 	int max_reports = MAX_OA_BUF_SIZE / format_size;
3168*d83cc019SAndroid Build Coastguard Worker 	int buf_size = sample_size * max_reports * 1.5;
3169*d83cc019SAndroid Build Coastguard Worker 	int child_ret;
3170*d83cc019SAndroid Build Coastguard Worker 	uint8_t *buf = malloc(buf_size);
3171*d83cc019SAndroid Build Coastguard Worker 	ssize_t len;
3172*d83cc019SAndroid Build Coastguard Worker 	struct igt_helper_process child = {};
3173*d83cc019SAndroid Build Coastguard Worker 
3174*d83cc019SAndroid Build Coastguard Worker 	/* should be default, but just to be sure... */
3175*d83cc019SAndroid Build Coastguard Worker 	write_u64_file("/proc/sys/dev/i915/perf_stream_paranoid", 1);
3176*d83cc019SAndroid Build Coastguard Worker 
3177*d83cc019SAndroid Build Coastguard Worker 	do {
3178*d83cc019SAndroid Build Coastguard Worker 
3179*d83cc019SAndroid Build Coastguard Worker 		igt_fork_helper(&child) {
3180*d83cc019SAndroid Build Coastguard Worker 			struct drm_i915_perf_record_header *header;
3181*d83cc019SAndroid Build Coastguard Worker 			drm_intel_bufmgr *bufmgr;
3182*d83cc019SAndroid Build Coastguard Worker 			drm_intel_context *context0, *context1;
3183*d83cc019SAndroid Build Coastguard Worker 			struct intel_batchbuffer *batch;
3184*d83cc019SAndroid Build Coastguard Worker 			struct igt_buf src[3], dst[3];
3185*d83cc019SAndroid Build Coastguard Worker 			drm_intel_bo *bo;
3186*d83cc019SAndroid Build Coastguard Worker 			uint32_t *report0_32, *report1_32;
3187*d83cc019SAndroid Build Coastguard Worker 			uint32_t *prev, *lprev = NULL;
3188*d83cc019SAndroid Build Coastguard Worker 			uint64_t timestamp0_64, timestamp1_64;
3189*d83cc019SAndroid Build Coastguard Worker 			uint32_t delta_ts64, delta_oa32;
3190*d83cc019SAndroid Build Coastguard Worker 			uint64_t delta_ts64_ns, delta_oa32_ns;
3191*d83cc019SAndroid Build Coastguard Worker 			uint32_t delta_delta;
3192*d83cc019SAndroid Build Coastguard Worker 			int width = 800;
3193*d83cc019SAndroid Build Coastguard Worker 			int height = 600;
3194*d83cc019SAndroid Build Coastguard Worker 			uint32_t ctx_id = 0xffffffff; /* invalid handle */
3195*d83cc019SAndroid Build Coastguard Worker 			uint32_t ctx1_id = 0xffffffff;  /* invalid handle */
3196*d83cc019SAndroid Build Coastguard Worker 			uint32_t current_ctx_id = 0xffffffff;
3197*d83cc019SAndroid Build Coastguard Worker 			uint32_t n_invalid_ctx = 0;
3198*d83cc019SAndroid Build Coastguard Worker 			int ret;
3199*d83cc019SAndroid Build Coastguard Worker 			struct accumulator accumulator = {
3200*d83cc019SAndroid Build Coastguard Worker 				.format = test_oa_format
3201*d83cc019SAndroid Build Coastguard Worker 			};
3202*d83cc019SAndroid Build Coastguard Worker 
3203*d83cc019SAndroid Build Coastguard Worker 			bufmgr = drm_intel_bufmgr_gem_init(drm_fd, 4096);
3204*d83cc019SAndroid Build Coastguard Worker 			drm_intel_bufmgr_gem_enable_reuse(bufmgr);
3205*d83cc019SAndroid Build Coastguard Worker 
3206*d83cc019SAndroid Build Coastguard Worker 			for (int i = 0; i < ARRAY_SIZE(src); i++) {
3207*d83cc019SAndroid Build Coastguard Worker 				scratch_buf_init(bufmgr, &src[i], width, height, 0xff0000ff);
3208*d83cc019SAndroid Build Coastguard Worker 				scratch_buf_init(bufmgr, &dst[i], width, height, 0x00ff00ff);
3209*d83cc019SAndroid Build Coastguard Worker 			}
3210*d83cc019SAndroid Build Coastguard Worker 
3211*d83cc019SAndroid Build Coastguard Worker 			batch = intel_batchbuffer_alloc(bufmgr, devid);
3212*d83cc019SAndroid Build Coastguard Worker 
3213*d83cc019SAndroid Build Coastguard Worker 			context0 = drm_intel_gem_context_create(bufmgr);
3214*d83cc019SAndroid Build Coastguard Worker 			igt_assert(context0);
3215*d83cc019SAndroid Build Coastguard Worker 
3216*d83cc019SAndroid Build Coastguard Worker 			context1 = drm_intel_gem_context_create(bufmgr);
3217*d83cc019SAndroid Build Coastguard Worker 			igt_assert(context1);
3218*d83cc019SAndroid Build Coastguard Worker 
3219*d83cc019SAndroid Build Coastguard Worker 			igt_debug("submitting warm up render_copy\n");
3220*d83cc019SAndroid Build Coastguard Worker 
3221*d83cc019SAndroid Build Coastguard Worker 			/* Submit some early, unmeasured, work to the context we want
3222*d83cc019SAndroid Build Coastguard Worker 			 * to measure to try and catch issues with i915-perf
3223*d83cc019SAndroid Build Coastguard Worker 			 * initializing the HW context ID for filtering.
3224*d83cc019SAndroid Build Coastguard Worker 			 *
3225*d83cc019SAndroid Build Coastguard Worker 			 * We do this because i915-perf single context filtering had
3226*d83cc019SAndroid Build Coastguard Worker 			 * previously only relied on a hook into context pinning to
3227*d83cc019SAndroid Build Coastguard Worker 			 * initialize the HW context ID, instead of also trying to
3228*d83cc019SAndroid Build Coastguard Worker 			 * determine the HW ID while opening the stream, in case it
3229*d83cc019SAndroid Build Coastguard Worker 			 * has already been pinned.
3230*d83cc019SAndroid Build Coastguard Worker 			 *
3231*d83cc019SAndroid Build Coastguard Worker 			 * This wasn't noticed by the previous unit test because we
3232*d83cc019SAndroid Build Coastguard Worker 			 * were opening the stream while the context hadn't been
3233*d83cc019SAndroid Build Coastguard Worker 			 * touched or pinned yet and so it worked out correctly to wait
3234*d83cc019SAndroid Build Coastguard Worker 			 * for the pinning hook.
3235*d83cc019SAndroid Build Coastguard Worker 			 *
3236*d83cc019SAndroid Build Coastguard Worker 			 * Now a buggy version of i915-perf will fail to measure
3237*d83cc019SAndroid Build Coastguard Worker 			 * anything for context0 once this initial render_copy() ends
3238*d83cc019SAndroid Build Coastguard Worker 			 * up pinning the context since there won't ever be a pinning
3239*d83cc019SAndroid Build Coastguard Worker 			 * hook callback.
3240*d83cc019SAndroid Build Coastguard Worker 			 */
3241*d83cc019SAndroid Build Coastguard Worker 			render_copy(batch,
3242*d83cc019SAndroid Build Coastguard Worker 				    context0,
3243*d83cc019SAndroid Build Coastguard Worker 				    &src[0], 0, 0, width, height,
3244*d83cc019SAndroid Build Coastguard Worker 				    &dst[0], 0, 0);
3245*d83cc019SAndroid Build Coastguard Worker 
3246*d83cc019SAndroid Build Coastguard Worker 			ret = drm_intel_gem_context_get_id(context0, &ctx_id);
3247*d83cc019SAndroid Build Coastguard Worker 			igt_assert_eq(ret, 0);
3248*d83cc019SAndroid Build Coastguard Worker 			igt_assert_neq(ctx_id, 0xffffffff);
3249*d83cc019SAndroid Build Coastguard Worker 			properties[1] = ctx_id;
3250*d83cc019SAndroid Build Coastguard Worker 
3251*d83cc019SAndroid Build Coastguard Worker 			scratch_buf_memset(src[0].bo, width, height, 0xff0000ff);
3252*d83cc019SAndroid Build Coastguard Worker 			scratch_buf_memset(dst[0].bo, width, height, 0x00ff00ff);
3253*d83cc019SAndroid Build Coastguard Worker 
3254*d83cc019SAndroid Build Coastguard Worker 			igt_debug("opening i915-perf stream\n");
3255*d83cc019SAndroid Build Coastguard Worker 			stream_fd = __perf_open(drm_fd, &param, false);
3256*d83cc019SAndroid Build Coastguard Worker 
3257*d83cc019SAndroid Build Coastguard Worker 			bo = drm_intel_bo_alloc(bufmgr, "mi_rpc dest bo", 4096, 64);
3258*d83cc019SAndroid Build Coastguard Worker 
3259*d83cc019SAndroid Build Coastguard Worker 			ret = drm_intel_bo_map(bo, true /* write enable */);
3260*d83cc019SAndroid Build Coastguard Worker 			igt_assert_eq(ret, 0);
3261*d83cc019SAndroid Build Coastguard Worker 
3262*d83cc019SAndroid Build Coastguard Worker 			memset(bo->virtual, 0x80, 4096);
3263*d83cc019SAndroid Build Coastguard Worker 			drm_intel_bo_unmap(bo);
3264*d83cc019SAndroid Build Coastguard Worker 
3265*d83cc019SAndroid Build Coastguard Worker 			emit_stall_timestamp_and_rpc(batch,
3266*d83cc019SAndroid Build Coastguard Worker 						     bo,
3267*d83cc019SAndroid Build Coastguard Worker 						     512 /* timestamp offset */,
3268*d83cc019SAndroid Build Coastguard Worker 						     0, /* report dst offset */
3269*d83cc019SAndroid Build Coastguard Worker 						     0xdeadbeef); /* report id */
3270*d83cc019SAndroid Build Coastguard Worker 
3271*d83cc019SAndroid Build Coastguard Worker 			/* Explicitly flush here (even though the render_copy() call
3272*d83cc019SAndroid Build Coastguard Worker 			 * will itself flush before/after the copy) to clarify that
3273*d83cc019SAndroid Build Coastguard Worker 			 * that the PIPE_CONTROL + MI_RPC commands will be in a
3274*d83cc019SAndroid Build Coastguard Worker 			 * separate batch from the copy.
3275*d83cc019SAndroid Build Coastguard Worker 			 */
3276*d83cc019SAndroid Build Coastguard Worker 			intel_batchbuffer_flush_with_context(batch, context0);
3277*d83cc019SAndroid Build Coastguard Worker 
3278*d83cc019SAndroid Build Coastguard Worker 			render_copy(batch,
3279*d83cc019SAndroid Build Coastguard Worker 				    context0,
3280*d83cc019SAndroid Build Coastguard Worker 				    &src[0], 0, 0, width, height,
3281*d83cc019SAndroid Build Coastguard Worker 				    &dst[0], 0, 0);
3282*d83cc019SAndroid Build Coastguard Worker 
3283*d83cc019SAndroid Build Coastguard Worker 			/* Another redundant flush to clarify batch bo is free to reuse */
3284*d83cc019SAndroid Build Coastguard Worker 			intel_batchbuffer_flush_with_context(batch, context0);
3285*d83cc019SAndroid Build Coastguard Worker 
3286*d83cc019SAndroid Build Coastguard Worker 			/* submit two copies on the other context to avoid a false
3287*d83cc019SAndroid Build Coastguard Worker 			 * positive in case the driver somehow ended up filtering for
3288*d83cc019SAndroid Build Coastguard Worker 			 * context1
3289*d83cc019SAndroid Build Coastguard Worker 			 */
3290*d83cc019SAndroid Build Coastguard Worker 			render_copy(batch,
3291*d83cc019SAndroid Build Coastguard Worker 				    context1,
3292*d83cc019SAndroid Build Coastguard Worker 				    &src[1], 0, 0, width, height,
3293*d83cc019SAndroid Build Coastguard Worker 				    &dst[1], 0, 0);
3294*d83cc019SAndroid Build Coastguard Worker 
3295*d83cc019SAndroid Build Coastguard Worker 			ret = drm_intel_gem_context_get_id(context1, &ctx1_id);
3296*d83cc019SAndroid Build Coastguard Worker 			igt_assert_eq(ret, 0);
3297*d83cc019SAndroid Build Coastguard Worker 			igt_assert_neq(ctx1_id, 0xffffffff);
3298*d83cc019SAndroid Build Coastguard Worker 
3299*d83cc019SAndroid Build Coastguard Worker 			render_copy(batch,
3300*d83cc019SAndroid Build Coastguard Worker 				    context1,
3301*d83cc019SAndroid Build Coastguard Worker 				    &src[2], 0, 0, width, height,
3302*d83cc019SAndroid Build Coastguard Worker 				    &dst[2], 0, 0);
3303*d83cc019SAndroid Build Coastguard Worker 
3304*d83cc019SAndroid Build Coastguard Worker 			/* And another */
3305*d83cc019SAndroid Build Coastguard Worker 			intel_batchbuffer_flush_with_context(batch, context1);
3306*d83cc019SAndroid Build Coastguard Worker 
3307*d83cc019SAndroid Build Coastguard Worker 			emit_stall_timestamp_and_rpc(batch,
3308*d83cc019SAndroid Build Coastguard Worker 						     bo,
3309*d83cc019SAndroid Build Coastguard Worker 						     520 /* timestamp offset */,
3310*d83cc019SAndroid Build Coastguard Worker 						     256, /* report dst offset */
3311*d83cc019SAndroid Build Coastguard Worker 						     0xbeefbeef); /* report id */
3312*d83cc019SAndroid Build Coastguard Worker 
3313*d83cc019SAndroid Build Coastguard Worker 			intel_batchbuffer_flush_with_context(batch, context1);
3314*d83cc019SAndroid Build Coastguard Worker 
3315*d83cc019SAndroid Build Coastguard Worker 			ret = drm_intel_bo_map(bo, false /* write enable */);
3316*d83cc019SAndroid Build Coastguard Worker 			igt_assert_eq(ret, 0);
3317*d83cc019SAndroid Build Coastguard Worker 
3318*d83cc019SAndroid Build Coastguard Worker 			report0_32 = bo->virtual;
3319*d83cc019SAndroid Build Coastguard Worker 			igt_assert_eq(report0_32[0], 0xdeadbeef); /* report ID */
3320*d83cc019SAndroid Build Coastguard Worker 			igt_assert_neq(report0_32[1], 0); /* timestamp */
3321*d83cc019SAndroid Build Coastguard Worker 			prev = report0_32;
3322*d83cc019SAndroid Build Coastguard Worker 			ctx_id = prev[2];
3323*d83cc019SAndroid Build Coastguard Worker 			igt_debug("MI_RPC(start) CTX ID: %u\n", ctx_id);
3324*d83cc019SAndroid Build Coastguard Worker 
3325*d83cc019SAndroid Build Coastguard Worker 			report1_32 = report0_32 + 64; /* 64 uint32_t = 256bytes offset */
3326*d83cc019SAndroid Build Coastguard Worker 			igt_assert_eq(report1_32[0], 0xbeefbeef); /* report ID */
3327*d83cc019SAndroid Build Coastguard Worker 			igt_assert_neq(report1_32[1], 0); /* timestamp */
3328*d83cc019SAndroid Build Coastguard Worker 			ctx1_id = report1_32[2];
3329*d83cc019SAndroid Build Coastguard Worker 
3330*d83cc019SAndroid Build Coastguard Worker 			memset(accumulator.deltas, 0, sizeof(accumulator.deltas));
3331*d83cc019SAndroid Build Coastguard Worker 			accumulate_reports(&accumulator, report0_32, report1_32);
3332*d83cc019SAndroid Build Coastguard Worker 			igt_debug("total: A0 = %"PRIu64", A21 = %"PRIu64", A26 = %"PRIu64"\n",
3333*d83cc019SAndroid Build Coastguard Worker 				  accumulator.deltas[2 + 0], /* skip timestamp + clock cycles */
3334*d83cc019SAndroid Build Coastguard Worker 				  accumulator.deltas[2 + 21],
3335*d83cc019SAndroid Build Coastguard Worker 				  accumulator.deltas[2 + 26]);
3336*d83cc019SAndroid Build Coastguard Worker 
3337*d83cc019SAndroid Build Coastguard Worker 			igt_debug("oa_timestamp32 0 = %u\n", report0_32[1]);
3338*d83cc019SAndroid Build Coastguard Worker 			igt_debug("oa_timestamp32 1 = %u\n", report1_32[1]);
3339*d83cc019SAndroid Build Coastguard Worker 			igt_debug("ctx_id 0 = %u\n", report0_32[2]);
3340*d83cc019SAndroid Build Coastguard Worker 			igt_debug("ctx_id 1 = %u\n", report1_32[2]);
3341*d83cc019SAndroid Build Coastguard Worker 
3342*d83cc019SAndroid Build Coastguard Worker 			timestamp0_64 = *(uint64_t *)(((uint8_t *)bo->virtual) + 512);
3343*d83cc019SAndroid Build Coastguard Worker 			timestamp1_64 = *(uint64_t *)(((uint8_t *)bo->virtual) + 520);
3344*d83cc019SAndroid Build Coastguard Worker 
3345*d83cc019SAndroid Build Coastguard Worker 			igt_debug("ts_timestamp64 0 = %"PRIu64"\n", timestamp0_64);
3346*d83cc019SAndroid Build Coastguard Worker 			igt_debug("ts_timestamp64 1 = %"PRIu64"\n", timestamp1_64);
3347*d83cc019SAndroid Build Coastguard Worker 
3348*d83cc019SAndroid Build Coastguard Worker 			delta_ts64 = timestamp1_64 - timestamp0_64;
3349*d83cc019SAndroid Build Coastguard Worker 			delta_oa32 = report1_32[1] - report0_32[1];
3350*d83cc019SAndroid Build Coastguard Worker 
3351*d83cc019SAndroid Build Coastguard Worker 			/* sanity check that we can pass the delta to timebase_scale */
3352*d83cc019SAndroid Build Coastguard Worker 			igt_assert(delta_ts64 < UINT32_MAX);
3353*d83cc019SAndroid Build Coastguard Worker 			delta_oa32_ns = timebase_scale(delta_oa32);
3354*d83cc019SAndroid Build Coastguard Worker 			delta_ts64_ns = timebase_scale(delta_ts64);
3355*d83cc019SAndroid Build Coastguard Worker 
3356*d83cc019SAndroid Build Coastguard Worker 			igt_debug("oa32 delta = %u, = %uns\n",
3357*d83cc019SAndroid Build Coastguard Worker 				  delta_oa32, (unsigned)delta_oa32_ns);
3358*d83cc019SAndroid Build Coastguard Worker 			igt_debug("ts64 delta = %u, = %uns\n",
3359*d83cc019SAndroid Build Coastguard Worker 				  delta_ts64, (unsigned)delta_ts64_ns);
3360*d83cc019SAndroid Build Coastguard Worker 
3361*d83cc019SAndroid Build Coastguard Worker 			/* The delta as calculated via the PIPE_CONTROL timestamp or
3362*d83cc019SAndroid Build Coastguard Worker 			 * the OA report timestamps should be almost identical but
3363*d83cc019SAndroid Build Coastguard Worker 			 * allow a 500 nanoseconds margin.
3364*d83cc019SAndroid Build Coastguard Worker 			 */
3365*d83cc019SAndroid Build Coastguard Worker 			delta_delta = delta_ts64_ns > delta_oa32_ns ?
3366*d83cc019SAndroid Build Coastguard Worker 				(delta_ts64_ns - delta_oa32_ns) :
3367*d83cc019SAndroid Build Coastguard Worker 				(delta_oa32_ns - delta_ts64_ns);
3368*d83cc019SAndroid Build Coastguard Worker 			if (delta_delta > 500) {
3369*d83cc019SAndroid Build Coastguard Worker 				igt_debug("skipping\n");
3370*d83cc019SAndroid Build Coastguard Worker 				exit(EAGAIN);
3371*d83cc019SAndroid Build Coastguard Worker 			}
3372*d83cc019SAndroid Build Coastguard Worker 
3373*d83cc019SAndroid Build Coastguard Worker 			len = i915_read_reports_until_timestamp(test_oa_format,
3374*d83cc019SAndroid Build Coastguard Worker 								buf, buf_size,
3375*d83cc019SAndroid Build Coastguard Worker 								report0_32[1],
3376*d83cc019SAndroid Build Coastguard Worker 								report1_32[1]);
3377*d83cc019SAndroid Build Coastguard Worker 
3378*d83cc019SAndroid Build Coastguard Worker 			igt_assert(len > 0);
3379*d83cc019SAndroid Build Coastguard Worker 			igt_debug("read %d bytes\n", (int)len);
3380*d83cc019SAndroid Build Coastguard Worker 
3381*d83cc019SAndroid Build Coastguard Worker 			memset(accumulator.deltas, 0, sizeof(accumulator.deltas));
3382*d83cc019SAndroid Build Coastguard Worker 
3383*d83cc019SAndroid Build Coastguard Worker 			for (size_t offset = 0; offset < len; offset += header->size) {
3384*d83cc019SAndroid Build Coastguard Worker 				uint32_t *report;
3385*d83cc019SAndroid Build Coastguard Worker 				uint32_t reason;
3386*d83cc019SAndroid Build Coastguard Worker 				const char *skip_reason = NULL, *report_reason = NULL;
3387*d83cc019SAndroid Build Coastguard Worker 				struct accumulator laccumulator = {
3388*d83cc019SAndroid Build Coastguard Worker 					.format = test_oa_format
3389*d83cc019SAndroid Build Coastguard Worker 				};
3390*d83cc019SAndroid Build Coastguard Worker 
3391*d83cc019SAndroid Build Coastguard Worker 
3392*d83cc019SAndroid Build Coastguard Worker 				header = (void *)(buf + offset);
3393*d83cc019SAndroid Build Coastguard Worker 
3394*d83cc019SAndroid Build Coastguard Worker 				igt_assert_eq(header->pad, 0); /* Reserved */
3395*d83cc019SAndroid Build Coastguard Worker 
3396*d83cc019SAndroid Build Coastguard Worker 				/* Currently the only test that should ever expect to
3397*d83cc019SAndroid Build Coastguard Worker 				 * see a _BUFFER_LOST error is the buffer_fill test,
3398*d83cc019SAndroid Build Coastguard Worker 				 * otherwise something bad has probably happened...
3399*d83cc019SAndroid Build Coastguard Worker 				 */
3400*d83cc019SAndroid Build Coastguard Worker 				igt_assert_neq(header->type, DRM_I915_PERF_RECORD_OA_BUFFER_LOST);
3401*d83cc019SAndroid Build Coastguard Worker 
3402*d83cc019SAndroid Build Coastguard Worker 				/* At high sampling frequencies the OA HW might not be
3403*d83cc019SAndroid Build Coastguard Worker 				 * able to cope with all write requests and will notify
3404*d83cc019SAndroid Build Coastguard Worker 				 * us that a report was lost.
3405*d83cc019SAndroid Build Coastguard Worker 				 *
3406*d83cc019SAndroid Build Coastguard Worker 				 * XXX: we should maybe restart the test in this case?
3407*d83cc019SAndroid Build Coastguard Worker 				 */
3408*d83cc019SAndroid Build Coastguard Worker 				if (header->type == DRM_I915_PERF_RECORD_OA_REPORT_LOST) {
3409*d83cc019SAndroid Build Coastguard Worker 					igt_debug("OA trigger collision / report lost\n");
3410*d83cc019SAndroid Build Coastguard Worker 					exit(EAGAIN);
3411*d83cc019SAndroid Build Coastguard Worker 				}
3412*d83cc019SAndroid Build Coastguard Worker 
3413*d83cc019SAndroid Build Coastguard Worker 				/* Currently the only other record type expected is a
3414*d83cc019SAndroid Build Coastguard Worker 				 * _SAMPLE. Notably this test will need updating if
3415*d83cc019SAndroid Build Coastguard Worker 				 * i915-perf is extended in the future with additional
3416*d83cc019SAndroid Build Coastguard Worker 				 * record types.
3417*d83cc019SAndroid Build Coastguard Worker 				 */
3418*d83cc019SAndroid Build Coastguard Worker 				igt_assert_eq(header->type, DRM_I915_PERF_RECORD_SAMPLE);
3419*d83cc019SAndroid Build Coastguard Worker 
3420*d83cc019SAndroid Build Coastguard Worker 				igt_assert_eq(header->size, sample_size);
3421*d83cc019SAndroid Build Coastguard Worker 
3422*d83cc019SAndroid Build Coastguard Worker 				report = (void *)(header + 1);
3423*d83cc019SAndroid Build Coastguard Worker 
3424*d83cc019SAndroid Build Coastguard Worker 				/* Don't expect zero for timestamps */
3425*d83cc019SAndroid Build Coastguard Worker 				igt_assert_neq(report[1], 0);
3426*d83cc019SAndroid Build Coastguard Worker 
3427*d83cc019SAndroid Build Coastguard Worker 				igt_debug("report %p:\n", report);
3428*d83cc019SAndroid Build Coastguard Worker 
3429*d83cc019SAndroid Build Coastguard Worker 				/* Discard reports not contained in between the
3430*d83cc019SAndroid Build Coastguard Worker 				 * timestamps we're looking at. */
3431*d83cc019SAndroid Build Coastguard Worker 				{
3432*d83cc019SAndroid Build Coastguard Worker 					uint32_t time_delta = report[1] - report0_32[1];
3433*d83cc019SAndroid Build Coastguard Worker 
3434*d83cc019SAndroid Build Coastguard Worker 					if (timebase_scale(time_delta) > 1000000000) {
3435*d83cc019SAndroid Build Coastguard Worker 						skip_reason = "prior first mi-rpc";
3436*d83cc019SAndroid Build Coastguard Worker 					}
3437*d83cc019SAndroid Build Coastguard Worker 				}
3438*d83cc019SAndroid Build Coastguard Worker 
3439*d83cc019SAndroid Build Coastguard Worker 				{
3440*d83cc019SAndroid Build Coastguard Worker 					uint32_t time_delta = report[1] - report1_32[1];
3441*d83cc019SAndroid Build Coastguard Worker 
3442*d83cc019SAndroid Build Coastguard Worker 					if (timebase_scale(time_delta) <= 1000000000) {
3443*d83cc019SAndroid Build Coastguard Worker 						igt_debug("    comes after last MI_RPC (%u)\n",
3444*d83cc019SAndroid Build Coastguard Worker 							  report1_32[1]);
3445*d83cc019SAndroid Build Coastguard Worker 						report = report1_32;
3446*d83cc019SAndroid Build Coastguard Worker 					}
3447*d83cc019SAndroid Build Coastguard Worker 				}
3448*d83cc019SAndroid Build Coastguard Worker 
3449*d83cc019SAndroid Build Coastguard Worker 				/* Print out deltas for a few significant
3450*d83cc019SAndroid Build Coastguard Worker 				 * counters for each report. */
3451*d83cc019SAndroid Build Coastguard Worker 				if (lprev) {
3452*d83cc019SAndroid Build Coastguard Worker 					memset(laccumulator.deltas, 0, sizeof(laccumulator.deltas));
3453*d83cc019SAndroid Build Coastguard Worker 					accumulate_reports(&laccumulator, lprev, report);
3454*d83cc019SAndroid Build Coastguard Worker 					igt_debug("    deltas: A0=%"PRIu64" A21=%"PRIu64", A26=%"PRIu64"\n",
3455*d83cc019SAndroid Build Coastguard Worker 						  laccumulator.deltas[2 + 0], /* skip timestamp + clock cycles */
3456*d83cc019SAndroid Build Coastguard Worker 						  laccumulator.deltas[2 + 21],
3457*d83cc019SAndroid Build Coastguard Worker 						  laccumulator.deltas[2 + 26]);
3458*d83cc019SAndroid Build Coastguard Worker 				}
3459*d83cc019SAndroid Build Coastguard Worker 				lprev = report;
3460*d83cc019SAndroid Build Coastguard Worker 
3461*d83cc019SAndroid Build Coastguard Worker 				/* Print out reason for the report. */
3462*d83cc019SAndroid Build Coastguard Worker 				reason = ((report[0] >> OAREPORT_REASON_SHIFT) &
3463*d83cc019SAndroid Build Coastguard Worker 					  OAREPORT_REASON_MASK);
3464*d83cc019SAndroid Build Coastguard Worker 
3465*d83cc019SAndroid Build Coastguard Worker 				if (reason & OAREPORT_REASON_CTX_SWITCH) {
3466*d83cc019SAndroid Build Coastguard Worker 					report_reason = "ctx-load";
3467*d83cc019SAndroid Build Coastguard Worker 				} else if (reason & OAREPORT_REASON_TIMER) {
3468*d83cc019SAndroid Build Coastguard Worker 					report_reason = "timer";
3469*d83cc019SAndroid Build Coastguard Worker 				} else if (reason & OAREPORT_REASON_INTERNAL ||
3470*d83cc019SAndroid Build Coastguard Worker 					   reason & OAREPORT_REASON_GO ||
3471*d83cc019SAndroid Build Coastguard Worker 					   reason & OAREPORT_REASON_CLK_RATIO) {
3472*d83cc019SAndroid Build Coastguard Worker 					report_reason = "internal/go/clk-ratio";
3473*d83cc019SAndroid Build Coastguard Worker 				} else {
3474*d83cc019SAndroid Build Coastguard Worker 					report_reason = "end-mi-rpc";
3475*d83cc019SAndroid Build Coastguard Worker 				}
3476*d83cc019SAndroid Build Coastguard Worker 				igt_debug("    ctx_id=%u/%x reason=%s oa_timestamp32=%u\n",
3477*d83cc019SAndroid Build Coastguard Worker 					  report[2], report[2], report_reason, report[1]);
3478*d83cc019SAndroid Build Coastguard Worker 
3479*d83cc019SAndroid Build Coastguard Worker 				/* Should we skip this report?
3480*d83cc019SAndroid Build Coastguard Worker 				 *
3481*d83cc019SAndroid Build Coastguard Worker 				 *   Only if the current context id of
3482*d83cc019SAndroid Build Coastguard Worker 				 *   the stream is not the one we want
3483*d83cc019SAndroid Build Coastguard Worker 				 *   to measure.
3484*d83cc019SAndroid Build Coastguard Worker 				 */
3485*d83cc019SAndroid Build Coastguard Worker 				if (current_ctx_id != ctx_id) {
3486*d83cc019SAndroid Build Coastguard Worker 					skip_reason = "not our context";
3487*d83cc019SAndroid Build Coastguard Worker 				}
3488*d83cc019SAndroid Build Coastguard Worker 
3489*d83cc019SAndroid Build Coastguard Worker 				if (n_invalid_ctx > 1) {
3490*d83cc019SAndroid Build Coastguard Worker 					skip_reason = "too many invalid context events";
3491*d83cc019SAndroid Build Coastguard Worker 				}
3492*d83cc019SAndroid Build Coastguard Worker 
3493*d83cc019SAndroid Build Coastguard Worker 				if (!skip_reason) {
3494*d83cc019SAndroid Build Coastguard Worker 					accumulate_reports(&accumulator, prev, report);
3495*d83cc019SAndroid Build Coastguard Worker 					igt_debug(" -> Accumulated deltas A0=%"PRIu64" A21=%"PRIu64", A26=%"PRIu64"\n",
3496*d83cc019SAndroid Build Coastguard Worker 						  accumulator.deltas[2 + 0], /* skip timestamp + clock cycles */
3497*d83cc019SAndroid Build Coastguard Worker 						  accumulator.deltas[2 + 21],
3498*d83cc019SAndroid Build Coastguard Worker 						  accumulator.deltas[2 + 26]);
3499*d83cc019SAndroid Build Coastguard Worker 				} else {
3500*d83cc019SAndroid Build Coastguard Worker 					igt_debug(" -> Skipping: %s\n", skip_reason);
3501*d83cc019SAndroid Build Coastguard Worker 				}
3502*d83cc019SAndroid Build Coastguard Worker 
3503*d83cc019SAndroid Build Coastguard Worker 
3504*d83cc019SAndroid Build Coastguard Worker 				/* Finally update current-ctx_id, only possible
3505*d83cc019SAndroid Build Coastguard Worker 				 * with a valid context id. */
3506*d83cc019SAndroid Build Coastguard Worker 				if (oa_report_ctx_is_valid(report)) {
3507*d83cc019SAndroid Build Coastguard Worker 					current_ctx_id = report[2];
3508*d83cc019SAndroid Build Coastguard Worker 					n_invalid_ctx = 0;
3509*d83cc019SAndroid Build Coastguard Worker 				} else {
3510*d83cc019SAndroid Build Coastguard Worker 					n_invalid_ctx++;
3511*d83cc019SAndroid Build Coastguard Worker 				}
3512*d83cc019SAndroid Build Coastguard Worker 
3513*d83cc019SAndroid Build Coastguard Worker 				prev = report;
3514*d83cc019SAndroid Build Coastguard Worker 
3515*d83cc019SAndroid Build Coastguard Worker 				if (report == report1_32) {
3516*d83cc019SAndroid Build Coastguard Worker 					igt_debug("Breaking on end of report\n");
3517*d83cc019SAndroid Build Coastguard Worker 					print_reports(report0_32, report1_32,
3518*d83cc019SAndroid Build Coastguard Worker 						      lookup_format(test_oa_format));
3519*d83cc019SAndroid Build Coastguard Worker 					break;
3520*d83cc019SAndroid Build Coastguard Worker 				}
3521*d83cc019SAndroid Build Coastguard Worker 			}
3522*d83cc019SAndroid Build Coastguard Worker 
3523*d83cc019SAndroid Build Coastguard Worker 			igt_debug("n samples written = %"PRIu64"/%"PRIu64" (%ix%i)\n",
3524*d83cc019SAndroid Build Coastguard Worker 				  accumulator.deltas[2 + 21],/* skip timestamp + clock cycles */
3525*d83cc019SAndroid Build Coastguard Worker 				  accumulator.deltas[2 + 26],
3526*d83cc019SAndroid Build Coastguard Worker 				  width, height);
3527*d83cc019SAndroid Build Coastguard Worker 			accumulator_print(&accumulator, "filtered");
3528*d83cc019SAndroid Build Coastguard Worker 
3529*d83cc019SAndroid Build Coastguard Worker 			ret = drm_intel_bo_map(src[0].bo, false /* write enable */);
3530*d83cc019SAndroid Build Coastguard Worker 			igt_assert_eq(ret, 0);
3531*d83cc019SAndroid Build Coastguard Worker 			ret = drm_intel_bo_map(dst[0].bo, false /* write enable */);
3532*d83cc019SAndroid Build Coastguard Worker 			igt_assert_eq(ret, 0);
3533*d83cc019SAndroid Build Coastguard Worker 
3534*d83cc019SAndroid Build Coastguard Worker 			ret = memcmp(src[0].bo->virtual, dst[0].bo->virtual, 4 * width * height);
3535*d83cc019SAndroid Build Coastguard Worker 			if (ret != 0) {
3536*d83cc019SAndroid Build Coastguard Worker 				accumulator_print(&accumulator, "total");
3537*d83cc019SAndroid Build Coastguard Worker 				/* This needs to be investigated... From time
3538*d83cc019SAndroid Build Coastguard Worker 				 * to time, the work we kick off doesn't seem
3539*d83cc019SAndroid Build Coastguard Worker 				 * to happen. WTH?? */
3540*d83cc019SAndroid Build Coastguard Worker 				exit(EAGAIN);
3541*d83cc019SAndroid Build Coastguard Worker 			}
3542*d83cc019SAndroid Build Coastguard Worker 
3543*d83cc019SAndroid Build Coastguard Worker 			drm_intel_bo_unmap(src[0].bo);
3544*d83cc019SAndroid Build Coastguard Worker 			drm_intel_bo_unmap(dst[0].bo);
3545*d83cc019SAndroid Build Coastguard Worker 
3546*d83cc019SAndroid Build Coastguard Worker 			igt_assert_eq(accumulator.deltas[2 + 26], width * height);
3547*d83cc019SAndroid Build Coastguard Worker 
3548*d83cc019SAndroid Build Coastguard Worker 			for (int i = 0; i < ARRAY_SIZE(src); i++) {
3549*d83cc019SAndroid Build Coastguard Worker 				drm_intel_bo_unreference(src[i].bo);
3550*d83cc019SAndroid Build Coastguard Worker 				drm_intel_bo_unreference(dst[i].bo);
3551*d83cc019SAndroid Build Coastguard Worker 			}
3552*d83cc019SAndroid Build Coastguard Worker 
3553*d83cc019SAndroid Build Coastguard Worker 			drm_intel_bo_unmap(bo);
3554*d83cc019SAndroid Build Coastguard Worker 			drm_intel_bo_unreference(bo);
3555*d83cc019SAndroid Build Coastguard Worker 			intel_batchbuffer_free(batch);
3556*d83cc019SAndroid Build Coastguard Worker 			drm_intel_gem_context_destroy(context0);
3557*d83cc019SAndroid Build Coastguard Worker 			drm_intel_gem_context_destroy(context1);
3558*d83cc019SAndroid Build Coastguard Worker 			drm_intel_bufmgr_destroy(bufmgr);
3559*d83cc019SAndroid Build Coastguard Worker 			__perf_close(stream_fd);
3560*d83cc019SAndroid Build Coastguard Worker 		}
3561*d83cc019SAndroid Build Coastguard Worker 
3562*d83cc019SAndroid Build Coastguard Worker 		child_ret = igt_wait_helper(&child);
3563*d83cc019SAndroid Build Coastguard Worker 
3564*d83cc019SAndroid Build Coastguard Worker 		igt_assert(WEXITSTATUS(child_ret) == EAGAIN ||
3565*d83cc019SAndroid Build Coastguard Worker 			   WEXITSTATUS(child_ret) == 0);
3566*d83cc019SAndroid Build Coastguard Worker 
3567*d83cc019SAndroid Build Coastguard Worker 	} while (WEXITSTATUS(child_ret) == EAGAIN);
3568*d83cc019SAndroid Build Coastguard Worker }
3569*d83cc019SAndroid Build Coastguard Worker 
rc6_residency_ms(void)3570*d83cc019SAndroid Build Coastguard Worker static unsigned long rc6_residency_ms(void)
3571*d83cc019SAndroid Build Coastguard Worker {
3572*d83cc019SAndroid Build Coastguard Worker 	return sysfs_read("power/rc6_residency_ms");
3573*d83cc019SAndroid Build Coastguard Worker }
3574*d83cc019SAndroid Build Coastguard Worker 
3575*d83cc019SAndroid Build Coastguard Worker static void
test_rc6_disable(void)3576*d83cc019SAndroid Build Coastguard Worker test_rc6_disable(void)
3577*d83cc019SAndroid Build Coastguard Worker {
3578*d83cc019SAndroid Build Coastguard Worker 	uint64_t properties[] = {
3579*d83cc019SAndroid Build Coastguard Worker 		/* Include OA reports in samples */
3580*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_SAMPLE_OA, true,
3581*d83cc019SAndroid Build Coastguard Worker 
3582*d83cc019SAndroid Build Coastguard Worker 		/* OA unit configuration */
3583*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_METRICS_SET, test_metric_set_id,
3584*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_FORMAT, test_oa_format,
3585*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_EXPONENT, oa_exp_1_millisec,
3586*d83cc019SAndroid Build Coastguard Worker 	};
3587*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_perf_open_param param = {
3588*d83cc019SAndroid Build Coastguard Worker 		.flags = I915_PERF_FLAG_FD_CLOEXEC,
3589*d83cc019SAndroid Build Coastguard Worker 		.num_properties = sizeof(properties) / 16,
3590*d83cc019SAndroid Build Coastguard Worker 		.properties_ptr = to_user_pointer(properties),
3591*d83cc019SAndroid Build Coastguard Worker 	};
3592*d83cc019SAndroid Build Coastguard Worker 	unsigned long n_events_start, n_events_end;
3593*d83cc019SAndroid Build Coastguard Worker 	unsigned long rc6_enabled;
3594*d83cc019SAndroid Build Coastguard Worker 
3595*d83cc019SAndroid Build Coastguard Worker 	rc6_enabled = 0;
3596*d83cc019SAndroid Build Coastguard Worker 	igt_sysfs_scanf(sysfs, "power/rc6_enable", "%lu", &rc6_enabled);
3597*d83cc019SAndroid Build Coastguard Worker 	igt_require(rc6_enabled);
3598*d83cc019SAndroid Build Coastguard Worker 
3599*d83cc019SAndroid Build Coastguard Worker 	stream_fd = __perf_open(drm_fd, &param, false);
3600*d83cc019SAndroid Build Coastguard Worker 
3601*d83cc019SAndroid Build Coastguard Worker 	n_events_start = rc6_residency_ms();
3602*d83cc019SAndroid Build Coastguard Worker 	nanosleep(&(struct timespec){ .tv_sec = 0, .tv_nsec = 500000000 }, NULL);
3603*d83cc019SAndroid Build Coastguard Worker 	n_events_end = rc6_residency_ms();
3604*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(n_events_end - n_events_start, 0);
3605*d83cc019SAndroid Build Coastguard Worker 
3606*d83cc019SAndroid Build Coastguard Worker 	__perf_close(stream_fd);
3607*d83cc019SAndroid Build Coastguard Worker 	gem_quiescent_gpu(drm_fd);
3608*d83cc019SAndroid Build Coastguard Worker 
3609*d83cc019SAndroid Build Coastguard Worker 	n_events_start = rc6_residency_ms();
3610*d83cc019SAndroid Build Coastguard Worker 	nanosleep(&(struct timespec){ .tv_sec = 1, .tv_nsec = 0 }, NULL);
3611*d83cc019SAndroid Build Coastguard Worker 	n_events_end = rc6_residency_ms();
3612*d83cc019SAndroid Build Coastguard Worker 	igt_assert_neq(n_events_end - n_events_start, 0);
3613*d83cc019SAndroid Build Coastguard Worker }
3614*d83cc019SAndroid Build Coastguard Worker 
__i915_perf_add_config(int fd,struct drm_i915_perf_oa_config * config)3615*d83cc019SAndroid Build Coastguard Worker static int __i915_perf_add_config(int fd, struct drm_i915_perf_oa_config *config)
3616*d83cc019SAndroid Build Coastguard Worker {
3617*d83cc019SAndroid Build Coastguard Worker 	int ret = igt_ioctl(fd, DRM_IOCTL_I915_PERF_ADD_CONFIG, config);
3618*d83cc019SAndroid Build Coastguard Worker 	if (ret < 0)
3619*d83cc019SAndroid Build Coastguard Worker 		ret = -errno;
3620*d83cc019SAndroid Build Coastguard Worker 	return ret;
3621*d83cc019SAndroid Build Coastguard Worker }
3622*d83cc019SAndroid Build Coastguard Worker 
i915_perf_add_config(int fd,struct drm_i915_perf_oa_config * config)3623*d83cc019SAndroid Build Coastguard Worker static int i915_perf_add_config(int fd, struct drm_i915_perf_oa_config *config)
3624*d83cc019SAndroid Build Coastguard Worker {
3625*d83cc019SAndroid Build Coastguard Worker 	int config_id = __i915_perf_add_config(fd, config);
3626*d83cc019SAndroid Build Coastguard Worker 
3627*d83cc019SAndroid Build Coastguard Worker 	igt_debug("config_id=%i\n", config_id);
3628*d83cc019SAndroid Build Coastguard Worker 	igt_assert(config_id > 0);
3629*d83cc019SAndroid Build Coastguard Worker 
3630*d83cc019SAndroid Build Coastguard Worker 	return config_id;
3631*d83cc019SAndroid Build Coastguard Worker }
3632*d83cc019SAndroid Build Coastguard Worker 
i915_perf_remove_config(int fd,uint64_t config_id)3633*d83cc019SAndroid Build Coastguard Worker static void i915_perf_remove_config(int fd, uint64_t config_id)
3634*d83cc019SAndroid Build Coastguard Worker {
3635*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_I915_PERF_REMOVE_CONFIG,
3636*d83cc019SAndroid Build Coastguard Worker 				&config_id), 0);
3637*d83cc019SAndroid Build Coastguard Worker }
3638*d83cc019SAndroid Build Coastguard Worker 
has_i915_perf_userspace_config(int fd)3639*d83cc019SAndroid Build Coastguard Worker static bool has_i915_perf_userspace_config(int fd)
3640*d83cc019SAndroid Build Coastguard Worker {
3641*d83cc019SAndroid Build Coastguard Worker 	uint64_t config = 0;
3642*d83cc019SAndroid Build Coastguard Worker 	int ret = igt_ioctl(fd, DRM_IOCTL_I915_PERF_REMOVE_CONFIG, &config);
3643*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(ret, -1);
3644*d83cc019SAndroid Build Coastguard Worker 
3645*d83cc019SAndroid Build Coastguard Worker 	igt_debug("errno=%i\n", errno);
3646*d83cc019SAndroid Build Coastguard Worker 
3647*d83cc019SAndroid Build Coastguard Worker 	return errno != EINVAL;
3648*d83cc019SAndroid Build Coastguard Worker }
3649*d83cc019SAndroid Build Coastguard Worker 
3650*d83cc019SAndroid Build Coastguard Worker static void
test_invalid_create_userspace_config(void)3651*d83cc019SAndroid Build Coastguard Worker test_invalid_create_userspace_config(void)
3652*d83cc019SAndroid Build Coastguard Worker {
3653*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_perf_oa_config config;
3654*d83cc019SAndroid Build Coastguard Worker 	const char *uuid = "01234567-0123-0123-0123-0123456789ab";
3655*d83cc019SAndroid Build Coastguard Worker 	const char *invalid_uuid = "blablabla-wrong";
3656*d83cc019SAndroid Build Coastguard Worker 	uint32_t mux_regs[] = { 0x9888 /* NOA_WRITE */, 0x0 };
3657*d83cc019SAndroid Build Coastguard Worker 	uint32_t invalid_mux_regs[] = { 0x12345678 /* invalid register */, 0x0 };
3658*d83cc019SAndroid Build Coastguard Worker 
3659*d83cc019SAndroid Build Coastguard Worker 	igt_require(has_i915_perf_userspace_config(drm_fd));
3660*d83cc019SAndroid Build Coastguard Worker 
3661*d83cc019SAndroid Build Coastguard Worker 	memset(&config, 0, sizeof(config));
3662*d83cc019SAndroid Build Coastguard Worker 
3663*d83cc019SAndroid Build Coastguard Worker 	/* invalid uuid */
3664*d83cc019SAndroid Build Coastguard Worker 	strncpy(config.uuid, invalid_uuid, sizeof(config.uuid));
3665*d83cc019SAndroid Build Coastguard Worker 	config.n_mux_regs = 1;
3666*d83cc019SAndroid Build Coastguard Worker 	config.mux_regs_ptr = to_user_pointer(mux_regs);
3667*d83cc019SAndroid Build Coastguard Worker 	config.n_boolean_regs = 0;
3668*d83cc019SAndroid Build Coastguard Worker 	config.n_flex_regs = 0;
3669*d83cc019SAndroid Build Coastguard Worker 
3670*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(__i915_perf_add_config(drm_fd, &config), -EINVAL);
3671*d83cc019SAndroid Build Coastguard Worker 
3672*d83cc019SAndroid Build Coastguard Worker 	/* invalid mux_regs */
3673*d83cc019SAndroid Build Coastguard Worker 	memcpy(config.uuid, uuid, sizeof(config.uuid));
3674*d83cc019SAndroid Build Coastguard Worker 	config.n_mux_regs = 1;
3675*d83cc019SAndroid Build Coastguard Worker 	config.mux_regs_ptr = to_user_pointer(invalid_mux_regs);
3676*d83cc019SAndroid Build Coastguard Worker 	config.n_boolean_regs = 0;
3677*d83cc019SAndroid Build Coastguard Worker 	config.n_flex_regs = 0;
3678*d83cc019SAndroid Build Coastguard Worker 
3679*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(__i915_perf_add_config(drm_fd, &config), -EINVAL);
3680*d83cc019SAndroid Build Coastguard Worker 
3681*d83cc019SAndroid Build Coastguard Worker 	/* empty config */
3682*d83cc019SAndroid Build Coastguard Worker 	memcpy(config.uuid, uuid, sizeof(config.uuid));
3683*d83cc019SAndroid Build Coastguard Worker 	config.n_mux_regs = 0;
3684*d83cc019SAndroid Build Coastguard Worker 	config.mux_regs_ptr = to_user_pointer(mux_regs);
3685*d83cc019SAndroid Build Coastguard Worker 	config.n_boolean_regs = 0;
3686*d83cc019SAndroid Build Coastguard Worker 	config.n_flex_regs = 0;
3687*d83cc019SAndroid Build Coastguard Worker 
3688*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(__i915_perf_add_config(drm_fd, &config), -EINVAL);
3689*d83cc019SAndroid Build Coastguard Worker 
3690*d83cc019SAndroid Build Coastguard Worker 	/* empty config with null pointers */
3691*d83cc019SAndroid Build Coastguard Worker 	memcpy(config.uuid, uuid, sizeof(config.uuid));
3692*d83cc019SAndroid Build Coastguard Worker 	config.n_mux_regs = 1;
3693*d83cc019SAndroid Build Coastguard Worker 	config.mux_regs_ptr = to_user_pointer(NULL);
3694*d83cc019SAndroid Build Coastguard Worker 	config.n_boolean_regs = 2;
3695*d83cc019SAndroid Build Coastguard Worker 	config.boolean_regs_ptr = to_user_pointer(NULL);
3696*d83cc019SAndroid Build Coastguard Worker 	config.n_flex_regs = 3;
3697*d83cc019SAndroid Build Coastguard Worker 	config.flex_regs_ptr = to_user_pointer(NULL);
3698*d83cc019SAndroid Build Coastguard Worker 
3699*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(__i915_perf_add_config(drm_fd, &config), -EINVAL);
3700*d83cc019SAndroid Build Coastguard Worker 
3701*d83cc019SAndroid Build Coastguard Worker 	/* invalid pointers */
3702*d83cc019SAndroid Build Coastguard Worker 	memcpy(config.uuid, uuid, sizeof(config.uuid));
3703*d83cc019SAndroid Build Coastguard Worker 	config.n_mux_regs = 42;
3704*d83cc019SAndroid Build Coastguard Worker 	config.mux_regs_ptr = to_user_pointer((void *) 0xDEADBEEF);
3705*d83cc019SAndroid Build Coastguard Worker 	config.n_boolean_regs = 0;
3706*d83cc019SAndroid Build Coastguard Worker 	config.n_flex_regs = 0;
3707*d83cc019SAndroid Build Coastguard Worker 
3708*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(__i915_perf_add_config(drm_fd, &config), -EFAULT);
3709*d83cc019SAndroid Build Coastguard Worker }
3710*d83cc019SAndroid Build Coastguard Worker 
3711*d83cc019SAndroid Build Coastguard Worker static void
test_invalid_remove_userspace_config(void)3712*d83cc019SAndroid Build Coastguard Worker test_invalid_remove_userspace_config(void)
3713*d83cc019SAndroid Build Coastguard Worker {
3714*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_perf_oa_config config;
3715*d83cc019SAndroid Build Coastguard Worker 	const char *uuid = "01234567-0123-0123-0123-0123456789ab";
3716*d83cc019SAndroid Build Coastguard Worker 	uint32_t mux_regs[] = { 0x9888 /* NOA_WRITE */, 0x0 };
3717*d83cc019SAndroid Build Coastguard Worker 	uint64_t config_id, wrong_config_id = 999999999;
3718*d83cc019SAndroid Build Coastguard Worker 	char path[512];
3719*d83cc019SAndroid Build Coastguard Worker 
3720*d83cc019SAndroid Build Coastguard Worker 	igt_require(has_i915_perf_userspace_config(drm_fd));
3721*d83cc019SAndroid Build Coastguard Worker 
3722*d83cc019SAndroid Build Coastguard Worker 	snprintf(path, sizeof(path), "metrics/%s/id", uuid);
3723*d83cc019SAndroid Build Coastguard Worker 
3724*d83cc019SAndroid Build Coastguard Worker 	/* Destroy previous configuration if present */
3725*d83cc019SAndroid Build Coastguard Worker 	if (try_sysfs_read_u64(path, &config_id))
3726*d83cc019SAndroid Build Coastguard Worker 		i915_perf_remove_config(drm_fd, config_id);
3727*d83cc019SAndroid Build Coastguard Worker 
3728*d83cc019SAndroid Build Coastguard Worker 	memset(&config, 0, sizeof(config));
3729*d83cc019SAndroid Build Coastguard Worker 
3730*d83cc019SAndroid Build Coastguard Worker 	memcpy(config.uuid, uuid, sizeof(config.uuid));
3731*d83cc019SAndroid Build Coastguard Worker 
3732*d83cc019SAndroid Build Coastguard Worker 	config.n_mux_regs = 1;
3733*d83cc019SAndroid Build Coastguard Worker 	config.mux_regs_ptr = to_user_pointer(mux_regs);
3734*d83cc019SAndroid Build Coastguard Worker 	config.n_boolean_regs = 0;
3735*d83cc019SAndroid Build Coastguard Worker 	config.n_flex_regs = 0;
3736*d83cc019SAndroid Build Coastguard Worker 
3737*d83cc019SAndroid Build Coastguard Worker 	config_id = i915_perf_add_config(drm_fd, &config);
3738*d83cc019SAndroid Build Coastguard Worker 
3739*d83cc019SAndroid Build Coastguard Worker 	/* Removing configs without permissions should fail. */
3740*d83cc019SAndroid Build Coastguard Worker 	igt_fork(child, 1) {
3741*d83cc019SAndroid Build Coastguard Worker 		igt_drop_root();
3742*d83cc019SAndroid Build Coastguard Worker 
3743*d83cc019SAndroid Build Coastguard Worker 		do_ioctl_err(drm_fd, DRM_IOCTL_I915_PERF_REMOVE_CONFIG, &config_id, EACCES);
3744*d83cc019SAndroid Build Coastguard Worker 	}
3745*d83cc019SAndroid Build Coastguard Worker 	igt_waitchildren();
3746*d83cc019SAndroid Build Coastguard Worker 
3747*d83cc019SAndroid Build Coastguard Worker 	/* Removing invalid config ID should fail. */
3748*d83cc019SAndroid Build Coastguard Worker 	do_ioctl_err(drm_fd, DRM_IOCTL_I915_PERF_REMOVE_CONFIG, &wrong_config_id, ENOENT);
3749*d83cc019SAndroid Build Coastguard Worker 
3750*d83cc019SAndroid Build Coastguard Worker 	i915_perf_remove_config(drm_fd, config_id);
3751*d83cc019SAndroid Build Coastguard Worker }
3752*d83cc019SAndroid Build Coastguard Worker 
3753*d83cc019SAndroid Build Coastguard Worker static void
test_create_destroy_userspace_config(void)3754*d83cc019SAndroid Build Coastguard Worker test_create_destroy_userspace_config(void)
3755*d83cc019SAndroid Build Coastguard Worker {
3756*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_perf_oa_config config;
3757*d83cc019SAndroid Build Coastguard Worker 	const char *uuid = "01234567-0123-0123-0123-0123456789ab";
3758*d83cc019SAndroid Build Coastguard Worker 	uint32_t mux_regs[] = { 0x9888 /* NOA_WRITE */, 0x0 };
3759*d83cc019SAndroid Build Coastguard Worker 	uint32_t flex_regs[100];
3760*d83cc019SAndroid Build Coastguard Worker 	int i;
3761*d83cc019SAndroid Build Coastguard Worker 	uint64_t config_id;
3762*d83cc019SAndroid Build Coastguard Worker 	uint64_t properties[] = {
3763*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_METRICS_SET, 0, /* Filled later */
3764*d83cc019SAndroid Build Coastguard Worker 
3765*d83cc019SAndroid Build Coastguard Worker 		/* OA unit configuration */
3766*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_SAMPLE_OA, true,
3767*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_FORMAT, test_oa_format,
3768*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_EXPONENT, oa_exp_1_millisec,
3769*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_METRICS_SET
3770*d83cc019SAndroid Build Coastguard Worker 	};
3771*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_perf_open_param param = {
3772*d83cc019SAndroid Build Coastguard Worker 		.flags = I915_PERF_FLAG_FD_CLOEXEC |
3773*d83cc019SAndroid Build Coastguard Worker 		I915_PERF_FLAG_FD_NONBLOCK |
3774*d83cc019SAndroid Build Coastguard Worker 		I915_PERF_FLAG_DISABLED,
3775*d83cc019SAndroid Build Coastguard Worker 		.num_properties = ARRAY_SIZE(properties) / 2,
3776*d83cc019SAndroid Build Coastguard Worker 		.properties_ptr = to_user_pointer(properties),
3777*d83cc019SAndroid Build Coastguard Worker 	};
3778*d83cc019SAndroid Build Coastguard Worker 	char path[512];
3779*d83cc019SAndroid Build Coastguard Worker 
3780*d83cc019SAndroid Build Coastguard Worker 	igt_require(has_i915_perf_userspace_config(drm_fd));
3781*d83cc019SAndroid Build Coastguard Worker 
3782*d83cc019SAndroid Build Coastguard Worker 	snprintf(path, sizeof(path), "metrics/%s/id", uuid);
3783*d83cc019SAndroid Build Coastguard Worker 
3784*d83cc019SAndroid Build Coastguard Worker 	/* Destroy previous configuration if present */
3785*d83cc019SAndroid Build Coastguard Worker 	if (try_sysfs_read_u64(path, &config_id))
3786*d83cc019SAndroid Build Coastguard Worker 		i915_perf_remove_config(drm_fd, config_id);
3787*d83cc019SAndroid Build Coastguard Worker 
3788*d83cc019SAndroid Build Coastguard Worker 	memset(&config, 0, sizeof(config));
3789*d83cc019SAndroid Build Coastguard Worker 	memcpy(config.uuid, uuid, sizeof(config.uuid));
3790*d83cc019SAndroid Build Coastguard Worker 
3791*d83cc019SAndroid Build Coastguard Worker 	config.n_mux_regs = 1;
3792*d83cc019SAndroid Build Coastguard Worker 	config.mux_regs_ptr = to_user_pointer(mux_regs);
3793*d83cc019SAndroid Build Coastguard Worker 
3794*d83cc019SAndroid Build Coastguard Worker 	/* Flex EU counters are only available on gen8+ */
3795*d83cc019SAndroid Build Coastguard Worker 	if (intel_gen(devid) >= 8) {
3796*d83cc019SAndroid Build Coastguard Worker 		for (i = 0; i < ARRAY_SIZE(flex_regs) / 2; i++) {
3797*d83cc019SAndroid Build Coastguard Worker 			flex_regs[i * 2] = 0xe458; /* EU_PERF_CNTL0 */
3798*d83cc019SAndroid Build Coastguard Worker 			flex_regs[i * 2 + 1] = 0x0;
3799*d83cc019SAndroid Build Coastguard Worker 		}
3800*d83cc019SAndroid Build Coastguard Worker 		config.flex_regs_ptr = to_user_pointer(flex_regs);
3801*d83cc019SAndroid Build Coastguard Worker 		config.n_flex_regs = ARRAY_SIZE(flex_regs) / 2;
3802*d83cc019SAndroid Build Coastguard Worker 	}
3803*d83cc019SAndroid Build Coastguard Worker 
3804*d83cc019SAndroid Build Coastguard Worker 	config.n_boolean_regs = 0;
3805*d83cc019SAndroid Build Coastguard Worker 
3806*d83cc019SAndroid Build Coastguard Worker 	/* Creating configs without permissions shouldn't work. */
3807*d83cc019SAndroid Build Coastguard Worker 	igt_fork(child, 1) {
3808*d83cc019SAndroid Build Coastguard Worker 		igt_drop_root();
3809*d83cc019SAndroid Build Coastguard Worker 
3810*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(__i915_perf_add_config(drm_fd, &config), -EACCES);
3811*d83cc019SAndroid Build Coastguard Worker 	}
3812*d83cc019SAndroid Build Coastguard Worker 	igt_waitchildren();
3813*d83cc019SAndroid Build Coastguard Worker 
3814*d83cc019SAndroid Build Coastguard Worker 	/* Create a new config */
3815*d83cc019SAndroid Build Coastguard Worker 	config_id = i915_perf_add_config(drm_fd, &config);
3816*d83cc019SAndroid Build Coastguard Worker 
3817*d83cc019SAndroid Build Coastguard Worker 	/* Verify that adding the another config with the same uuid fails. */
3818*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(__i915_perf_add_config(drm_fd, &config), -EADDRINUSE);
3819*d83cc019SAndroid Build Coastguard Worker 
3820*d83cc019SAndroid Build Coastguard Worker 	/* Try to use the new config */
3821*d83cc019SAndroid Build Coastguard Worker 	properties[1] = config_id;
3822*d83cc019SAndroid Build Coastguard Worker 	stream_fd = __perf_open(drm_fd, &param, false);
3823*d83cc019SAndroid Build Coastguard Worker 
3824*d83cc019SAndroid Build Coastguard Worker 	/* Verify that destroying the config doesn't yield any error. */
3825*d83cc019SAndroid Build Coastguard Worker 	i915_perf_remove_config(drm_fd, config_id);
3826*d83cc019SAndroid Build Coastguard Worker 
3827*d83cc019SAndroid Build Coastguard Worker 	/* Read the config to verify shouldn't raise any issue. */
3828*d83cc019SAndroid Build Coastguard Worker 	config_id = i915_perf_add_config(drm_fd, &config);
3829*d83cc019SAndroid Build Coastguard Worker 
3830*d83cc019SAndroid Build Coastguard Worker 	__perf_close(stream_fd);
3831*d83cc019SAndroid Build Coastguard Worker 
3832*d83cc019SAndroid Build Coastguard Worker 	i915_perf_remove_config(drm_fd, config_id);
3833*d83cc019SAndroid Build Coastguard Worker }
3834*d83cc019SAndroid Build Coastguard Worker 
3835*d83cc019SAndroid Build Coastguard Worker /* Registers required by userspace. This list should be maintained by
3836*d83cc019SAndroid Build Coastguard Worker  * the OA configs developers and agreed upon with kernel developers as
3837*d83cc019SAndroid Build Coastguard Worker  * some of the registers have bits used by the kernel (for workarounds
3838*d83cc019SAndroid Build Coastguard Worker  * for instance) and other bits that need to be set by the OA configs.
3839*d83cc019SAndroid Build Coastguard Worker  */
3840*d83cc019SAndroid Build Coastguard Worker static void
test_whitelisted_registers_userspace_config(void)3841*d83cc019SAndroid Build Coastguard Worker test_whitelisted_registers_userspace_config(void)
3842*d83cc019SAndroid Build Coastguard Worker {
3843*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_perf_oa_config config;
3844*d83cc019SAndroid Build Coastguard Worker 	const char *uuid = "01234567-0123-0123-0123-0123456789ab";
3845*d83cc019SAndroid Build Coastguard Worker 	uint32_t mux_regs[200];
3846*d83cc019SAndroid Build Coastguard Worker 	uint32_t b_counters_regs[200];
3847*d83cc019SAndroid Build Coastguard Worker 	uint32_t flex_regs[200];
3848*d83cc019SAndroid Build Coastguard Worker 	uint32_t i;
3849*d83cc019SAndroid Build Coastguard Worker 	uint64_t config_id;
3850*d83cc019SAndroid Build Coastguard Worker 	char path[512];
3851*d83cc019SAndroid Build Coastguard Worker 	int ret;
3852*d83cc019SAndroid Build Coastguard Worker 	const uint32_t flex[] = {
3853*d83cc019SAndroid Build Coastguard Worker 		0xe458,
3854*d83cc019SAndroid Build Coastguard Worker 		0xe558,
3855*d83cc019SAndroid Build Coastguard Worker 		0xe658,
3856*d83cc019SAndroid Build Coastguard Worker 		0xe758,
3857*d83cc019SAndroid Build Coastguard Worker 		0xe45c,
3858*d83cc019SAndroid Build Coastguard Worker 		0xe55c,
3859*d83cc019SAndroid Build Coastguard Worker 		0xe65c
3860*d83cc019SAndroid Build Coastguard Worker 	};
3861*d83cc019SAndroid Build Coastguard Worker 
3862*d83cc019SAndroid Build Coastguard Worker 	igt_require(has_i915_perf_userspace_config(drm_fd));
3863*d83cc019SAndroid Build Coastguard Worker 
3864*d83cc019SAndroid Build Coastguard Worker 	snprintf(path, sizeof(path), "metrics/%s/id", uuid);
3865*d83cc019SAndroid Build Coastguard Worker 
3866*d83cc019SAndroid Build Coastguard Worker 	if (try_sysfs_read_u64(path, &config_id))
3867*d83cc019SAndroid Build Coastguard Worker 		i915_perf_remove_config(drm_fd, config_id);
3868*d83cc019SAndroid Build Coastguard Worker 
3869*d83cc019SAndroid Build Coastguard Worker 	memset(&config, 0, sizeof(config));
3870*d83cc019SAndroid Build Coastguard Worker 	memcpy(config.uuid, uuid, sizeof(config.uuid));
3871*d83cc019SAndroid Build Coastguard Worker 
3872*d83cc019SAndroid Build Coastguard Worker 	/* OASTARTTRIG[1-8] */
3873*d83cc019SAndroid Build Coastguard Worker 	for (i = 0x2710; i <= 0x272c; i += 4) {
3874*d83cc019SAndroid Build Coastguard Worker 		b_counters_regs[config.n_boolean_regs * 2] = i;
3875*d83cc019SAndroid Build Coastguard Worker 		b_counters_regs[config.n_boolean_regs * 2 + 1] = 0;
3876*d83cc019SAndroid Build Coastguard Worker 		config.n_boolean_regs++;
3877*d83cc019SAndroid Build Coastguard Worker 	}
3878*d83cc019SAndroid Build Coastguard Worker 	/* OAREPORTTRIG[1-8] */
3879*d83cc019SAndroid Build Coastguard Worker 	for (i = 0x2740; i <= 0x275c; i += 4) {
3880*d83cc019SAndroid Build Coastguard Worker 		b_counters_regs[config.n_boolean_regs * 2] = i;
3881*d83cc019SAndroid Build Coastguard Worker 		b_counters_regs[config.n_boolean_regs * 2 + 1] = 0;
3882*d83cc019SAndroid Build Coastguard Worker 		config.n_boolean_regs++;
3883*d83cc019SAndroid Build Coastguard Worker 	}
3884*d83cc019SAndroid Build Coastguard Worker 	config.boolean_regs_ptr = (uintptr_t) b_counters_regs;
3885*d83cc019SAndroid Build Coastguard Worker 
3886*d83cc019SAndroid Build Coastguard Worker 	if (intel_gen(devid) >= 8) {
3887*d83cc019SAndroid Build Coastguard Worker 		/* Flex EU registers, only from Gen8+. */
3888*d83cc019SAndroid Build Coastguard Worker 		for (i = 0; i < ARRAY_SIZE(flex); i++) {
3889*d83cc019SAndroid Build Coastguard Worker 			flex_regs[config.n_flex_regs * 2] = flex[i];
3890*d83cc019SAndroid Build Coastguard Worker 			flex_regs[config.n_flex_regs * 2 + 1] = 0;
3891*d83cc019SAndroid Build Coastguard Worker 			config.n_flex_regs++;
3892*d83cc019SAndroid Build Coastguard Worker 		}
3893*d83cc019SAndroid Build Coastguard Worker 		config.flex_regs_ptr = (uintptr_t) flex_regs;
3894*d83cc019SAndroid Build Coastguard Worker 	}
3895*d83cc019SAndroid Build Coastguard Worker 
3896*d83cc019SAndroid Build Coastguard Worker 	/* Mux registers (too many of them, just checking bounds) */
3897*d83cc019SAndroid Build Coastguard Worker 	i = 0;
3898*d83cc019SAndroid Build Coastguard Worker 
3899*d83cc019SAndroid Build Coastguard Worker 	/* NOA_WRITE */
3900*d83cc019SAndroid Build Coastguard Worker 	mux_regs[i++] = 0x9800;
3901*d83cc019SAndroid Build Coastguard Worker 	mux_regs[i++] = 0;
3902*d83cc019SAndroid Build Coastguard Worker 
3903*d83cc019SAndroid Build Coastguard Worker 	if (IS_HASWELL(devid)) {
3904*d83cc019SAndroid Build Coastguard Worker 		/* Haswell specific. undocumented... */
3905*d83cc019SAndroid Build Coastguard Worker 		mux_regs[i++] = 0x9ec0;
3906*d83cc019SAndroid Build Coastguard Worker 		mux_regs[i++] = 0;
3907*d83cc019SAndroid Build Coastguard Worker 
3908*d83cc019SAndroid Build Coastguard Worker 		mux_regs[i++] = 0x25100;
3909*d83cc019SAndroid Build Coastguard Worker 		mux_regs[i++] = 0;
3910*d83cc019SAndroid Build Coastguard Worker 		mux_regs[i++] = 0x2ff90;
3911*d83cc019SAndroid Build Coastguard Worker 		mux_regs[i++] = 0;
3912*d83cc019SAndroid Build Coastguard Worker 	}
3913*d83cc019SAndroid Build Coastguard Worker 
3914*d83cc019SAndroid Build Coastguard Worker 	if (intel_gen(devid) >= 8 && !IS_CHERRYVIEW(devid)) {
3915*d83cc019SAndroid Build Coastguard Worker 		/* NOA_CONFIG */
3916*d83cc019SAndroid Build Coastguard Worker 		mux_regs[i++] = 0xD04;
3917*d83cc019SAndroid Build Coastguard Worker 		mux_regs[i++] = 0;
3918*d83cc019SAndroid Build Coastguard Worker 		mux_regs[i++] = 0xD2C;
3919*d83cc019SAndroid Build Coastguard Worker 		mux_regs[i++] = 0;
3920*d83cc019SAndroid Build Coastguard Worker 		/* WAIT_FOR_RC6_EXIT */
3921*d83cc019SAndroid Build Coastguard Worker 		mux_regs[i++] = 0x20CC;
3922*d83cc019SAndroid Build Coastguard Worker 		mux_regs[i++] = 0;
3923*d83cc019SAndroid Build Coastguard Worker 	}
3924*d83cc019SAndroid Build Coastguard Worker 
3925*d83cc019SAndroid Build Coastguard Worker 	/* HALF_SLICE_CHICKEN2 (shared with kernel workaround) */
3926*d83cc019SAndroid Build Coastguard Worker 	mux_regs[i++] = 0xE180;
3927*d83cc019SAndroid Build Coastguard Worker 	mux_regs[i++] = 0;
3928*d83cc019SAndroid Build Coastguard Worker 
3929*d83cc019SAndroid Build Coastguard Worker 	if (IS_CHERRYVIEW(devid)) {
3930*d83cc019SAndroid Build Coastguard Worker 		/* Cherryview specific. undocumented... */
3931*d83cc019SAndroid Build Coastguard Worker 		mux_regs[i++] = 0x182300;
3932*d83cc019SAndroid Build Coastguard Worker 		mux_regs[i++] = 0;
3933*d83cc019SAndroid Build Coastguard Worker 		mux_regs[i++] = 0x1823A4;
3934*d83cc019SAndroid Build Coastguard Worker 		mux_regs[i++] = 0;
3935*d83cc019SAndroid Build Coastguard Worker 	}
3936*d83cc019SAndroid Build Coastguard Worker 
3937*d83cc019SAndroid Build Coastguard Worker 	/* PERFCNT[12] */
3938*d83cc019SAndroid Build Coastguard Worker 	mux_regs[i++] = 0x91B8;
3939*d83cc019SAndroid Build Coastguard Worker 	mux_regs[i++] = 0;
3940*d83cc019SAndroid Build Coastguard Worker 	/* PERFMATRIX */
3941*d83cc019SAndroid Build Coastguard Worker 	mux_regs[i++] = 0x91C8;
3942*d83cc019SAndroid Build Coastguard Worker 	mux_regs[i++] = 0;
3943*d83cc019SAndroid Build Coastguard Worker 
3944*d83cc019SAndroid Build Coastguard Worker 	config.mux_regs_ptr = (uintptr_t) mux_regs;
3945*d83cc019SAndroid Build Coastguard Worker 	config.n_mux_regs = i / 2;
3946*d83cc019SAndroid Build Coastguard Worker 
3947*d83cc019SAndroid Build Coastguard Worker 	/* Create a new config */
3948*d83cc019SAndroid Build Coastguard Worker 	ret = igt_ioctl(drm_fd, DRM_IOCTL_I915_PERF_ADD_CONFIG, &config);
3949*d83cc019SAndroid Build Coastguard Worker 	igt_assert(ret > 0); /* Config 0 should be used by the kernel */
3950*d83cc019SAndroid Build Coastguard Worker 	config_id = ret;
3951*d83cc019SAndroid Build Coastguard Worker 
3952*d83cc019SAndroid Build Coastguard Worker 	i915_perf_remove_config(drm_fd, config_id);
3953*d83cc019SAndroid Build Coastguard Worker }
3954*d83cc019SAndroid Build Coastguard Worker 
3955*d83cc019SAndroid Build Coastguard Worker static unsigned
read_i915_module_ref(void)3956*d83cc019SAndroid Build Coastguard Worker read_i915_module_ref(void)
3957*d83cc019SAndroid Build Coastguard Worker {
3958*d83cc019SAndroid Build Coastguard Worker 	FILE *fp = fopen("/proc/modules", "r");
3959*d83cc019SAndroid Build Coastguard Worker 	char *line = NULL;
3960*d83cc019SAndroid Build Coastguard Worker 	size_t line_buf_size = 0;
3961*d83cc019SAndroid Build Coastguard Worker 	int len = 0;
3962*d83cc019SAndroid Build Coastguard Worker 	unsigned ref_count;
3963*d83cc019SAndroid Build Coastguard Worker 
3964*d83cc019SAndroid Build Coastguard Worker 	igt_assert(fp);
3965*d83cc019SAndroid Build Coastguard Worker 
3966*d83cc019SAndroid Build Coastguard Worker 	while ((len = getline(&line, &line_buf_size, fp)) > 0) {
3967*d83cc019SAndroid Build Coastguard Worker 		if (strncmp(line, "i915 ", 5) == 0) {
3968*d83cc019SAndroid Build Coastguard Worker 			unsigned long mem;
3969*d83cc019SAndroid Build Coastguard Worker 			int ret = sscanf(line + 5, "%lu %u", &mem, &ref_count);
3970*d83cc019SAndroid Build Coastguard Worker 			igt_assert(ret == 2);
3971*d83cc019SAndroid Build Coastguard Worker 			goto done;
3972*d83cc019SAndroid Build Coastguard Worker 		}
3973*d83cc019SAndroid Build Coastguard Worker 	}
3974*d83cc019SAndroid Build Coastguard Worker 
3975*d83cc019SAndroid Build Coastguard Worker 	igt_assert(!"reached");
3976*d83cc019SAndroid Build Coastguard Worker 
3977*d83cc019SAndroid Build Coastguard Worker done:
3978*d83cc019SAndroid Build Coastguard Worker 	free(line);
3979*d83cc019SAndroid Build Coastguard Worker 	fclose(fp);
3980*d83cc019SAndroid Build Coastguard Worker 	return ref_count;
3981*d83cc019SAndroid Build Coastguard Worker }
3982*d83cc019SAndroid Build Coastguard Worker 
3983*d83cc019SAndroid Build Coastguard Worker /* check that an open i915 perf stream holds a reference on the drm i915 module
3984*d83cc019SAndroid Build Coastguard Worker  * including in the corner case where the original drm fd has been closed.
3985*d83cc019SAndroid Build Coastguard Worker  */
3986*d83cc019SAndroid Build Coastguard Worker static void
test_i915_ref_count(void)3987*d83cc019SAndroid Build Coastguard Worker test_i915_ref_count(void)
3988*d83cc019SAndroid Build Coastguard Worker {
3989*d83cc019SAndroid Build Coastguard Worker 	uint64_t properties[] = {
3990*d83cc019SAndroid Build Coastguard Worker 		/* Include OA reports in samples */
3991*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_SAMPLE_OA, true,
3992*d83cc019SAndroid Build Coastguard Worker 
3993*d83cc019SAndroid Build Coastguard Worker 		/* OA unit configuration */
3994*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_METRICS_SET, 0 /* updated below */,
3995*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_FORMAT, 0, /* update below */
3996*d83cc019SAndroid Build Coastguard Worker 		DRM_I915_PERF_PROP_OA_EXPONENT, 0, /* update below */
3997*d83cc019SAndroid Build Coastguard Worker 	};
3998*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_perf_open_param param = {
3999*d83cc019SAndroid Build Coastguard Worker 		.flags = I915_PERF_FLAG_FD_CLOEXEC,
4000*d83cc019SAndroid Build Coastguard Worker 		.num_properties = sizeof(properties) / 16,
4001*d83cc019SAndroid Build Coastguard Worker 		.properties_ptr = to_user_pointer(properties),
4002*d83cc019SAndroid Build Coastguard Worker 	};
4003*d83cc019SAndroid Build Coastguard Worker 	unsigned baseline, ref_count0, ref_count1;
4004*d83cc019SAndroid Build Coastguard Worker 	uint32_t oa_report0[64];
4005*d83cc019SAndroid Build Coastguard Worker 	uint32_t oa_report1[64];
4006*d83cc019SAndroid Build Coastguard Worker 
4007*d83cc019SAndroid Build Coastguard Worker 	/* This should be the first test before the first fixture so no drm_fd
4008*d83cc019SAndroid Build Coastguard Worker 	 * should have been opened so far...
4009*d83cc019SAndroid Build Coastguard Worker 	 */
4010*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(drm_fd, -1);
4011*d83cc019SAndroid Build Coastguard Worker 
4012*d83cc019SAndroid Build Coastguard Worker 	baseline = read_i915_module_ref();
4013*d83cc019SAndroid Build Coastguard Worker 	igt_debug("baseline ref count (drm fd closed) = %u\n", baseline);
4014*d83cc019SAndroid Build Coastguard Worker 
4015*d83cc019SAndroid Build Coastguard Worker 	drm_fd = __drm_open_driver(DRIVER_INTEL);
4016*d83cc019SAndroid Build Coastguard Worker 	devid = intel_get_drm_devid(drm_fd);
4017*d83cc019SAndroid Build Coastguard Worker 	sysfs = igt_sysfs_open(drm_fd);
4018*d83cc019SAndroid Build Coastguard Worker 
4019*d83cc019SAndroid Build Coastguard Worker 	/* Note: these global variables are only initialized after calling
4020*d83cc019SAndroid Build Coastguard Worker 	 * init_sys_info()...
4021*d83cc019SAndroid Build Coastguard Worker 	 */
4022*d83cc019SAndroid Build Coastguard Worker 	igt_require(init_sys_info());
4023*d83cc019SAndroid Build Coastguard Worker 	properties[3] = test_metric_set_id;
4024*d83cc019SAndroid Build Coastguard Worker 	properties[5] = test_oa_format;
4025*d83cc019SAndroid Build Coastguard Worker 	properties[7] = oa_exp_1_millisec;
4026*d83cc019SAndroid Build Coastguard Worker 
4027*d83cc019SAndroid Build Coastguard Worker 	ref_count0 = read_i915_module_ref();
4028*d83cc019SAndroid Build Coastguard Worker 	igt_debug("initial ref count with drm_fd open = %u\n", ref_count0);
4029*d83cc019SAndroid Build Coastguard Worker 	igt_assert(ref_count0 > baseline);
4030*d83cc019SAndroid Build Coastguard Worker 
4031*d83cc019SAndroid Build Coastguard Worker 	stream_fd = __perf_open(drm_fd, &param, false);
4032*d83cc019SAndroid Build Coastguard Worker 	ref_count1 = read_i915_module_ref();
4033*d83cc019SAndroid Build Coastguard Worker 	igt_debug("ref count after opening i915 perf stream = %u\n", ref_count1);
4034*d83cc019SAndroid Build Coastguard Worker 	igt_assert(ref_count1 > ref_count0);
4035*d83cc019SAndroid Build Coastguard Worker 
4036*d83cc019SAndroid Build Coastguard Worker 	close(drm_fd);
4037*d83cc019SAndroid Build Coastguard Worker 	close(sysfs);
4038*d83cc019SAndroid Build Coastguard Worker 	drm_fd = -1;
4039*d83cc019SAndroid Build Coastguard Worker 	sysfs = -1;
4040*d83cc019SAndroid Build Coastguard Worker 	ref_count0 = read_i915_module_ref();
4041*d83cc019SAndroid Build Coastguard Worker 	igt_debug("ref count after closing drm fd = %u\n", ref_count0);
4042*d83cc019SAndroid Build Coastguard Worker 
4043*d83cc019SAndroid Build Coastguard Worker 	igt_assert(ref_count0 > baseline);
4044*d83cc019SAndroid Build Coastguard Worker 
4045*d83cc019SAndroid Build Coastguard Worker 	read_2_oa_reports(test_oa_format,
4046*d83cc019SAndroid Build Coastguard Worker 			  oa_exp_1_millisec,
4047*d83cc019SAndroid Build Coastguard Worker 			  oa_report0,
4048*d83cc019SAndroid Build Coastguard Worker 			  oa_report1,
4049*d83cc019SAndroid Build Coastguard Worker 			  false); /* not just timer reports */
4050*d83cc019SAndroid Build Coastguard Worker 
4051*d83cc019SAndroid Build Coastguard Worker 	__perf_close(stream_fd);
4052*d83cc019SAndroid Build Coastguard Worker 	ref_count0 = read_i915_module_ref();
4053*d83cc019SAndroid Build Coastguard Worker 	igt_debug("ref count after closing i915 perf stream fd = %u\n", ref_count0);
4054*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(ref_count0, baseline);
4055*d83cc019SAndroid Build Coastguard Worker }
4056*d83cc019SAndroid Build Coastguard Worker 
4057*d83cc019SAndroid Build Coastguard Worker static void
test_sysctl_defaults(void)4058*d83cc019SAndroid Build Coastguard Worker test_sysctl_defaults(void)
4059*d83cc019SAndroid Build Coastguard Worker {
4060*d83cc019SAndroid Build Coastguard Worker 	int paranoid = read_u64_file("/proc/sys/dev/i915/perf_stream_paranoid");
4061*d83cc019SAndroid Build Coastguard Worker 	int max_freq = read_u64_file("/proc/sys/dev/i915/oa_max_sample_rate");
4062*d83cc019SAndroid Build Coastguard Worker 
4063*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(paranoid, 1);
4064*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(max_freq, 100000);
4065*d83cc019SAndroid Build Coastguard Worker }
4066*d83cc019SAndroid Build Coastguard Worker 
4067*d83cc019SAndroid Build Coastguard Worker igt_main
4068*d83cc019SAndroid Build Coastguard Worker {
4069*d83cc019SAndroid Build Coastguard Worker 	igt_skip_on_simulation();
4070*d83cc019SAndroid Build Coastguard Worker 
4071*d83cc019SAndroid Build Coastguard Worker 	igt_fixture {
4072*d83cc019SAndroid Build Coastguard Worker 		struct stat sb;
4073*d83cc019SAndroid Build Coastguard Worker 
4074*d83cc019SAndroid Build Coastguard Worker 		igt_require(stat("/proc/sys/dev/i915/perf_stream_paranoid", &sb)
4075*d83cc019SAndroid Build Coastguard Worker 			    == 0);
4076*d83cc019SAndroid Build Coastguard Worker 		igt_require(stat("/proc/sys/dev/i915/oa_max_sample_rate", &sb)
4077*d83cc019SAndroid Build Coastguard Worker 			    == 0);
4078*d83cc019SAndroid Build Coastguard Worker 	}
4079*d83cc019SAndroid Build Coastguard Worker 
4080*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("i915-ref-count")
4081*d83cc019SAndroid Build Coastguard Worker 		test_i915_ref_count();
4082*d83cc019SAndroid Build Coastguard Worker 
4083*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("sysctl-defaults")
4084*d83cc019SAndroid Build Coastguard Worker 		test_sysctl_defaults();
4085*d83cc019SAndroid Build Coastguard Worker 
4086*d83cc019SAndroid Build Coastguard Worker 	igt_fixture {
4087*d83cc019SAndroid Build Coastguard Worker 		/* We expect that the ref count test before these fixtures
4088*d83cc019SAndroid Build Coastguard Worker 		 * should have closed drm_fd...
4089*d83cc019SAndroid Build Coastguard Worker 		 */
4090*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(drm_fd, -1);
4091*d83cc019SAndroid Build Coastguard Worker 
4092*d83cc019SAndroid Build Coastguard Worker 		drm_fd = drm_open_driver(DRIVER_INTEL);
4093*d83cc019SAndroid Build Coastguard Worker 		igt_require_gem(drm_fd);
4094*d83cc019SAndroid Build Coastguard Worker 
4095*d83cc019SAndroid Build Coastguard Worker 		devid = intel_get_drm_devid(drm_fd);
4096*d83cc019SAndroid Build Coastguard Worker 		sysfs = igt_sysfs_open(drm_fd);
4097*d83cc019SAndroid Build Coastguard Worker 
4098*d83cc019SAndroid Build Coastguard Worker 		igt_require(init_sys_info());
4099*d83cc019SAndroid Build Coastguard Worker 
4100*d83cc019SAndroid Build Coastguard Worker 		write_u64_file("/proc/sys/dev/i915/perf_stream_paranoid", 1);
4101*d83cc019SAndroid Build Coastguard Worker 		write_u64_file("/proc/sys/dev/i915/oa_max_sample_rate", 100000);
4102*d83cc019SAndroid Build Coastguard Worker 
4103*d83cc019SAndroid Build Coastguard Worker 		gt_max_freq_mhz = sysfs_read("gt_boost_freq_mhz");
4104*d83cc019SAndroid Build Coastguard Worker 
4105*d83cc019SAndroid Build Coastguard Worker 		render_copy = igt_get_render_copyfunc(devid);
4106*d83cc019SAndroid Build Coastguard Worker 		igt_require_f(render_copy, "no render-copy function\n");
4107*d83cc019SAndroid Build Coastguard Worker 	}
4108*d83cc019SAndroid Build Coastguard Worker 
4109*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("non-system-wide-paranoid")
4110*d83cc019SAndroid Build Coastguard Worker 		test_system_wide_paranoid();
4111*d83cc019SAndroid Build Coastguard Worker 
4112*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("invalid-open-flags")
4113*d83cc019SAndroid Build Coastguard Worker 		test_invalid_open_flags();
4114*d83cc019SAndroid Build Coastguard Worker 
4115*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("invalid-oa-metric-set-id")
4116*d83cc019SAndroid Build Coastguard Worker 		test_invalid_oa_metric_set_id();
4117*d83cc019SAndroid Build Coastguard Worker 
4118*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("invalid-oa-format-id")
4119*d83cc019SAndroid Build Coastguard Worker 		test_invalid_oa_format_id();
4120*d83cc019SAndroid Build Coastguard Worker 
4121*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("missing-sample-flags")
4122*d83cc019SAndroid Build Coastguard Worker 		test_missing_sample_flags();
4123*d83cc019SAndroid Build Coastguard Worker 
4124*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("oa-formats")
4125*d83cc019SAndroid Build Coastguard Worker 		test_oa_formats();
4126*d83cc019SAndroid Build Coastguard Worker 
4127*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("invalid-oa-exponent")
4128*d83cc019SAndroid Build Coastguard Worker 		test_invalid_oa_exponent();
4129*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("low-oa-exponent-permissions")
4130*d83cc019SAndroid Build Coastguard Worker 		test_low_oa_exponent_permissions();
4131*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("oa-exponents")
4132*d83cc019SAndroid Build Coastguard Worker 		test_oa_exponents();
4133*d83cc019SAndroid Build Coastguard Worker 
4134*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("per-context-mode-unprivileged") {
4135*d83cc019SAndroid Build Coastguard Worker 		igt_require(IS_HASWELL(devid));
4136*d83cc019SAndroid Build Coastguard Worker 		test_per_context_mode_unprivileged();
4137*d83cc019SAndroid Build Coastguard Worker 	}
4138*d83cc019SAndroid Build Coastguard Worker 
4139*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("buffer-fill")
4140*d83cc019SAndroid Build Coastguard Worker 		test_buffer_fill();
4141*d83cc019SAndroid Build Coastguard Worker 
4142*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("disabled-read-error")
4143*d83cc019SAndroid Build Coastguard Worker 		test_disabled_read_error();
4144*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("non-sampling-read-error")
4145*d83cc019SAndroid Build Coastguard Worker 		test_non_sampling_read_error();
4146*d83cc019SAndroid Build Coastguard Worker 
4147*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("enable-disable")
4148*d83cc019SAndroid Build Coastguard Worker 		test_enable_disable();
4149*d83cc019SAndroid Build Coastguard Worker 
4150*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("blocking")
4151*d83cc019SAndroid Build Coastguard Worker 		test_blocking();
4152*d83cc019SAndroid Build Coastguard Worker 
4153*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("polling")
4154*d83cc019SAndroid Build Coastguard Worker 		test_polling();
4155*d83cc019SAndroid Build Coastguard Worker 
4156*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("short-reads")
4157*d83cc019SAndroid Build Coastguard Worker 		test_short_reads();
4158*d83cc019SAndroid Build Coastguard Worker 
4159*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("mi-rpc")
4160*d83cc019SAndroid Build Coastguard Worker 		test_mi_rpc();
4161*d83cc019SAndroid Build Coastguard Worker 
4162*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("unprivileged-single-ctx-counters") {
4163*d83cc019SAndroid Build Coastguard Worker 		igt_require(IS_HASWELL(devid));
4164*d83cc019SAndroid Build Coastguard Worker 		hsw_test_single_ctx_counters();
4165*d83cc019SAndroid Build Coastguard Worker 	}
4166*d83cc019SAndroid Build Coastguard Worker 
4167*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("gen8-unprivileged-single-ctx-counters") {
4168*d83cc019SAndroid Build Coastguard Worker 		/* For Gen8+ the OA unit can no longer be made to clock gate
4169*d83cc019SAndroid Build Coastguard Worker 		 * for a specific context. Additionally the partial-replacement
4170*d83cc019SAndroid Build Coastguard Worker 		 * functionality to HW filter timer reports for a specific
4171*d83cc019SAndroid Build Coastguard Worker 		 * context (SKL+) can't stop multiple applications viewing
4172*d83cc019SAndroid Build Coastguard Worker 		 * system-wide data via MI_REPORT_PERF_COUNT commands.
4173*d83cc019SAndroid Build Coastguard Worker 		 */
4174*d83cc019SAndroid Build Coastguard Worker 		igt_require(intel_gen(devid) >= 8);
4175*d83cc019SAndroid Build Coastguard Worker 		gen8_test_single_ctx_render_target_writes_a_counter();
4176*d83cc019SAndroid Build Coastguard Worker 	}
4177*d83cc019SAndroid Build Coastguard Worker 
4178*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("rc6-disable")
4179*d83cc019SAndroid Build Coastguard Worker 		test_rc6_disable();
4180*d83cc019SAndroid Build Coastguard Worker 
4181*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("invalid-create-userspace-config")
4182*d83cc019SAndroid Build Coastguard Worker 		test_invalid_create_userspace_config();
4183*d83cc019SAndroid Build Coastguard Worker 
4184*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("invalid-remove-userspace-config")
4185*d83cc019SAndroid Build Coastguard Worker 		test_invalid_remove_userspace_config();
4186*d83cc019SAndroid Build Coastguard Worker 
4187*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("create-destroy-userspace-config")
4188*d83cc019SAndroid Build Coastguard Worker 		test_create_destroy_userspace_config();
4189*d83cc019SAndroid Build Coastguard Worker 
4190*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("whitelisted-registers-userspace-config")
4191*d83cc019SAndroid Build Coastguard Worker 		test_whitelisted_registers_userspace_config();
4192*d83cc019SAndroid Build Coastguard Worker 
4193*d83cc019SAndroid Build Coastguard Worker 	igt_fixture {
4194*d83cc019SAndroid Build Coastguard Worker 		/* leave sysctl options in their default state... */
4195*d83cc019SAndroid Build Coastguard Worker 		write_u64_file("/proc/sys/dev/i915/oa_max_sample_rate", 100000);
4196*d83cc019SAndroid Build Coastguard Worker 		write_u64_file("/proc/sys/dev/i915/perf_stream_paranoid", 1);
4197*d83cc019SAndroid Build Coastguard Worker 
4198*d83cc019SAndroid Build Coastguard Worker 		close(drm_fd);
4199*d83cc019SAndroid Build Coastguard Worker 	}
4200*d83cc019SAndroid Build Coastguard Worker }
4201