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, ¶m, 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, ¶m, 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, ¶m, 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, ¶m, 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, ¶m, 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, ¶m, 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, ¶m, 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, ¶m, 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, ¶m, 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, ¶m, 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, ¶m, 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, ¶m, 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, ¶m, 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, ¶m, 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, ¶m, 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, ¶m, 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, ¶m, 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, ¶m, 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, ¶m, 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, ¶m, 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, ¶m, 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, ¶m, 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, ¶m, 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, ¶m, 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, ¶m, 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, ¶m, 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, ¶m, 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, ¶m, 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, ¶m, 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, ¶m, 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, ¶m, 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, ¶m, 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, ¶m, 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, ¶m, 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