diff options
| author | Dave Airlie <airlied@redhat.com> | 2017-12-03 18:40:35 -0500 |
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2017-12-03 19:56:53 -0500 |
| commit | ca797d29cd63e7b71b4eea29aff3b1cefd1ecb59 (patch) | |
| tree | db1ada69f713da68b43c828bd15f90e250f86ab7 /drivers/gpu/drm/i915/selftests | |
| parent | 2c1c55cb75a9c72f9726fabb8c3607947711a8df (diff) | |
| parent | 010d118c20617021025a930bc8e90f371ab99da5 (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.c | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/selftests/i915_gem_coherency.c | 16 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/selftests/i915_gem_context.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | 48 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/selftests/i915_gem_object.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/selftests/i915_gem_request.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/selftests/i915_gem_timeline.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/selftests/i915_live_selftests.h | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/selftests/i915_syncmap.c | 6 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/selftests/i915_vma.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/selftests/intel_guc.c | 367 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/selftests/intel_uncore.c | 11 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/selftests/mock_engine.c | 41 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/selftests/mock_gem_device.c | 7 |
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); |
| 962 | restart: | 980 | restart: |
| @@ -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); |
| 1091 | out_remove: | 1111 | out_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 | ||
| 420 | out_unlock: | 421 | out_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); |
| 423 | out: | 425 | out: |
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) | |||
| 20 | selftest(hugepages, i915_gem_huge_page_live_selftests) | 20 | selftest(hugepages, i915_gem_huge_page_live_selftests) |
| 21 | selftest(contexts, i915_gem_context_live_selftests) | 21 | selftest(contexts, i915_gem_context_live_selftests) |
| 22 | selftest(hangcheck, intel_hangcheck_live_selftests) | 22 | selftest(hangcheck, intel_hangcheck_live_selftests) |
| 23 | selftest(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 | |||
| 30 | struct intel_guc_client *clients[ATTEMPTS]; | ||
| 31 | |||
| 32 | static 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 | |||
| 53 | static 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 | */ | ||
| 71 | static 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 | */ | ||
| 97 | static 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 | |||
| 222 | out: | ||
| 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); | ||
| 229 | unlock: | ||
| 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 | */ | ||
| 239 | static 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 | |||
| 347 | out: | ||
| 348 | for (i = 0; i < ATTEMPTS; i++) | ||
| 349 | if (!IS_ERR_OR_NULL(clients[i])) | ||
| 350 | guc_client_free(clients[i]); | ||
| 351 | unlock: | ||
| 352 | mutex_unlock(&dev_priv->drm.struct_mutex); | ||
| 353 | return err; | ||
| 354 | } | ||
| 355 | |||
| 356 | int 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 | ||
| 35 | static 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 | |||
| 35 | static void hw_delay_complete(struct timer_list *t) | 42 | static 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 | ||
| 106 | static struct intel_ring *mock_ring(struct intel_engine_cs *engine) | 125 | static 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); |
