1 /*
2 * Copyright © 2011 Intel Corporation
3 *
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:
10 *
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
13 * Software.
14 *
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
21 * IN THE SOFTWARE.
22 *
23 * Authors:
24 * Daniel Vetter <daniel.vetter@ffwll.ch> (based on gem_storedw_*.c)
25 *
26 */
27
28 #include "igt.h"
29
30 IGT_TEST_DESCRIPTION("Basic check of ring<->ring write synchronisation.");
31
32 /*
33 * Testcase: Basic check of ring<->ring sync using a dummy reloc
34 *
35 * Extremely efficient at catching missed irqs with semaphores=0 ...
36 */
37
38 static void
sync_loop(int fd)39 sync_loop(int fd)
40 {
41 const uint32_t bbe = MI_BATCH_BUFFER_END;
42 struct drm_i915_gem_execbuffer2 execbuf;
43 struct drm_i915_gem_exec_object2 object[2];
44 struct drm_i915_gem_relocation_entry reloc[1];
45 unsigned engines[16];
46 unsigned nengine;
47 unsigned engine;
48 int i;
49
50 nengine = 0;
51 for_each_physical_engine(fd, engine)
52 engines[nengine++] = engine;
53 igt_require(nengine);
54
55 memset(object, 0, sizeof(object));
56 object[0].handle = gem_create(fd, 4096);
57 object[0].flags = EXEC_OBJECT_WRITE;
58 object[1].handle = gem_create(fd, 4096);
59 gem_write(fd, object[1].handle, 0, &bbe, sizeof(bbe));
60
61 memset(&execbuf, 0, sizeof(execbuf));
62 execbuf.buffers_ptr = to_user_pointer(object);
63 execbuf.buffer_count = 2;
64
65 /* Check if we have no-reloc support first */
66 if (__gem_execbuf(fd, &execbuf)) {
67 object[0].flags = 0;
68 object[1].relocs_ptr = to_user_pointer(reloc);
69 object[1].relocation_count = 1;
70
71 /* Add a dummy relocation to mark the object as writing */
72 memset(reloc, 0, sizeof(reloc));
73 reloc->offset = 1000;
74 reloc->target_handle = object[0].handle;
75 reloc->read_domains = I915_GEM_DOMAIN_RENDER;
76 reloc->write_domain = I915_GEM_DOMAIN_RENDER;
77
78 gem_execbuf(fd, &execbuf);
79 }
80
81 srandom(0xdeadbeef);
82
83 for (i = 0; i < SLOW_QUICK(0x100000, 10); i++) {
84 execbuf.flags = engines[rand() % nengine];
85 gem_execbuf(fd, &execbuf);
86 }
87
88 gem_sync(fd, object[1].handle);
89 gem_close(fd, object[1].handle);
90 gem_close(fd, object[0].handle);
91 }
92
93 igt_simple_main
94 {
95 int fd;
96
97 fd = drm_open_driver(DRIVER_INTEL);
98 igt_require_gem(fd);
99 intel_detect_and_clear_missed_interrupts(fd);
100
101 sync_loop(fd);
102
103 igt_assert_eq(intel_detect_and_clear_missed_interrupts(fd), 0);
104 close(fd);
105 }
106