2 * Copyright © 2011,2012,2014 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24 * Chris Wilson <chris@chris-wilson.co.uk>
25 * Daniel Vetter <daniel.vetter@ffwll.ch>
30 * Testcase: run a couple of big batches to force the eviction code.
42 #include <sys/ioctl.h>
45 #include "ioctl_wrappers.h"
47 #include "intel_chipset.h"
49 #include "eviction_common.c"
55 copy(int fd, uint32_t dst, uint32_t src, uint32_t *all_bo, int n_bo)
58 struct drm_i915_gem_relocation_entry reloc[2];
59 struct drm_i915_gem_exec_object2 *obj;
60 struct drm_i915_gem_execbuffer2 exec;
64 batch[i++] = (XY_SRC_COPY_BLT_CMD |
65 XY_SRC_COPY_BLT_WRITE_ALPHA |
66 XY_SRC_COPY_BLT_WRITE_RGB | 6);
67 if (intel_gen(intel_get_drm_devid(fd)) >= 8)
69 batch[i++] = (3 << 24) | /* 32 bits */
70 (0xcc << 16) | /* copy ROP */
72 batch[i++] = 0; /* dst x1,y1 */
73 batch[i++] = (HEIGHT << 16) | WIDTH; /* dst x2,y2 */
74 batch[i++] = 0; /* dst reloc */
75 if (intel_gen(intel_get_drm_devid(fd)) >= 8)
76 batch[i++] = 0; /* FIXME */
77 batch[i++] = 0; /* src x1,y1 */
79 batch[i++] = 0; /* src reloc */
80 if (intel_gen(intel_get_drm_devid(fd)) >= 8)
81 batch[i++] = 0; /* FIXME */
82 batch[i++] = MI_BATCH_BUFFER_END;
85 handle = gem_create(fd, 4096);
86 gem_write(fd, handle, 0, batch, sizeof(batch));
88 reloc[0].target_handle = dst;
90 reloc[0].offset = 4 * sizeof(batch[0]);
91 reloc[0].presumed_offset = 0;
92 reloc[0].read_domains = I915_GEM_DOMAIN_RENDER;
93 reloc[0].write_domain = I915_GEM_DOMAIN_RENDER;
95 reloc[1].target_handle = src;
97 reloc[1].offset = 7 * sizeof(batch[0]);
98 if (intel_gen(intel_get_drm_devid(fd)) >= 8)
99 reloc[1].offset += sizeof(batch[0]);
100 reloc[1].presumed_offset = 0;
101 reloc[1].read_domains = I915_GEM_DOMAIN_RENDER;
102 reloc[1].write_domain = 0;
104 obj = calloc(n_bo + 1, sizeof(*obj));
105 for (n = 0; n < n_bo; n++)
106 obj[n].handle = all_bo[n];
107 obj[n].handle = handle;
108 obj[n].relocation_count = 2;
109 obj[n].relocs_ptr = (uintptr_t)reloc;
111 exec.buffers_ptr = (uintptr_t)obj;
112 exec.buffer_count = n_bo + 1;
113 exec.batch_start_offset = 0;
114 exec.batch_len = i * 4;
115 exec.DR1 = exec.DR4 = 0;
116 exec.num_cliprects = 0;
117 exec.cliprects_ptr = 0;
118 exec.flags = HAS_BLT_RING(intel_get_drm_devid(fd)) ? I915_EXEC_BLT : 0;
119 i915_execbuffer2_set_context_id(exec, 0);
122 ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &exec);
126 gem_close(fd, handle);
132 static void clear(int fd, uint32_t handle, int size)
134 void *base = gem_mmap__cpu(fd, handle, size, PROT_READ | PROT_WRITE);
136 igt_assert(base != NULL);
137 memset(base, 0, size);
141 static struct igt_eviction_test_ops fault_ops = {
142 .create = gem_create,
148 static void test_forking_evictions(int fd, int size, int count,
153 trash_count = intel_get_total_ram_mb() * 11 / 10;
154 igt_require(intel_check_memory(trash_count, size, CHECK_RAM | CHECK_SWAP));
156 forking_evictions(fd, &fault_ops, size, count, trash_count, flags);
159 static void test_swapping_evictions(int fd, int size, int count)
163 trash_count = intel_get_total_ram_mb() * 11 / 10;
164 igt_require(intel_check_memory(trash_count, size, CHECK_RAM | CHECK_SWAP));
166 swapping_evictions(fd, &fault_ops, size, count, trash_count);
169 static void test_minor_evictions(int fd, int size, int count)
171 minor_evictions(fd, &fault_ops, size, count);
174 static void test_major_evictions(int fd, int size, int count)
176 major_evictions(fd, &fault_ops, size, count);
185 igt_skip_on_simulation();
191 count = 3*gem_aperture_size(fd) / size / 4;
194 for (unsigned flags = 0; flags < ALL_FORKING_EVICTIONS + 1; flags++) {
195 igt_subtest_f("forked%s%s%s-%s",
196 flags & FORKING_EVICTIONS_SWAPPING ? "-swapping" : "",
197 flags & FORKING_EVICTIONS_DUP_DRMFD ? "-multifd" : "",
198 flags & FORKING_EVICTIONS_MEMORY_PRESSURE ?
200 flags & FORKING_EVICTIONS_INTERRUPTIBLE ?
201 "interruptible" : "normal") {
202 test_forking_evictions(fd, size, count, flags);
206 igt_subtest("swapping-normal")
207 test_swapping_evictions(fd, size, count);
209 igt_subtest("minor-normal")
210 test_minor_evictions(fd, size, count);
212 igt_subtest("major-normal") {
213 size = 3*gem_aperture_size(fd) / 4;
215 test_major_evictions(fd, size, count);
220 count = 3*gem_aperture_size(fd) / size / 4;
223 igt_fork_signal_helper();
225 igt_subtest("swapping-interruptible")
226 test_swapping_evictions(fd, size, count);
228 igt_subtest("minor-interruptible")
229 test_minor_evictions(fd, size, count);
231 igt_subtest("major-interruptible") {
232 size = 3*gem_aperture_size(fd) / 4;
234 test_major_evictions(fd, size, count);
237 igt_stop_signal_helper();