1*d83cc019SAndroid Build Coastguard Worker /*
2*d83cc019SAndroid Build Coastguard Worker * Copyright © 2011 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 * Authors:
24*d83cc019SAndroid Build Coastguard Worker * Chris Wilson <[email protected]>
25*d83cc019SAndroid Build Coastguard Worker *
26*d83cc019SAndroid Build Coastguard Worker */
27*d83cc019SAndroid Build Coastguard Worker
28*d83cc019SAndroid Build Coastguard Worker #include <unistd.h>
29*d83cc019SAndroid Build Coastguard Worker #include <stdlib.h>
30*d83cc019SAndroid Build Coastguard Worker #include <stdio.h>
31*d83cc019SAndroid Build Coastguard Worker #include <string.h>
32*d83cc019SAndroid Build Coastguard Worker #include <fcntl.h>
33*d83cc019SAndroid Build Coastguard Worker #include <inttypes.h>
34*d83cc019SAndroid Build Coastguard Worker #include <pthread.h>
35*d83cc019SAndroid Build Coastguard Worker #include <errno.h>
36*d83cc019SAndroid Build Coastguard Worker #include <sys/stat.h>
37*d83cc019SAndroid Build Coastguard Worker #include <sys/ioctl.h>
38*d83cc019SAndroid Build Coastguard Worker #include "drm.h"
39*d83cc019SAndroid Build Coastguard Worker
40*d83cc019SAndroid Build Coastguard Worker #include "igt.h"
41*d83cc019SAndroid Build Coastguard Worker #include "igt_sysfs.h"
42*d83cc019SAndroid Build Coastguard Worker #include "igt_x86.h"
43*d83cc019SAndroid Build Coastguard Worker
44*d83cc019SAndroid Build Coastguard Worker #ifndef PAGE_SIZE
45*d83cc019SAndroid Build Coastguard Worker #define PAGE_SIZE 4096
46*d83cc019SAndroid Build Coastguard Worker #endif
47*d83cc019SAndroid Build Coastguard Worker
48*d83cc019SAndroid Build Coastguard Worker #define abs(x) ((x) >= 0 ? (x) : -(x))
49*d83cc019SAndroid Build Coastguard Worker
50*d83cc019SAndroid Build Coastguard Worker static int OBJECT_SIZE = 16*1024*1024;
51*d83cc019SAndroid Build Coastguard Worker
52*d83cc019SAndroid Build Coastguard Worker static void
set_domain_gtt(int fd,uint32_t handle)53*d83cc019SAndroid Build Coastguard Worker set_domain_gtt(int fd, uint32_t handle)
54*d83cc019SAndroid Build Coastguard Worker {
55*d83cc019SAndroid Build Coastguard Worker gem_set_domain(fd, handle, I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
56*d83cc019SAndroid Build Coastguard Worker }
57*d83cc019SAndroid Build Coastguard Worker
58*d83cc019SAndroid Build Coastguard Worker static void *
mmap_bo(int fd,uint32_t handle)59*d83cc019SAndroid Build Coastguard Worker mmap_bo(int fd, uint32_t handle)
60*d83cc019SAndroid Build Coastguard Worker {
61*d83cc019SAndroid Build Coastguard Worker void *ptr;
62*d83cc019SAndroid Build Coastguard Worker
63*d83cc019SAndroid Build Coastguard Worker ptr = gem_mmap__gtt(fd, handle, OBJECT_SIZE, PROT_READ | PROT_WRITE);
64*d83cc019SAndroid Build Coastguard Worker
65*d83cc019SAndroid Build Coastguard Worker return ptr;
66*d83cc019SAndroid Build Coastguard Worker }
67*d83cc019SAndroid Build Coastguard Worker
68*d83cc019SAndroid Build Coastguard Worker static void *
create_pointer(int fd)69*d83cc019SAndroid Build Coastguard Worker create_pointer(int fd)
70*d83cc019SAndroid Build Coastguard Worker {
71*d83cc019SAndroid Build Coastguard Worker uint32_t handle;
72*d83cc019SAndroid Build Coastguard Worker void *ptr;
73*d83cc019SAndroid Build Coastguard Worker
74*d83cc019SAndroid Build Coastguard Worker handle = gem_create(fd, OBJECT_SIZE);
75*d83cc019SAndroid Build Coastguard Worker
76*d83cc019SAndroid Build Coastguard Worker ptr = mmap_bo(fd, handle);
77*d83cc019SAndroid Build Coastguard Worker
78*d83cc019SAndroid Build Coastguard Worker gem_close(fd, handle);
79*d83cc019SAndroid Build Coastguard Worker
80*d83cc019SAndroid Build Coastguard Worker return ptr;
81*d83cc019SAndroid Build Coastguard Worker }
82*d83cc019SAndroid Build Coastguard Worker
83*d83cc019SAndroid Build Coastguard Worker static void
test_access(int fd)84*d83cc019SAndroid Build Coastguard Worker test_access(int fd)
85*d83cc019SAndroid Build Coastguard Worker {
86*d83cc019SAndroid Build Coastguard Worker uint32_t handle, flink, handle2;
87*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_mmap_gtt mmap_arg;
88*d83cc019SAndroid Build Coastguard Worker int fd2;
89*d83cc019SAndroid Build Coastguard Worker
90*d83cc019SAndroid Build Coastguard Worker handle = gem_create(fd, OBJECT_SIZE);
91*d83cc019SAndroid Build Coastguard Worker igt_assert(handle);
92*d83cc019SAndroid Build Coastguard Worker
93*d83cc019SAndroid Build Coastguard Worker fd2 = drm_open_driver(DRIVER_INTEL);
94*d83cc019SAndroid Build Coastguard Worker
95*d83cc019SAndroid Build Coastguard Worker /* Check that fd1 can mmap. */
96*d83cc019SAndroid Build Coastguard Worker mmap_arg.handle = handle;
97*d83cc019SAndroid Build Coastguard Worker do_ioctl(fd, DRM_IOCTL_I915_GEM_MMAP_GTT, &mmap_arg);
98*d83cc019SAndroid Build Coastguard Worker
99*d83cc019SAndroid Build Coastguard Worker igt_assert(mmap64(0, OBJECT_SIZE, PROT_READ | PROT_WRITE,
100*d83cc019SAndroid Build Coastguard Worker MAP_SHARED, fd, mmap_arg.offset));
101*d83cc019SAndroid Build Coastguard Worker
102*d83cc019SAndroid Build Coastguard Worker /* Check that the same offset on the other fd doesn't work. */
103*d83cc019SAndroid Build Coastguard Worker igt_assert(mmap64(0, OBJECT_SIZE, PROT_READ | PROT_WRITE,
104*d83cc019SAndroid Build Coastguard Worker MAP_SHARED, fd2, mmap_arg.offset) == MAP_FAILED);
105*d83cc019SAndroid Build Coastguard Worker igt_assert(errno == EACCES);
106*d83cc019SAndroid Build Coastguard Worker
107*d83cc019SAndroid Build Coastguard Worker flink = gem_flink(fd, handle);
108*d83cc019SAndroid Build Coastguard Worker igt_assert(flink);
109*d83cc019SAndroid Build Coastguard Worker handle2 = gem_open(fd2, flink);
110*d83cc019SAndroid Build Coastguard Worker igt_assert(handle2);
111*d83cc019SAndroid Build Coastguard Worker
112*d83cc019SAndroid Build Coastguard Worker /* Recheck that it works after flink. */
113*d83cc019SAndroid Build Coastguard Worker /* Check that the same offset on the other fd doesn't work. */
114*d83cc019SAndroid Build Coastguard Worker igt_assert(mmap64(0, OBJECT_SIZE, PROT_READ | PROT_WRITE,
115*d83cc019SAndroid Build Coastguard Worker MAP_SHARED, fd2, mmap_arg.offset));
116*d83cc019SAndroid Build Coastguard Worker }
117*d83cc019SAndroid Build Coastguard Worker
118*d83cc019SAndroid Build Coastguard Worker static void
test_short(int fd)119*d83cc019SAndroid Build Coastguard Worker test_short(int fd)
120*d83cc019SAndroid Build Coastguard Worker {
121*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_mmap_gtt mmap_arg;
122*d83cc019SAndroid Build Coastguard Worker int pages, p;
123*d83cc019SAndroid Build Coastguard Worker
124*d83cc019SAndroid Build Coastguard Worker mmap_arg.handle = gem_create(fd, OBJECT_SIZE);
125*d83cc019SAndroid Build Coastguard Worker igt_assert(mmap_arg.handle);
126*d83cc019SAndroid Build Coastguard Worker
127*d83cc019SAndroid Build Coastguard Worker do_ioctl(fd, DRM_IOCTL_I915_GEM_MMAP_GTT, &mmap_arg);
128*d83cc019SAndroid Build Coastguard Worker for (pages = 1; pages <= OBJECT_SIZE / PAGE_SIZE; pages <<= 1) {
129*d83cc019SAndroid Build Coastguard Worker uint8_t *r, *w;
130*d83cc019SAndroid Build Coastguard Worker
131*d83cc019SAndroid Build Coastguard Worker w = mmap64(0, pages * PAGE_SIZE, PROT_READ | PROT_WRITE,
132*d83cc019SAndroid Build Coastguard Worker MAP_SHARED, fd, mmap_arg.offset);
133*d83cc019SAndroid Build Coastguard Worker igt_assert(w != MAP_FAILED);
134*d83cc019SAndroid Build Coastguard Worker
135*d83cc019SAndroid Build Coastguard Worker r = mmap64(0, pages * PAGE_SIZE, PROT_READ,
136*d83cc019SAndroid Build Coastguard Worker MAP_SHARED, fd, mmap_arg.offset);
137*d83cc019SAndroid Build Coastguard Worker igt_assert(r != MAP_FAILED);
138*d83cc019SAndroid Build Coastguard Worker
139*d83cc019SAndroid Build Coastguard Worker for (p = 0; p < pages; p++) {
140*d83cc019SAndroid Build Coastguard Worker w[p*PAGE_SIZE] = r[p*PAGE_SIZE];
141*d83cc019SAndroid Build Coastguard Worker w[p*PAGE_SIZE+(PAGE_SIZE-1)] =
142*d83cc019SAndroid Build Coastguard Worker r[p*PAGE_SIZE+(PAGE_SIZE-1)];
143*d83cc019SAndroid Build Coastguard Worker }
144*d83cc019SAndroid Build Coastguard Worker
145*d83cc019SAndroid Build Coastguard Worker munmap(r, pages * PAGE_SIZE);
146*d83cc019SAndroid Build Coastguard Worker munmap(w, pages * PAGE_SIZE);
147*d83cc019SAndroid Build Coastguard Worker }
148*d83cc019SAndroid Build Coastguard Worker gem_close(fd, mmap_arg.handle);
149*d83cc019SAndroid Build Coastguard Worker }
150*d83cc019SAndroid Build Coastguard Worker
151*d83cc019SAndroid Build Coastguard Worker static void
test_copy(int fd)152*d83cc019SAndroid Build Coastguard Worker test_copy(int fd)
153*d83cc019SAndroid Build Coastguard Worker {
154*d83cc019SAndroid Build Coastguard Worker void *src, *dst;
155*d83cc019SAndroid Build Coastguard Worker
156*d83cc019SAndroid Build Coastguard Worker /* copy from a fresh src to fresh dst to force pagefault on both */
157*d83cc019SAndroid Build Coastguard Worker src = create_pointer(fd);
158*d83cc019SAndroid Build Coastguard Worker dst = create_pointer(fd);
159*d83cc019SAndroid Build Coastguard Worker
160*d83cc019SAndroid Build Coastguard Worker memcpy(dst, src, OBJECT_SIZE);
161*d83cc019SAndroid Build Coastguard Worker memcpy(src, dst, OBJECT_SIZE);
162*d83cc019SAndroid Build Coastguard Worker
163*d83cc019SAndroid Build Coastguard Worker munmap(dst, OBJECT_SIZE);
164*d83cc019SAndroid Build Coastguard Worker munmap(src, OBJECT_SIZE);
165*d83cc019SAndroid Build Coastguard Worker }
166*d83cc019SAndroid Build Coastguard Worker
167*d83cc019SAndroid Build Coastguard Worker enum test_read_write {
168*d83cc019SAndroid Build Coastguard Worker READ_BEFORE_WRITE,
169*d83cc019SAndroid Build Coastguard Worker READ_AFTER_WRITE,
170*d83cc019SAndroid Build Coastguard Worker };
171*d83cc019SAndroid Build Coastguard Worker
172*d83cc019SAndroid Build Coastguard Worker static void
test_read_write(int fd,enum test_read_write order)173*d83cc019SAndroid Build Coastguard Worker test_read_write(int fd, enum test_read_write order)
174*d83cc019SAndroid Build Coastguard Worker {
175*d83cc019SAndroid Build Coastguard Worker uint32_t handle;
176*d83cc019SAndroid Build Coastguard Worker void *ptr;
177*d83cc019SAndroid Build Coastguard Worker volatile uint32_t val = 0;
178*d83cc019SAndroid Build Coastguard Worker
179*d83cc019SAndroid Build Coastguard Worker handle = gem_create(fd, OBJECT_SIZE);
180*d83cc019SAndroid Build Coastguard Worker
181*d83cc019SAndroid Build Coastguard Worker ptr = gem_mmap__gtt(fd, handle, OBJECT_SIZE, PROT_READ | PROT_WRITE);
182*d83cc019SAndroid Build Coastguard Worker gem_set_domain(fd, handle, I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
183*d83cc019SAndroid Build Coastguard Worker
184*d83cc019SAndroid Build Coastguard Worker if (order == READ_BEFORE_WRITE) {
185*d83cc019SAndroid Build Coastguard Worker val = *(uint32_t *)ptr;
186*d83cc019SAndroid Build Coastguard Worker *(uint32_t *)ptr = val;
187*d83cc019SAndroid Build Coastguard Worker } else {
188*d83cc019SAndroid Build Coastguard Worker *(uint32_t *)ptr = val;
189*d83cc019SAndroid Build Coastguard Worker val = *(uint32_t *)ptr;
190*d83cc019SAndroid Build Coastguard Worker }
191*d83cc019SAndroid Build Coastguard Worker
192*d83cc019SAndroid Build Coastguard Worker gem_close(fd, handle);
193*d83cc019SAndroid Build Coastguard Worker munmap(ptr, OBJECT_SIZE);
194*d83cc019SAndroid Build Coastguard Worker }
195*d83cc019SAndroid Build Coastguard Worker
196*d83cc019SAndroid Build Coastguard Worker static void
test_read_write2(int fd,enum test_read_write order)197*d83cc019SAndroid Build Coastguard Worker test_read_write2(int fd, enum test_read_write order)
198*d83cc019SAndroid Build Coastguard Worker {
199*d83cc019SAndroid Build Coastguard Worker uint32_t handle;
200*d83cc019SAndroid Build Coastguard Worker void *r, *w;
201*d83cc019SAndroid Build Coastguard Worker volatile uint32_t val = 0;
202*d83cc019SAndroid Build Coastguard Worker
203*d83cc019SAndroid Build Coastguard Worker handle = gem_create(fd, OBJECT_SIZE);
204*d83cc019SAndroid Build Coastguard Worker
205*d83cc019SAndroid Build Coastguard Worker r = gem_mmap__gtt(fd, handle, OBJECT_SIZE, PROT_READ);
206*d83cc019SAndroid Build Coastguard Worker w = gem_mmap__gtt(fd, handle, OBJECT_SIZE, PROT_READ | PROT_WRITE);
207*d83cc019SAndroid Build Coastguard Worker
208*d83cc019SAndroid Build Coastguard Worker gem_set_domain(fd, handle, I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
209*d83cc019SAndroid Build Coastguard Worker
210*d83cc019SAndroid Build Coastguard Worker if (order == READ_BEFORE_WRITE) {
211*d83cc019SAndroid Build Coastguard Worker val = *(uint32_t *)r;
212*d83cc019SAndroid Build Coastguard Worker *(uint32_t *)w = val;
213*d83cc019SAndroid Build Coastguard Worker } else {
214*d83cc019SAndroid Build Coastguard Worker *(uint32_t *)w = val;
215*d83cc019SAndroid Build Coastguard Worker val = *(uint32_t *)r;
216*d83cc019SAndroid Build Coastguard Worker }
217*d83cc019SAndroid Build Coastguard Worker
218*d83cc019SAndroid Build Coastguard Worker gem_close(fd, handle);
219*d83cc019SAndroid Build Coastguard Worker munmap(r, OBJECT_SIZE);
220*d83cc019SAndroid Build Coastguard Worker munmap(w, OBJECT_SIZE);
221*d83cc019SAndroid Build Coastguard Worker }
222*d83cc019SAndroid Build Coastguard Worker
223*d83cc019SAndroid Build Coastguard Worker static void
test_write(int fd)224*d83cc019SAndroid Build Coastguard Worker test_write(int fd)
225*d83cc019SAndroid Build Coastguard Worker {
226*d83cc019SAndroid Build Coastguard Worker void *src;
227*d83cc019SAndroid Build Coastguard Worker uint32_t dst;
228*d83cc019SAndroid Build Coastguard Worker
229*d83cc019SAndroid Build Coastguard Worker /* copy from a fresh src to fresh dst to force pagefault on both */
230*d83cc019SAndroid Build Coastguard Worker src = create_pointer(fd);
231*d83cc019SAndroid Build Coastguard Worker dst = gem_create(fd, OBJECT_SIZE);
232*d83cc019SAndroid Build Coastguard Worker
233*d83cc019SAndroid Build Coastguard Worker gem_write(fd, dst, 0, src, OBJECT_SIZE);
234*d83cc019SAndroid Build Coastguard Worker
235*d83cc019SAndroid Build Coastguard Worker gem_close(fd, dst);
236*d83cc019SAndroid Build Coastguard Worker munmap(src, OBJECT_SIZE);
237*d83cc019SAndroid Build Coastguard Worker }
238*d83cc019SAndroid Build Coastguard Worker
239*d83cc019SAndroid Build Coastguard Worker static void
test_wc(int fd)240*d83cc019SAndroid Build Coastguard Worker test_wc(int fd)
241*d83cc019SAndroid Build Coastguard Worker {
242*d83cc019SAndroid Build Coastguard Worker unsigned long gtt_reads, gtt_writes, cpu_writes;
243*d83cc019SAndroid Build Coastguard Worker uint32_t handle;
244*d83cc019SAndroid Build Coastguard Worker void *gtt, *cpu;
245*d83cc019SAndroid Build Coastguard Worker
246*d83cc019SAndroid Build Coastguard Worker handle = gem_create(fd, 4096);
247*d83cc019SAndroid Build Coastguard Worker cpu = gem_mmap__cpu(fd, handle, 0, 4096, PROT_READ | PROT_WRITE);
248*d83cc019SAndroid Build Coastguard Worker gem_set_domain(fd, handle, I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
249*d83cc019SAndroid Build Coastguard Worker gem_close(fd, handle);
250*d83cc019SAndroid Build Coastguard Worker
251*d83cc019SAndroid Build Coastguard Worker handle = gem_create(fd, 4096);
252*d83cc019SAndroid Build Coastguard Worker gtt = gem_mmap__gtt(fd, handle, 4096, PROT_READ | PROT_WRITE);
253*d83cc019SAndroid Build Coastguard Worker gem_set_domain(fd, handle, I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
254*d83cc019SAndroid Build Coastguard Worker gem_close(fd, handle);
255*d83cc019SAndroid Build Coastguard Worker
256*d83cc019SAndroid Build Coastguard Worker gtt_reads = 0;
257*d83cc019SAndroid Build Coastguard Worker igt_for_milliseconds(200) {
258*d83cc019SAndroid Build Coastguard Worker memcpy(cpu, gtt, 4096);
259*d83cc019SAndroid Build Coastguard Worker gtt_reads++;
260*d83cc019SAndroid Build Coastguard Worker }
261*d83cc019SAndroid Build Coastguard Worker igt_debug("%lu GTT reads in 200us\n", gtt_reads);
262*d83cc019SAndroid Build Coastguard Worker
263*d83cc019SAndroid Build Coastguard Worker gtt_writes = 0;
264*d83cc019SAndroid Build Coastguard Worker igt_for_milliseconds(200) {
265*d83cc019SAndroid Build Coastguard Worker memcpy(gtt, cpu, 4096);
266*d83cc019SAndroid Build Coastguard Worker gtt_writes++;
267*d83cc019SAndroid Build Coastguard Worker }
268*d83cc019SAndroid Build Coastguard Worker igt_debug("%lu GTT writes in 200us\n", gtt_writes);
269*d83cc019SAndroid Build Coastguard Worker
270*d83cc019SAndroid Build Coastguard Worker if (igt_setup_clflush()) {
271*d83cc019SAndroid Build Coastguard Worker cpu_writes = 0;
272*d83cc019SAndroid Build Coastguard Worker igt_for_milliseconds(200) {
273*d83cc019SAndroid Build Coastguard Worker igt_clflush_range(cpu, 4096);
274*d83cc019SAndroid Build Coastguard Worker cpu_writes++;
275*d83cc019SAndroid Build Coastguard Worker }
276*d83cc019SAndroid Build Coastguard Worker igt_debug("%lu CPU writes in 200us\n", cpu_writes);
277*d83cc019SAndroid Build Coastguard Worker } else
278*d83cc019SAndroid Build Coastguard Worker cpu_writes = gtt_writes;
279*d83cc019SAndroid Build Coastguard Worker
280*d83cc019SAndroid Build Coastguard Worker munmap(cpu, 4096);
281*d83cc019SAndroid Build Coastguard Worker munmap(gtt, 4096);
282*d83cc019SAndroid Build Coastguard Worker
283*d83cc019SAndroid Build Coastguard Worker igt_assert_f(gtt_writes > 2*gtt_reads,
284*d83cc019SAndroid Build Coastguard Worker "Write-Combined writes are expected to be much faster than reads: read=%.2fMiB/s, write=%.2fMiB/s\n",
285*d83cc019SAndroid Build Coastguard Worker 5*gtt_reads/256., 5*gtt_writes/256.);
286*d83cc019SAndroid Build Coastguard Worker
287*d83cc019SAndroid Build Coastguard Worker igt_assert_f(gtt_writes > cpu_writes/2,
288*d83cc019SAndroid Build Coastguard Worker "Write-Combined writes are expected to be roughly equivalent to WB writes: WC (gtt)=%.2fMiB/s, WB (cpu)=%.2fMiB/s\n",
289*d83cc019SAndroid Build Coastguard Worker 5*gtt_writes/256., 5*cpu_writes/256.);
290*d83cc019SAndroid Build Coastguard Worker }
291*d83cc019SAndroid Build Coastguard Worker
mmap_gtt_version(int i915)292*d83cc019SAndroid Build Coastguard Worker static int mmap_gtt_version(int i915)
293*d83cc019SAndroid Build Coastguard Worker {
294*d83cc019SAndroid Build Coastguard Worker int val = 0;
295*d83cc019SAndroid Build Coastguard Worker struct drm_i915_getparam gp = {
296*d83cc019SAndroid Build Coastguard Worker gp.param = 40, /* MMAP_GTT_VERSION */
297*d83cc019SAndroid Build Coastguard Worker gp.value = &val,
298*d83cc019SAndroid Build Coastguard Worker };
299*d83cc019SAndroid Build Coastguard Worker
300*d83cc019SAndroid Build Coastguard Worker ioctl(i915, DRM_IOCTL_I915_GETPARAM, &gp);
301*d83cc019SAndroid Build Coastguard Worker return val;
302*d83cc019SAndroid Build Coastguard Worker }
303*d83cc019SAndroid Build Coastguard Worker
304*d83cc019SAndroid Build Coastguard Worker static void
test_pf_nonblock(int i915)305*d83cc019SAndroid Build Coastguard Worker test_pf_nonblock(int i915)
306*d83cc019SAndroid Build Coastguard Worker {
307*d83cc019SAndroid Build Coastguard Worker igt_spin_t *spin;
308*d83cc019SAndroid Build Coastguard Worker uint32_t *ptr;
309*d83cc019SAndroid Build Coastguard Worker
310*d83cc019SAndroid Build Coastguard Worker igt_require(mmap_gtt_version(i915) >= 3);
311*d83cc019SAndroid Build Coastguard Worker
312*d83cc019SAndroid Build Coastguard Worker spin = igt_spin_new(i915);
313*d83cc019SAndroid Build Coastguard Worker
314*d83cc019SAndroid Build Coastguard Worker igt_set_timeout(1, "initial pagefaulting did not complete within 1s");
315*d83cc019SAndroid Build Coastguard Worker
316*d83cc019SAndroid Build Coastguard Worker ptr = gem_mmap__gtt(i915, spin->handle, 4096, PROT_WRITE);
317*d83cc019SAndroid Build Coastguard Worker ptr[256] = 0;
318*d83cc019SAndroid Build Coastguard Worker munmap(ptr, 4096);
319*d83cc019SAndroid Build Coastguard Worker
320*d83cc019SAndroid Build Coastguard Worker igt_reset_timeout();
321*d83cc019SAndroid Build Coastguard Worker
322*d83cc019SAndroid Build Coastguard Worker igt_spin_free(i915, spin);
323*d83cc019SAndroid Build Coastguard Worker }
324*d83cc019SAndroid Build Coastguard Worker
325*d83cc019SAndroid Build Coastguard Worker static void
test_isolation(int i915)326*d83cc019SAndroid Build Coastguard Worker test_isolation(int i915)
327*d83cc019SAndroid Build Coastguard Worker {
328*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_mmap_gtt mmap_arg;
329*d83cc019SAndroid Build Coastguard Worker int A = gem_reopen_driver(i915);
330*d83cc019SAndroid Build Coastguard Worker int B = gem_reopen_driver(i915);
331*d83cc019SAndroid Build Coastguard Worker uint64_t offset_a, offset_b;
332*d83cc019SAndroid Build Coastguard Worker uint32_t a, b;
333*d83cc019SAndroid Build Coastguard Worker void *ptr;
334*d83cc019SAndroid Build Coastguard Worker
335*d83cc019SAndroid Build Coastguard Worker a = gem_create(A, 4096);
336*d83cc019SAndroid Build Coastguard Worker b = gem_open(B, gem_flink(A, a));
337*d83cc019SAndroid Build Coastguard Worker
338*d83cc019SAndroid Build Coastguard Worker mmap_arg.handle = a;
339*d83cc019SAndroid Build Coastguard Worker do_ioctl(A, DRM_IOCTL_I915_GEM_MMAP_GTT, &mmap_arg);
340*d83cc019SAndroid Build Coastguard Worker offset_a = mmap_arg.offset;
341*d83cc019SAndroid Build Coastguard Worker
342*d83cc019SAndroid Build Coastguard Worker mmap_arg.handle = b;
343*d83cc019SAndroid Build Coastguard Worker do_ioctl(B, DRM_IOCTL_I915_GEM_MMAP_GTT, &mmap_arg);
344*d83cc019SAndroid Build Coastguard Worker offset_b = mmap_arg.offset;
345*d83cc019SAndroid Build Coastguard Worker
346*d83cc019SAndroid Build Coastguard Worker igt_info("A: {fd:%d, handle:%d, offset:%"PRIx64"}\n",
347*d83cc019SAndroid Build Coastguard Worker A, a, offset_a);
348*d83cc019SAndroid Build Coastguard Worker igt_info("B: {fd:%d, handle:%d, offset:%"PRIx64"}\n",
349*d83cc019SAndroid Build Coastguard Worker B, b, offset_b);
350*d83cc019SAndroid Build Coastguard Worker
351*d83cc019SAndroid Build Coastguard Worker close(B);
352*d83cc019SAndroid Build Coastguard Worker
353*d83cc019SAndroid Build Coastguard Worker ptr = mmap64(0, 4096, PROT_READ, MAP_SHARED, A, offset_a);
354*d83cc019SAndroid Build Coastguard Worker igt_assert(ptr != MAP_FAILED);
355*d83cc019SAndroid Build Coastguard Worker munmap(ptr, 4096);
356*d83cc019SAndroid Build Coastguard Worker
357*d83cc019SAndroid Build Coastguard Worker close(A);
358*d83cc019SAndroid Build Coastguard Worker
359*d83cc019SAndroid Build Coastguard Worker ptr = mmap64(0, 4096, PROT_READ, MAP_SHARED, A, offset_a);
360*d83cc019SAndroid Build Coastguard Worker igt_assert(ptr == MAP_FAILED);
361*d83cc019SAndroid Build Coastguard Worker }
362*d83cc019SAndroid Build Coastguard Worker
363*d83cc019SAndroid Build Coastguard Worker static void
test_write_gtt(int fd)364*d83cc019SAndroid Build Coastguard Worker test_write_gtt(int fd)
365*d83cc019SAndroid Build Coastguard Worker {
366*d83cc019SAndroid Build Coastguard Worker uint32_t dst;
367*d83cc019SAndroid Build Coastguard Worker char *dst_gtt;
368*d83cc019SAndroid Build Coastguard Worker void *src;
369*d83cc019SAndroid Build Coastguard Worker
370*d83cc019SAndroid Build Coastguard Worker dst = gem_create(fd, OBJECT_SIZE);
371*d83cc019SAndroid Build Coastguard Worker
372*d83cc019SAndroid Build Coastguard Worker /* prefault object into gtt */
373*d83cc019SAndroid Build Coastguard Worker dst_gtt = mmap_bo(fd, dst);
374*d83cc019SAndroid Build Coastguard Worker set_domain_gtt(fd, dst);
375*d83cc019SAndroid Build Coastguard Worker memset(dst_gtt, 0, OBJECT_SIZE);
376*d83cc019SAndroid Build Coastguard Worker munmap(dst_gtt, OBJECT_SIZE);
377*d83cc019SAndroid Build Coastguard Worker
378*d83cc019SAndroid Build Coastguard Worker src = create_pointer(fd);
379*d83cc019SAndroid Build Coastguard Worker
380*d83cc019SAndroid Build Coastguard Worker gem_write(fd, dst, 0, src, OBJECT_SIZE);
381*d83cc019SAndroid Build Coastguard Worker
382*d83cc019SAndroid Build Coastguard Worker gem_close(fd, dst);
383*d83cc019SAndroid Build Coastguard Worker munmap(src, OBJECT_SIZE);
384*d83cc019SAndroid Build Coastguard Worker }
385*d83cc019SAndroid Build Coastguard Worker
is_coherent(int i915)386*d83cc019SAndroid Build Coastguard Worker static bool is_coherent(int i915)
387*d83cc019SAndroid Build Coastguard Worker {
388*d83cc019SAndroid Build Coastguard Worker int val = 1; /* by default, we assume GTT is coherent, hence the test */
389*d83cc019SAndroid Build Coastguard Worker struct drm_i915_getparam gp = {
390*d83cc019SAndroid Build Coastguard Worker gp.param = 52, /* GTT_COHERENT */
391*d83cc019SAndroid Build Coastguard Worker gp.value = &val,
392*d83cc019SAndroid Build Coastguard Worker };
393*d83cc019SAndroid Build Coastguard Worker
394*d83cc019SAndroid Build Coastguard Worker ioctl(i915, DRM_IOCTL_I915_GETPARAM, &gp);
395*d83cc019SAndroid Build Coastguard Worker return val;
396*d83cc019SAndroid Build Coastguard Worker }
397*d83cc019SAndroid Build Coastguard Worker
398*d83cc019SAndroid Build Coastguard Worker static void
test_coherency(int fd)399*d83cc019SAndroid Build Coastguard Worker test_coherency(int fd)
400*d83cc019SAndroid Build Coastguard Worker {
401*d83cc019SAndroid Build Coastguard Worker uint32_t handle;
402*d83cc019SAndroid Build Coastguard Worker uint32_t *gtt, *cpu;
403*d83cc019SAndroid Build Coastguard Worker int i;
404*d83cc019SAndroid Build Coastguard Worker
405*d83cc019SAndroid Build Coastguard Worker igt_require(is_coherent(fd));
406*d83cc019SAndroid Build Coastguard Worker igt_require(igt_setup_clflush());
407*d83cc019SAndroid Build Coastguard Worker
408*d83cc019SAndroid Build Coastguard Worker handle = gem_create(fd, OBJECT_SIZE);
409*d83cc019SAndroid Build Coastguard Worker
410*d83cc019SAndroid Build Coastguard Worker gtt = gem_mmap__gtt(fd, handle, OBJECT_SIZE, PROT_READ | PROT_WRITE);
411*d83cc019SAndroid Build Coastguard Worker cpu = gem_mmap__cpu(fd, handle, 0, OBJECT_SIZE, PROT_READ | PROT_WRITE);
412*d83cc019SAndroid Build Coastguard Worker set_domain_gtt(fd, handle);
413*d83cc019SAndroid Build Coastguard Worker
414*d83cc019SAndroid Build Coastguard Worker /* On byt/bsw/bxt this detects an interesting behaviour where the
415*d83cc019SAndroid Build Coastguard Worker * CPU cannot flush the iobar and so the read may bypass the write.
416*d83cc019SAndroid Build Coastguard Worker * https://bugs.freedesktop.org/show_bug.cgi?id=94314
417*d83cc019SAndroid Build Coastguard Worker */
418*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < OBJECT_SIZE / 64; i++) {
419*d83cc019SAndroid Build Coastguard Worker int x = 16*i + (i%16);
420*d83cc019SAndroid Build Coastguard Worker gtt[x] = i;
421*d83cc019SAndroid Build Coastguard Worker igt_clflush_range(&cpu[x], sizeof(cpu[x]));
422*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(cpu[x], i);
423*d83cc019SAndroid Build Coastguard Worker }
424*d83cc019SAndroid Build Coastguard Worker
425*d83cc019SAndroid Build Coastguard Worker munmap(cpu, OBJECT_SIZE);
426*d83cc019SAndroid Build Coastguard Worker munmap(gtt, OBJECT_SIZE);
427*d83cc019SAndroid Build Coastguard Worker gem_close(fd, handle);
428*d83cc019SAndroid Build Coastguard Worker }
429*d83cc019SAndroid Build Coastguard Worker
430*d83cc019SAndroid Build Coastguard Worker static void
test_clflush(int fd)431*d83cc019SAndroid Build Coastguard Worker test_clflush(int fd)
432*d83cc019SAndroid Build Coastguard Worker {
433*d83cc019SAndroid Build Coastguard Worker uint32_t handle;
434*d83cc019SAndroid Build Coastguard Worker uint32_t *gtt;
435*d83cc019SAndroid Build Coastguard Worker
436*d83cc019SAndroid Build Coastguard Worker igt_require(igt_setup_clflush());
437*d83cc019SAndroid Build Coastguard Worker
438*d83cc019SAndroid Build Coastguard Worker handle = gem_create(fd, OBJECT_SIZE);
439*d83cc019SAndroid Build Coastguard Worker
440*d83cc019SAndroid Build Coastguard Worker gtt = gem_mmap__gtt(fd, handle, OBJECT_SIZE, PROT_READ | PROT_WRITE);
441*d83cc019SAndroid Build Coastguard Worker set_domain_gtt(fd, handle);
442*d83cc019SAndroid Build Coastguard Worker
443*d83cc019SAndroid Build Coastguard Worker igt_clflush_range(gtt, OBJECT_SIZE);
444*d83cc019SAndroid Build Coastguard Worker
445*d83cc019SAndroid Build Coastguard Worker munmap(gtt, OBJECT_SIZE);
446*d83cc019SAndroid Build Coastguard Worker gem_close(fd, handle);
447*d83cc019SAndroid Build Coastguard Worker }
448*d83cc019SAndroid Build Coastguard Worker
449*d83cc019SAndroid Build Coastguard Worker static void
test_hang(int fd)450*d83cc019SAndroid Build Coastguard Worker test_hang(int fd)
451*d83cc019SAndroid Build Coastguard Worker {
452*d83cc019SAndroid Build Coastguard Worker const uint32_t patterns[] = {
453*d83cc019SAndroid Build Coastguard Worker 0, 0xaaaaaaaa, 0x55555555, 0xcccccccc,
454*d83cc019SAndroid Build Coastguard Worker };
455*d83cc019SAndroid Build Coastguard Worker const int ncpus = sysconf(_SC_NPROCESSORS_ONLN);
456*d83cc019SAndroid Build Coastguard Worker struct {
457*d83cc019SAndroid Build Coastguard Worker bool done;
458*d83cc019SAndroid Build Coastguard Worker bool error;
459*d83cc019SAndroid Build Coastguard Worker } *control;
460*d83cc019SAndroid Build Coastguard Worker unsigned long count;
461*d83cc019SAndroid Build Coastguard Worker igt_hang_t hang;
462*d83cc019SAndroid Build Coastguard Worker int dir;
463*d83cc019SAndroid Build Coastguard Worker
464*d83cc019SAndroid Build Coastguard Worker hang = igt_allow_hang(fd, 0, 0);
465*d83cc019SAndroid Build Coastguard Worker igt_require(igt_sysfs_set_parameter(fd, "reset", "1")); /* global */
466*d83cc019SAndroid Build Coastguard Worker
467*d83cc019SAndroid Build Coastguard Worker control = mmap(NULL, 4096, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
468*d83cc019SAndroid Build Coastguard Worker igt_assert(control != MAP_FAILED);
469*d83cc019SAndroid Build Coastguard Worker
470*d83cc019SAndroid Build Coastguard Worker igt_fork(child, ncpus) {
471*d83cc019SAndroid Build Coastguard Worker int last_pattern = 0;
472*d83cc019SAndroid Build Coastguard Worker int next_pattern = 1;
473*d83cc019SAndroid Build Coastguard Worker uint32_t *gtt[2];
474*d83cc019SAndroid Build Coastguard Worker
475*d83cc019SAndroid Build Coastguard Worker for (int i = 0; i < ARRAY_SIZE(gtt); i++) {
476*d83cc019SAndroid Build Coastguard Worker uint32_t handle;
477*d83cc019SAndroid Build Coastguard Worker
478*d83cc019SAndroid Build Coastguard Worker handle = gem_create(fd, OBJECT_SIZE);
479*d83cc019SAndroid Build Coastguard Worker gem_set_tiling(fd, handle, I915_TILING_X + i, 2048);
480*d83cc019SAndroid Build Coastguard Worker
481*d83cc019SAndroid Build Coastguard Worker gtt[i] = gem_mmap__gtt(fd, handle, OBJECT_SIZE, PROT_WRITE);
482*d83cc019SAndroid Build Coastguard Worker set_domain_gtt(fd, handle);
483*d83cc019SAndroid Build Coastguard Worker gem_close(fd, handle);
484*d83cc019SAndroid Build Coastguard Worker }
485*d83cc019SAndroid Build Coastguard Worker
486*d83cc019SAndroid Build Coastguard Worker while (!READ_ONCE(control->done)) {
487*d83cc019SAndroid Build Coastguard Worker for (int i = 0; i < OBJECT_SIZE / 64; i++) {
488*d83cc019SAndroid Build Coastguard Worker const unsigned int x = 16 * i + ( i% 16);
489*d83cc019SAndroid Build Coastguard Worker uint32_t expected = patterns[last_pattern];
490*d83cc019SAndroid Build Coastguard Worker uint32_t found[2];
491*d83cc019SAndroid Build Coastguard Worker
492*d83cc019SAndroid Build Coastguard Worker found[0] = READ_ONCE(gtt[0][x]);
493*d83cc019SAndroid Build Coastguard Worker found[1] = READ_ONCE(gtt[1][x]);
494*d83cc019SAndroid Build Coastguard Worker
495*d83cc019SAndroid Build Coastguard Worker if (found[0] != expected ||
496*d83cc019SAndroid Build Coastguard Worker found[1] != expected) {
497*d83cc019SAndroid Build Coastguard Worker igt_warn("child[%d] found (%x, %x), expecting %x\n",
498*d83cc019SAndroid Build Coastguard Worker child,
499*d83cc019SAndroid Build Coastguard Worker found[0], found[1],
500*d83cc019SAndroid Build Coastguard Worker expected);
501*d83cc019SAndroid Build Coastguard Worker control->error = true;
502*d83cc019SAndroid Build Coastguard Worker exit(0);
503*d83cc019SAndroid Build Coastguard Worker }
504*d83cc019SAndroid Build Coastguard Worker
505*d83cc019SAndroid Build Coastguard Worker gtt[0][x] = patterns[next_pattern];
506*d83cc019SAndroid Build Coastguard Worker gtt[1][x] = patterns[next_pattern];
507*d83cc019SAndroid Build Coastguard Worker }
508*d83cc019SAndroid Build Coastguard Worker
509*d83cc019SAndroid Build Coastguard Worker last_pattern = next_pattern;
510*d83cc019SAndroid Build Coastguard Worker next_pattern = (next_pattern + 1) % ARRAY_SIZE(patterns);
511*d83cc019SAndroid Build Coastguard Worker }
512*d83cc019SAndroid Build Coastguard Worker }
513*d83cc019SAndroid Build Coastguard Worker
514*d83cc019SAndroid Build Coastguard Worker count = 0;
515*d83cc019SAndroid Build Coastguard Worker dir = igt_debugfs_dir(fd);
516*d83cc019SAndroid Build Coastguard Worker igt_until_timeout(5) {
517*d83cc019SAndroid Build Coastguard Worker igt_sysfs_set(dir, "i915_wedged", "-1");
518*d83cc019SAndroid Build Coastguard Worker if (READ_ONCE(control->error))
519*d83cc019SAndroid Build Coastguard Worker break;
520*d83cc019SAndroid Build Coastguard Worker count++;
521*d83cc019SAndroid Build Coastguard Worker }
522*d83cc019SAndroid Build Coastguard Worker close(dir);
523*d83cc019SAndroid Build Coastguard Worker igt_info("%lu resets\n", count);
524*d83cc019SAndroid Build Coastguard Worker
525*d83cc019SAndroid Build Coastguard Worker control->done = true;
526*d83cc019SAndroid Build Coastguard Worker igt_waitchildren_timeout(2, NULL);
527*d83cc019SAndroid Build Coastguard Worker
528*d83cc019SAndroid Build Coastguard Worker igt_assert(!control->error);
529*d83cc019SAndroid Build Coastguard Worker munmap(control, 4096);
530*d83cc019SAndroid Build Coastguard Worker
531*d83cc019SAndroid Build Coastguard Worker igt_disallow_hang(fd, hang);
532*d83cc019SAndroid Build Coastguard Worker }
533*d83cc019SAndroid Build Coastguard Worker
min_tile_width(uint32_t devid,int tiling)534*d83cc019SAndroid Build Coastguard Worker static int min_tile_width(uint32_t devid, int tiling)
535*d83cc019SAndroid Build Coastguard Worker {
536*d83cc019SAndroid Build Coastguard Worker if (tiling < 0) {
537*d83cc019SAndroid Build Coastguard Worker if (intel_gen(devid) >= 4)
538*d83cc019SAndroid Build Coastguard Worker return 4096 - min_tile_width(devid, -tiling);
539*d83cc019SAndroid Build Coastguard Worker else
540*d83cc019SAndroid Build Coastguard Worker return 1024;
541*d83cc019SAndroid Build Coastguard Worker
542*d83cc019SAndroid Build Coastguard Worker }
543*d83cc019SAndroid Build Coastguard Worker
544*d83cc019SAndroid Build Coastguard Worker if (intel_gen(devid) == 2)
545*d83cc019SAndroid Build Coastguard Worker return 128;
546*d83cc019SAndroid Build Coastguard Worker else if (tiling == I915_TILING_X)
547*d83cc019SAndroid Build Coastguard Worker return 512;
548*d83cc019SAndroid Build Coastguard Worker else if (IS_915(devid))
549*d83cc019SAndroid Build Coastguard Worker return 512;
550*d83cc019SAndroid Build Coastguard Worker else
551*d83cc019SAndroid Build Coastguard Worker return 128;
552*d83cc019SAndroid Build Coastguard Worker }
553*d83cc019SAndroid Build Coastguard Worker
max_tile_width(uint32_t devid,int tiling)554*d83cc019SAndroid Build Coastguard Worker static int max_tile_width(uint32_t devid, int tiling)
555*d83cc019SAndroid Build Coastguard Worker {
556*d83cc019SAndroid Build Coastguard Worker if (tiling < 0) {
557*d83cc019SAndroid Build Coastguard Worker if (intel_gen(devid) >= 4)
558*d83cc019SAndroid Build Coastguard Worker return 4096 + min_tile_width(devid, -tiling);
559*d83cc019SAndroid Build Coastguard Worker else
560*d83cc019SAndroid Build Coastguard Worker return 2048;
561*d83cc019SAndroid Build Coastguard Worker }
562*d83cc019SAndroid Build Coastguard Worker
563*d83cc019SAndroid Build Coastguard Worker if (intel_gen(devid) >= 7)
564*d83cc019SAndroid Build Coastguard Worker return 256 << 10;
565*d83cc019SAndroid Build Coastguard Worker else if (intel_gen(devid) >= 4)
566*d83cc019SAndroid Build Coastguard Worker return 128 << 10;
567*d83cc019SAndroid Build Coastguard Worker else
568*d83cc019SAndroid Build Coastguard Worker return 8 << 10;
569*d83cc019SAndroid Build Coastguard Worker }
570*d83cc019SAndroid Build Coastguard Worker
known_swizzling(int fd,uint32_t handle)571*d83cc019SAndroid Build Coastguard Worker static bool known_swizzling(int fd, uint32_t handle)
572*d83cc019SAndroid Build Coastguard Worker {
573*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_get_tiling2 {
574*d83cc019SAndroid Build Coastguard Worker uint32_t handle;
575*d83cc019SAndroid Build Coastguard Worker uint32_t tiling_mode;
576*d83cc019SAndroid Build Coastguard Worker uint32_t swizzle_mode;
577*d83cc019SAndroid Build Coastguard Worker uint32_t phys_swizzle_mode;
578*d83cc019SAndroid Build Coastguard Worker } arg = {
579*d83cc019SAndroid Build Coastguard Worker .handle = handle,
580*d83cc019SAndroid Build Coastguard Worker };
581*d83cc019SAndroid Build Coastguard Worker #define DRM_IOCTL_I915_GEM_GET_TILING2 DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_TILING, struct drm_i915_gem_get_tiling2)
582*d83cc019SAndroid Build Coastguard Worker
583*d83cc019SAndroid Build Coastguard Worker if (igt_ioctl(fd, DRM_IOCTL_I915_GEM_GET_TILING2, &arg))
584*d83cc019SAndroid Build Coastguard Worker return false;
585*d83cc019SAndroid Build Coastguard Worker
586*d83cc019SAndroid Build Coastguard Worker return arg.phys_swizzle_mode == arg.swizzle_mode;
587*d83cc019SAndroid Build Coastguard Worker }
588*d83cc019SAndroid Build Coastguard Worker
589*d83cc019SAndroid Build Coastguard Worker static void
test_huge_bo(int fd,int huge,int tiling)590*d83cc019SAndroid Build Coastguard Worker test_huge_bo(int fd, int huge, int tiling)
591*d83cc019SAndroid Build Coastguard Worker {
592*d83cc019SAndroid Build Coastguard Worker uint32_t bo;
593*d83cc019SAndroid Build Coastguard Worker char *ptr;
594*d83cc019SAndroid Build Coastguard Worker char *tiled_pattern;
595*d83cc019SAndroid Build Coastguard Worker char *linear_pattern;
596*d83cc019SAndroid Build Coastguard Worker uint64_t size, last_offset;
597*d83cc019SAndroid Build Coastguard Worker uint32_t devid = intel_get_drm_devid(fd);
598*d83cc019SAndroid Build Coastguard Worker int pitch = min_tile_width(devid, tiling);
599*d83cc019SAndroid Build Coastguard Worker int i;
600*d83cc019SAndroid Build Coastguard Worker
601*d83cc019SAndroid Build Coastguard Worker switch (huge) {
602*d83cc019SAndroid Build Coastguard Worker case -1:
603*d83cc019SAndroid Build Coastguard Worker size = gem_mappable_aperture_size() / 2;
604*d83cc019SAndroid Build Coastguard Worker
605*d83cc019SAndroid Build Coastguard Worker /* Power of two fence size, natural fence
606*d83cc019SAndroid Build Coastguard Worker * alignment, and the guard page at the end
607*d83cc019SAndroid Build Coastguard Worker * gtt means that if the entire gtt is
608*d83cc019SAndroid Build Coastguard Worker * mappable, we can't usually fit in a tiled
609*d83cc019SAndroid Build Coastguard Worker * object half the size of the gtt. Let's use
610*d83cc019SAndroid Build Coastguard Worker * a quarter size one instead.
611*d83cc019SAndroid Build Coastguard Worker */
612*d83cc019SAndroid Build Coastguard Worker if (tiling &&
613*d83cc019SAndroid Build Coastguard Worker intel_gen(intel_get_drm_devid(fd)) < 4 &&
614*d83cc019SAndroid Build Coastguard Worker size >= gem_global_aperture_size(fd) / 2)
615*d83cc019SAndroid Build Coastguard Worker size /= 2;
616*d83cc019SAndroid Build Coastguard Worker break;
617*d83cc019SAndroid Build Coastguard Worker case 0:
618*d83cc019SAndroid Build Coastguard Worker size = gem_mappable_aperture_size() + PAGE_SIZE;
619*d83cc019SAndroid Build Coastguard Worker break;
620*d83cc019SAndroid Build Coastguard Worker default:
621*d83cc019SAndroid Build Coastguard Worker size = gem_global_aperture_size(fd) + PAGE_SIZE;
622*d83cc019SAndroid Build Coastguard Worker break;
623*d83cc019SAndroid Build Coastguard Worker }
624*d83cc019SAndroid Build Coastguard Worker intel_require_memory(1, size, CHECK_RAM);
625*d83cc019SAndroid Build Coastguard Worker
626*d83cc019SAndroid Build Coastguard Worker last_offset = size - PAGE_SIZE;
627*d83cc019SAndroid Build Coastguard Worker
628*d83cc019SAndroid Build Coastguard Worker /* Create pattern */
629*d83cc019SAndroid Build Coastguard Worker bo = gem_create(fd, PAGE_SIZE);
630*d83cc019SAndroid Build Coastguard Worker if (tiling)
631*d83cc019SAndroid Build Coastguard Worker igt_require(__gem_set_tiling(fd, bo, tiling, pitch) == 0);
632*d83cc019SAndroid Build Coastguard Worker igt_require(known_swizzling(fd, bo));
633*d83cc019SAndroid Build Coastguard Worker
634*d83cc019SAndroid Build Coastguard Worker linear_pattern = gem_mmap__gtt(fd, bo, PAGE_SIZE,
635*d83cc019SAndroid Build Coastguard Worker PROT_READ | PROT_WRITE);
636*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < PAGE_SIZE; i++)
637*d83cc019SAndroid Build Coastguard Worker linear_pattern[i] = i;
638*d83cc019SAndroid Build Coastguard Worker tiled_pattern = gem_mmap__cpu(fd, bo, 0, PAGE_SIZE, PROT_READ);
639*d83cc019SAndroid Build Coastguard Worker
640*d83cc019SAndroid Build Coastguard Worker gem_set_domain(fd, bo, I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT, 0);
641*d83cc019SAndroid Build Coastguard Worker gem_close(fd, bo);
642*d83cc019SAndroid Build Coastguard Worker
643*d83cc019SAndroid Build Coastguard Worker bo = gem_create(fd, size);
644*d83cc019SAndroid Build Coastguard Worker if (tiling)
645*d83cc019SAndroid Build Coastguard Worker igt_require(__gem_set_tiling(fd, bo, tiling, pitch) == 0);
646*d83cc019SAndroid Build Coastguard Worker
647*d83cc019SAndroid Build Coastguard Worker /* Initialise first/last page through CPU mmap */
648*d83cc019SAndroid Build Coastguard Worker ptr = gem_mmap__cpu(fd, bo, 0, size, PROT_READ | PROT_WRITE);
649*d83cc019SAndroid Build Coastguard Worker memcpy(ptr, tiled_pattern, PAGE_SIZE);
650*d83cc019SAndroid Build Coastguard Worker memcpy(ptr + last_offset, tiled_pattern, PAGE_SIZE);
651*d83cc019SAndroid Build Coastguard Worker munmap(ptr, size);
652*d83cc019SAndroid Build Coastguard Worker
653*d83cc019SAndroid Build Coastguard Worker /* Obtain mapping for the object through GTT. */
654*d83cc019SAndroid Build Coastguard Worker ptr = __gem_mmap__gtt(fd, bo, size, PROT_READ | PROT_WRITE);
655*d83cc019SAndroid Build Coastguard Worker igt_require_f(ptr, "Huge BO GTT mapping not supported.\n");
656*d83cc019SAndroid Build Coastguard Worker
657*d83cc019SAndroid Build Coastguard Worker set_domain_gtt(fd, bo);
658*d83cc019SAndroid Build Coastguard Worker
659*d83cc019SAndroid Build Coastguard Worker /* Access through GTT should still provide the CPU written values. */
660*d83cc019SAndroid Build Coastguard Worker igt_assert(memcmp(ptr , linear_pattern, PAGE_SIZE) == 0);
661*d83cc019SAndroid Build Coastguard Worker igt_assert(memcmp(ptr + last_offset, linear_pattern, PAGE_SIZE) == 0);
662*d83cc019SAndroid Build Coastguard Worker
663*d83cc019SAndroid Build Coastguard Worker gem_set_tiling(fd, bo, I915_TILING_NONE, 0);
664*d83cc019SAndroid Build Coastguard Worker
665*d83cc019SAndroid Build Coastguard Worker igt_assert(memcmp(ptr , tiled_pattern, PAGE_SIZE) == 0);
666*d83cc019SAndroid Build Coastguard Worker igt_assert(memcmp(ptr + last_offset, tiled_pattern, PAGE_SIZE) == 0);
667*d83cc019SAndroid Build Coastguard Worker
668*d83cc019SAndroid Build Coastguard Worker munmap(ptr, size);
669*d83cc019SAndroid Build Coastguard Worker
670*d83cc019SAndroid Build Coastguard Worker gem_close(fd, bo);
671*d83cc019SAndroid Build Coastguard Worker munmap(tiled_pattern, PAGE_SIZE);
672*d83cc019SAndroid Build Coastguard Worker munmap(linear_pattern, PAGE_SIZE);
673*d83cc019SAndroid Build Coastguard Worker }
674*d83cc019SAndroid Build Coastguard Worker
copy_wc_page(void * dst,const void * src)675*d83cc019SAndroid Build Coastguard Worker static void copy_wc_page(void *dst, const void *src)
676*d83cc019SAndroid Build Coastguard Worker {
677*d83cc019SAndroid Build Coastguard Worker igt_memcpy_from_wc(dst, src, PAGE_SIZE);
678*d83cc019SAndroid Build Coastguard Worker }
679*d83cc019SAndroid Build Coastguard Worker
tile_row_size(int tiling,unsigned int stride)680*d83cc019SAndroid Build Coastguard Worker static unsigned int tile_row_size(int tiling, unsigned int stride)
681*d83cc019SAndroid Build Coastguard Worker {
682*d83cc019SAndroid Build Coastguard Worker if (tiling < 0)
683*d83cc019SAndroid Build Coastguard Worker tiling = -tiling;
684*d83cc019SAndroid Build Coastguard Worker
685*d83cc019SAndroid Build Coastguard Worker return stride * (tiling == I915_TILING_Y ? 32 : 8);
686*d83cc019SAndroid Build Coastguard Worker }
687*d83cc019SAndroid Build Coastguard Worker
688*d83cc019SAndroid Build Coastguard Worker #define rounddown(x, y) (x - (x%y))
689*d83cc019SAndroid Build Coastguard Worker
690*d83cc019SAndroid Build Coastguard Worker static void
test_huge_copy(int fd,int huge,int tiling_a,int tiling_b,int ncpus)691*d83cc019SAndroid Build Coastguard Worker test_huge_copy(int fd, int huge, int tiling_a, int tiling_b, int ncpus)
692*d83cc019SAndroid Build Coastguard Worker {
693*d83cc019SAndroid Build Coastguard Worker const uint32_t devid = intel_get_drm_devid(fd);
694*d83cc019SAndroid Build Coastguard Worker uint64_t huge_object_size, i;
695*d83cc019SAndroid Build Coastguard Worker unsigned mode = CHECK_RAM;
696*d83cc019SAndroid Build Coastguard Worker
697*d83cc019SAndroid Build Coastguard Worker igt_fail_on_f(intel_gen(devid) >= 11 && ncpus > 1,
698*d83cc019SAndroid Build Coastguard Worker "Please adjust your expectations, https://bugs.freedesktop.org/show_bug.cgi?id=110882\n");
699*d83cc019SAndroid Build Coastguard Worker
700*d83cc019SAndroid Build Coastguard Worker switch (huge) {
701*d83cc019SAndroid Build Coastguard Worker case -2:
702*d83cc019SAndroid Build Coastguard Worker huge_object_size = gem_mappable_aperture_size() / 4;
703*d83cc019SAndroid Build Coastguard Worker break;
704*d83cc019SAndroid Build Coastguard Worker case -1:
705*d83cc019SAndroid Build Coastguard Worker huge_object_size = gem_mappable_aperture_size() / 2;
706*d83cc019SAndroid Build Coastguard Worker break;
707*d83cc019SAndroid Build Coastguard Worker case 0:
708*d83cc019SAndroid Build Coastguard Worker huge_object_size = gem_mappable_aperture_size() + PAGE_SIZE;
709*d83cc019SAndroid Build Coastguard Worker break;
710*d83cc019SAndroid Build Coastguard Worker case 1:
711*d83cc019SAndroid Build Coastguard Worker huge_object_size = gem_global_aperture_size(fd) + PAGE_SIZE;
712*d83cc019SAndroid Build Coastguard Worker break;
713*d83cc019SAndroid Build Coastguard Worker default:
714*d83cc019SAndroid Build Coastguard Worker huge_object_size = (intel_get_total_ram_mb() << 19) + PAGE_SIZE;
715*d83cc019SAndroid Build Coastguard Worker mode |= CHECK_SWAP;
716*d83cc019SAndroid Build Coastguard Worker break;
717*d83cc019SAndroid Build Coastguard Worker }
718*d83cc019SAndroid Build Coastguard Worker intel_require_memory(2*ncpus, huge_object_size, mode);
719*d83cc019SAndroid Build Coastguard Worker
720*d83cc019SAndroid Build Coastguard Worker igt_fork(child, ncpus) {
721*d83cc019SAndroid Build Coastguard Worker uint64_t valid_size = huge_object_size;
722*d83cc019SAndroid Build Coastguard Worker uint32_t bo[2];
723*d83cc019SAndroid Build Coastguard Worker char *a, *b;
724*d83cc019SAndroid Build Coastguard Worker
725*d83cc019SAndroid Build Coastguard Worker bo[0] = gem_create(fd, huge_object_size);
726*d83cc019SAndroid Build Coastguard Worker if (tiling_a) {
727*d83cc019SAndroid Build Coastguard Worker igt_require(__gem_set_tiling(fd, bo[0], abs(tiling_a), min_tile_width(devid, tiling_a)) == 0);
728*d83cc019SAndroid Build Coastguard Worker valid_size = rounddown(valid_size, tile_row_size(tiling_a, min_tile_width(devid, tiling_a)));
729*d83cc019SAndroid Build Coastguard Worker }
730*d83cc019SAndroid Build Coastguard Worker a = __gem_mmap__gtt(fd, bo[0], huge_object_size, PROT_READ | PROT_WRITE);
731*d83cc019SAndroid Build Coastguard Worker igt_require(a);
732*d83cc019SAndroid Build Coastguard Worker
733*d83cc019SAndroid Build Coastguard Worker bo[1] = gem_create(fd, huge_object_size);
734*d83cc019SAndroid Build Coastguard Worker if (tiling_b) {
735*d83cc019SAndroid Build Coastguard Worker igt_require(__gem_set_tiling(fd, bo[1], abs(tiling_b), max_tile_width(devid, tiling_b)) == 0);
736*d83cc019SAndroid Build Coastguard Worker valid_size = rounddown(valid_size, tile_row_size(tiling_b, max_tile_width(devid, tiling_b)));
737*d83cc019SAndroid Build Coastguard Worker }
738*d83cc019SAndroid Build Coastguard Worker b = __gem_mmap__gtt(fd, bo[1], huge_object_size, PROT_READ | PROT_WRITE);
739*d83cc019SAndroid Build Coastguard Worker igt_require(b);
740*d83cc019SAndroid Build Coastguard Worker
741*d83cc019SAndroid Build Coastguard Worker gem_set_domain(fd, bo[0], I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
742*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < valid_size / PAGE_SIZE; i++) {
743*d83cc019SAndroid Build Coastguard Worker uint32_t *ptr = (uint32_t *)(a + PAGE_SIZE*i);
744*d83cc019SAndroid Build Coastguard Worker for (int j = 0; j < PAGE_SIZE/4; j++)
745*d83cc019SAndroid Build Coastguard Worker ptr[j] = i + j;
746*d83cc019SAndroid Build Coastguard Worker igt_progress("Writing a ", i, valid_size / PAGE_SIZE);
747*d83cc019SAndroid Build Coastguard Worker }
748*d83cc019SAndroid Build Coastguard Worker
749*d83cc019SAndroid Build Coastguard Worker gem_set_domain(fd, bo[1], I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
750*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < valid_size / PAGE_SIZE; i++) {
751*d83cc019SAndroid Build Coastguard Worker uint32_t *ptr = (uint32_t *)(b + PAGE_SIZE*i);
752*d83cc019SAndroid Build Coastguard Worker for (int j = 0; j < PAGE_SIZE/4; j++)
753*d83cc019SAndroid Build Coastguard Worker ptr[j] = ~(i + j);
754*d83cc019SAndroid Build Coastguard Worker igt_progress("Writing b ", i, valid_size / PAGE_SIZE);
755*d83cc019SAndroid Build Coastguard Worker }
756*d83cc019SAndroid Build Coastguard Worker
757*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < valid_size / PAGE_SIZE; i++) {
758*d83cc019SAndroid Build Coastguard Worker uint32_t *A = (uint32_t *)(a + PAGE_SIZE*i);
759*d83cc019SAndroid Build Coastguard Worker uint32_t *B = (uint32_t *)(b + PAGE_SIZE*i);
760*d83cc019SAndroid Build Coastguard Worker uint32_t A_tmp[PAGE_SIZE/sizeof(uint32_t)];
761*d83cc019SAndroid Build Coastguard Worker uint32_t B_tmp[PAGE_SIZE/sizeof(uint32_t)];
762*d83cc019SAndroid Build Coastguard Worker
763*d83cc019SAndroid Build Coastguard Worker copy_wc_page(A_tmp, A);
764*d83cc019SAndroid Build Coastguard Worker copy_wc_page(B_tmp, B);
765*d83cc019SAndroid Build Coastguard Worker for (int j = 0; j < PAGE_SIZE/4; j++)
766*d83cc019SAndroid Build Coastguard Worker if ((i + j) & 1)
767*d83cc019SAndroid Build Coastguard Worker A_tmp[j] = B_tmp[j];
768*d83cc019SAndroid Build Coastguard Worker else
769*d83cc019SAndroid Build Coastguard Worker B_tmp[j] = A_tmp[j];
770*d83cc019SAndroid Build Coastguard Worker
771*d83cc019SAndroid Build Coastguard Worker gem_set_domain(fd, bo[0], I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
772*d83cc019SAndroid Build Coastguard Worker memcpy(A, A_tmp, PAGE_SIZE);
773*d83cc019SAndroid Build Coastguard Worker
774*d83cc019SAndroid Build Coastguard Worker gem_set_domain(fd, bo[1], I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
775*d83cc019SAndroid Build Coastguard Worker memcpy(B, B_tmp, PAGE_SIZE);
776*d83cc019SAndroid Build Coastguard Worker
777*d83cc019SAndroid Build Coastguard Worker igt_progress("Copying a<->b ", i, valid_size / PAGE_SIZE);
778*d83cc019SAndroid Build Coastguard Worker }
779*d83cc019SAndroid Build Coastguard Worker
780*d83cc019SAndroid Build Coastguard Worker gem_close(fd, bo[0]);
781*d83cc019SAndroid Build Coastguard Worker gem_close(fd, bo[1]);
782*d83cc019SAndroid Build Coastguard Worker
783*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < valid_size / PAGE_SIZE; i++) {
784*d83cc019SAndroid Build Coastguard Worker uint32_t page[PAGE_SIZE/sizeof(uint32_t)];
785*d83cc019SAndroid Build Coastguard Worker copy_wc_page(page, a + PAGE_SIZE*i);
786*d83cc019SAndroid Build Coastguard Worker for (int j = 0; j < PAGE_SIZE/sizeof(uint32_t); j++)
787*d83cc019SAndroid Build Coastguard Worker if ((i + j) & 1)
788*d83cc019SAndroid Build Coastguard Worker igt_assert_eq_u32(page[j], ~(i + j));
789*d83cc019SAndroid Build Coastguard Worker else
790*d83cc019SAndroid Build Coastguard Worker igt_assert_eq_u32(page[j], i + j);
791*d83cc019SAndroid Build Coastguard Worker igt_progress("Checking a ", i, valid_size / PAGE_SIZE);
792*d83cc019SAndroid Build Coastguard Worker }
793*d83cc019SAndroid Build Coastguard Worker munmap(a, huge_object_size);
794*d83cc019SAndroid Build Coastguard Worker
795*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < valid_size / PAGE_SIZE; i++) {
796*d83cc019SAndroid Build Coastguard Worker uint32_t page[PAGE_SIZE/sizeof(uint32_t)];
797*d83cc019SAndroid Build Coastguard Worker copy_wc_page(page, b + PAGE_SIZE*i);
798*d83cc019SAndroid Build Coastguard Worker for (int j = 0; j < PAGE_SIZE/sizeof(uint32_t); j++)
799*d83cc019SAndroid Build Coastguard Worker if ((i + j) & 1)
800*d83cc019SAndroid Build Coastguard Worker igt_assert_eq_u32(page[j], ~(i + j));
801*d83cc019SAndroid Build Coastguard Worker else
802*d83cc019SAndroid Build Coastguard Worker igt_assert_eq_u32(page[j], i + j);
803*d83cc019SAndroid Build Coastguard Worker igt_progress("Checking b ", i, valid_size / PAGE_SIZE);
804*d83cc019SAndroid Build Coastguard Worker }
805*d83cc019SAndroid Build Coastguard Worker munmap(b, huge_object_size);
806*d83cc019SAndroid Build Coastguard Worker }
807*d83cc019SAndroid Build Coastguard Worker igt_waitchildren();
808*d83cc019SAndroid Build Coastguard Worker }
809*d83cc019SAndroid Build Coastguard Worker
810*d83cc019SAndroid Build Coastguard Worker static void
test_read(int fd)811*d83cc019SAndroid Build Coastguard Worker test_read(int fd)
812*d83cc019SAndroid Build Coastguard Worker {
813*d83cc019SAndroid Build Coastguard Worker void *dst;
814*d83cc019SAndroid Build Coastguard Worker uint32_t src;
815*d83cc019SAndroid Build Coastguard Worker
816*d83cc019SAndroid Build Coastguard Worker /* copy from a fresh src to fresh dst to force pagefault on both */
817*d83cc019SAndroid Build Coastguard Worker dst = create_pointer(fd);
818*d83cc019SAndroid Build Coastguard Worker src = gem_create(fd, OBJECT_SIZE);
819*d83cc019SAndroid Build Coastguard Worker
820*d83cc019SAndroid Build Coastguard Worker gem_read(fd, src, 0, dst, OBJECT_SIZE);
821*d83cc019SAndroid Build Coastguard Worker
822*d83cc019SAndroid Build Coastguard Worker gem_close(fd, src);
823*d83cc019SAndroid Build Coastguard Worker munmap(dst, OBJECT_SIZE);
824*d83cc019SAndroid Build Coastguard Worker }
825*d83cc019SAndroid Build Coastguard Worker
826*d83cc019SAndroid Build Coastguard Worker static void
test_write_cpu_read_gtt(int fd)827*d83cc019SAndroid Build Coastguard Worker test_write_cpu_read_gtt(int fd)
828*d83cc019SAndroid Build Coastguard Worker {
829*d83cc019SAndroid Build Coastguard Worker uint32_t handle;
830*d83cc019SAndroid Build Coastguard Worker uint32_t *src, *dst;
831*d83cc019SAndroid Build Coastguard Worker
832*d83cc019SAndroid Build Coastguard Worker igt_require(gem_has_llc(fd));
833*d83cc019SAndroid Build Coastguard Worker
834*d83cc019SAndroid Build Coastguard Worker handle = gem_create(fd, OBJECT_SIZE);
835*d83cc019SAndroid Build Coastguard Worker
836*d83cc019SAndroid Build Coastguard Worker dst = gem_mmap__gtt(fd, handle, OBJECT_SIZE, PROT_READ);
837*d83cc019SAndroid Build Coastguard Worker
838*d83cc019SAndroid Build Coastguard Worker src = gem_mmap__cpu(fd, handle, 0, OBJECT_SIZE, PROT_WRITE);
839*d83cc019SAndroid Build Coastguard Worker
840*d83cc019SAndroid Build Coastguard Worker gem_close(fd, handle);
841*d83cc019SAndroid Build Coastguard Worker
842*d83cc019SAndroid Build Coastguard Worker memset(src, 0xaa, OBJECT_SIZE);
843*d83cc019SAndroid Build Coastguard Worker igt_assert(memcmp(dst, src, OBJECT_SIZE) == 0);
844*d83cc019SAndroid Build Coastguard Worker
845*d83cc019SAndroid Build Coastguard Worker munmap(src, OBJECT_SIZE);
846*d83cc019SAndroid Build Coastguard Worker munmap(dst, OBJECT_SIZE);
847*d83cc019SAndroid Build Coastguard Worker }
848*d83cc019SAndroid Build Coastguard Worker
849*d83cc019SAndroid Build Coastguard Worker struct thread_fault_concurrent {
850*d83cc019SAndroid Build Coastguard Worker pthread_t thread;
851*d83cc019SAndroid Build Coastguard Worker int id;
852*d83cc019SAndroid Build Coastguard Worker uint32_t **ptr;
853*d83cc019SAndroid Build Coastguard Worker };
854*d83cc019SAndroid Build Coastguard Worker
855*d83cc019SAndroid Build Coastguard Worker static void *
thread_fault_concurrent(void * closure)856*d83cc019SAndroid Build Coastguard Worker thread_fault_concurrent(void *closure)
857*d83cc019SAndroid Build Coastguard Worker {
858*d83cc019SAndroid Build Coastguard Worker struct thread_fault_concurrent *t = closure;
859*d83cc019SAndroid Build Coastguard Worker uint32_t val = 0;
860*d83cc019SAndroid Build Coastguard Worker int n;
861*d83cc019SAndroid Build Coastguard Worker
862*d83cc019SAndroid Build Coastguard Worker for (n = 0; n < 32; n++) {
863*d83cc019SAndroid Build Coastguard Worker if (n & 1)
864*d83cc019SAndroid Build Coastguard Worker *t->ptr[(n + t->id) % 32] = val;
865*d83cc019SAndroid Build Coastguard Worker else
866*d83cc019SAndroid Build Coastguard Worker val = *t->ptr[(n + t->id) % 32];
867*d83cc019SAndroid Build Coastguard Worker }
868*d83cc019SAndroid Build Coastguard Worker
869*d83cc019SAndroid Build Coastguard Worker return NULL;
870*d83cc019SAndroid Build Coastguard Worker }
871*d83cc019SAndroid Build Coastguard Worker
872*d83cc019SAndroid Build Coastguard Worker static void
test_fault_concurrent(int fd)873*d83cc019SAndroid Build Coastguard Worker test_fault_concurrent(int fd)
874*d83cc019SAndroid Build Coastguard Worker {
875*d83cc019SAndroid Build Coastguard Worker uint32_t *ptr[32];
876*d83cc019SAndroid Build Coastguard Worker struct thread_fault_concurrent thread[64];
877*d83cc019SAndroid Build Coastguard Worker int n;
878*d83cc019SAndroid Build Coastguard Worker
879*d83cc019SAndroid Build Coastguard Worker for (n = 0; n < 32; n++) {
880*d83cc019SAndroid Build Coastguard Worker ptr[n] = create_pointer(fd);
881*d83cc019SAndroid Build Coastguard Worker }
882*d83cc019SAndroid Build Coastguard Worker
883*d83cc019SAndroid Build Coastguard Worker for (n = 0; n < 64; n++) {
884*d83cc019SAndroid Build Coastguard Worker thread[n].ptr = ptr;
885*d83cc019SAndroid Build Coastguard Worker thread[n].id = n;
886*d83cc019SAndroid Build Coastguard Worker pthread_create(&thread[n].thread, NULL, thread_fault_concurrent, &thread[n]);
887*d83cc019SAndroid Build Coastguard Worker }
888*d83cc019SAndroid Build Coastguard Worker
889*d83cc019SAndroid Build Coastguard Worker for (n = 0; n < 64; n++)
890*d83cc019SAndroid Build Coastguard Worker pthread_join(thread[n].thread, NULL);
891*d83cc019SAndroid Build Coastguard Worker
892*d83cc019SAndroid Build Coastguard Worker for (n = 0; n < 32; n++) {
893*d83cc019SAndroid Build Coastguard Worker munmap(ptr[n], OBJECT_SIZE);
894*d83cc019SAndroid Build Coastguard Worker }
895*d83cc019SAndroid Build Coastguard Worker }
896*d83cc019SAndroid Build Coastguard Worker
897*d83cc019SAndroid Build Coastguard Worker static void
run_without_prefault(int fd,void (* func)(int fd))898*d83cc019SAndroid Build Coastguard Worker run_without_prefault(int fd,
899*d83cc019SAndroid Build Coastguard Worker void (*func)(int fd))
900*d83cc019SAndroid Build Coastguard Worker {
901*d83cc019SAndroid Build Coastguard Worker igt_disable_prefault();
902*d83cc019SAndroid Build Coastguard Worker func(fd);
903*d83cc019SAndroid Build Coastguard Worker igt_enable_prefault();
904*d83cc019SAndroid Build Coastguard Worker }
905*d83cc019SAndroid Build Coastguard Worker
mmap_ioctl(int i915,struct drm_i915_gem_mmap_gtt * arg)906*d83cc019SAndroid Build Coastguard Worker static int mmap_ioctl(int i915, struct drm_i915_gem_mmap_gtt *arg)
907*d83cc019SAndroid Build Coastguard Worker {
908*d83cc019SAndroid Build Coastguard Worker int err = 0;
909*d83cc019SAndroid Build Coastguard Worker
910*d83cc019SAndroid Build Coastguard Worker if (igt_ioctl(i915, DRM_IOCTL_I915_GEM_MMAP_GTT, arg))
911*d83cc019SAndroid Build Coastguard Worker err = -errno;
912*d83cc019SAndroid Build Coastguard Worker
913*d83cc019SAndroid Build Coastguard Worker errno = 0;
914*d83cc019SAndroid Build Coastguard Worker return err;
915*d83cc019SAndroid Build Coastguard Worker }
916*d83cc019SAndroid Build Coastguard Worker
917*d83cc019SAndroid Build Coastguard Worker int fd;
918*d83cc019SAndroid Build Coastguard Worker
919*d83cc019SAndroid Build Coastguard Worker igt_main
920*d83cc019SAndroid Build Coastguard Worker {
921*d83cc019SAndroid Build Coastguard Worker if (igt_run_in_simulation())
922*d83cc019SAndroid Build Coastguard Worker OBJECT_SIZE = 1 * 1024 * 1024;
923*d83cc019SAndroid Build Coastguard Worker
924*d83cc019SAndroid Build Coastguard Worker igt_fixture
925*d83cc019SAndroid Build Coastguard Worker fd = drm_open_driver(DRIVER_INTEL);
926*d83cc019SAndroid Build Coastguard Worker
927*d83cc019SAndroid Build Coastguard Worker igt_subtest("bad-object") {
928*d83cc019SAndroid Build Coastguard Worker uint32_t real_handle = gem_create(fd, 4096);
929*d83cc019SAndroid Build Coastguard Worker uint32_t handles[20];
930*d83cc019SAndroid Build Coastguard Worker size_t i = 0, len;
931*d83cc019SAndroid Build Coastguard Worker
932*d83cc019SAndroid Build Coastguard Worker handles[i++] = 0xdeadbeef;
933*d83cc019SAndroid Build Coastguard Worker for(int bit = 0; bit < 16; bit++)
934*d83cc019SAndroid Build Coastguard Worker handles[i++] = real_handle | (1 << (bit + 16));
935*d83cc019SAndroid Build Coastguard Worker handles[i++] = real_handle + 1;
936*d83cc019SAndroid Build Coastguard Worker len = i;
937*d83cc019SAndroid Build Coastguard Worker
938*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < len; ++i) {
939*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_mmap_gtt arg = {
940*d83cc019SAndroid Build Coastguard Worker .handle = handles[i],
941*d83cc019SAndroid Build Coastguard Worker };
942*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(mmap_ioctl(fd, &arg), -ENOENT);
943*d83cc019SAndroid Build Coastguard Worker }
944*d83cc019SAndroid Build Coastguard Worker
945*d83cc019SAndroid Build Coastguard Worker gem_close(fd, real_handle);
946*d83cc019SAndroid Build Coastguard Worker }
947*d83cc019SAndroid Build Coastguard Worker
948*d83cc019SAndroid Build Coastguard Worker igt_subtest("basic")
949*d83cc019SAndroid Build Coastguard Worker test_access(fd);
950*d83cc019SAndroid Build Coastguard Worker igt_subtest("basic-short")
951*d83cc019SAndroid Build Coastguard Worker test_short(fd);
952*d83cc019SAndroid Build Coastguard Worker igt_subtest("basic-copy")
953*d83cc019SAndroid Build Coastguard Worker test_copy(fd);
954*d83cc019SAndroid Build Coastguard Worker igt_subtest("basic-read")
955*d83cc019SAndroid Build Coastguard Worker test_read(fd);
956*d83cc019SAndroid Build Coastguard Worker igt_subtest("basic-write")
957*d83cc019SAndroid Build Coastguard Worker test_write(fd);
958*d83cc019SAndroid Build Coastguard Worker igt_subtest("basic-write-gtt")
959*d83cc019SAndroid Build Coastguard Worker test_write_gtt(fd);
960*d83cc019SAndroid Build Coastguard Worker igt_subtest("coherency")
961*d83cc019SAndroid Build Coastguard Worker test_coherency(fd);
962*d83cc019SAndroid Build Coastguard Worker igt_subtest("clflush")
963*d83cc019SAndroid Build Coastguard Worker test_clflush(fd);
964*d83cc019SAndroid Build Coastguard Worker igt_subtest("hang")
965*d83cc019SAndroid Build Coastguard Worker test_hang(fd);
966*d83cc019SAndroid Build Coastguard Worker igt_subtest("basic-read-write")
967*d83cc019SAndroid Build Coastguard Worker test_read_write(fd, READ_BEFORE_WRITE);
968*d83cc019SAndroid Build Coastguard Worker igt_subtest("basic-write-read")
969*d83cc019SAndroid Build Coastguard Worker test_read_write(fd, READ_AFTER_WRITE);
970*d83cc019SAndroid Build Coastguard Worker igt_subtest("basic-read-write-distinct")
971*d83cc019SAndroid Build Coastguard Worker test_read_write2(fd, READ_BEFORE_WRITE);
972*d83cc019SAndroid Build Coastguard Worker igt_subtest("basic-write-read-distinct")
973*d83cc019SAndroid Build Coastguard Worker test_read_write2(fd, READ_AFTER_WRITE);
974*d83cc019SAndroid Build Coastguard Worker igt_subtest("fault-concurrent")
975*d83cc019SAndroid Build Coastguard Worker test_fault_concurrent(fd);
976*d83cc019SAndroid Build Coastguard Worker igt_subtest("basic-read-no-prefault")
977*d83cc019SAndroid Build Coastguard Worker run_without_prefault(fd, test_read);
978*d83cc019SAndroid Build Coastguard Worker igt_subtest("basic-write-no-prefault")
979*d83cc019SAndroid Build Coastguard Worker run_without_prefault(fd, test_write);
980*d83cc019SAndroid Build Coastguard Worker igt_subtest("basic-write-gtt-no-prefault")
981*d83cc019SAndroid Build Coastguard Worker run_without_prefault(fd, test_write_gtt);
982*d83cc019SAndroid Build Coastguard Worker igt_subtest("basic-write-cpu-read-gtt")
983*d83cc019SAndroid Build Coastguard Worker test_write_cpu_read_gtt(fd);
984*d83cc019SAndroid Build Coastguard Worker igt_subtest("basic-wc")
985*d83cc019SAndroid Build Coastguard Worker test_wc(fd);
986*d83cc019SAndroid Build Coastguard Worker igt_subtest("isolation")
987*d83cc019SAndroid Build Coastguard Worker test_isolation(fd);
988*d83cc019SAndroid Build Coastguard Worker igt_subtest("pf-nonblock")
989*d83cc019SAndroid Build Coastguard Worker test_pf_nonblock(fd);
990*d83cc019SAndroid Build Coastguard Worker
991*d83cc019SAndroid Build Coastguard Worker igt_subtest("basic-small-bo")
992*d83cc019SAndroid Build Coastguard Worker test_huge_bo(fd, -1, I915_TILING_NONE);
993*d83cc019SAndroid Build Coastguard Worker igt_subtest("basic-small-bo-tiledX")
994*d83cc019SAndroid Build Coastguard Worker test_huge_bo(fd, -1, I915_TILING_X);
995*d83cc019SAndroid Build Coastguard Worker igt_subtest("basic-small-bo-tiledY")
996*d83cc019SAndroid Build Coastguard Worker test_huge_bo(fd, -1, I915_TILING_Y);
997*d83cc019SAndroid Build Coastguard Worker
998*d83cc019SAndroid Build Coastguard Worker igt_subtest("big-bo")
999*d83cc019SAndroid Build Coastguard Worker test_huge_bo(fd, 0, I915_TILING_NONE);
1000*d83cc019SAndroid Build Coastguard Worker igt_subtest("big-bo-tiledX")
1001*d83cc019SAndroid Build Coastguard Worker test_huge_bo(fd, 0, I915_TILING_X);
1002*d83cc019SAndroid Build Coastguard Worker igt_subtest("big-bo-tiledY")
1003*d83cc019SAndroid Build Coastguard Worker test_huge_bo(fd, 0, I915_TILING_Y);
1004*d83cc019SAndroid Build Coastguard Worker
1005*d83cc019SAndroid Build Coastguard Worker igt_subtest("huge-bo")
1006*d83cc019SAndroid Build Coastguard Worker test_huge_bo(fd, 1, I915_TILING_NONE);
1007*d83cc019SAndroid Build Coastguard Worker igt_subtest("huge-bo-tiledX")
1008*d83cc019SAndroid Build Coastguard Worker test_huge_bo(fd, 1, I915_TILING_X);
1009*d83cc019SAndroid Build Coastguard Worker igt_subtest("huge-bo-tiledY")
1010*d83cc019SAndroid Build Coastguard Worker test_huge_bo(fd, 1, I915_TILING_Y);
1011*d83cc019SAndroid Build Coastguard Worker
1012*d83cc019SAndroid Build Coastguard Worker igt_subtest_group {
1013*d83cc019SAndroid Build Coastguard Worker const struct copy_size {
1014*d83cc019SAndroid Build Coastguard Worker const char *prefix;
1015*d83cc019SAndroid Build Coastguard Worker int size;
1016*d83cc019SAndroid Build Coastguard Worker } copy_sizes[] = {
1017*d83cc019SAndroid Build Coastguard Worker { "basic-small", -2 },
1018*d83cc019SAndroid Build Coastguard Worker { "medium", -1 },
1019*d83cc019SAndroid Build Coastguard Worker { "big", 0 },
1020*d83cc019SAndroid Build Coastguard Worker { "huge", 1 },
1021*d83cc019SAndroid Build Coastguard Worker { "swap", 2 },
1022*d83cc019SAndroid Build Coastguard Worker { }
1023*d83cc019SAndroid Build Coastguard Worker };
1024*d83cc019SAndroid Build Coastguard Worker const struct copy_mode {
1025*d83cc019SAndroid Build Coastguard Worker const char *suffix;
1026*d83cc019SAndroid Build Coastguard Worker int tiling_x, tiling_y;
1027*d83cc019SAndroid Build Coastguard Worker } copy_modes[] = {
1028*d83cc019SAndroid Build Coastguard Worker { "", I915_TILING_NONE, I915_TILING_NONE},
1029*d83cc019SAndroid Build Coastguard Worker { "-XY", I915_TILING_X, I915_TILING_Y},
1030*d83cc019SAndroid Build Coastguard Worker { "-odd", -I915_TILING_X, -I915_TILING_Y},
1031*d83cc019SAndroid Build Coastguard Worker {}
1032*d83cc019SAndroid Build Coastguard Worker };
1033*d83cc019SAndroid Build Coastguard Worker const int ncpus = sysconf(_SC_NPROCESSORS_ONLN);
1034*d83cc019SAndroid Build Coastguard Worker
1035*d83cc019SAndroid Build Coastguard Worker for (const struct copy_size *s = copy_sizes; s->prefix; s++)
1036*d83cc019SAndroid Build Coastguard Worker for (const struct copy_mode *m = copy_modes; m->suffix; m++) {
1037*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("%s-copy%s", s->prefix, m->suffix)
1038*d83cc019SAndroid Build Coastguard Worker test_huge_copy(fd,
1039*d83cc019SAndroid Build Coastguard Worker s->size,
1040*d83cc019SAndroid Build Coastguard Worker m->tiling_x,
1041*d83cc019SAndroid Build Coastguard Worker m->tiling_y,
1042*d83cc019SAndroid Build Coastguard Worker 1);
1043*d83cc019SAndroid Build Coastguard Worker
1044*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("forked-%s-copy%s", s->prefix, m->suffix)
1045*d83cc019SAndroid Build Coastguard Worker test_huge_copy(fd,
1046*d83cc019SAndroid Build Coastguard Worker s->size,
1047*d83cc019SAndroid Build Coastguard Worker m->tiling_x,
1048*d83cc019SAndroid Build Coastguard Worker m->tiling_y,
1049*d83cc019SAndroid Build Coastguard Worker ncpus);
1050*d83cc019SAndroid Build Coastguard Worker }
1051*d83cc019SAndroid Build Coastguard Worker }
1052*d83cc019SAndroid Build Coastguard Worker
1053*d83cc019SAndroid Build Coastguard Worker
1054*d83cc019SAndroid Build Coastguard Worker igt_fixture
1055*d83cc019SAndroid Build Coastguard Worker close(fd);
1056*d83cc019SAndroid Build Coastguard Worker }
1057