aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/selftests
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2017-12-03 18:40:35 -0500
committerDave Airlie <airlied@redhat.com>2017-12-03 19:56:53 -0500
commitca797d29cd63e7b71b4eea29aff3b1cefd1ecb59 (patch)
treedb1ada69f713da68b43c828bd15f90e250f86ab7 /drivers/gpu/drm/i915/selftests
parent2c1c55cb75a9c72f9726fabb8c3607947711a8df (diff)
parent010d118c20617021025a930bc8e90f371ab99da5 (diff)
Merge tag 'drm-intel-next-2017-11-17-1' of git://anongit.freedesktop.org/drm/drm-intel into drm-next
More change sets for 4.16: - Many improvements for selftests and other igt tests (Chris) - Forcewake with PUNIT->PMIC bus fixes and robustness (Hans) - Define an engine class for uABI (Tvrtko) - Context switch fixes and improvements (Chris) - GT powersavings and power gating simplification and fixes (Chris) - Other general driver clean-ups (Chris, Lucas, Ville) - Removing old, useless and/or bad workarounds (Chris, Oscar, Radhakrishna) - IPS, pipe config, etc in preparation for another Fast Boot attempt (Maarten) - OA perf fixes and support to Coffee Lake and Cannonlake (Lionel) - Fixes around GPU fault registers (Michel) - GEM Proxy (Tina) - Refactor of Geminilake and Cannonlake plane color handling (James) - Generalize transcoder loop (Mika Kahola) - New HW Workaround for Cannonlake and Geminilake (Rodrigo) - Resume GuC before using GEM (Chris) - Stolen Memory handling improvements (Ville) - Initialize entry in PPAT for older compilers (Chris) - Other fixes and robustness improvements on execbuf (Chris) - Improve logs of GEM_BUG_ON (Mika Kuoppala) - Rework with massive rename of GuC functions and files (Sagar) - Don't sanitize frame start delay if pipe is off (Ville) - Cannonlake clock fixes (Rodrigo) - Cannonlake HDMI 2.0 support (Rodrigo) - Add a GuC doorbells selftest (Michel) - Add might_sleep() check to our wait_for() (Chris) Many GVT changes for 4.16: - CSB HWSP update support (Weinan) - GVT debug helpers, dyndbg and debugfs (Chuanxiao, Shuo) - full virtualized opregion (Xiaolin) - VM health check for sane fallback (Fred) - workload submission code refactor for future enabling (Zhi) - Updated repo URL in MAINTAINERS (Zhenyu) - other many misc fixes * tag 'drm-intel-next-2017-11-17-1' of git://anongit.freedesktop.org/drm/drm-intel: (260 commits) drm/i915: Update DRIVER_DATE to 20171117 drm/i915: Add a policy note for removing workarounds drm/i915/selftests: Report ENOMEM clearly for an allocation failure Revert "drm/i915: Display WA #1133 WaFbcSkipSegments:cnl, glk" drm/i915: Calculate g4x intermediate watermarks correctly drm/i915: Calculate vlv/chv intermediate watermarks correctly, v3. drm/i915: Pass crtc_state to ips toggle functions, v2 drm/i915: Pass idle crtc_state to intel_dp_sink_crc drm/i915: Enable FIFO underrun reporting after initial fastset, v4. drm/i915: Mark the userptr invalidate workqueue as WQ_MEM_RECLAIM drm/i915: Add might_sleep() check to wait_for() drm/i915/selftests: Add a GuC doorbells selftest drm/i915/cnl: Extend HDMI 2.0 support to CNL. drm/i915/cnl: Simplify dco_fraction calculation. drm/i915/cnl: Don't blindly replace qdiv. drm/i915/cnl: Fix wrpll math for higher freqs. drm/i915/cnl: Fix, simplify and unify wrpll variable sizes. drm/i915/cnl: Remove useless conversion. drm/i915/cnl: Remove spurious central_freq. drm/i915/selftests: exercise_ggtt may have nothing to do ...
Diffstat (limited to 'drivers/gpu/drm/i915/selftests')
-rw-r--r--drivers/gpu/drm/i915/selftests/huge_pages.c3
-rw-r--r--drivers/gpu/drm/i915/selftests/i915_gem_coherency.c16
-rw-r--r--drivers/gpu/drm/i915/selftests/i915_gem_context.c2
-rw-r--r--drivers/gpu/drm/i915/selftests/i915_gem_gtt.c48
-rw-r--r--drivers/gpu/drm/i915/selftests/i915_gem_object.c2
-rw-r--r--drivers/gpu/drm/i915/selftests/i915_gem_request.c2
-rw-r--r--drivers/gpu/drm/i915/selftests/i915_gem_timeline.c2
-rw-r--r--drivers/gpu/drm/i915/selftests/i915_live_selftests.h1
-rw-r--r--drivers/gpu/drm/i915/selftests/i915_syncmap.c6
-rw-r--r--drivers/gpu/drm/i915/selftests/i915_vma.c2
-rw-r--r--drivers/gpu/drm/i915/selftests/intel_guc.c367
-rw-r--r--drivers/gpu/drm/i915/selftests/intel_uncore.c11
-rw-r--r--drivers/gpu/drm/i915/selftests/mock_engine.c41
-rw-r--r--drivers/gpu/drm/i915/selftests/mock_gem_device.c7
14 files changed, 461 insertions, 49 deletions
diff --git a/drivers/gpu/drm/i915/selftests/huge_pages.c b/drivers/gpu/drm/i915/selftests/huge_pages.c
index 5cc8101bb2b1..01af540b6ef9 100644
--- a/drivers/gpu/drm/i915/selftests/huge_pages.c
+++ b/drivers/gpu/drm/i915/selftests/huge_pages.c
@@ -1159,6 +1159,9 @@ static int igt_ppgtt_exhaust_huge(void *arg)
1159 int n, i; 1159 int n, i;
1160 int err = -ENODEV; 1160 int err = -ENODEV;
1161 1161
1162 if (supported == I915_GTT_PAGE_SIZE_4K)
1163 return 0;
1164
1162 /* 1165 /*
1163 * Sanity check creating objects with a varying mix of page sizes -- 1166 * Sanity check creating objects with a varying mix of page sizes --
1164 * ensuring that our writes lands in the right place. 1167 * ensuring that our writes lands in the right place.
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_coherency.c b/drivers/gpu/drm/i915/selftests/i915_gem_coherency.c
index 35d778d70626..7a0d1e17c1ad 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_coherency.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_coherency.c
@@ -33,7 +33,7 @@ static int cpu_set(struct drm_i915_gem_object *obj,
33{ 33{
34 unsigned int needs_clflush; 34 unsigned int needs_clflush;
35 struct page *page; 35 struct page *page;
36 typeof(v) *map; 36 u32 *map;
37 int err; 37 int err;
38 38
39 err = i915_gem_obj_prepare_shmem_write(obj, &needs_clflush); 39 err = i915_gem_obj_prepare_shmem_write(obj, &needs_clflush);
@@ -59,7 +59,7 @@ static int cpu_get(struct drm_i915_gem_object *obj,
59{ 59{
60 unsigned int needs_clflush; 60 unsigned int needs_clflush;
61 struct page *page; 61 struct page *page;
62 typeof(v) map; 62 u32 *map;
63 int err; 63 int err;
64 64
65 err = i915_gem_obj_prepare_shmem_read(obj, &needs_clflush); 65 err = i915_gem_obj_prepare_shmem_read(obj, &needs_clflush);
@@ -82,7 +82,7 @@ static int gtt_set(struct drm_i915_gem_object *obj,
82 u32 v) 82 u32 v)
83{ 83{
84 struct i915_vma *vma; 84 struct i915_vma *vma;
85 typeof(v) *map; 85 u32 __iomem *map;
86 int err; 86 int err;
87 87
88 err = i915_gem_object_set_to_gtt_domain(obj, true); 88 err = i915_gem_object_set_to_gtt_domain(obj, true);
@@ -98,7 +98,7 @@ static int gtt_set(struct drm_i915_gem_object *obj,
98 if (IS_ERR(map)) 98 if (IS_ERR(map))
99 return PTR_ERR(map); 99 return PTR_ERR(map);
100 100
101 map[offset / sizeof(*map)] = v; 101 iowrite32(v, &map[offset / sizeof(*map)]);
102 i915_vma_unpin_iomap(vma); 102 i915_vma_unpin_iomap(vma);
103 103
104 return 0; 104 return 0;
@@ -109,7 +109,7 @@ static int gtt_get(struct drm_i915_gem_object *obj,
109 u32 *v) 109 u32 *v)
110{ 110{
111 struct i915_vma *vma; 111 struct i915_vma *vma;
112 typeof(v) map; 112 u32 __iomem *map;
113 int err; 113 int err;
114 114
115 err = i915_gem_object_set_to_gtt_domain(obj, false); 115 err = i915_gem_object_set_to_gtt_domain(obj, false);
@@ -125,7 +125,7 @@ static int gtt_get(struct drm_i915_gem_object *obj,
125 if (IS_ERR(map)) 125 if (IS_ERR(map))
126 return PTR_ERR(map); 126 return PTR_ERR(map);
127 127
128 *v = map[offset / sizeof(*map)]; 128 *v = ioread32(&map[offset / sizeof(*map)]);
129 i915_vma_unpin_iomap(vma); 129 i915_vma_unpin_iomap(vma);
130 130
131 return 0; 131 return 0;
@@ -135,7 +135,7 @@ static int wc_set(struct drm_i915_gem_object *obj,
135 unsigned long offset, 135 unsigned long offset,
136 u32 v) 136 u32 v)
137{ 137{
138 typeof(v) *map; 138 u32 *map;
139 int err; 139 int err;
140 140
141 err = i915_gem_object_set_to_wc_domain(obj, true); 141 err = i915_gem_object_set_to_wc_domain(obj, true);
@@ -156,7 +156,7 @@ static int wc_get(struct drm_i915_gem_object *obj,
156 unsigned long offset, 156 unsigned long offset,
157 u32 *v) 157 u32 *v)
158{ 158{
159 typeof(v) map; 159 u32 *map;
160 int err; 160 int err;
161 161
162 err = i915_gem_object_set_to_wc_domain(obj, false); 162 err = i915_gem_object_set_to_wc_domain(obj, false);
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_context.c b/drivers/gpu/drm/i915/selftests/i915_gem_context.c
index def5052862ae..c82780a9d455 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_context.c
@@ -325,7 +325,7 @@ static int igt_ctx_exec(void *arg)
325 LIST_HEAD(objects); 325 LIST_HEAD(objects);
326 unsigned long ncontexts, ndwords, dw; 326 unsigned long ncontexts, ndwords, dw;
327 bool first_shared_gtt = true; 327 bool first_shared_gtt = true;
328 int err; 328 int err = -ENODEV;
329 329
330 /* Create a few different contexts (with different mm) and write 330 /* Create a few different contexts (with different mm) and write
331 * through each ctx/mm using the GPU making sure those writes end 331 * through each ctx/mm using the GPU making sure those writes end
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
index 9da0c9f99916..6491cf0a4f46 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
@@ -216,13 +216,21 @@ static int lowlevel_hole(struct drm_i915_private *i915,
216 hole_size = (hole_end - hole_start) >> size; 216 hole_size = (hole_end - hole_start) >> size;
217 if (hole_size > KMALLOC_MAX_SIZE / sizeof(u32)) 217 if (hole_size > KMALLOC_MAX_SIZE / sizeof(u32))
218 hole_size = KMALLOC_MAX_SIZE / sizeof(u32); 218 hole_size = KMALLOC_MAX_SIZE / sizeof(u32);
219 count = hole_size; 219 count = hole_size >> 1;
220 if (!count) {
221 pr_debug("%s: hole is too small [%llx - %llx] >> %d: %lld\n",
222 __func__, hole_start, hole_end, size, hole_size);
223 break;
224 }
225
220 do { 226 do {
221 count >>= 1;
222 order = i915_random_order(count, &prng); 227 order = i915_random_order(count, &prng);
223 } while (!order && count); 228 if (order)
224 if (!order) 229 break;
225 break; 230 } while (count >>= 1);
231 if (!count)
232 return -ENOMEM;
233 GEM_BUG_ON(!order);
226 234
227 GEM_BUG_ON(count * BIT_ULL(size) > vm->total); 235 GEM_BUG_ON(count * BIT_ULL(size) > vm->total);
228 GEM_BUG_ON(hole_start + count * BIT_ULL(size) > hole_end); 236 GEM_BUG_ON(hole_start + count * BIT_ULL(size) > hole_end);
@@ -267,7 +275,9 @@ static int lowlevel_hole(struct drm_i915_private *i915,
267 mock_vma.node.size = BIT_ULL(size); 275 mock_vma.node.size = BIT_ULL(size);
268 mock_vma.node.start = addr; 276 mock_vma.node.start = addr;
269 277
278 intel_runtime_pm_get(i915);
270 vm->insert_entries(vm, &mock_vma, I915_CACHE_NONE, 0); 279 vm->insert_entries(vm, &mock_vma, I915_CACHE_NONE, 0);
280 intel_runtime_pm_put(i915);
271 } 281 }
272 count = n; 282 count = n;
273 283
@@ -697,18 +707,26 @@ static int drunk_hole(struct drm_i915_private *i915,
697 unsigned int *order, count, n; 707 unsigned int *order, count, n;
698 struct i915_vma *vma; 708 struct i915_vma *vma;
699 u64 hole_size; 709 u64 hole_size;
700 int err; 710 int err = -ENODEV;
701 711
702 hole_size = (hole_end - hole_start) >> size; 712 hole_size = (hole_end - hole_start) >> size;
703 if (hole_size > KMALLOC_MAX_SIZE / sizeof(u32)) 713 if (hole_size > KMALLOC_MAX_SIZE / sizeof(u32))
704 hole_size = KMALLOC_MAX_SIZE / sizeof(u32); 714 hole_size = KMALLOC_MAX_SIZE / sizeof(u32);
705 count = hole_size; 715 count = hole_size >> 1;
716 if (!count) {
717 pr_debug("%s: hole is too small [%llx - %llx] >> %d: %lld\n",
718 __func__, hole_start, hole_end, size, hole_size);
719 break;
720 }
721
706 do { 722 do {
707 count >>= 1;
708 order = i915_random_order(count, &prng); 723 order = i915_random_order(count, &prng);
709 } while (!order && count); 724 if (order)
710 if (!order) 725 break;
711 break; 726 } while (count >>= 1);
727 if (!count)
728 return -ENOMEM;
729 GEM_BUG_ON(!order);
712 730
713 /* Ignore allocation failures (i.e. don't report them as 731 /* Ignore allocation failures (i.e. don't report them as
714 * a test failure) as we are purposefully allocating very 732 * a test failure) as we are purposefully allocating very
@@ -956,7 +974,7 @@ static int exercise_ggtt(struct drm_i915_private *i915,
956 u64 hole_start, hole_end, last = 0; 974 u64 hole_start, hole_end, last = 0;
957 struct drm_mm_node *node; 975 struct drm_mm_node *node;
958 IGT_TIMEOUT(end_time); 976 IGT_TIMEOUT(end_time);
959 int err; 977 int err = 0;
960 978
961 mutex_lock(&i915->drm.struct_mutex); 979 mutex_lock(&i915->drm.struct_mutex);
962restart: 980restart:
@@ -1047,6 +1065,7 @@ static int igt_ggtt_page(void *arg)
1047 goto out_remove; 1065 goto out_remove;
1048 } 1066 }
1049 1067
1068 intel_runtime_pm_get(i915);
1050 for (n = 0; n < count; n++) { 1069 for (n = 0; n < count; n++) {
1051 u64 offset = tmp.start + order[n] * PAGE_SIZE; 1070 u64 offset = tmp.start + order[n] * PAGE_SIZE;
1052 u32 __iomem *vaddr; 1071 u32 __iomem *vaddr;
@@ -1086,6 +1105,7 @@ static int igt_ggtt_page(void *arg)
1086 break; 1105 break;
1087 } 1106 }
1088 } 1107 }
1108 intel_runtime_pm_put(i915);
1089 1109
1090 kfree(order); 1110 kfree(order);
1091out_remove: 1111out_remove:
@@ -1160,7 +1180,7 @@ static int igt_gtt_reserve(void *arg)
1160 struct drm_i915_gem_object *obj, *on; 1180 struct drm_i915_gem_object *obj, *on;
1161 LIST_HEAD(objects); 1181 LIST_HEAD(objects);
1162 u64 total; 1182 u64 total;
1163 int err; 1183 int err = -ENODEV;
1164 1184
1165 /* i915_gem_gtt_reserve() tries to reserve the precise range 1185 /* i915_gem_gtt_reserve() tries to reserve the precise range
1166 * for the node, and evicts if it has to. So our test checks that 1186 * for the node, and evicts if it has to. So our test checks that
@@ -1351,7 +1371,7 @@ static int igt_gtt_insert(void *arg)
1351 }, *ii; 1371 }, *ii;
1352 LIST_HEAD(objects); 1372 LIST_HEAD(objects);
1353 u64 total; 1373 u64 total;
1354 int err; 1374 int err = -ENODEV;
1355 1375
1356 /* i915_gem_gtt_insert() tries to allocate some free space in the GTT 1376 /* i915_gem_gtt_insert() tries to allocate some free space in the GTT
1357 * to the node, evicting if required. 1377 * to the node, evicting if required.
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_object.c b/drivers/gpu/drm/i915/selftests/i915_gem_object.c
index 1b8774a42e48..f32aa6bb79e2 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_object.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_object.c
@@ -317,6 +317,7 @@ static int igt_partial_tiling(void *arg)
317 } 317 }
318 318
319 mutex_lock(&i915->drm.struct_mutex); 319 mutex_lock(&i915->drm.struct_mutex);
320 intel_runtime_pm_get(i915);
320 321
321 if (1) { 322 if (1) {
322 IGT_TIMEOUT(end); 323 IGT_TIMEOUT(end);
@@ -418,6 +419,7 @@ next_tiling: ;
418 } 419 }
419 420
420out_unlock: 421out_unlock:
422 intel_runtime_pm_put(i915);
421 mutex_unlock(&i915->drm.struct_mutex); 423 mutex_unlock(&i915->drm.struct_mutex);
422 i915_gem_object_unpin_pages(obj); 424 i915_gem_object_unpin_pages(obj);
423out: 425out:
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_request.c b/drivers/gpu/drm/i915/selftests/i915_gem_request.c
index a999161e8db1..6bce99050e94 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_request.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_request.c
@@ -332,7 +332,7 @@ static int live_nop_request(void *arg)
332 struct intel_engine_cs *engine; 332 struct intel_engine_cs *engine;
333 struct live_test t; 333 struct live_test t;
334 unsigned int id; 334 unsigned int id;
335 int err; 335 int err = -ENODEV;
336 336
337 /* Submit various sized batches of empty requests, to each engine 337 /* Submit various sized batches of empty requests, to each engine
338 * (individually), and wait for the batch to complete. We can check 338 * (individually), and wait for the batch to complete. We can check
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_timeline.c b/drivers/gpu/drm/i915/selftests/i915_gem_timeline.c
index 4795877abe56..3000e6a7d82d 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_timeline.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_timeline.c
@@ -79,7 +79,7 @@ static int igt_sync(void *arg)
79 }, *p; 79 }, *p;
80 struct intel_timeline *tl; 80 struct intel_timeline *tl;
81 int order, offset; 81 int order, offset;
82 int ret; 82 int ret = -ENODEV;
83 83
84 tl = mock_timeline(0); 84 tl = mock_timeline(0);
85 if (!tl) 85 if (!tl)
diff --git a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
index d7dd98a6acad..088f45bc6199 100644
--- a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
+++ b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
@@ -20,3 +20,4 @@ selftest(evict, i915_gem_evict_live_selftests)
20selftest(hugepages, i915_gem_huge_page_live_selftests) 20selftest(hugepages, i915_gem_huge_page_live_selftests)
21selftest(contexts, i915_gem_context_live_selftests) 21selftest(contexts, i915_gem_context_live_selftests)
22selftest(hangcheck, intel_hangcheck_live_selftests) 22selftest(hangcheck, intel_hangcheck_live_selftests)
23selftest(guc, intel_guc_live_selftest)
diff --git a/drivers/gpu/drm/i915/selftests/i915_syncmap.c b/drivers/gpu/drm/i915/selftests/i915_syncmap.c
index bcab3d00a785..47f4ae18a1ef 100644
--- a/drivers/gpu/drm/i915/selftests/i915_syncmap.c
+++ b/drivers/gpu/drm/i915/selftests/i915_syncmap.c
@@ -333,7 +333,7 @@ static int igt_syncmap_join_below(void *arg)
333{ 333{
334 struct i915_syncmap *sync; 334 struct i915_syncmap *sync;
335 unsigned int step, order, idx; 335 unsigned int step, order, idx;
336 int err; 336 int err = -ENODEV;
337 337
338 i915_syncmap_init(&sync); 338 i915_syncmap_init(&sync);
339 339
@@ -402,7 +402,7 @@ static int igt_syncmap_neighbours(void *arg)
402 I915_RND_STATE(prng); 402 I915_RND_STATE(prng);
403 IGT_TIMEOUT(end_time); 403 IGT_TIMEOUT(end_time);
404 struct i915_syncmap *sync; 404 struct i915_syncmap *sync;
405 int err; 405 int err = -ENODEV;
406 406
407 /* 407 /*
408 * Each leaf holds KSYNCMAP seqno. Check that when we create KSYNCMAP 408 * Each leaf holds KSYNCMAP seqno. Check that when we create KSYNCMAP
@@ -447,7 +447,7 @@ static int igt_syncmap_compact(void *arg)
447{ 447{
448 struct i915_syncmap *sync; 448 struct i915_syncmap *sync;
449 unsigned int idx, order; 449 unsigned int idx, order;
450 int err; 450 int err = -ENODEV;
451 451
452 i915_syncmap_init(&sync); 452 i915_syncmap_init(&sync);
453 453
diff --git a/drivers/gpu/drm/i915/selftests/i915_vma.c b/drivers/gpu/drm/i915/selftests/i915_vma.c
index 2e86ec136b35..eb89e301b602 100644
--- a/drivers/gpu/drm/i915/selftests/i915_vma.c
+++ b/drivers/gpu/drm/i915/selftests/i915_vma.c
@@ -150,7 +150,7 @@ static int igt_vma_create(void *arg)
150 IGT_TIMEOUT(end_time); 150 IGT_TIMEOUT(end_time);
151 LIST_HEAD(contexts); 151 LIST_HEAD(contexts);
152 LIST_HEAD(objects); 152 LIST_HEAD(objects);
153 int err; 153 int err = -ENOMEM;
154 154
155 /* Exercise creating many vma amonst many objections, checking the 155 /* Exercise creating many vma amonst many objections, checking the
156 * vma creation and lookup routines. 156 * vma creation and lookup routines.
diff --git a/drivers/gpu/drm/i915/selftests/intel_guc.c b/drivers/gpu/drm/i915/selftests/intel_guc.c
new file mode 100644
index 000000000000..f10029e18820
--- /dev/null
+++ b/drivers/gpu/drm/i915/selftests/intel_guc.c
@@ -0,0 +1,367 @@
1/*
2 * Copyright © 2017 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 */
24
25#include "../i915_selftest.h"
26
27/* max doorbell number + negative test for each client type */
28#define ATTEMPTS (GUC_NUM_DOORBELLS + GUC_CLIENT_PRIORITY_NUM)
29
30struct intel_guc_client *clients[ATTEMPTS];
31
32static bool available_dbs(struct intel_guc *guc, u32 priority)
33{
34 unsigned long offset;
35 unsigned long end;
36 u16 id;
37
38 /* first half is used for normal priority, second half for high */
39 offset = 0;
40 end = GUC_NUM_DOORBELLS / 2;
41 if (priority <= GUC_CLIENT_PRIORITY_HIGH) {
42 offset = end;
43 end += offset;
44 }
45
46 id = find_next_zero_bit(guc->doorbell_bitmap, end, offset);
47 if (id < end)
48 return true;
49
50 return false;
51}
52
53static int check_all_doorbells(struct intel_guc *guc)
54{
55 u16 db_id;
56
57 pr_info_once("Max number of doorbells: %d", GUC_NUM_DOORBELLS);
58 for (db_id = 0; db_id < GUC_NUM_DOORBELLS; ++db_id) {
59 if (!doorbell_ok(guc, db_id)) {
60 pr_err("doorbell %d, not ok\n", db_id);
61 return -EIO;
62 }
63 }
64
65 return 0;
66}
67
68/*
69 * Basic client sanity check, handy to validate create_clients.
70 */
71static int validate_client(struct intel_guc_client *client,
72 int client_priority,
73 bool is_preempt_client)
74{
75 struct drm_i915_private *dev_priv = guc_to_i915(client->guc);
76 struct i915_gem_context *ctx_owner = is_preempt_client ?
77 dev_priv->preempt_context : dev_priv->kernel_context;
78
79 if (client->owner != ctx_owner ||
80 client->engines != INTEL_INFO(dev_priv)->ring_mask ||
81 client->priority != client_priority ||
82 client->doorbell_id == GUC_DOORBELL_INVALID)
83 return -EINVAL;
84 else
85 return 0;
86}
87
88/*
89 * Check that guc_init_doorbell_hw is doing what it should.
90 *
91 * During GuC submission enable, we create GuC clients and their doorbells,
92 * but after resetting the microcontroller (resume & gpu reset), these
93 * GuC clients are still around, but the status of their doorbells may be
94 * incorrect. This is the reason behind validating that the doorbells status
95 * expected by the driver matches what the GuC/HW have.
96 */
97static int igt_guc_init_doorbell_hw(void *args)
98{
99 struct drm_i915_private *dev_priv = args;
100 struct intel_guc *guc;
101 DECLARE_BITMAP(db_bitmap_bk, GUC_NUM_DOORBELLS);
102 int i, err = 0;
103
104 GEM_BUG_ON(!HAS_GUC(dev_priv));
105 mutex_lock(&dev_priv->drm.struct_mutex);
106
107 guc = &dev_priv->guc;
108 if (!guc) {
109 pr_err("No guc object!\n");
110 err = -EINVAL;
111 goto unlock;
112 }
113
114 err = check_all_doorbells(guc);
115 if (err)
116 goto unlock;
117
118 /*
119 * Get rid of clients created during driver load because the test will
120 * recreate them.
121 */
122 guc_clients_destroy(guc);
123 if (guc->execbuf_client || guc->preempt_client) {
124 pr_err("guc_clients_destroy lied!\n");
125 err = -EINVAL;
126 goto unlock;
127 }
128
129 err = guc_clients_create(guc);
130 if (err) {
131 pr_err("Failed to create clients\n");
132 goto unlock;
133 }
134
135 err = validate_client(guc->execbuf_client,
136 GUC_CLIENT_PRIORITY_KMD_NORMAL, false);
137 if (err) {
138 pr_err("execbug client validation failed\n");
139 goto out;
140 }
141
142 err = validate_client(guc->preempt_client,
143 GUC_CLIENT_PRIORITY_KMD_HIGH, true);
144 if (err) {
145 pr_err("preempt client validation failed\n");
146 goto out;
147 }
148
149 /* each client should have received a doorbell during alloc */
150 if (!has_doorbell(guc->execbuf_client) ||
151 !has_doorbell(guc->preempt_client)) {
152 pr_err("guc_clients_create didn't create doorbells\n");
153 err = -EINVAL;
154 goto out;
155 }
156
157 /*
158 * Basic test - an attempt to reallocate a valid doorbell to the
159 * client it is currently assigned should not cause a failure.
160 */
161 err = guc_init_doorbell_hw(guc);
162 if (err)
163 goto out;
164
165 /*
166 * Negative test - a client with no doorbell (invalid db id).
167 * Each client gets a doorbell when it is created, after destroying
168 * the doorbell, the db id is changed to GUC_DOORBELL_INVALID and the
169 * firmware will reject any attempt to allocate a doorbell with an
170 * invalid id (db has to be reserved before allocation).
171 */
172 destroy_doorbell(guc->execbuf_client);
173 if (has_doorbell(guc->execbuf_client)) {
174 pr_err("destroy db did not work\n");
175 err = -EINVAL;
176 goto out;
177 }
178
179 err = guc_init_doorbell_hw(guc);
180 if (err != -EIO) {
181 pr_err("unexpected (err = %d)", err);
182 goto out;
183 }
184
185 if (!available_dbs(guc, guc->execbuf_client->priority)) {
186 pr_err("doorbell not available when it should\n");
187 err = -EIO;
188 goto out;
189 }
190
191 /* clean after test */
192 err = create_doorbell(guc->execbuf_client);
193 if (err) {
194 pr_err("recreate doorbell failed\n");
195 goto out;
196 }
197
198 /*
199 * Negative test - doorbell_bitmap out of sync, will trigger a few of
200 * WARN_ON(!doorbell_ok(guc, db_id)) but that's ok as long as the
201 * doorbells from our clients don't fail.
202 */
203 bitmap_copy(db_bitmap_bk, guc->doorbell_bitmap, GUC_NUM_DOORBELLS);
204 for (i = 0; i < GUC_NUM_DOORBELLS; i++)
205 if (i % 2)
206 test_and_change_bit(i, guc->doorbell_bitmap);
207
208 err = guc_init_doorbell_hw(guc);
209 if (err) {
210 pr_err("out of sync doorbell caused an error\n");
211 goto out;
212 }
213
214 /* restore 'correct' db bitmap */
215 bitmap_copy(guc->doorbell_bitmap, db_bitmap_bk, GUC_NUM_DOORBELLS);
216 err = guc_init_doorbell_hw(guc);
217 if (err) {
218 pr_err("restored doorbell caused an error\n");
219 goto out;
220 }
221
222out:
223 /*
224 * Leave clean state for other test, plus the driver always destroy the
225 * clients during unload.
226 */
227 guc_clients_destroy(guc);
228 guc_clients_create(guc);
229unlock:
230 mutex_unlock(&dev_priv->drm.struct_mutex);
231 return err;
232}
233
234/*
235 * Create as many clients as number of doorbells. Note that there's already
236 * client(s)/doorbell(s) created during driver load, but this test creates
237 * its own and do not interact with the existing ones.
238 */
239static int igt_guc_doorbells(void *arg)
240{
241 struct drm_i915_private *dev_priv = arg;
242 struct intel_guc *guc;
243 int i, err = 0;
244 u16 db_id;
245
246 GEM_BUG_ON(!HAS_GUC(dev_priv));
247 mutex_lock(&dev_priv->drm.struct_mutex);
248
249 guc = &dev_priv->guc;
250 if (!guc) {
251 pr_err("No guc object!\n");
252 err = -EINVAL;
253 goto unlock;
254 }
255
256 err = check_all_doorbells(guc);
257 if (err)
258 goto unlock;
259
260 for (i = 0; i < ATTEMPTS; i++) {
261 clients[i] = guc_client_alloc(dev_priv,
262 INTEL_INFO(dev_priv)->ring_mask,
263 i % GUC_CLIENT_PRIORITY_NUM,
264 dev_priv->kernel_context);
265
266 if (!clients[i]) {
267 pr_err("[%d] No guc client\n", i);
268 err = -EINVAL;
269 goto out;
270 }
271
272 if (IS_ERR(clients[i])) {
273 if (PTR_ERR(clients[i]) != -ENOSPC) {
274 pr_err("[%d] unexpected error\n", i);
275 err = PTR_ERR(clients[i]);
276 goto out;
277 }
278
279 if (available_dbs(guc, i % GUC_CLIENT_PRIORITY_NUM)) {
280 pr_err("[%d] non-db related alloc fail\n", i);
281 err = -EINVAL;
282 goto out;
283 }
284
285 /* expected, ran out of dbs for this client type */
286 continue;
287 }
288
289 /*
290 * The check below is only valid because we keep a doorbell
291 * assigned during the whole life of the client.
292 */
293 if (clients[i]->stage_id >= GUC_NUM_DOORBELLS) {
294 pr_err("[%d] more clients than doorbells (%d >= %d)\n",
295 i, clients[i]->stage_id, GUC_NUM_DOORBELLS);
296 err = -EINVAL;
297 goto out;
298 }
299
300 err = validate_client(clients[i],
301 i % GUC_CLIENT_PRIORITY_NUM, false);
302 if (err) {
303 pr_err("[%d] client_alloc sanity check failed!\n", i);
304 err = -EINVAL;
305 goto out;
306 }
307
308 db_id = clients[i]->doorbell_id;
309
310 /*
311 * Client alloc gives us a doorbell, but we want to exercise
312 * this ourselves (this resembles guc_init_doorbell_hw)
313 */
314 destroy_doorbell(clients[i]);
315 if (clients[i]->doorbell_id != GUC_DOORBELL_INVALID) {
316 pr_err("[%d] destroy db did not work!\n", i);
317 err = -EINVAL;
318 goto out;
319 }
320
321 err = __reserve_doorbell(clients[i]);
322 if (err) {
323 pr_err("[%d] Failed to reserve a doorbell\n", i);
324 goto out;
325 }
326
327 __update_doorbell_desc(clients[i], clients[i]->doorbell_id);
328 err = __create_doorbell(clients[i]);
329 if (err) {
330 pr_err("[%d] Failed to create a doorbell\n", i);
331 goto out;
332 }
333
334 /* doorbell id shouldn't change, we are holding the mutex */
335 if (db_id != clients[i]->doorbell_id) {
336 pr_err("[%d] doorbell id changed (%d != %d)\n",
337 i, db_id, clients[i]->doorbell_id);
338 err = -EINVAL;
339 goto out;
340 }
341
342 err = check_all_doorbells(guc);
343 if (err)
344 goto out;
345 }
346
347out:
348 for (i = 0; i < ATTEMPTS; i++)
349 if (!IS_ERR_OR_NULL(clients[i]))
350 guc_client_free(clients[i]);
351unlock:
352 mutex_unlock(&dev_priv->drm.struct_mutex);
353 return err;
354}
355
356int intel_guc_live_selftest(struct drm_i915_private *dev_priv)
357{
358 static const struct i915_subtest tests[] = {
359 SUBTEST(igt_guc_init_doorbell_hw),
360 SUBTEST(igt_guc_doorbells),
361 };
362
363 if (!i915_modparams.enable_guc_submission)
364 return 0;
365
366 return i915_subtests(tests, dev_priv);
367}
diff --git a/drivers/gpu/drm/i915/selftests/intel_uncore.c b/drivers/gpu/drm/i915/selftests/intel_uncore.c
index 3cac22eb47ce..2f6367643171 100644
--- a/drivers/gpu/drm/i915/selftests/intel_uncore.c
+++ b/drivers/gpu/drm/i915/selftests/intel_uncore.c
@@ -120,10 +120,10 @@ static int intel_uncore_check_forcewake_domains(struct drm_i915_private *dev_pri
120 !IS_CHERRYVIEW(dev_priv)) 120 !IS_CHERRYVIEW(dev_priv))
121 return 0; 121 return 0;
122 122
123 if (IS_VALLEYVIEW(dev_priv)) /* XXX system lockup! */ 123 /*
124 return 0; 124 * This test may lockup the machine or cause GPU hangs afterwards.
125 125 */
126 if (IS_BROADWELL(dev_priv)) /* XXX random GPU hang afterwards! */ 126 if (!IS_ENABLED(CONFIG_DRM_I915_SELFTEST_BROKEN))
127 return 0; 127 return 0;
128 128
129 valid = kzalloc(BITS_TO_LONGS(FW_RANGE) * sizeof(*valid), 129 valid = kzalloc(BITS_TO_LONGS(FW_RANGE) * sizeof(*valid),
@@ -148,7 +148,10 @@ static int intel_uncore_check_forcewake_domains(struct drm_i915_private *dev_pri
148 for_each_set_bit(offset, valid, FW_RANGE) { 148 for_each_set_bit(offset, valid, FW_RANGE) {
149 i915_reg_t reg = { offset }; 149 i915_reg_t reg = { offset };
150 150
151 iosf_mbi_punit_acquire();
151 intel_uncore_forcewake_reset(dev_priv, false); 152 intel_uncore_forcewake_reset(dev_priv, false);
153 iosf_mbi_punit_release();
154
152 check_for_unclaimed_mmio(dev_priv); 155 check_for_unclaimed_mmio(dev_priv);
153 156
154 (void)I915_READ(reg); 157 (void)I915_READ(reg);
diff --git a/drivers/gpu/drm/i915/selftests/mock_engine.c b/drivers/gpu/drm/i915/selftests/mock_engine.c
index 331c2b09869e..55c0e2c15782 100644
--- a/drivers/gpu/drm/i915/selftests/mock_engine.c
+++ b/drivers/gpu/drm/i915/selftests/mock_engine.c
@@ -32,6 +32,13 @@ static struct mock_request *first_request(struct mock_engine *engine)
32 link); 32 link);
33} 33}
34 34
35static void advance(struct mock_engine *engine,
36 struct mock_request *request)
37{
38 list_del_init(&request->link);
39 mock_seqno_advance(&engine->base, request->base.global_seqno);
40}
41
35static void hw_delay_complete(struct timer_list *t) 42static void hw_delay_complete(struct timer_list *t)
36{ 43{
37 struct mock_engine *engine = from_timer(engine, t, hw_delay); 44 struct mock_engine *engine = from_timer(engine, t, hw_delay);
@@ -39,15 +46,23 @@ static void hw_delay_complete(struct timer_list *t)
39 46
40 spin_lock(&engine->hw_lock); 47 spin_lock(&engine->hw_lock);
41 48
42 request = first_request(engine); 49 /* Timer fired, first request is complete */
43 if (request) {
44 list_del_init(&request->link);
45 mock_seqno_advance(&engine->base, request->base.global_seqno);
46 }
47
48 request = first_request(engine); 50 request = first_request(engine);
49 if (request) 51 if (request)
50 mod_timer(&engine->hw_delay, jiffies + request->delay); 52 advance(engine, request);
53
54 /*
55 * Also immediately signal any subsequent 0-delay requests, but
56 * requeue the timer for the next delayed request.
57 */
58 while ((request = first_request(engine))) {
59 if (request->delay) {
60 mod_timer(&engine->hw_delay, jiffies + request->delay);
61 break;
62 }
63
64 advance(engine, request);
65 }
51 66
52 spin_unlock(&engine->hw_lock); 67 spin_unlock(&engine->hw_lock);
53} 68}
@@ -98,16 +113,22 @@ static void mock_submit_request(struct drm_i915_gem_request *request)
98 113
99 spin_lock_irq(&engine->hw_lock); 114 spin_lock_irq(&engine->hw_lock);
100 list_add_tail(&mock->link, &engine->hw_queue); 115 list_add_tail(&mock->link, &engine->hw_queue);
101 if (mock->link.prev == &engine->hw_queue) 116 if (mock->link.prev == &engine->hw_queue) {
102 mod_timer(&engine->hw_delay, jiffies + mock->delay); 117 if (mock->delay)
118 mod_timer(&engine->hw_delay, jiffies + mock->delay);
119 else
120 advance(engine, mock);
121 }
103 spin_unlock_irq(&engine->hw_lock); 122 spin_unlock_irq(&engine->hw_lock);
104} 123}
105 124
106static struct intel_ring *mock_ring(struct intel_engine_cs *engine) 125static struct intel_ring *mock_ring(struct intel_engine_cs *engine)
107{ 126{
108 const unsigned long sz = roundup_pow_of_two(sizeof(struct intel_ring)); 127 const unsigned long sz = PAGE_SIZE / 2;
109 struct intel_ring *ring; 128 struct intel_ring *ring;
110 129
130 BUILD_BUG_ON(MIN_SPACE_FOR_ADD_REQUEST > sz);
131
111 ring = kzalloc(sizeof(*ring) + sz, GFP_KERNEL); 132 ring = kzalloc(sizeof(*ring) + sz, GFP_KERNEL);
112 if (!ring) 133 if (!ring)
113 return NULL; 134 return NULL;
diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
index 04eb9362f4f8..80f152aaedf9 100644
--- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
+++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
@@ -179,8 +179,8 @@ struct drm_i915_private *mock_gem_device(void)
179 I915_GTT_PAGE_SIZE_64K | 179 I915_GTT_PAGE_SIZE_64K |
180 I915_GTT_PAGE_SIZE_2M; 180 I915_GTT_PAGE_SIZE_2M;
181 181
182 spin_lock_init(&i915->mm.object_stat_lock);
183 mock_uncore_init(i915); 182 mock_uncore_init(i915);
183 i915_gem_init__mm(i915);
184 184
185 init_waitqueue_head(&i915->gpu_error.wait_queue); 185 init_waitqueue_head(&i915->gpu_error.wait_queue);
186 init_waitqueue_head(&i915->gpu_error.reset_queue); 186 init_waitqueue_head(&i915->gpu_error.reset_queue);
@@ -189,11 +189,6 @@ struct drm_i915_private *mock_gem_device(void)
189 if (!i915->wq) 189 if (!i915->wq)
190 goto put_device; 190 goto put_device;
191 191
192 INIT_WORK(&i915->mm.free_work, __i915_gem_free_work);
193 init_llist_head(&i915->mm.free_list);
194 INIT_LIST_HEAD(&i915->mm.unbound_list);
195 INIT_LIST_HEAD(&i915->mm.bound_list);
196
197 mock_init_contexts(i915); 192 mock_init_contexts(i915);
198 193
199 INIT_DELAYED_WORK(&i915->gt.retire_work, mock_retire_work_handler); 194 INIT_DELAYED_WORK(&i915->gt.retire_work, mock_retire_work_handler);