History

Merge tag 'topic/i915-gem-next-2021-03-26' of ssh://git.freedesktop.org/git/drm/drm into drm-next

special i915-gem-next pull as requested - Conversion to dma_resv_locking, obj->mm.lock is gone (Maarten, with help from Thomas Hellström) - watchdog (Tvrtko, one patch to cancel individual request from Chris) - legacy ioctl cleanup (Jason+Ashutosh) - i915-gem TODO and RFC process doc (me) - i915_ prefix for vma_lookup (Liam Howlett) just because I spotted it and put it in here too Signed-off-by: Dave Airlie <airlied@redhat.com>

Dave Airlie committed 5 years ago

Commit 2f835b52 parents fe8a057 e1a5e6a117 files · +2749 −2165Browse files

Unified · Split

117 files
  1. Documentation/gpu/index.rst +1 −0
  2. Documentation/gpu/rfc/index.rst +17 −0
  3. drivers/gpu/drm/i915/Kconfig.profile +14 −0
  4. drivers/gpu/drm/i915/Makefile +0 −1
  5. drivers/gpu/drm/i915/TODO.txt +41 −0
  6. drivers/gpu/drm/i915/display/intel_display.c +44 −27
  7. drivers/gpu/drm/i915/display/intel_display.h +1 −1
  8. drivers/gpu/drm/i915/display/intel_dsb.c +1 −1
  9. drivers/gpu/drm/i915/display/intel_fbdev.c +1 −1
  10. drivers/gpu/drm/i915/display/intel_overlay.c +29 −5
  11. drivers/gpu/drm/i915/gem/i915_gem_clflush.c +7 −8
  12. drivers/gpu/drm/i915/gem/i915_gem_context.c +40 −33
  13. drivers/gpu/drm/i915/gem/i915_gem_context_types.h +4 −0
  14. drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c +35 −29
  15. drivers/gpu/drm/i915/gem/i915_gem_domain.c +39 −33
  16. drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c +204 −131
  17. drivers/gpu/drm/i915/gem/i915_gem_fence.c +0 −95
  18. drivers/gpu/drm/i915/gem/i915_gem_internal.c +3 −3
  19. drivers/gpu/drm/i915/gem/i915_gem_ioctls.h +0 −2
  20. drivers/gpu/drm/i915/gem/i915_gem_lmem.c +2 −2
  21. drivers/gpu/drm/i915/gem/i915_gem_mman.c +29 −6
  22. drivers/gpu/drm/i915/gem/i915_gem_object.c +3 −7
  23. drivers/gpu/drm/i915/gem/i915_gem_object.h +60 −36
  24. drivers/gpu/drm/i915/gem/i915_gem_object_blt.c +6 −0
  25. drivers/gpu/drm/i915/gem/i915_gem_object_types.h +14 −9
  26. drivers/gpu/drm/i915/gem/i915_gem_pages.c +69 −40
  27. drivers/gpu/drm/i915/gem/i915_gem_phys.c +47 −63
  28. drivers/gpu/drm/i915/gem/i915_gem_pm.c +1 −1
  29. drivers/gpu/drm/i915/gem/i915_gem_region.c +1 −3
  30. drivers/gpu/drm/i915/gem/i915_gem_region.h +1 −2
  31. drivers/gpu/drm/i915/gem/i915_gem_shmem.c +31 −8
  32. drivers/gpu/drm/i915/gem/i915_gem_shrinker.c +28 −11
  33. drivers/gpu/drm/i915/gem/i915_gem_shrinker.h +3 −1
  34. drivers/gpu/drm/i915/gem/i915_gem_stolen.c +8 −6
  35. drivers/gpu/drm/i915/gem/i915_gem_tiling.c +0 −2
  36. drivers/gpu/drm/i915/gem/i915_gem_userptr.c +320 −582
  37. drivers/gpu/drm/i915/gem/selftests/huge_gem_object.c +2 −2
  38. drivers/gpu/drm/i915/gem/selftests/huge_pages.c +26 −12
  39. drivers/gpu/drm/i915/gem/selftests/i915_gem_client_blt.c +4 −4
  40. drivers/gpu/drm/i915/gem/selftests/i915_gem_coherency.c +6 −8
  41. drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c +5 −5
  42. drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c +1 −1
  43. drivers/gpu/drm/i915/gem/selftests/i915_gem_execbuffer.c +1 −1
  44. drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c +10 −11
  45. drivers/gpu/drm/i915/gem/selftests/i915_gem_object.c +1 −1
  46. drivers/gpu/drm/i915/gem/selftests/i915_gem_object_blt.c +3 −3
  47. drivers/gpu/drm/i915/gem/selftests/i915_gem_phys.c +9 −1
  48. drivers/gpu/drm/i915/gem/selftests/igt_gem_utils.c +1 −1
  49. drivers/gpu/drm/i915/gt/gen2_engine_cs.c +1 −1
  50. drivers/gpu/drm/i915/gt/gen6_engine_cs.c +4 −4
  51. drivers/gpu/drm/i915/gt/gen8_engine_cs.c +6 −7
  52. drivers/gpu/drm/i915/gt/intel_context_param.h +10 −1
  53. drivers/gpu/drm/i915/gt/intel_context_types.h +4 −0
  54. drivers/gpu/drm/i915/gt/intel_engine_cs.c +25 −13
  55. drivers/gpu/drm/i915/gt/intel_engine_heartbeat.c +1 −0
  56. drivers/gpu/drm/i915/gt/intel_engine_pm.c +4 −0
  57. drivers/gpu/drm/i915/gt/intel_execlists_submission.c +39 −10
  58. drivers/gpu/drm/i915/gt/intel_execlists_submission.h +2 −0
  59. drivers/gpu/drm/i915/gt/intel_ggtt.c +8 −2
  60. drivers/gpu/drm/i915/gt/intel_gt.c +3 −0
  61. drivers/gpu/drm/i915/gt/intel_gt.h +2 −0
  62. drivers/gpu/drm/i915/gt/intel_gt_buffer_pool.c +21 −26
  63. drivers/gpu/drm/i915/gt/intel_gt_buffer_pool.h +5 −0
  64. drivers/gpu/drm/i915/gt/intel_gt_buffer_pool_types.h +1 −0
  65. drivers/gpu/drm/i915/gt/intel_gt_requests.c +28 −0
  66. drivers/gpu/drm/i915/gt/intel_gt_types.h +7 −4
  67. drivers/gpu/drm/i915/gt/intel_gtt.c +50 −2
  68. drivers/gpu/drm/i915/gt/intel_gtt.h +8 −0
  69. drivers/gpu/drm/i915/gt/intel_lrc.c +38 −11
  70. drivers/gpu/drm/i915/gt/intel_ppgtt.c +2 −1
  71. drivers/gpu/drm/i915/gt/intel_renderstate.c +1 −1
  72. drivers/gpu/drm/i915/gt/intel_reset.c +7 −2
  73. drivers/gpu/drm/i915/gt/intel_ring_submission.c +118 −66
  74. drivers/gpu/drm/i915/gt/intel_timeline.c +94 −332
  75. drivers/gpu/drm/i915/gt/intel_timeline.h +2 −0
  76. drivers/gpu/drm/i915/gt/intel_timeline_types.h +3 −14
  77. drivers/gpu/drm/i915/gt/intel_workarounds.c +8 −2
  78. drivers/gpu/drm/i915/gt/mock_engine.c +20 −2
  79. drivers/gpu/drm/i915/gt/selftest_context.c +2 −2
  80. drivers/gpu/drm/i915/gt/selftest_engine_cs.c +6 −3
  81. drivers/gpu/drm/i915/gt/selftest_execlists.c +12 −11
  82. drivers/gpu/drm/i915/gt/selftest_hangcheck.c +4 −4
  83. drivers/gpu/drm/i915/gt/selftest_lrc.c +9 −9
  84. drivers/gpu/drm/i915/gt/selftest_mocs.c +3 −2
  85. drivers/gpu/drm/i915/gt/selftest_ring_submission.c +2 −2
  86. drivers/gpu/drm/i915/gt/selftest_timeline.c +109 −68
  87. drivers/gpu/drm/i915/gt/selftest_workarounds.c +52 −30
  88. drivers/gpu/drm/i915/gt/shmem_utils.c +1 −1
  89. drivers/gpu/drm/i915/gt/uc/intel_guc.c +1 −1
  90. drivers/gpu/drm/i915/gt/uc/intel_guc_log.c +2 −2
  91. drivers/gpu/drm/i915/gt/uc/intel_huc.c +1 −1
  92. drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c +1 −1
  93. drivers/gpu/drm/i915/gvt/dmabuf.c +1 −1
  94. drivers/gpu/drm/i915/i915_active.c +10 −10
  95. drivers/gpu/drm/i915/i915_cmd_parser.c +43 −61
  96. drivers/gpu/drm/i915/i915_debugfs.c +2 −2
  97. drivers/gpu/drm/i915/i915_drv.c +1 −1
  98. drivers/gpu/drm/i915/i915_drv.h +11 −7
  99. drivers/gpu/drm/i915/i915_gem.c +141 −117
  100. drivers/gpu/drm/i915/i915_gem_gtt.c +1 −1
  101. drivers/gpu/drm/i915/i915_memcpy.c +1 −1
  102. drivers/gpu/drm/i915/i915_memcpy.h +1 −1
  103. drivers/gpu/drm/i915/i915_params.c +5 −0
  104. drivers/gpu/drm/i915/i915_params.h +1 −0
  105. drivers/gpu/drm/i915/i915_perf.c +43 −13
  106. drivers/gpu/drm/i915/i915_request.c +126 −7
  107. drivers/gpu/drm/i915/i915_request.h +36 −11
  108. drivers/gpu/drm/i915/i915_selftest.h +2 −0
  109. drivers/gpu/drm/i915/i915_vma.c +22 −8
  110. drivers/gpu/drm/i915/i915_vma.h +19 −1
  111. drivers/gpu/drm/i915/selftests/i915_gem_gtt.c +68 −26
  112. drivers/gpu/drm/i915/selftests/i915_request.c +206 −5
  113. drivers/gpu/drm/i915/selftests/igt_spinner.c +90 −46
  114. drivers/gpu/drm/i915/selftests/igt_spinner.h +5 −0
  115. drivers/gpu/drm/i915/selftests/intel_memory_region.c +11 −7
  116. drivers/gpu/drm/i915/selftests/mock_region.c +2 −2
  117. include/uapi/drm/i915_drm.h +1 −0
Documentation/gpu/index.rst+1−0
@@ -16,6 +16,7 @@ Linux GPU Driver Developer's Guide · 15 unmodified lines
16 vga-switcheroo16 vga-switcheroo
17 vgaarbiter17 vgaarbiter
18 todo18 todo
19 rfc/index
19 20
20.. only:: subproject and html21.. only:: subproject and html
21 22
Documentation/gpu/rfc/index.rst+17−0
@@ -0,0 +1,17 @@
1===============
2GPU RFC Section
3===============
4
5For complex work, especially new uapi, it is often good to nail the high level
6design issues before getting lost in the code details. This section is meant to
7host such documentation:
8
9* Each RFC should be a section in this file, explaining the goal and main design
10 considerations. Especially for uapi make sure you Cc: all relevant project
11 mailing lists and involved people outside of dri-devel.
12
13* For uapi structures add a file to this directory with and then pull the
14 kerneldoc in like with real uapi headers.
15
16* Once the code has landed move all the documentation to the right places in
17 the main core, helper or driver sections.
drivers/gpu/drm/i915/Kconfig.profile+14−0
@@ -1,3 +1,17 @@
1config DRM_I915_REQUEST_TIMEOUT
2 int "Default timeout for requests (ms)"
3 default 20000 # milliseconds
4 help
5 Configures the default timeout after which any user submissions will
6 be forcefully terminated.
7
8 Beware setting this value lower, or close to heartbeat interval
9 rounded to whole seconds times three, in order to avoid allowing
10 misbehaving applications causing total rendering failure in unrelated
11 clients.
12
13 May be 0 to disable the timeout.
14
1config DRM_I915_FENCE_TIMEOUT15config DRM_I915_FENCE_TIMEOUT
2 int "Timeout for unsignaled foreign fences (ms, jiffy granularity)"16 int "Timeout for unsignaled foreign fences (ms, jiffy granularity)"
3 default 10000 # milliseconds17 default 10000 # milliseconds
drivers/gpu/drm/i915/Makefile+0−1
@@ -139,7 +139,6 @@ gem-y += \ · 138 unmodified lines
139 gem/i915_gem_dmabuf.o \139 gem/i915_gem_dmabuf.o \
140 gem/i915_gem_domain.o \140 gem/i915_gem_domain.o \
141 gem/i915_gem_execbuffer.o \141 gem/i915_gem_execbuffer.o \
142 gem/i915_gem_fence.o \
143 gem/i915_gem_internal.o \142 gem/i915_gem_internal.o \
144 gem/i915_gem_object.o \143 gem/i915_gem_object.o \
145 gem/i915_gem_object_blt.o \144 gem/i915_gem_object_blt.o \
drivers/gpu/drm/i915/TODO.txt+41−0
@@ -0,0 +1,41 @@
1gem/gt TODO items
2-----------------
3
4- For discrete memory manager, merge enough dg1 to be able to refactor it to
5 TTM. Then land pci ids (just in case that turns up an uapi problem). TTM has
6 improved a lot the past 2 years, there's no reason anymore not to use it.
7
8- Come up with a plan what to do with drm/scheduler and how to get there.
9
10- Roll out dma_fence critical section annotations.
11
12- There's a lot of complexity added past few years to make relocations faster.
13 That doesn't make sense given hw and gpu apis moved away from this model years
14 ago:
15 1. Land a modern pre-bound uapi like VM_BIND
16 2. Any complexity added in this area past few years which can't be justified
17 with VM_BIND using userspace should be removed. Looking at amdgpu dma_resv on
18 the bo and vm, plus some lru locks is all that needed. No complex rcu,
19 refcounts, caching, ... on everything.
20 This is the matching task on the vm side compared to ttm/dma_resv on the
21 backing storage side.
22
23- i915_sw_fence seems to be the main structure for the i915-gem dma_fence model.
24 How-to-dma_fence is core and drivers really shouldn't build their own world
25 here, treating everything else as a fixed platform. i915_sw_fence concepts
26 should be moved to dma_fence, drm/scheduler or atomic commit helpers. Or
27 removed if dri-devel consensus is that it's not a good idea. Once that's done
28 maybe even remove it if there's nothing left.
29
30Smaller things:
31- i915_utils.h needs to be moved to the right places.
32
33- dma_fence_work should be in drivers/dma-buf
34
35- i915_mm.c should be moved to the right places. Some of the helpers also look a
36 bit fishy:
37
38 https://lore.kernel.org/linux-mm/20210301083320.943079-1-hch@lst.de/
39
40- tasklet helpers in i915_gem.h also look a bit misplaced and should
41 probably be moved to tasklet headers.
drivers/gpu/drm/i915/display/intel_display.c+44−27
@@ -1091,6 +1091,7 @@ static bool intel_plane_uses_fence(const struct intel_plane_state *plane_state) · 1090 unmodified lines
1091 1091
1092struct i915_vma *1092struct i915_vma *
1093intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb,1093intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb,
1094 bool phys_cursor,
1094 const struct i915_ggtt_view *view,1095 const struct i915_ggtt_view *view,
1095 bool uses_fence,1096 bool uses_fence,
1096 unsigned long *out_flags)1097 unsigned long *out_flags)
@@ -1099,14 +1100,19 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, · 2 unmodified lines
1099 struct drm_i915_private *dev_priv = to_i915(dev);1100 struct drm_i915_private *dev_priv = to_i915(dev);
1100 struct drm_i915_gem_object *obj = intel_fb_obj(fb);1101 struct drm_i915_gem_object *obj = intel_fb_obj(fb);
1101 intel_wakeref_t wakeref;1102 intel_wakeref_t wakeref;
1103 struct i915_gem_ww_ctx ww;
1102 struct i915_vma *vma;1104 struct i915_vma *vma;
1103 unsigned int pinctl;1105 unsigned int pinctl;
1104 u32 alignment;1106 u32 alignment;
1107 int ret;
1105 1108
1106 if (drm_WARN_ON(dev, !i915_gem_object_is_framebuffer(obj)))1109 if (drm_WARN_ON(dev, !i915_gem_object_is_framebuffer(obj)))
1107 return ERR_PTR(-EINVAL);1110 return ERR_PTR(-EINVAL);
1108 1111
1109 alignment = intel_surf_alignment(fb, 0);1112 if (phys_cursor)
1113 alignment = intel_cursor_alignment(dev_priv);
1114 else
1115 alignment = intel_surf_alignment(fb, 0);
1110 if (drm_WARN_ON(dev, alignment && !is_power_of_2(alignment)))1116 if (drm_WARN_ON(dev, alignment && !is_power_of_2(alignment)))
1111 return ERR_PTR(-EINVAL);1117 return ERR_PTR(-EINVAL);
1112 1118
@@ -1141,14 +1147,26 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, · 28 unmodified lines
1141 if (HAS_GMCH(dev_priv))1147 if (HAS_GMCH(dev_priv))
1142 pinctl |= PIN_MAPPABLE;1148 pinctl |= PIN_MAPPABLE;
1143 1149
1144 vma = i915_gem_object_pin_to_display_plane(obj,1150 i915_gem_ww_ctx_init(&ww, true);
1145 alignment, view, pinctl);1151retry:
1146 if (IS_ERR(vma))1152 ret = i915_gem_object_lock(obj, &ww);
1153 if (!ret && phys_cursor)
1154 ret = i915_gem_object_attach_phys(obj, alignment);
1155 if (!ret)
1156 ret = i915_gem_object_pin_pages(obj);
1157 if (ret)
1147 goto err;1158 goto err;
1148 1159
1149 if (uses_fence && i915_vma_is_map_and_fenceable(vma)) {1160 if (!ret) {
1150 int ret;1161 vma = i915_gem_object_pin_to_display_plane(obj, &ww, alignment,
1162 view, pinctl);
1163 if (IS_ERR(vma)) {
1164 ret = PTR_ERR(vma);
1165 goto err_unpin;
1166 }
1167 }
1151 1168
1169 if (uses_fence && i915_vma_is_map_and_fenceable(vma)) {
1152 /*1170 /*
1153 * Install a fence for tiled scan-out. Pre-i965 always needs a1171 * Install a fence for tiled scan-out. Pre-i965 always needs a
1154 * fence, whereas 965+ only requires a fence if using1172 * fence, whereas 965+ only requires a fence if using
@@ -1169,16 +1187,28 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, · 14 unmodified lines
1169 ret = i915_vma_pin_fence(vma);1187 ret = i915_vma_pin_fence(vma);
1170 if (ret != 0 && INTEL_GEN(dev_priv) < 4) {1188 if (ret != 0 && INTEL_GEN(dev_priv) < 4) {
1171 i915_vma_unpin(vma);1189 i915_vma_unpin(vma);
1172 vma = ERR_PTR(ret);1190 goto err_unpin;
1173 goto err;
1174 }1191 }
1192 ret = 0;
1175 1193
1176 if (ret == 0 && vma->fence)1194 if (vma->fence)
1177 *out_flags |= PLANE_HAS_FENCE;1195 *out_flags |= PLANE_HAS_FENCE;
1178 }1196 }
1179 1197
1180 i915_vma_get(vma);1198 i915_vma_get(vma);
1199
1200err_unpin:
1201 i915_gem_object_unpin_pages(obj);
1181err:1202err:
1203 if (ret == -EDEADLK) {
1204 ret = i915_gem_ww_ctx_backoff(&ww);
1205 if (!ret)
1206 goto retry;
1207 }
1208 i915_gem_ww_ctx_fini(&ww);
1209 if (ret)
1210 vma = ERR_PTR(ret);
1211
1182 atomic_dec(&dev_priv->gpu_error.pending_fb_pin);1212 atomic_dec(&dev_priv->gpu_error.pending_fb_pin);
1183 intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref);1213 intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref);
1184 return vma;1214 return vma;
@@ -11333,19 +11363,11 @@ int intel_plane_pin_fb(struct intel_plane_state *plane_state) · 10148 unmodified lines
11333 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);11363 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
11334 struct drm_framebuffer *fb = plane_state->hw.fb;11364 struct drm_framebuffer *fb = plane_state->hw.fb;
11335 struct i915_vma *vma;11365 struct i915_vma *vma;
11366 bool phys_cursor =
11367 plane->id == PLANE_CURSOR &&
11368 INTEL_INFO(dev_priv)->display.cursor_needs_physical;
11336 11369
11337 if (plane->id == PLANE_CURSOR &&11370 vma = intel_pin_and_fence_fb_obj(fb, phys_cursor,
11338 INTEL_INFO(dev_priv)->display.cursor_needs_physical) {
11339 struct drm_i915_gem_object *obj = intel_fb_obj(fb);
11340 const int align = intel_cursor_alignment(dev_priv);
11341 int err;
11342
11343 err = i915_gem_object_attach_phys(obj, align);
11344 if (err)
11345 return err;
11346 }
11347
11348 vma = intel_pin_and_fence_fb_obj(fb,
11349 &plane_state->view,11371 &plane_state->view,
11350 intel_plane_uses_fence(plane_state),11372 intel_plane_uses_fence(plane_state),
11351 &plane_state->flags);11373 &plane_state->flags);
@@ -11437,13 +11459,8 @@ intel_prepare_plane_fb(struct drm_plane *_plane, · 85 unmodified lines
11437 if (!obj)11459 if (!obj)
11438 return 0;11460 return 0;
11439 11461
11440 ret = i915_gem_object_pin_pages(obj);
11441 if (ret)
11442 return ret;
11443 11462
11444 ret = intel_plane_pin_fb(new_plane_state);11463 ret = intel_plane_pin_fb(new_plane_state);
11445
11446 i915_gem_object_unpin_pages(obj);
11447 if (ret)11464 if (ret)
11448 return ret;11465 return ret;
11449 11466
@@ -11905,7 +11922,7 @@ static int intel_user_framebuffer_create_handle(struct drm_framebuffer *fb, · 455 unmodified lines
11905 struct drm_i915_gem_object *obj = intel_fb_obj(fb);11922 struct drm_i915_gem_object *obj = intel_fb_obj(fb);
11906 struct drm_i915_private *i915 = to_i915(obj->base.dev);11923 struct drm_i915_private *i915 = to_i915(obj->base.dev);
11907 11924
11908 if (obj->userptr.mm) {11925 if (i915_gem_object_is_userptr(obj)) {
11909 drm_dbg(&i915->drm,11926 drm_dbg(&i915->drm,
11910 "attempting to use a userptr for a framebuffer, denied\n");11927 "attempting to use a userptr for a framebuffer, denied\n");
11911 return -EINVAL;11928 return -EINVAL;
drivers/gpu/drm/i915/display/intel_display.h+1−1
@@ -573,7 +573,7 @@ void intel_release_load_detect_pipe(struct drm_connector *connector, · 572 unmodified lines
573 struct intel_load_detect_pipe *old,573 struct intel_load_detect_pipe *old,
574 struct drm_modeset_acquire_ctx *ctx);574 struct drm_modeset_acquire_ctx *ctx);
575struct i915_vma *575struct i915_vma *
576intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb,576intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, bool phys_cursor,
577 const struct i915_ggtt_view *view,577 const struct i915_ggtt_view *view,
578 bool uses_fence,578 bool uses_fence,
579 unsigned long *out_flags);579 unsigned long *out_flags);
drivers/gpu/drm/i915/display/intel_dsb.c+1−1
@@ -293,7 +293,7 @@ void intel_dsb_prepare(struct intel_crtc_state *crtc_state) · 292 unmodified lines
293 goto out;293 goto out;
294 }294 }
295 295
296 buf = i915_gem_object_pin_map(vma->obj, I915_MAP_WC);296 buf = i915_gem_object_pin_map_unlocked(vma->obj, I915_MAP_WC);
297 if (IS_ERR(buf)) {297 if (IS_ERR(buf)) {
298 drm_err(&i915->drm, "Command buffer creation failed\n");298 drm_err(&i915->drm, "Command buffer creation failed\n");
299 i915_vma_unpin_and_release(&vma, I915_VMA_RELEASE_MAP);299 i915_vma_unpin_and_release(&vma, I915_VMA_RELEASE_MAP);
drivers/gpu/drm/i915/display/intel_fbdev.c+1−1
@@ -211,7 +211,7 @@ static int intelfb_create(struct drm_fb_helper *helper, · 210 unmodified lines
211 * This also validates that any existing fb inherited from the211 * This also validates that any existing fb inherited from the
212 * BIOS is suitable for own access.212 * BIOS is suitable for own access.
213 */213 */
214 vma = intel_pin_and_fence_fb_obj(&ifbdev->fb->base,214 vma = intel_pin_and_fence_fb_obj(&ifbdev->fb->base, false,
215 &view, false, &flags);215 &view, false, &flags);
216 if (IS_ERR(vma)) {216 if (IS_ERR(vma)) {
217 ret = PTR_ERR(vma);217 ret = PTR_ERR(vma);
drivers/gpu/drm/i915/display/intel_overlay.c+29−5
@@ -755,6 +755,32 @@ static u32 overlay_cmd_reg(struct drm_intel_overlay_put_image *params) · 754 unmodified lines
755 return cmd;755 return cmd;
756}756}
757 757
758static struct i915_vma *intel_overlay_pin_fb(struct drm_i915_gem_object *new_bo)
759{
760 struct i915_gem_ww_ctx ww;
761 struct i915_vma *vma;
762 int ret;
763
764 i915_gem_ww_ctx_init(&ww, true);
765retry:
766 ret = i915_gem_object_lock(new_bo, &ww);
767 if (!ret) {
768 vma = i915_gem_object_pin_to_display_plane(new_bo, &ww, 0,
769 NULL, PIN_MAPPABLE);
770 ret = PTR_ERR_OR_ZERO(vma);
771 }
772 if (ret == -EDEADLK) {
773 ret = i915_gem_ww_ctx_backoff(&ww);
774 if (!ret)
775 goto retry;
776 }
777 i915_gem_ww_ctx_fini(&ww);
778 if (ret)
779 return ERR_PTR(ret);
780
781 return vma;
782}
783
758static int intel_overlay_do_put_image(struct intel_overlay *overlay,784static int intel_overlay_do_put_image(struct intel_overlay *overlay,
759 struct drm_i915_gem_object *new_bo,785 struct drm_i915_gem_object *new_bo,
760 struct drm_intel_overlay_put_image *params)786 struct drm_intel_overlay_put_image *params)
@@ -776,12 +802,10 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay, · 15 unmodified lines
776 802
777 atomic_inc(&dev_priv->gpu_error.pending_fb_pin);803 atomic_inc(&dev_priv->gpu_error.pending_fb_pin);
778 804
779 vma = i915_gem_object_pin_to_display_plane(new_bo,805 vma = intel_overlay_pin_fb(new_bo);
780 0, NULL, PIN_MAPPABLE);806 if (IS_ERR(vma))
781 if (IS_ERR(vma)) {
782 ret = PTR_ERR(vma);
783 goto out_pin_section;807 goto out_pin_section;
784 }808
785 i915_gem_object_flush_frontbuffer(new_bo, ORIGIN_DIRTYFB);809 i915_gem_object_flush_frontbuffer(new_bo, ORIGIN_DIRTYFB);
786 810
787 if (!overlay->active) {811 if (!overlay->active) {
drivers/gpu/drm/i915/gem/i915_gem_clflush.c+7−8
@@ -27,15 +27,8 @@ static void __do_clflush(struct drm_i915_gem_object *obj) · 26 unmodified lines
27static int clflush_work(struct dma_fence_work *base)27static int clflush_work(struct dma_fence_work *base)
28{28{
29 struct clflush *clflush = container_of(base, typeof(*clflush), base);29 struct clflush *clflush = container_of(base, typeof(*clflush), base);
30 struct drm_i915_gem_object *obj = clflush->obj;
31 int err;
32 30
33 err = i915_gem_object_pin_pages(obj);31 __do_clflush(clflush->obj);
34 if (err)
35 return err;
36
37 __do_clflush(obj);
38 i915_gem_object_unpin_pages(obj);
39 32
40 return 0;33 return 0;
41}34}
@@ -44,6 +37,7 @@ static void clflush_release(struct dma_fence_work *base) · 2 unmodified lines
44{37{
45 struct clflush *clflush = container_of(base, typeof(*clflush), base);38 struct clflush *clflush = container_of(base, typeof(*clflush), base);
46 39
40 i915_gem_object_unpin_pages(clflush->obj);
47 i915_gem_object_put(clflush->obj);41 i915_gem_object_put(clflush->obj);
48}42}
49 43
@@ -63,6 +57,11 @@ static struct clflush *clflush_work_create(struct drm_i915_gem_object *obj) · 13 unmodified lines
63 if (!clflush)57 if (!clflush)
64 return NULL;58 return NULL;
65 59
60 if (__i915_gem_object_get_pages(obj) < 0) {
61 kfree(clflush);
62 return NULL;
63 }
64
66 dma_fence_work_init(&clflush->base, &clflush_ops);65 dma_fence_work_init(&clflush->base, &clflush_ops);
67 clflush->obj = i915_gem_object_get(obj); /* obj <-> clflush cycle */66 clflush->obj = i915_gem_object_get(obj); /* obj <-> clflush cycle */
68 67
drivers/gpu/drm/i915/gem/i915_gem_context.c+40−33
@@ -232,6 +232,8 @@ static void intel_context_set_gem(struct intel_context *ce, · 231 unmodified lines
232 if (ctx->sched.priority >= I915_PRIORITY_NORMAL &&232 if (ctx->sched.priority >= I915_PRIORITY_NORMAL &&
233 intel_engine_has_timeslices(ce->engine))233 intel_engine_has_timeslices(ce->engine))
234 __set_bit(CONTEXT_USE_SEMAPHORES, &ce->flags);234 __set_bit(CONTEXT_USE_SEMAPHORES, &ce->flags);
235
236 intel_context_set_watchdog_us(ce, ctx->watchdog.timeout_us);
235}237}
236 238
237static void __free_engines(struct i915_gem_engines *e, unsigned int count)239static void __free_engines(struct i915_gem_engines *e, unsigned int count)
@@ -386,38 +388,6 @@ static bool __cancel_engine(struct intel_engine_cs *engine) · 148 unmodified lines
386 return intel_engine_pulse(engine) == 0;388 return intel_engine_pulse(engine) == 0;
387}389}
388 390
389static bool
390__active_engine(struct i915_request *rq, struct intel_engine_cs **active)
391{
392 struct intel_engine_cs *engine, *locked;
393 bool ret = false;
394
395 /*
396 * Serialise with __i915_request_submit() so that it sees
397 * is-banned?, or we know the request is already inflight.
398 *
399 * Note that rq->engine is unstable, and so we double
400 * check that we have acquired the lock on the final engine.
401 */
402 locked = READ_ONCE(rq->engine);
403 spin_lock_irq(&locked->active.lock);
404 while (unlikely(locked != (engine = READ_ONCE(rq->engine)))) {
405 spin_unlock(&locked->active.lock);
406 locked = engine;
407 spin_lock(&locked->active.lock);
408 }
409
410 if (i915_request_is_active(rq)) {
411 if (!__i915_request_is_complete(rq))
412 *active = locked;
413 ret = true;
414 }
415
416 spin_unlock_irq(&locked->active.lock);
417
418 return ret;
419}
420
421static struct intel_engine_cs *active_engine(struct intel_context *ce)391static struct intel_engine_cs *active_engine(struct intel_context *ce)
422{392{
423 struct intel_engine_cs *engine = NULL;393 struct intel_engine_cs *engine = NULL;
@@ -445,7 +415,7 @@ static struct intel_engine_cs *active_engine(struct intel_context *ce) · 21 unmodified lines
445 /* Check with the backend if the request is inflight */415 /* Check with the backend if the request is inflight */
446 found = true;416 found = true;
447 if (likely(rcu_access_pointer(rq->timeline) == ce->timeline))417 if (likely(rcu_access_pointer(rq->timeline) == ce->timeline))
448 found = __active_engine(rq, &engine);418 found = i915_request_active_engine(rq, &engine);
449 419
450 i915_request_put(rq);420 i915_request_put(rq);
451 if (found)421 if (found)
@@ -822,6 +792,41 @@ static void __assign_timeline(struct i915_gem_context *ctx, · 370 unmodified lines
822 context_apply_all(ctx, __apply_timeline, timeline);792 context_apply_all(ctx, __apply_timeline, timeline);
823}793}
824 794
795static int __apply_watchdog(struct intel_context *ce, void *timeout_us)
796{
797 return intel_context_set_watchdog_us(ce, (uintptr_t)timeout_us);
798}
799
800static int
801__set_watchdog(struct i915_gem_context *ctx, unsigned long timeout_us)
802{
803 int ret;
804
805 ret = context_apply_all(ctx, __apply_watchdog,
806 (void *)(uintptr_t)timeout_us);
807 if (!ret)
808 ctx->watchdog.timeout_us = timeout_us;
809
810 return ret;
811}
812
813static void __set_default_fence_expiry(struct i915_gem_context *ctx)
814{
815 struct drm_i915_private *i915 = ctx->i915;
816 int ret;
817
818 if (!IS_ACTIVE(CONFIG_DRM_I915_REQUEST_TIMEOUT) ||
819 !i915->params.request_timeout_ms)
820 return;
821
822 /* Default expiry for user fences. */
823 ret = __set_watchdog(ctx, i915->params.request_timeout_ms * 1000);
824 if (ret)
825 drm_notice(&i915->drm,
826 "Failed to configure default fence expiry! (%d)",
827 ret);
828}
829
825static struct i915_gem_context *830static struct i915_gem_context *
826i915_gem_create_context(struct drm_i915_private *i915, unsigned int flags)831i915_gem_create_context(struct drm_i915_private *i915, unsigned int flags)
827{832{
@@ -866,6 +871,8 @@ i915_gem_create_context(struct drm_i915_private *i915, unsigned int flags) · 38 unmodified lines
866 intel_timeline_put(timeline);871 intel_timeline_put(timeline);
867 }872 }
868 873
874 __set_default_fence_expiry(ctx);
875
869 trace_i915_context_create(ctx);876 trace_i915_context_create(ctx);
870 877
871 return ctx;878 return ctx;
drivers/gpu/drm/i915/gem/i915_gem_context_types.h+4−0
@@ -154,6 +154,10 @@ struct i915_gem_context { · 153 unmodified lines
154 */154 */
155 atomic_t active_count;155 atomic_t active_count;
156 156
157 struct {
158 u64 timeout_us;
159 } watchdog;
160
157 /**161 /**
158 * @hang_timestamp: The last time(s) this context caused a GPU hang162 * @hang_timestamp: The last time(s) this context caused a GPU hang
159 */163 */
drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c+35−29
@@ -25,7 +25,7 @@ static struct sg_table *i915_gem_map_dma_buf(struct dma_buf_attachment *attachme · 24 unmodified lines
25 struct scatterlist *src, *dst;25 struct scatterlist *src, *dst;
26 int ret, i;26 int ret, i;
27 27
28 ret = i915_gem_object_pin_pages(obj);28 ret = i915_gem_object_pin_pages_unlocked(obj);
29 if (ret)29 if (ret)
30 goto err;30 goto err;
31 31
@@ -82,7 +82,7 @@ static int i915_gem_dmabuf_vmap(struct dma_buf *dma_buf, struct dma_buf_map *map · 50 unmodified lines
82 struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf);82 struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf);
83 void *vaddr;83 void *vaddr;
84 84
85 vaddr = i915_gem_object_pin_map(obj, I915_MAP_WB);85 vaddr = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WB);
86 if (IS_ERR(vaddr))86 if (IS_ERR(vaddr))
87 return PTR_ERR(vaddr);87 return PTR_ERR(vaddr);
88 88
@@ -123,42 +123,48 @@ static int i915_gem_begin_cpu_access(struct dma_buf *dma_buf, enum dma_data_dire · 34 unmodified lines
123{123{
124 struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf);124 struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf);
125 bool write = (direction == DMA_BIDIRECTIONAL || direction == DMA_TO_DEVICE);125 bool write = (direction == DMA_BIDIRECTIONAL || direction == DMA_TO_DEVICE);
126 struct i915_gem_ww_ctx ww;
126 int err;127 int err;
127 128
128 err = i915_gem_object_pin_pages(obj);129 i915_gem_ww_ctx_init(&ww, true);
129 if (err)130retry:
130 return err;131 err = i915_gem_object_lock(obj, &ww);
131 132 if (!err)
132 err = i915_gem_object_lock_interruptible(obj, NULL);133 err = i915_gem_object_pin_pages(obj);
133 if (err)134 if (!err) {
134 goto out;135 err = i915_gem_object_set_to_cpu_domain(obj, write);
135 136 i915_gem_object_unpin_pages(obj);
136 err = i915_gem_object_set_to_cpu_domain(obj, write);137 }
137 i915_gem_object_unlock(obj);138 if (err == -EDEADLK) {
138 139 err = i915_gem_ww_ctx_backoff(&ww);
139out:140 if (!err)
140 i915_gem_object_unpin_pages(obj);141 goto retry;
142 }
143 i915_gem_ww_ctx_fini(&ww);
141 return err;144 return err;
142}145}
143 146
144static int i915_gem_end_cpu_access(struct dma_buf *dma_buf, enum dma_data_direction direction)147static int i915_gem_end_cpu_access(struct dma_buf *dma_buf, enum dma_data_direction direction)
145{148{
146 struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf);149 struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf);
150 struct i915_gem_ww_ctx ww;
147 int err;151 int err;
148 152
149 err = i915_gem_object_pin_pages(obj);153 i915_gem_ww_ctx_init(&ww, true);
150 if (err)154retry:
151 return err;155 err = i915_gem_object_lock(obj, &ww);
152 156 if (!err)
153 err = i915_gem_object_lock_interruptible(obj, NULL);157 err = i915_gem_object_pin_pages(obj);
154 if (err)158 if (!err) {
155 goto out;159 err = i915_gem_object_set_to_gtt_domain(obj, false);
156 160 i915_gem_object_unpin_pages(obj);
157 err = i915_gem_object_set_to_gtt_domain(obj, false);161 }
158 i915_gem_object_unlock(obj);162 if (err == -EDEADLK) {
159 163 err = i915_gem_ww_ctx_backoff(&ww);
160out:164 if (!err)
161 i915_gem_object_unpin_pages(obj);165 goto retry;
166 }
167 i915_gem_ww_ctx_fini(&ww);
162 return err;168 return err;
163}169}
164 170
@@ -258,7 +264,7 @@ struct drm_gem_object *i915_gem_prime_import(struct drm_device *dev, · 93 unmodified lines
258 }264 }
259 265
260 drm_gem_private_object_init(dev, &obj->base, dma_buf->size);266 drm_gem_private_object_init(dev, &obj->base, dma_buf->size);
261 i915_gem_object_init(obj, &i915_gem_object_dmabuf_ops, &lock_class);267 i915_gem_object_init(obj, &i915_gem_object_dmabuf_ops, &lock_class, 0);
262 obj->base.import_attach = attach;268 obj->base.import_attach = attach;
263 obj->base.resv = dma_buf->resv;269 obj->base.resv = dma_buf->resv;
264 270
drivers/gpu/drm/i915/gem/i915_gem_domain.c+39−33
@@ -335,7 +335,14 @@ int i915_gem_set_caching_ioctl(struct drm_device *dev, void *data, · 334 unmodified lines
335 * not allowed to be changed by userspace.335 * not allowed to be changed by userspace.
336 */336 */
337 if (i915_gem_object_is_proxy(obj)) {337 if (i915_gem_object_is_proxy(obj)) {
338 ret = -ENXIO;338 /*
339 * Silently allow cached for userptr; the vulkan driver
340 * sets all objects to cached
341 */
342 if (!i915_gem_object_is_userptr(obj) ||
343 args->caching != I915_CACHING_CACHED)
344 ret = -ENXIO;
345
339 goto out;346 goto out;
340 }347 }
341 348
@@ -359,12 +366,12 @@ out: · 17 unmodified lines
359 */366 */
360struct i915_vma *367struct i915_vma *
361i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,368i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
369 struct i915_gem_ww_ctx *ww,
362 u32 alignment,370 u32 alignment,
363 const struct i915_ggtt_view *view,371 const struct i915_ggtt_view *view,
364 unsigned int flags)372 unsigned int flags)
365{373{
366 struct drm_i915_private *i915 = to_i915(obj->base.dev);374 struct drm_i915_private *i915 = to_i915(obj->base.dev);
367 struct i915_gem_ww_ctx ww;
368 struct i915_vma *vma;375 struct i915_vma *vma;
369 int ret;376 int ret;
370 377
@@ -372,11 +379,6 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj, · 1 unmodified line
372 if (HAS_LMEM(i915) && !i915_gem_object_is_lmem(obj))379 if (HAS_LMEM(i915) && !i915_gem_object_is_lmem(obj))
373 return ERR_PTR(-EINVAL);380 return ERR_PTR(-EINVAL);
374 381
375 i915_gem_ww_ctx_init(&ww, true);
376retry:
377 ret = i915_gem_object_lock(obj, &ww);
378 if (ret)
379 goto err;
380 /*382 /*
381 * The display engine is not coherent with the LLC cache on gen6. As383 * The display engine is not coherent with the LLC cache on gen6. As
382 * a result, we make sure that the pinning that is about to occur is384 * a result, we make sure that the pinning that is about to occur is
@@ -391,7 +393,7 @@ retry: · 8 unmodified lines
391 HAS_WT(i915) ?393 HAS_WT(i915) ?
392 I915_CACHE_WT : I915_CACHE_NONE);394 I915_CACHE_WT : I915_CACHE_NONE);
393 if (ret)395 if (ret)
394 goto err;396 return ERR_PTR(ret);
395 397
396 /*398 /*
397 * As the user may map the buffer once pinned in the display plane399 * As the user may map the buffer once pinned in the display plane
@@ -404,33 +406,20 @@ retry: · 6 unmodified lines
404 vma = ERR_PTR(-ENOSPC);406 vma = ERR_PTR(-ENOSPC);
405 if ((flags & PIN_MAPPABLE) == 0 &&407 if ((flags & PIN_MAPPABLE) == 0 &&
406 (!view || view->type == I915_GGTT_VIEW_NORMAL))408 (!view || view->type == I915_GGTT_VIEW_NORMAL))
407 vma = i915_gem_object_ggtt_pin_ww(obj, &ww, view, 0, alignment,409 vma = i915_gem_object_ggtt_pin_ww(obj, ww, view, 0, alignment,
408 flags | PIN_MAPPABLE |410 flags | PIN_MAPPABLE |
409 PIN_NONBLOCK);411 PIN_NONBLOCK);
410 if (IS_ERR(vma) && vma != ERR_PTR(-EDEADLK))412 if (IS_ERR(vma) && vma != ERR_PTR(-EDEADLK))
411 vma = i915_gem_object_ggtt_pin_ww(obj, &ww, view, 0,413 vma = i915_gem_object_ggtt_pin_ww(obj, ww, view, 0,
412 alignment, flags);414 alignment, flags);
413 if (IS_ERR(vma)) {415 if (IS_ERR(vma))
414 ret = PTR_ERR(vma);416 return vma;
415 goto err;
416 }
417 417
418 vma->display_alignment = max_t(u64, vma->display_alignment, alignment);418 vma->display_alignment = max_t(u64, vma->display_alignment, alignment);
419 i915_vma_mark_scanout(vma);419 i915_vma_mark_scanout(vma);
420 420
421 i915_gem_object_flush_if_display_locked(obj);421 i915_gem_object_flush_if_display_locked(obj);
422 422
423err:
424 if (ret == -EDEADLK) {
425 ret = i915_gem_ww_ctx_backoff(&ww);
426 if (!ret)
427 goto retry;
428 }
429 i915_gem_ww_ctx_fini(&ww);
430
431 if (ret)
432 return ERR_PTR(ret);
433
434 return vma;423 return vma;
435}424}
436 425
@@ -526,6 +515,21 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, · 89 unmodified lines
526 if (err)515 if (err)
527 goto out;516 goto out;
528 517
518 if (i915_gem_object_is_userptr(obj)) {
519 /*
520 * Try to grab userptr pages, iris uses set_domain to check
521 * userptr validity
522 */
523 err = i915_gem_object_userptr_validate(obj);
524 if (!err)
525 err = i915_gem_object_wait(obj,
526 I915_WAIT_INTERRUPTIBLE |
527 I915_WAIT_PRIORITY |
528 (write_domain ? I915_WAIT_ALL : 0),
529 MAX_SCHEDULE_TIMEOUT);
530 goto out;
531 }
532
529 /*533 /*
530 * Proxy objects do not control access to the backing storage, ergo534 * Proxy objects do not control access to the backing storage, ergo
531 * they cannot be used as a means to manipulate the cache domain535 * they cannot be used as a means to manipulate the cache domain
@@ -537,6 +541,10 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, · 5 unmodified lines
537 goto out;541 goto out;
538 }542 }
539 543
544 err = i915_gem_object_lock_interruptible(obj, NULL);
545 if (err)
546 goto out;
547
540 /*548 /*
541 * Flush and acquire obj->pages so that we are coherent through549 * Flush and acquire obj->pages so that we are coherent through
542 * direct access in memory with previous cached writes through550 * direct access in memory with previous cached writes through
@@ -548,7 +556,7 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, · 5 unmodified lines
548 */556 */
549 err = i915_gem_object_pin_pages(obj);557 err = i915_gem_object_pin_pages(obj);
550 if (err)558 if (err)
551 goto out;559 goto out_unlock;
552 560
553 /*561 /*
554 * Already in the desired write domain? Nothing for us to do!562 * Already in the desired write domain? Nothing for us to do!
@@ -563,10 +571,6 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, · 8 unmodified lines
563 if (READ_ONCE(obj->write_domain) == read_domains)571 if (READ_ONCE(obj->write_domain) == read_domains)
564 goto out_unpin;572 goto out_unpin;
565 573
566 err = i915_gem_object_lock_interruptible(obj, NULL);
567 if (err)
568 goto out_unpin;
569
570 if (read_domains & I915_GEM_DOMAIN_WC)574 if (read_domains & I915_GEM_DOMAIN_WC)
571 err = i915_gem_object_set_to_wc_domain(obj, write_domain);575 err = i915_gem_object_set_to_wc_domain(obj, write_domain);
572 else if (read_domains & I915_GEM_DOMAIN_GTT)576 else if (read_domains & I915_GEM_DOMAIN_GTT)
@@ -574,13 +578,15 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, · 1 unmodified line
574 else578 else
575 err = i915_gem_object_set_to_cpu_domain(obj, write_domain);579 err = i915_gem_object_set_to_cpu_domain(obj, write_domain);
576 580
581out_unpin:
582 i915_gem_object_unpin_pages(obj);
583
584out_unlock:
577 i915_gem_object_unlock(obj);585 i915_gem_object_unlock(obj);
578 586
579 if (write_domain)587 if (!err && write_domain)
580 i915_gem_object_invalidate_frontbuffer(obj, ORIGIN_CPU);588 i915_gem_object_invalidate_frontbuffer(obj, ORIGIN_CPU);
581 589
582out_unpin:
583 i915_gem_object_unpin_pages(obj);
584out:590out:
585 i915_gem_object_put(obj);591 i915_gem_object_put(obj);
586 return err;592 return err;
drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c+204−131
@@ -28,6 +28,7 @@ · 27 unmodified lines
28#include "i915_sw_fence_work.h"28#include "i915_sw_fence_work.h"
29#include "i915_trace.h"29#include "i915_trace.h"
30#include "i915_user_extensions.h"30#include "i915_user_extensions.h"
31#include "i915_memcpy.h"
31 32
32struct eb_vma {33struct eb_vma {
33 struct i915_vma *vma;34 struct i915_vma *vma;
@@ -49,16 +50,19 @@ enum { · 15 unmodified lines
49#define DBG_FORCE_RELOC 0 /* choose one of the above! */50#define DBG_FORCE_RELOC 0 /* choose one of the above! */
50};51};
51 52
52#define __EXEC_OBJECT_HAS_PIN BIT(31)53/* __EXEC_OBJECT_NO_RESERVE is BIT(31), defined in i915_vma.h */
53#define __EXEC_OBJECT_HAS_FENCE BIT(30)54#define __EXEC_OBJECT_HAS_PIN BIT(30)
54#define __EXEC_OBJECT_NEEDS_MAP BIT(29)55#define __EXEC_OBJECT_HAS_FENCE BIT(29)
55#define __EXEC_OBJECT_NEEDS_BIAS BIT(28)56#define __EXEC_OBJECT_USERPTR_INIT BIT(28)
56#define __EXEC_OBJECT_INTERNAL_FLAGS (~0u << 28) /* all of the above */57#define __EXEC_OBJECT_NEEDS_MAP BIT(27)
58#define __EXEC_OBJECT_NEEDS_BIAS BIT(26)
59#define __EXEC_OBJECT_INTERNAL_FLAGS (~0u << 26) /* all of the above + */
57#define __EXEC_OBJECT_RESERVED (__EXEC_OBJECT_HAS_PIN | __EXEC_OBJECT_HAS_FENCE)60#define __EXEC_OBJECT_RESERVED (__EXEC_OBJECT_HAS_PIN | __EXEC_OBJECT_HAS_FENCE)
58 61
59#define __EXEC_HAS_RELOC BIT(31)62#define __EXEC_HAS_RELOC BIT(31)
60#define __EXEC_ENGINE_PINNED BIT(30)63#define __EXEC_ENGINE_PINNED BIT(30)
61#define __EXEC_INTERNAL_FLAGS (~0u << 30)64#define __EXEC_USERPTR_USED BIT(29)
65#define __EXEC_INTERNAL_FLAGS (~0u << 29)
62#define UPDATE PIN_OFFSET_FIXED66#define UPDATE PIN_OFFSET_FIXED
63 67
64#define BATCH_OFFSET_BIAS (256*1024)68#define BATCH_OFFSET_BIAS (256*1024)
@@ -419,13 +423,14 @@ static u64 eb_pin_flags(const struct drm_i915_gem_exec_object2 *entry, · 354 unmodified lines
419 return pin_flags;423 return pin_flags;
420}424}
421 425
422static inline bool426static inline int
423eb_pin_vma(struct i915_execbuffer *eb,427eb_pin_vma(struct i915_execbuffer *eb,
424 const struct drm_i915_gem_exec_object2 *entry,428 const struct drm_i915_gem_exec_object2 *entry,
425 struct eb_vma *ev)429 struct eb_vma *ev)
426{430{
427 struct i915_vma *vma = ev->vma;431 struct i915_vma *vma = ev->vma;
428 u64 pin_flags;432 u64 pin_flags;
433 int err;
429 434
430 if (vma->node.size)435 if (vma->node.size)
431 pin_flags = vma->node.start;436 pin_flags = vma->node.start;
@@ -437,24 +442,29 @@ eb_pin_vma(struct i915_execbuffer *eb, · 5 unmodified lines
437 pin_flags |= PIN_GLOBAL;442 pin_flags |= PIN_GLOBAL;
438 443
439 /* Attempt to reuse the current location if available */444 /* Attempt to reuse the current location if available */
440 /* TODO: Add -EDEADLK handling here */445 err = i915_vma_pin_ww(vma, &eb->ww, 0, 0, pin_flags);
441 if (unlikely(i915_vma_pin_ww(vma, &eb->ww, 0, 0, pin_flags))) {446 if (err == -EDEADLK)
447 return err;
448
449 if (unlikely(err)) {
442 if (entry->flags & EXEC_OBJECT_PINNED)450 if (entry->flags & EXEC_OBJECT_PINNED)
443 return false;451 return err;
444 452
445 /* Failing that pick any _free_ space if suitable */453 /* Failing that pick any _free_ space if suitable */
446 if (unlikely(i915_vma_pin_ww(vma, &eb->ww,454 err = i915_vma_pin_ww(vma, &eb->ww,
447 entry->pad_to_size,455 entry->pad_to_size,
448 entry->alignment,456 entry->alignment,
449 eb_pin_flags(entry, ev->flags) |457 eb_pin_flags(entry, ev->flags) |
450 PIN_USER | PIN_NOEVICT)))458 PIN_USER | PIN_NOEVICT);
451 return false;459 if (unlikely(err))
460 return err;
452 }461 }
453 462
454 if (unlikely(ev->flags & EXEC_OBJECT_NEEDS_FENCE)) {463 if (unlikely(ev->flags & EXEC_OBJECT_NEEDS_FENCE)) {
455 if (unlikely(i915_vma_pin_fence(vma))) {464 err = i915_vma_pin_fence(vma);
465 if (unlikely(err)) {
456 i915_vma_unpin(vma);466 i915_vma_unpin(vma);
457 return false;467 return err;
458 }468 }
459 469
460 if (vma->fence)470 if (vma->fence)
@@ -462,7 +472,10 @@ eb_pin_vma(struct i915_execbuffer *eb, · 1 unmodified line
462 }472 }
463 473
464 ev->flags |= __EXEC_OBJECT_HAS_PIN;474 ev->flags |= __EXEC_OBJECT_HAS_PIN;
465 return !eb_vma_misplaced(entry, vma, ev->flags);475 if (eb_vma_misplaced(entry, vma, ev->flags))
476 return -EBADSLT;
477
478 return 0;
466}479}
467 480
468static inline void481static inline void
@@ -483,6 +496,13 @@ eb_validate_vma(struct i915_execbuffer *eb, · 14 unmodified lines
483 struct drm_i915_gem_exec_object2 *entry,496 struct drm_i915_gem_exec_object2 *entry,
484 struct i915_vma *vma)497 struct i915_vma *vma)
485{498{
499 /* Relocations are disallowed for all platforms after TGL-LP. This
500 * also covers all platforms with local memory.
501 */
502 if (entry->relocation_count &&
503 INTEL_GEN(eb->i915) >= 12 && !IS_TIGERLAKE(eb->i915))
504 return -EINVAL;
505
486 if (unlikely(entry->flags & eb->invalid_flags))506 if (unlikely(entry->flags & eb->invalid_flags))
487 return -EINVAL;507 return -EINVAL;
488 508
@@ -853,6 +873,26 @@ static int eb_lookup_vmas(struct i915_execbuffer *eb) · 364 unmodified lines
853 }873 }
854 874
855 eb_add_vma(eb, i, batch, vma);875 eb_add_vma(eb, i, batch, vma);
876
877 if (i915_gem_object_is_userptr(vma->obj)) {
878 err = i915_gem_object_userptr_submit_init(vma->obj);
879 if (err) {
880 if (i + 1 < eb->buffer_count) {
881 /*
882 * Execbuffer code expects last vma entry to be NULL,
883 * since we already initialized this entry,
884 * set the next value to NULL or we mess up
885 * cleanup handling.
886 */
887 eb->vma[i + 1].vma = NULL;
888 }
889
890 return err;
891 }
892
893 eb->vma[i].flags |= __EXEC_OBJECT_USERPTR_INIT;
894 eb->args->flags |= __EXEC_USERPTR_USED;
895 }
856 }896 }
857 897
858 if (unlikely(eb->batch->flags & EXEC_OBJECT_WRITE)) {898 if (unlikely(eb->batch->flags & EXEC_OBJECT_WRITE)) {
@@ -898,7 +938,11 @@ static int eb_validate_vmas(struct i915_execbuffer *eb) · 39 unmodified lines
898 if (err)938 if (err)
899 return err;939 return err;
900 940
901 if (eb_pin_vma(eb, entry, ev)) {941 err = eb_pin_vma(eb, entry, ev);
942 if (err == -EDEADLK)
943 return err;
944
945 if (!err) {
902 if (entry->offset != vma->node.start) {946 if (entry->offset != vma->node.start) {
903 entry->offset = vma->node.start | UPDATE;947 entry->offset = vma->node.start | UPDATE;
904 eb->args->flags |= __EXEC_HAS_RELOC;948 eb->args->flags |= __EXEC_HAS_RELOC;
@@ -914,6 +958,12 @@ static int eb_validate_vmas(struct i915_execbuffer *eb) · 9 unmodified lines
914 }958 }
915 }959 }
916 960
961 if (!(ev->flags & EXEC_OBJECT_WRITE)) {
962 err = dma_resv_reserve_shared(vma->resv, 1);
963 if (err)
964 return err;
965 }
966
917 GEM_BUG_ON(drm_mm_node_allocated(&vma->node) &&967 GEM_BUG_ON(drm_mm_node_allocated(&vma->node) &&
918 eb_vma_misplaced(&eb->exec[i], vma, ev->flags));968 eb_vma_misplaced(&eb->exec[i], vma, ev->flags));
919 }969 }
@@ -944,7 +994,7 @@ eb_get_vma(const struct i915_execbuffer *eb, unsigned long handle) · 24 unmodified lines
944 }994 }
945}995}
946 996
947static void eb_release_vmas(struct i915_execbuffer *eb, bool final)997static void eb_release_vmas(struct i915_execbuffer *eb, bool final, bool release_userptr)
948{998{
949 const unsigned int count = eb->buffer_count;999 const unsigned int count = eb->buffer_count;
950 unsigned int i;1000 unsigned int i;
@@ -958,6 +1008,11 @@ static void eb_release_vmas(struct i915_execbuffer *eb, bool final) · 7 unmodified lines
958 1008
959 eb_unreserve_vma(ev);1009 eb_unreserve_vma(ev);
960 1010
1011 if (release_userptr && ev->flags & __EXEC_OBJECT_USERPTR_INIT) {
1012 ev->flags &= ~__EXEC_OBJECT_USERPTR_INIT;
1013 i915_gem_object_userptr_submit_fini(vma->obj);
1014 }
1015
961 if (final)1016 if (final)
962 i915_vma_put(vma);1017 i915_vma_put(vma);
963 }1018 }
@@ -1294,6 +1349,7 @@ static int __reloc_gpu_alloc(struct i915_execbuffer *eb, · 330 unmodified lines
1294 err = PTR_ERR(cmd);1349 err = PTR_ERR(cmd);
1295 goto err_pool;1350 goto err_pool;
1296 }1351 }
1352 intel_gt_buffer_pool_mark_used(pool);
1297 1353
1298 memset32(cmd, 0, pool->obj->base.size / sizeof(u32));1354 memset32(cmd, 0, pool->obj->base.size / sizeof(u32));
1299 1355
@@ -1895,6 +1951,31 @@ static int eb_prefault_relocations(const struct i915_execbuffer *eb) · 595 unmodified lines
1895 return 0;1951 return 0;
1896}1952}
1897 1953
1954static int eb_reinit_userptr(struct i915_execbuffer *eb)
1955{
1956 const unsigned int count = eb->buffer_count;
1957 unsigned int i;
1958 int ret;
1959
1960 if (likely(!(eb->args->flags & __EXEC_USERPTR_USED)))
1961 return 0;
1962
1963 for (i = 0; i < count; i++) {
1964 struct eb_vma *ev = &eb->vma[i];
1965
1966 if (!i915_gem_object_is_userptr(ev->vma->obj))
1967 continue;
1968
1969 ret = i915_gem_object_userptr_submit_init(ev->vma->obj);
1970 if (ret)
1971 return ret;
1972
1973 ev->flags |= __EXEC_OBJECT_USERPTR_INIT;
1974 }
1975
1976 return 0;
1977}
1978
1898static noinline int eb_relocate_parse_slow(struct i915_execbuffer *eb,1979static noinline int eb_relocate_parse_slow(struct i915_execbuffer *eb,
1899 struct i915_request *rq)1980 struct i915_request *rq)
1900{1981{
@@ -1909,7 +1990,7 @@ repeat: · 8 unmodified lines
1909 }1990 }
1910 1991
1911 /* We may process another execbuffer during the unlock... */1992 /* We may process another execbuffer during the unlock... */
1912 eb_release_vmas(eb, false);1993 eb_release_vmas(eb, false, true);
1913 i915_gem_ww_ctx_fini(&eb->ww);1994 i915_gem_ww_ctx_fini(&eb->ww);
1914 1995
1915 if (rq) {1996 if (rq) {
@@ -1951,7 +2032,7 @@ repeat: · 35 unmodified lines
1951 }2032 }
1952 2033
1953 if (!err)2034 if (!err)
1954 flush_workqueue(eb->i915->mm.userptr_wq);2035 err = eb_reinit_userptr(eb);
1955 2036
1956err_relock:2037err_relock:
1957 i915_gem_ww_ctx_init(&eb->ww, true);2038 i915_gem_ww_ctx_init(&eb->ww, true);
@@ -2013,7 +2094,7 @@ repeat_validate: · 55 unmodified lines
2013 2094
2014err:2095err:
2015 if (err == -EDEADLK) {2096 if (err == -EDEADLK) {
2016 eb_release_vmas(eb, false);2097 eb_release_vmas(eb, false, false);
2017 err = i915_gem_ww_ctx_backoff(&eb->ww);2098 err = i915_gem_ww_ctx_backoff(&eb->ww);
2018 if (!err)2099 if (!err)
2019 goto repeat_validate;2100 goto repeat_validate;
@@ -2110,7 +2191,7 @@ retry: · 90 unmodified lines
2110 2191
2111err:2192err:
2112 if (err == -EDEADLK) {2193 if (err == -EDEADLK) {
2113 eb_release_vmas(eb, false);2194 eb_release_vmas(eb, false, false);
2114 err = i915_gem_ww_ctx_backoff(&eb->ww);2195 err = i915_gem_ww_ctx_backoff(&eb->ww);
2115 if (!err)2196 if (!err)
2116 goto retry;2197 goto retry;
@@ -2181,8 +2262,33 @@ static int eb_move_to_gpu(struct i915_execbuffer *eb) · 64 unmodified lines
2181 }2262 }
2182 2263
2183 if (err == 0)2264 if (err == 0)
2184 err = i915_vma_move_to_active(vma, eb->request, flags);2265 err = i915_vma_move_to_active(vma, eb->request,
2266 flags | __EXEC_OBJECT_NO_RESERVE);
2267 }
2268
2269#ifdef CONFIG_MMU_NOTIFIER
2270 if (!err && (eb->args->flags & __EXEC_USERPTR_USED)) {
2271 spin_lock(&eb->i915->mm.notifier_lock);
2272
2273 /*
2274 * count is always at least 1, otherwise __EXEC_USERPTR_USED
2275 * could not have been set
2276 */
2277 for (i = 0; i < count; i++) {
2278 struct eb_vma *ev = &eb->vma[i];
2279 struct drm_i915_gem_object *obj = ev->vma->obj;
2280
2281 if (!i915_gem_object_is_userptr(obj))
2282 continue;
2283
2284 err = i915_gem_object_userptr_submit_done(obj);
2285 if (err)
2286 break;
2287 }
2288
2289 spin_unlock(&eb->i915->mm.notifier_lock);
2185 }2290 }
2291#endif
2186 2292
2187 if (unlikely(err))2293 if (unlikely(err))
2188 goto err_skip;2294 goto err_skip;
@@ -2274,24 +2380,45 @@ struct eb_parse_work { · 85 unmodified lines
2274 struct i915_vma *trampoline;2380 struct i915_vma *trampoline;
2275 unsigned long batch_offset;2381 unsigned long batch_offset;
2276 unsigned long batch_length;2382 unsigned long batch_length;
2383 unsigned long *jump_whitelist;
2384 const void *batch_map;
2385 void *shadow_map;
2277};2386};
2278 2387
2279static int __eb_parse(struct dma_fence_work *work)2388static int __eb_parse(struct dma_fence_work *work)
2280{2389{
2281 struct eb_parse_work *pw = container_of(work, typeof(*pw), base);2390 struct eb_parse_work *pw = container_of(work, typeof(*pw), base);
2391 int ret;
2392 bool cookie;
2282 2393
2283 return intel_engine_cmd_parser(pw->engine,2394 cookie = dma_fence_begin_signalling();
2284 pw->batch,2395 ret = intel_engine_cmd_parser(pw->engine,
2285 pw->batch_offset,2396 pw->batch,
2286 pw->batch_length,2397 pw->batch_offset,
2287 pw->shadow,2398 pw->batch_length,
2288 pw->trampoline);2399 pw->shadow,
2400 pw->jump_whitelist,
2401 pw->shadow_map,
2402 pw->batch_map);
2403 dma_fence_end_signalling(cookie);
2404
2405 return ret;
2289}2406}
2290 2407
2291static void __eb_parse_release(struct dma_fence_work *work)2408static void __eb_parse_release(struct dma_fence_work *work)
2292{2409{
2293 struct eb_parse_work *pw = container_of(work, typeof(*pw), base);2410 struct eb_parse_work *pw = container_of(work, typeof(*pw), base);
2294 2411
2412 if (!IS_ERR_OR_NULL(pw->jump_whitelist))
2413 kfree(pw->jump_whitelist);
2414
2415 if (pw->batch_map)
2416 i915_gem_object_unpin_map(pw->batch->obj);
2417 else
2418 i915_gem_object_unpin_pages(pw->batch->obj);
2419
2420 i915_gem_object_unpin_map(pw->shadow->obj);
2421
2295 if (pw->trampoline)2422 if (pw->trampoline)
2296 i915_active_release(&pw->trampoline->active);2423 i915_active_release(&pw->trampoline->active);
2297 i915_active_release(&pw->shadow->active);2424 i915_active_release(&pw->shadow->active);
@@ -2341,6 +2468,8 @@ static int eb_parse_pipeline(struct i915_execbuffer *eb, · 43 unmodified lines
2341 struct i915_vma *trampoline)2468 struct i915_vma *trampoline)
2342{2469{
2343 struct eb_parse_work *pw;2470 struct eb_parse_work *pw;
2471 struct drm_i915_gem_object *batch = eb->batch->vma->obj;
2472 bool needs_clflush;
2344 int err;2473 int err;
2345 2474
2346 GEM_BUG_ON(overflows_type(eb->batch_start_offset, pw->batch_offset));2475 GEM_BUG_ON(overflows_type(eb->batch_start_offset, pw->batch_offset));
@@ -2364,6 +2493,34 @@ static int eb_parse_pipeline(struct i915_execbuffer *eb, · 17 unmodified lines
2364 goto err_shadow;2493 goto err_shadow;
2365 }2494 }
2366 2495
2496 pw->shadow_map = i915_gem_object_pin_map(shadow->obj, I915_MAP_WB);
2497 if (IS_ERR(pw->shadow_map)) {
2498 err = PTR_ERR(pw->shadow_map);
2499 goto err_trampoline;
2500 }
2501
2502 needs_clflush =
2503 !(batch->cache_coherent & I915_BO_CACHE_COHERENT_FOR_READ);
2504
2505 pw->batch_map = ERR_PTR(-ENODEV);
2506 if (needs_clflush && i915_has_memcpy_from_wc())
2507 pw->batch_map = i915_gem_object_pin_map(batch, I915_MAP_WC);
2508
2509 if (IS_ERR(pw->batch_map)) {
2510 err = i915_gem_object_pin_pages(batch);
2511 if (err)
2512 goto err_unmap_shadow;
2513 pw->batch_map = NULL;
2514 }
2515
2516 pw->jump_whitelist =
2517 intel_engine_cmd_parser_alloc_jump_whitelist(eb->batch_len,
2518 trampoline);
2519 if (IS_ERR(pw->jump_whitelist)) {
2520 err = PTR_ERR(pw->jump_whitelist);
2521 goto err_unmap_batch;
2522 }
2523
2367 dma_fence_work_init(&pw->base, &eb_parse_ops);2524 dma_fence_work_init(&pw->base, &eb_parse_ops);
2368 2525
2369 pw->engine = eb->engine;2526 pw->engine = eb->engine;
@@ -2382,6 +2539,10 @@ static int eb_parse_pipeline(struct i915_execbuffer *eb, · 12 unmodified lines
2382 if (err)2539 if (err)
2383 goto err_commit;2540 goto err_commit;
2384 2541
2542 err = dma_resv_reserve_shared(shadow->resv, 1);
2543 if (err)
2544 goto err_commit;
2545
2385 /* Wait for all writes (and relocs) into the batch to complete */2546 /* Wait for all writes (and relocs) into the batch to complete */
2386 err = i915_sw_fence_await_reservation(&pw->base.chain,2547 err = i915_sw_fence_await_reservation(&pw->base.chain,
2387 pw->batch->resv, NULL, false,2548 pw->batch->resv, NULL, false,
@@ -2403,6 +2564,16 @@ err_commit: · 15 unmodified lines
2403 dma_fence_work_commit_imm(&pw->base);2564 dma_fence_work_commit_imm(&pw->base);
2404 return err;2565 return err;
2405 2566
2567err_unmap_batch:
2568 if (pw->batch_map)
2569 i915_gem_object_unpin_map(batch);
2570 else
2571 i915_gem_object_unpin_pages(batch);
2572err_unmap_shadow:
2573 i915_gem_object_unpin_map(shadow->obj);
2574err_trampoline:
2575 if (trampoline)
2576 i915_active_release(&trampoline->active);
2406err_shadow:2577err_shadow:
2407 i915_active_release(&shadow->active);2578 i915_active_release(&shadow->active);
2408err_batch:2579err_batch:
@@ -2474,6 +2645,7 @@ static int eb_parse(struct i915_execbuffer *eb) · 65 unmodified lines
2474 err = PTR_ERR(shadow);2645 err = PTR_ERR(shadow);
2475 goto err;2646 goto err;
2476 }2647 }
2648 intel_gt_buffer_pool_mark_used(pool);
2477 i915_gem_object_set_readonly(shadow->obj);2649 i915_gem_object_set_readonly(shadow->obj);
2478 shadow->private = pool;2650 shadow->private = pool;
2479 2651
@@ -3263,7 +3435,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, · 783 unmodified lines
3263 3435
3264 err = eb_lookup_vmas(&eb);3436 err = eb_lookup_vmas(&eb);
3265 if (err) {3437 if (err) {
3266 eb_release_vmas(&eb, true);3438 eb_release_vmas(&eb, true, true);
3267 goto err_engine;3439 goto err_engine;
3268 }3440 }
3269 3441
@@ -3335,6 +3507,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, · 65 unmodified lines
3335 3507
3336 trace_i915_request_queue(eb.request, eb.batch_flags);3508 trace_i915_request_queue(eb.request, eb.batch_flags);
3337 err = eb_submit(&eb, batch);3509 err = eb_submit(&eb, batch);
3510
3338err_request:3511err_request:
3339 i915_request_get(eb.request);3512 i915_request_get(eb.request);
3340 err = eb_request_add(&eb, err);3513 err = eb_request_add(&eb, err);
@@ -3355,7 +3528,7 @@ err_request: · 14 unmodified lines
3355 i915_request_put(eb.request);3528 i915_request_put(eb.request);
3356 3529
3357err_vma:3530err_vma:
3358 eb_release_vmas(&eb, true);3531 eb_release_vmas(&eb, true, true);
3359 if (eb.trampoline)3532 if (eb.trampoline)
3360 i915_vma_unpin(eb.trampoline);3533 i915_vma_unpin(eb.trampoline);
3361 WARN_ON(err == -EDEADLK);3534 WARN_ON(err == -EDEADLK);
@@ -3401,106 +3574,6 @@ static bool check_buffer_count(size_t count) · 39 unmodified lines
3401 return !(count < 1 || count > INT_MAX || count > SIZE_MAX / sz - 1);3574 return !(count < 1 || count > INT_MAX || count > SIZE_MAX / sz - 1);
3402}3575}
3403 3576
3404/*
3405 * Legacy execbuffer just creates an exec2 list from the original exec object
3406 * list array and passes it to the real function.
3407 */
3408int
3409i915_gem_execbuffer_ioctl(struct drm_device *dev, void *data,
3410 struct drm_file *file)
3411{
3412 struct drm_i915_private *i915 = to_i915(dev);
3413 struct drm_i915_gem_execbuffer *args = data;
3414 struct drm_i915_gem_execbuffer2 exec2;
3415 struct drm_i915_gem_exec_object *exec_list = NULL;
3416 struct drm_i915_gem_exec_object2 *exec2_list = NULL;
3417 const size_t count = args->buffer_count;
3418 unsigned int i;
3419 int err;
3420
3421 if (!check_buffer_count(count)) {
3422 drm_dbg(&i915->drm, "execbuf2 with %zd buffers\n", count);
3423 return -EINVAL;
3424 }
3425
3426 exec2.buffers_ptr = args->buffers_ptr;
3427 exec2.buffer_count = args->buffer_count;
3428 exec2.batch_start_offset = args->batch_start_offset;
3429 exec2.batch_len = args->batch_len;
3430 exec2.DR1 = args->DR1;
3431 exec2.DR4 = args->DR4;
3432 exec2.num_cliprects = args->num_cliprects;
3433 exec2.cliprects_ptr = args->cliprects_ptr;
3434 exec2.flags = I915_EXEC_RENDER;
3435 i915_execbuffer2_set_context_id(exec2, 0);
3436
3437 err = i915_gem_check_execbuffer(&exec2);
3438 if (err)
3439 return err;
3440
3441 /* Copy in the exec list from userland */
3442 exec_list = kvmalloc_array(count, sizeof(*exec_list),
3443 __GFP_NOWARN | GFP_KERNEL);
3444
3445 /* Allocate extra slots for use by the command parser */
3446 exec2_list = kvmalloc_array(count + 2, eb_element_size(),
3447 __GFP_NOWARN | GFP_KERNEL);
3448 if (exec_list == NULL || exec2_list == NULL) {
3449 drm_dbg(&i915->drm,
3450 "Failed to allocate exec list for %d buffers\n",
3451 args->buffer_count);
3452 kvfree(exec_list);
3453 kvfree(exec2_list);
3454 return -ENOMEM;
3455 }
3456 err = copy_from_user(exec_list,
3457 u64_to_user_ptr(args->buffers_ptr),
3458 sizeof(*exec_list) * count);
3459 if (err) {
3460 drm_dbg(&i915->drm, "copy %d exec entries failed %d\n",
3461 args->buffer_count, err);
3462 kvfree(exec_list);
3463 kvfree(exec2_list);
3464 return -EFAULT;
3465 }
3466
3467 for (i = 0; i < args->buffer_count; i++) {
3468 exec2_list[i].handle = exec_list[i].handle;
3469 exec2_list[i].relocation_count = exec_list[i].relocation_count;
3470 exec2_list[i].relocs_ptr = exec_list[i].relocs_ptr;
3471 exec2_list[i].alignment = exec_list[i].alignment;
3472 exec2_list[i].offset = exec_list[i].offset;
3473 if (INTEL_GEN(to_i915(dev)) < 4)
3474 exec2_list[i].flags = EXEC_OBJECT_NEEDS_FENCE;
3475 else
3476 exec2_list[i].flags = 0;
3477 }
3478
3479 err = i915_gem_do_execbuffer(dev, file, &exec2, exec2_list);
3480 if (exec2.flags & __EXEC_HAS_RELOC) {
3481 struct drm_i915_gem_exec_object __user *user_exec_list =
3482 u64_to_user_ptr(args->buffers_ptr);
3483
3484 /* Copy the new buffer offsets back to the user's exec list. */
3485 for (i = 0; i < args->buffer_count; i++) {
3486 if (!(exec2_list[i].offset & UPDATE))
3487 continue;
3488
3489 exec2_list[i].offset =
3490 gen8_canonical_addr(exec2_list[i].offset & PIN_OFFSET_MASK);
3491 exec2_list[i].offset &= PIN_OFFSET_MASK;
3492 if (__copy_to_user(&user_exec_list[i].offset,
3493 &exec2_list[i].offset,
3494 sizeof(user_exec_list[i].offset)))
3495 break;
3496 }
3497 }
3498
3499 kvfree(exec_list);
3500 kvfree(exec2_list);
3501 return err;
3502}
3503
3504int3577int
3505i915_gem_execbuffer2_ioctl(struct drm_device *dev, void *data,3578i915_gem_execbuffer2_ioctl(struct drm_device *dev, void *data,
3506 struct drm_file *file)3579 struct drm_file *file)
drivers/gpu/drm/i915/gem/i915_gem_fence.c+0−95
@@ -1,95 +0,0 @@
1/*
2 * SPDX-License-Identifier: MIT
3 *
4 * Copyright © 2019 Intel Corporation
5 */
6
7#include "i915_drv.h"
8#include "i915_gem_object.h"
9
10struct stub_fence {
11 struct dma_fence dma;
12 struct i915_sw_fence chain;
13};
14
15static int __i915_sw_fence_call
16stub_notify(struct i915_sw_fence *fence, enum i915_sw_fence_notify state)
17{
18 struct stub_fence *stub = container_of(fence, typeof(*stub), chain);
19
20 switch (state) {
21 case FENCE_COMPLETE:
22 dma_fence_signal(&stub->dma);
23 break;
24
25 case FENCE_FREE:
26 dma_fence_put(&stub->dma);
27 break;
28 }
29
30 return NOTIFY_DONE;
31}
32
33static const char *stub_driver_name(struct dma_fence *fence)
34{
35 return DRIVER_NAME;
36}
37
38static const char *stub_timeline_name(struct dma_fence *fence)
39{
40 return "object";
41}
42
43static void stub_release(struct dma_fence *fence)
44{
45 struct stub_fence *stub = container_of(fence, typeof(*stub), dma);
46
47 i915_sw_fence_fini(&stub->chain);
48
49 BUILD_BUG_ON(offsetof(typeof(*stub), dma));
50 dma_fence_free(&stub->dma);
51}
52
53static const struct dma_fence_ops stub_fence_ops = {
54 .get_driver_name = stub_driver_name,
55 .get_timeline_name = stub_timeline_name,
56 .release = stub_release,
57};
58
59struct dma_fence *
60i915_gem_object_lock_fence(struct drm_i915_gem_object *obj)
61{
62 struct stub_fence *stub;
63
64 assert_object_held(obj);
65
66 stub = kmalloc(sizeof(*stub), GFP_KERNEL);
67 if (!stub)
68 return NULL;
69
70 i915_sw_fence_init(&stub->chain, stub_notify);
71 dma_fence_init(&stub->dma, &stub_fence_ops, &stub->chain.wait.lock,
72 0, 0);
73
74 if (i915_sw_fence_await_reservation(&stub->chain,
75 obj->base.resv, NULL, true,
76 i915_fence_timeout(to_i915(obj->base.dev)),
77 I915_FENCE_GFP) < 0)
78 goto err;
79
80 dma_resv_add_excl_fence(obj->base.resv, &stub->dma);
81
82 return &stub->dma;
83
84err:
85 stub_release(&stub->dma);
86 return NULL;
87}
88
89void i915_gem_object_unlock_fence(struct drm_i915_gem_object *obj,
90 struct dma_fence *fence)
91{
92 struct stub_fence *stub = container_of(fence, typeof(*stub), dma);
93
94 i915_sw_fence_commit(&stub->chain);
95}
drivers/gpu/drm/i915/gem/i915_gem_internal.c+3−3
@@ -138,8 +138,7 @@ static void i915_gem_object_put_pages_internal(struct drm_i915_gem_object *obj, · 137 unmodified lines
138 138
139static const struct drm_i915_gem_object_ops i915_gem_object_internal_ops = {139static const struct drm_i915_gem_object_ops i915_gem_object_internal_ops = {
140 .name = "i915_gem_object_internal",140 .name = "i915_gem_object_internal",
141 .flags = I915_GEM_OBJECT_HAS_STRUCT_PAGE |141 .flags = I915_GEM_OBJECT_IS_SHRINKABLE,
142 I915_GEM_OBJECT_IS_SHRINKABLE,
143 .get_pages = i915_gem_object_get_pages_internal,142 .get_pages = i915_gem_object_get_pages_internal,
144 .put_pages = i915_gem_object_put_pages_internal,143 .put_pages = i915_gem_object_put_pages_internal,
145};144};
@@ -178,7 +177,8 @@ i915_gem_object_create_internal(struct drm_i915_private *i915, · 32 unmodified lines
178 return ERR_PTR(-ENOMEM);177 return ERR_PTR(-ENOMEM);
179 178
180 drm_gem_private_object_init(&i915->drm, &obj->base, size);179 drm_gem_private_object_init(&i915->drm, &obj->base, size);
181 i915_gem_object_init(obj, &i915_gem_object_internal_ops, &lock_class);180 i915_gem_object_init(obj, &i915_gem_object_internal_ops, &lock_class,
181 I915_BO_ALLOC_STRUCT_PAGE);
182 182
183 /*183 /*
184 * Mark the object as volatile, such that the pages are marked as184 * Mark the object as volatile, such that the pages are marked as
drivers/gpu/drm/i915/gem/i915_gem_ioctls.h+0−2
@@ -14,8 +14,6 @@ int i915_gem_busy_ioctl(struct drm_device *dev, void *data, · 13 unmodified lines
14 struct drm_file *file);14 struct drm_file *file);
15int i915_gem_create_ioctl(struct drm_device *dev, void *data,15int i915_gem_create_ioctl(struct drm_device *dev, void *data,
16 struct drm_file *file);16 struct drm_file *file);
17int i915_gem_execbuffer_ioctl(struct drm_device *dev, void *data,
18 struct drm_file *file);
19int i915_gem_execbuffer2_ioctl(struct drm_device *dev, void *data,17int i915_gem_execbuffer2_ioctl(struct drm_device *dev, void *data,
20 struct drm_file *file);18 struct drm_file *file);
21int i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data,19int i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data,
drivers/gpu/drm/i915/gem/i915_gem_lmem.c+2−2
@@ -40,13 +40,13 @@ int __i915_gem_lmem_object_init(struct intel_memory_region *mem, · 39 unmodified lines
40 struct drm_i915_private *i915 = mem->i915;40 struct drm_i915_private *i915 = mem->i915;
41 41
42 drm_gem_private_object_init(&i915->drm, &obj->base, size);42 drm_gem_private_object_init(&i915->drm, &obj->base, size);
43 i915_gem_object_init(obj, &i915_gem_lmem_obj_ops, &lock_class);43 i915_gem_object_init(obj, &i915_gem_lmem_obj_ops, &lock_class, flags);
44 44
45 obj->read_domains = I915_GEM_DOMAIN_WC | I915_GEM_DOMAIN_GTT;45 obj->read_domains = I915_GEM_DOMAIN_WC | I915_GEM_DOMAIN_GTT;
46 46
47 i915_gem_object_set_cache_coherency(obj, I915_CACHE_NONE);47 i915_gem_object_set_cache_coherency(obj, I915_CACHE_NONE);
48 48
49 i915_gem_object_init_memory_region(obj, mem, flags);49 i915_gem_object_init_memory_region(obj, mem);
50 50
51 return 0;51 return 0;
52}52}
drivers/gpu/drm/i915/gem/i915_gem_mman.c+29−6
@@ -246,12 +246,15 @@ static vm_fault_t vm_fault_cpu(struct vm_fault *vmf) · 245 unmodified lines
246 area->vm_flags & VM_WRITE))246 area->vm_flags & VM_WRITE))
247 return VM_FAULT_SIGBUS;247 return VM_FAULT_SIGBUS;
248 248
249 if (i915_gem_object_lock_interruptible(obj, NULL))
250 return VM_FAULT_NOPAGE;
251
249 err = i915_gem_object_pin_pages(obj);252 err = i915_gem_object_pin_pages(obj);
250 if (err)253 if (err)
251 goto out;254 goto out;
252 255
253 iomap = -1;256 iomap = -1;
254 if (!i915_gem_object_type_has(obj, I915_GEM_OBJECT_HAS_STRUCT_PAGE)) {257 if (!i915_gem_object_has_struct_page(obj)) {
255 iomap = obj->mm.region->iomap.base;258 iomap = obj->mm.region->iomap.base;
256 iomap -= obj->mm.region->region.start;259 iomap -= obj->mm.region->region.start;
257 }260 }
@@ -269,6 +272,7 @@ static vm_fault_t vm_fault_cpu(struct vm_fault *vmf) · 11 unmodified lines
269 i915_gem_object_unpin_pages(obj);272 i915_gem_object_unpin_pages(obj);
270 273
271out:274out:
275 i915_gem_object_unlock(obj);
272 return i915_error_to_vmf_fault(err);276 return i915_error_to_vmf_fault(err);
273}277}
274 278
@@ -417,7 +421,9 @@ vm_access(struct vm_area_struct *area, unsigned long addr, · 142 unmodified lines
417{421{
418 struct i915_mmap_offset *mmo = area->vm_private_data;422 struct i915_mmap_offset *mmo = area->vm_private_data;
419 struct drm_i915_gem_object *obj = mmo->obj;423 struct drm_i915_gem_object *obj = mmo->obj;
424 struct i915_gem_ww_ctx ww;
420 void *vaddr;425 void *vaddr;
426 int err = 0;
421 427
422 if (i915_gem_object_is_readonly(obj) && write)428 if (i915_gem_object_is_readonly(obj) && write)
423 return -EACCES;429 return -EACCES;
@@ -426,10 +432,18 @@ vm_access(struct vm_area_struct *area, unsigned long addr, · 2 unmodified lines
426 if (addr >= obj->base.size)432 if (addr >= obj->base.size)
427 return -EINVAL;433 return -EINVAL;
428 434
435 i915_gem_ww_ctx_init(&ww, true);
436retry:
437 err = i915_gem_object_lock(obj, &ww);
438 if (err)
439 goto out;
440
429 /* As this is primarily for debugging, let's focus on simplicity */441 /* As this is primarily for debugging, let's focus on simplicity */
430 vaddr = i915_gem_object_pin_map(obj, I915_MAP_FORCE_WC);442 vaddr = i915_gem_object_pin_map(obj, I915_MAP_FORCE_WC);
431 if (IS_ERR(vaddr))443 if (IS_ERR(vaddr)) {
432 return PTR_ERR(vaddr);444 err = PTR_ERR(vaddr);
445 goto out;
446 }
433 447
434 if (write) {448 if (write) {
435 memcpy(vaddr + addr, buf, len);449 memcpy(vaddr + addr, buf, len);
@@ -439,6 +453,16 @@ vm_access(struct vm_area_struct *area, unsigned long addr, · 3 unmodified lines
439 }453 }
440 454
441 i915_gem_object_unpin_map(obj);455 i915_gem_object_unpin_map(obj);
456out:
457 if (err == -EDEADLK) {
458 err = i915_gem_ww_ctx_backoff(&ww);
459 if (!err)
460 goto retry;
461 }
462 i915_gem_ww_ctx_fini(&ww);
463
464 if (err)
465 return err;
442 466
443 return len;467 return len;
444}468}
@@ -653,9 +677,8 @@ __assign_mmap_offset(struct drm_file *file, · 208 unmodified lines
653 }677 }
654 678
655 if (mmap_type != I915_MMAP_TYPE_GTT &&679 if (mmap_type != I915_MMAP_TYPE_GTT &&
656 !i915_gem_object_type_has(obj,680 !i915_gem_object_has_struct_page(obj) &&
657 I915_GEM_OBJECT_HAS_STRUCT_PAGE |681 !i915_gem_object_type_has(obj, I915_GEM_OBJECT_HAS_IOMEM)) {
658 I915_GEM_OBJECT_HAS_IOMEM)) {
659 err = -ENODEV;682 err = -ENODEV;
660 goto out;683 goto out;
661 }684 }
drivers/gpu/drm/i915/gem/i915_gem_object.c+3−7
@@ -60,10 +60,8 @@ void i915_gem_object_free(struct drm_i915_gem_object *obj) · 59 unmodified lines
60 60
61void i915_gem_object_init(struct drm_i915_gem_object *obj,61void i915_gem_object_init(struct drm_i915_gem_object *obj,
62 const struct drm_i915_gem_object_ops *ops,62 const struct drm_i915_gem_object_ops *ops,
63 struct lock_class_key *key)63 struct lock_class_key *key, unsigned flags)
64{64{
65 __mutex_init(&obj->mm.lock, ops->name ?: "obj->mm.lock", key);
66
67 spin_lock_init(&obj->vma.lock);65 spin_lock_init(&obj->vma.lock);
68 INIT_LIST_HEAD(&obj->vma.list);66 INIT_LIST_HEAD(&obj->vma.list);
69 67
@@ -78,16 +76,14 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj, · 8 unmodified lines
78 init_rcu_head(&obj->rcu);76 init_rcu_head(&obj->rcu);
79 77
80 obj->ops = ops;78 obj->ops = ops;
79 GEM_BUG_ON(flags & ~I915_BO_ALLOC_FLAGS);
80 obj->flags = flags;
81 81
82 obj->mm.madv = I915_MADV_WILLNEED;82 obj->mm.madv = I915_MADV_WILLNEED;
83 INIT_RADIX_TREE(&obj->mm.get_page.radix, GFP_KERNEL | __GFP_NOWARN);83 INIT_RADIX_TREE(&obj->mm.get_page.radix, GFP_KERNEL | __GFP_NOWARN);
84 mutex_init(&obj->mm.get_page.lock);84 mutex_init(&obj->mm.get_page.lock);
85 INIT_RADIX_TREE(&obj->mm.get_dma_page.radix, GFP_KERNEL | __GFP_NOWARN);85 INIT_RADIX_TREE(&obj->mm.get_dma_page.radix, GFP_KERNEL | __GFP_NOWARN);
86 mutex_init(&obj->mm.get_dma_page.lock);86 mutex_init(&obj->mm.get_dma_page.lock);
87
88 if (IS_ENABLED(CONFIG_LOCKDEP) && i915_gem_object_is_shrinkable(obj))
89 i915_gem_shrinker_taints_mutex(to_i915(obj->base.dev),
90 &obj->mm.lock);
91}87}
92 88
93/**89/**
drivers/gpu/drm/i915/gem/i915_gem_object.h+60−36
@@ -23,7 +23,8 @@ void i915_gem_object_free(struct drm_i915_gem_object *obj); · 22 unmodified lines
23 23
24void i915_gem_object_init(struct drm_i915_gem_object *obj,24void i915_gem_object_init(struct drm_i915_gem_object *obj,
25 const struct drm_i915_gem_object_ops *ops,25 const struct drm_i915_gem_object_ops *ops,
26 struct lock_class_key *key);26 struct lock_class_key *key,
27 unsigned alloc_flags);
27struct drm_i915_gem_object *28struct drm_i915_gem_object *
28i915_gem_object_create_shmem(struct drm_i915_private *i915,29i915_gem_object_create_shmem(struct drm_i915_private *i915,
29 resource_size_t size);30 resource_size_t size);
@@ -32,11 +33,21 @@ i915_gem_object_create_shmem_from_data(struct drm_i915_private *i915, · 2 unmodified lines
32 const void *data, resource_size_t size);33 const void *data, resource_size_t size);
33 34
34extern const struct drm_i915_gem_object_ops i915_gem_shmem_ops;35extern const struct drm_i915_gem_object_ops i915_gem_shmem_ops;
36
35void __i915_gem_object_release_shmem(struct drm_i915_gem_object *obj,37void __i915_gem_object_release_shmem(struct drm_i915_gem_object *obj,
36 struct sg_table *pages,38 struct sg_table *pages,
37 bool needs_clflush);39 bool needs_clflush);
38 40
41int i915_gem_object_pwrite_phys(struct drm_i915_gem_object *obj,
42 const struct drm_i915_gem_pwrite *args);
43int i915_gem_object_pread_phys(struct drm_i915_gem_object *obj,
44 const struct drm_i915_gem_pread *args);
45
39int i915_gem_object_attach_phys(struct drm_i915_gem_object *obj, int align);46int i915_gem_object_attach_phys(struct drm_i915_gem_object *obj, int align);
47void i915_gem_object_put_pages_shmem(struct drm_i915_gem_object *obj,
48 struct sg_table *pages);
49void i915_gem_object_put_pages_phys(struct drm_i915_gem_object *obj,
50 struct sg_table *pages);
40 51
41void i915_gem_flush_free_objects(struct drm_i915_private *i915);52void i915_gem_flush_free_objects(struct drm_i915_private *i915);
42 53
@@ -107,6 +118,20 @@ i915_gem_object_put(struct drm_i915_gem_object *obj) · 64 unmodified lines
107 118
108#define assert_object_held(obj) dma_resv_assert_held((obj)->base.resv)119#define assert_object_held(obj) dma_resv_assert_held((obj)->base.resv)
109 120
121/*
122 * If more than one potential simultaneous locker, assert held.
123 */
124static inline void assert_object_held_shared(struct drm_i915_gem_object *obj)
125{
126 /*
127 * Note mm list lookup is protected by
128 * kref_get_unless_zero().
129 */
130 if (IS_ENABLED(CONFIG_LOCKDEP) &&
131 kref_read(&obj->base.refcount) > 0)
132 assert_object_held(obj);
133}
134
110static inline int __i915_gem_object_lock(struct drm_i915_gem_object *obj,135static inline int __i915_gem_object_lock(struct drm_i915_gem_object *obj,
111 struct i915_gem_ww_ctx *ww,136 struct i915_gem_ww_ctx *ww,
112 bool intr)137 bool intr)
@@ -152,11 +177,6 @@ static inline void i915_gem_object_unlock(struct drm_i915_gem_object *obj) · 39 unmodified lines
152 dma_resv_unlock(obj->base.resv);177 dma_resv_unlock(obj->base.resv);
153}178}
154 179
155struct dma_fence *
156i915_gem_object_lock_fence(struct drm_i915_gem_object *obj);
157void i915_gem_object_unlock_fence(struct drm_i915_gem_object *obj,
158 struct dma_fence *fence);
159
160static inline void180static inline void
161i915_gem_object_set_readonly(struct drm_i915_gem_object *obj)181i915_gem_object_set_readonly(struct drm_i915_gem_object *obj)
162{182{
@@ -215,7 +235,7 @@ i915_gem_object_type_has(const struct drm_i915_gem_object *obj, · 52 unmodified lines
215static inline bool235static inline bool
216i915_gem_object_has_struct_page(const struct drm_i915_gem_object *obj)236i915_gem_object_has_struct_page(const struct drm_i915_gem_object *obj)
217{237{
218 return i915_gem_object_type_has(obj, I915_GEM_OBJECT_HAS_STRUCT_PAGE);238 return obj->flags & I915_BO_ALLOC_STRUCT_PAGE;
219}239}
220 240
221static inline bool241static inline bool
@@ -242,12 +262,6 @@ i915_gem_object_never_mmap(const struct drm_i915_gem_object *obj) · 20 unmodified lines
242 return i915_gem_object_type_has(obj, I915_GEM_OBJECT_NO_MMAP);262 return i915_gem_object_type_has(obj, I915_GEM_OBJECT_NO_MMAP);
243}263}
244 264
245static inline bool
246i915_gem_object_needs_async_cancel(const struct drm_i915_gem_object *obj)
247{
248 return i915_gem_object_type_has(obj, I915_GEM_OBJECT_ASYNC_CANCEL);
249}
250
251static inline bool265static inline bool
252i915_gem_object_is_framebuffer(const struct drm_i915_gem_object *obj)266i915_gem_object_is_framebuffer(const struct drm_i915_gem_object *obj)
253{267{
@@ -299,22 +313,22 @@ struct scatterlist * · 45 unmodified lines
299__i915_gem_object_get_sg(struct drm_i915_gem_object *obj,313__i915_gem_object_get_sg(struct drm_i915_gem_object *obj,
300 struct i915_gem_object_page_iter *iter,314 struct i915_gem_object_page_iter *iter,
301 unsigned int n,315 unsigned int n,
302 unsigned int *offset);316 unsigned int *offset, bool allow_alloc);
303 317
304static inline struct scatterlist *318static inline struct scatterlist *
305i915_gem_object_get_sg(struct drm_i915_gem_object *obj,319i915_gem_object_get_sg(struct drm_i915_gem_object *obj,
306 unsigned int n,320 unsigned int n,
307 unsigned int *offset)321 unsigned int *offset, bool allow_alloc)
308{322{
309 return __i915_gem_object_get_sg(obj, &obj->mm.get_page, n, offset);323 return __i915_gem_object_get_sg(obj, &obj->mm.get_page, n, offset, allow_alloc);
310}324}
311 325
312static inline struct scatterlist *326static inline struct scatterlist *
313i915_gem_object_get_sg_dma(struct drm_i915_gem_object *obj,327i915_gem_object_get_sg_dma(struct drm_i915_gem_object *obj,
314 unsigned int n,328 unsigned int n,
315 unsigned int *offset)329 unsigned int *offset, bool allow_alloc)
316{330{
317 return __i915_gem_object_get_sg(obj, &obj->mm.get_dma_page, n, offset);331 return __i915_gem_object_get_sg(obj, &obj->mm.get_dma_page, n, offset, allow_alloc);
318}332}
319 333
320struct page *334struct page *
@@ -341,27 +355,10 @@ void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj, · 20 unmodified lines
341int ____i915_gem_object_get_pages(struct drm_i915_gem_object *obj);355int ____i915_gem_object_get_pages(struct drm_i915_gem_object *obj);
342int __i915_gem_object_get_pages(struct drm_i915_gem_object *obj);356int __i915_gem_object_get_pages(struct drm_i915_gem_object *obj);
343 357
344enum i915_mm_subclass { /* lockdep subclass for obj->mm.lock/struct_mutex */
345 I915_MM_NORMAL = 0,
346 /*
347 * Only used by struct_mutex, when called "recursively" from
348 * direct-reclaim-esque. Safe because there is only every one
349 * struct_mutex in the entire system.
350 */
351 I915_MM_SHRINKER = 1,
352 /*
353 * Used for obj->mm.lock when allocating pages. Safe because the object
354 * isn't yet on any LRU, and therefore the shrinker can't deadlock on
355 * it. As soon as the object has pages, obj->mm.lock nests within
356 * fs_reclaim.
357 */
358 I915_MM_GET_PAGES = 1,
359};
360
361static inline int __must_check358static inline int __must_check
362i915_gem_object_pin_pages(struct drm_i915_gem_object *obj)359i915_gem_object_pin_pages(struct drm_i915_gem_object *obj)
363{360{
364 might_lock_nested(&obj->mm.lock, I915_MM_GET_PAGES);361 assert_object_held(obj);
365 362
366 if (atomic_inc_not_zero(&obj->mm.pages_pin_count))363 if (atomic_inc_not_zero(&obj->mm.pages_pin_count))
367 return 0;364 return 0;
@@ -369,6 +366,8 @@ i915_gem_object_pin_pages(struct drm_i915_gem_object *obj) · 1 unmodified line
369 return __i915_gem_object_get_pages(obj);366 return __i915_gem_object_get_pages(obj);
370}367}
371 368
369int i915_gem_object_pin_pages_unlocked(struct drm_i915_gem_object *obj);
370
372static inline bool371static inline bool
373i915_gem_object_has_pages(struct drm_i915_gem_object *obj)372i915_gem_object_has_pages(struct drm_i915_gem_object *obj)
374{373{
@@ -427,6 +426,9 @@ void i915_gem_object_writeback(struct drm_i915_gem_object *obj); · 52 unmodified lines
427void *__must_check i915_gem_object_pin_map(struct drm_i915_gem_object *obj,426void *__must_check i915_gem_object_pin_map(struct drm_i915_gem_object *obj,
428 enum i915_map_type type);427 enum i915_map_type type);
429 428
429void *__must_check i915_gem_object_pin_map_unlocked(struct drm_i915_gem_object *obj,
430 enum i915_map_type type);
431
430void __i915_gem_object_flush_map(struct drm_i915_gem_object *obj,432void __i915_gem_object_flush_map(struct drm_i915_gem_object *obj,
431 unsigned long offset,433 unsigned long offset,
432 unsigned long size);434 unsigned long size);
@@ -495,6 +497,7 @@ int __must_check · 62 unmodified lines
495i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, bool write);497i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, bool write);
496struct i915_vma * __must_check498struct i915_vma * __must_check
497i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,499i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
500 struct i915_gem_ww_ctx *ww,
498 u32 alignment,501 u32 alignment,
499 const struct i915_ggtt_view *view,502 const struct i915_ggtt_view *view,
500 unsigned int flags);503 unsigned int flags);
@@ -558,4 +561,25 @@ int i915_gem_object_read_from_page(struct drm_i915_gem_object *obj, u64 offset, · 57 unmodified lines
558 561
559bool i915_gem_object_is_shmem(const struct drm_i915_gem_object *obj);562bool i915_gem_object_is_shmem(const struct drm_i915_gem_object *obj);
560 563
564#ifdef CONFIG_MMU_NOTIFIER
565static inline bool
566i915_gem_object_is_userptr(struct drm_i915_gem_object *obj)
567{
568 return obj->userptr.notifier.mm;
569}
570
571int i915_gem_object_userptr_submit_init(struct drm_i915_gem_object *obj);
572int i915_gem_object_userptr_submit_done(struct drm_i915_gem_object *obj);
573void i915_gem_object_userptr_submit_fini(struct drm_i915_gem_object *obj);
574int i915_gem_object_userptr_validate(struct drm_i915_gem_object *obj);
575#else
576static inline bool i915_gem_object_is_userptr(struct drm_i915_gem_object *obj) { return false; }
577
578static inline int i915_gem_object_userptr_submit_init(struct drm_i915_gem_object *obj) { GEM_BUG_ON(1); return -ENODEV; }
579static inline int i915_gem_object_userptr_submit_done(struct drm_i915_gem_object *obj) { GEM_BUG_ON(1); return -ENODEV; }
580static inline void i915_gem_object_userptr_submit_fini(struct drm_i915_gem_object *obj) { GEM_BUG_ON(1); }
581static inline int i915_gem_object_userptr_validate(struct drm_i915_gem_object *obj) { GEM_BUG_ON(1); return -ENODEV; }
582
583#endif
584
561#endif585#endif
drivers/gpu/drm/i915/gem/i915_gem_object_blt.c+6−0
@@ -55,6 +55,9 @@ struct i915_vma *intel_emit_vma_fill_blt(struct intel_context *ce, · 54 unmodified lines
55 if (unlikely(err))55 if (unlikely(err))
56 goto out_put;56 goto out_put;
57 57
58 /* we pinned the pool, mark it as such */
59 intel_gt_buffer_pool_mark_used(pool);
60
58 cmd = i915_gem_object_pin_map(pool->obj, pool->type);61 cmd = i915_gem_object_pin_map(pool->obj, pool->type);
59 if (IS_ERR(cmd)) {62 if (IS_ERR(cmd)) {
60 err = PTR_ERR(cmd);63 err = PTR_ERR(cmd);
@@ -277,6 +280,9 @@ struct i915_vma *intel_emit_vma_copy_blt(struct intel_context *ce, · 216 unmodified lines
277 if (unlikely(err))280 if (unlikely(err))
278 goto out_put;281 goto out_put;
279 282
283 /* we pinned the pool, mark it as such */
284 intel_gt_buffer_pool_mark_used(pool);
285
280 cmd = i915_gem_object_pin_map(pool->obj, pool->type);286 cmd = i915_gem_object_pin_map(pool->obj, pool->type);
281 if (IS_ERR(cmd)) {287 if (IS_ERR(cmd)) {
282 err = PTR_ERR(cmd);288 err = PTR_ERR(cmd);
drivers/gpu/drm/i915/gem/i915_gem_object_types.h+14−9
@@ -7,6 +7,8 @@ · 6 unmodified lines
7#ifndef __I915_GEM_OBJECT_TYPES_H__7#ifndef __I915_GEM_OBJECT_TYPES_H__
8#define __I915_GEM_OBJECT_TYPES_H__8#define __I915_GEM_OBJECT_TYPES_H__
9 9
10#include <linux/mmu_notifier.h>
11
10#include <drm/drm_gem.h>12#include <drm/drm_gem.h>
11#include <uapi/drm/i915_drm.h>13#include <uapi/drm/i915_drm.h>
12 14
@@ -30,12 +32,10 @@ struct i915_lut_handle { · 17 unmodified lines
30 32
31struct drm_i915_gem_object_ops {33struct drm_i915_gem_object_ops {
32 unsigned int flags;34 unsigned int flags;
33#define I915_GEM_OBJECT_HAS_STRUCT_PAGE BIT(0)
34#define I915_GEM_OBJECT_HAS_IOMEM BIT(1)35#define I915_GEM_OBJECT_HAS_IOMEM BIT(1)
35#define I915_GEM_OBJECT_IS_SHRINKABLE BIT(2)36#define I915_GEM_OBJECT_IS_SHRINKABLE BIT(2)
36#define I915_GEM_OBJECT_IS_PROXY BIT(3)37#define I915_GEM_OBJECT_IS_PROXY BIT(3)
37#define I915_GEM_OBJECT_NO_MMAP BIT(4)38#define I915_GEM_OBJECT_NO_MMAP BIT(4)
38#define I915_GEM_OBJECT_ASYNC_CANCEL BIT(5)
39 39
40 /* Interface between the GEM object and its backing storage.40 /* Interface between the GEM object and its backing storage.
41 * get_pages() is called once prior to the use of the associated set41 * get_pages() is called once prior to the use of the associated set
@@ -171,9 +171,12 @@ struct drm_i915_gem_object { · 129 unmodified lines
171 unsigned long flags;171 unsigned long flags;
172#define I915_BO_ALLOC_CONTIGUOUS BIT(0)172#define I915_BO_ALLOC_CONTIGUOUS BIT(0)
173#define I915_BO_ALLOC_VOLATILE BIT(1)173#define I915_BO_ALLOC_VOLATILE BIT(1)
174#define I915_BO_ALLOC_FLAGS (I915_BO_ALLOC_CONTIGUOUS | I915_BO_ALLOC_VOLATILE)174#define I915_BO_ALLOC_STRUCT_PAGE BIT(2)
175#define I915_BO_READONLY BIT(2)175#define I915_BO_ALLOC_FLAGS (I915_BO_ALLOC_CONTIGUOUS | \
176#define I915_TILING_QUIRK_BIT 3 /* unknown swizzling; do not release! */176 I915_BO_ALLOC_VOLATILE | \
177 I915_BO_ALLOC_STRUCT_PAGE)
178#define I915_BO_READONLY BIT(3)
179#define I915_TILING_QUIRK_BIT 4 /* unknown swizzling; do not release! */
177 180
178 /*181 /*
179 * Is the object to be mapped as read-only to the GPU182 * Is the object to be mapped as read-only to the GPU
@@ -213,7 +216,6 @@ struct drm_i915_gem_object { · 33 unmodified lines
213 * Protects the pages and their use. Do not use directly, but216 * Protects the pages and their use. Do not use directly, but
214 * instead go through the pin/unpin interfaces.217 * instead go through the pin/unpin interfaces.
215 */218 */
216 struct mutex lock;
217 atomic_t pages_pin_count;219 atomic_t pages_pin_count;
218 atomic_t shrink_pin;220 atomic_t shrink_pin;
219 221
@@ -288,13 +290,16 @@ struct drm_i915_gem_object { · 68 unmodified lines
288 unsigned long *bit_17;290 unsigned long *bit_17;
289 291
290 union {292 union {
293#ifdef CONFIG_MMU_NOTIFIER
291 struct i915_gem_userptr {294 struct i915_gem_userptr {
292 uintptr_t ptr;295 uintptr_t ptr;
296 unsigned long notifier_seq;
293 297
294 struct i915_mm_struct *mm;298 struct mmu_interval_notifier notifier;
295 struct i915_mmu_object *mmu_object;299 struct page **pvec;
296 struct work_struct *work;300 int page_ref;
297 } userptr;301 } userptr;
302#endif
298 303
299 struct drm_mm_node *stolen;304 struct drm_mm_node *stolen;
300 305
drivers/gpu/drm/i915/gem/i915_gem_pages.c+69−40
@@ -19,7 +19,7 @@ void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj, · 18 unmodified lines
19 bool shrinkable;19 bool shrinkable;
20 int i;20 int i;
21 21
22 lockdep_assert_held(&obj->mm.lock);22 assert_object_held_shared(obj);
23 23
24 if (i915_gem_object_is_volatile(obj))24 if (i915_gem_object_is_volatile(obj))
25 obj->mm.madv = I915_MADV_DONTNEED;25 obj->mm.madv = I915_MADV_DONTNEED;
@@ -70,6 +70,7 @@ void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj, · 44 unmodified lines
70 struct list_head *list;70 struct list_head *list;
71 unsigned long flags;71 unsigned long flags;
72 72
73 assert_object_held(obj);
73 spin_lock_irqsave(&i915->mm.obj_lock, flags);74 spin_lock_irqsave(&i915->mm.obj_lock, flags);
74 75
75 i915->mm.shrink_count++;76 i915->mm.shrink_count++;
@@ -91,6 +92,8 @@ int ____i915_gem_object_get_pages(struct drm_i915_gem_object *obj) · 15 unmodified lines
91 struct drm_i915_private *i915 = to_i915(obj->base.dev);92 struct drm_i915_private *i915 = to_i915(obj->base.dev);
92 int err;93 int err;
93 94
95 assert_object_held_shared(obj);
96
94 if (unlikely(obj->mm.madv != I915_MADV_WILLNEED)) {97 if (unlikely(obj->mm.madv != I915_MADV_WILLNEED)) {
95 drm_dbg(&i915->drm,98 drm_dbg(&i915->drm,
96 "Attempting to obtain a purgeable object\n");99 "Attempting to obtain a purgeable object\n");
@@ -114,23 +117,41 @@ int __i915_gem_object_get_pages(struct drm_i915_gem_object *obj) · 17 unmodified lines
114{117{
115 int err;118 int err;
116 119
117 err = mutex_lock_interruptible_nested(&obj->mm.lock, I915_MM_GET_PAGES);120 assert_object_held(obj);
118 if (err)121
119 return err;122 assert_object_held_shared(obj);
120 123
121 if (unlikely(!i915_gem_object_has_pages(obj))) {124 if (unlikely(!i915_gem_object_has_pages(obj))) {
122 GEM_BUG_ON(i915_gem_object_has_pinned_pages(obj));125 GEM_BUG_ON(i915_gem_object_has_pinned_pages(obj));
123 126
124 err = ____i915_gem_object_get_pages(obj);127 err = ____i915_gem_object_get_pages(obj);
125 if (err)128 if (err)
126 goto unlock;129 return err;
127 130
128 smp_mb__before_atomic();131 smp_mb__before_atomic();
129 }132 }
130 atomic_inc(&obj->mm.pages_pin_count);133 atomic_inc(&obj->mm.pages_pin_count);
131 134
132unlock:135 return 0;
133 mutex_unlock(&obj->mm.lock);136}
137
138int i915_gem_object_pin_pages_unlocked(struct drm_i915_gem_object *obj)
139{
140 struct i915_gem_ww_ctx ww;
141 int err;
142
143 i915_gem_ww_ctx_init(&ww, true);
144retry:
145 err = i915_gem_object_lock(obj, &ww);
146 if (!err)
147 err = i915_gem_object_pin_pages(obj);
148
149 if (err == -EDEADLK) {
150 err = i915_gem_ww_ctx_backoff(&ww);
151 if (!err)
152 goto retry;
153 }
154 i915_gem_ww_ctx_fini(&ww);
134 return err;155 return err;
135}156}
136 157
@@ -145,7 +166,7 @@ void i915_gem_object_truncate(struct drm_i915_gem_object *obj) · 8 unmodified lines
145/* Try to discard unwanted pages */166/* Try to discard unwanted pages */
146void i915_gem_object_writeback(struct drm_i915_gem_object *obj)167void i915_gem_object_writeback(struct drm_i915_gem_object *obj)
147{168{
148 lockdep_assert_held(&obj->mm.lock);169 assert_object_held_shared(obj);
149 GEM_BUG_ON(i915_gem_object_has_pages(obj));170 GEM_BUG_ON(i915_gem_object_has_pages(obj));
150 171
151 if (obj->ops->writeback)172 if (obj->ops->writeback)
@@ -176,6 +197,8 @@ __i915_gem_object_unset_pages(struct drm_i915_gem_object *obj) · 24 unmodified lines
176{197{
177 struct sg_table *pages;198 struct sg_table *pages;
178 199
200 assert_object_held_shared(obj);
201
179 pages = fetch_and_zero(&obj->mm.pages);202 pages = fetch_and_zero(&obj->mm.pages);
180 if (IS_ERR_OR_NULL(pages))203 if (IS_ERR_OR_NULL(pages))
181 return pages;204 return pages;
@@ -199,17 +222,12 @@ __i915_gem_object_unset_pages(struct drm_i915_gem_object *obj) · 17 unmodified lines
199int __i915_gem_object_put_pages(struct drm_i915_gem_object *obj)222int __i915_gem_object_put_pages(struct drm_i915_gem_object *obj)
200{223{
201 struct sg_table *pages;224 struct sg_table *pages;
202 int err;
203 225
204 if (i915_gem_object_has_pinned_pages(obj))226 if (i915_gem_object_has_pinned_pages(obj))
205 return -EBUSY;227 return -EBUSY;
206 228
207 /* May be called by shrinker from within get_pages() (on another bo) */229 /* May be called by shrinker from within get_pages() (on another bo) */
208 mutex_lock(&obj->mm.lock);230 assert_object_held_shared(obj);
209 if (unlikely(atomic_read(&obj->mm.pages_pin_count))) {
210 err = -EBUSY;
211 goto unlock;
212 }
213 231
214 i915_gem_object_release_mmap_offset(obj);232 i915_gem_object_release_mmap_offset(obj);
215 233
@@ -226,17 +244,10 @@ int __i915_gem_object_put_pages(struct drm_i915_gem_object *obj) · 10 unmodified lines
226 * get_pages backends we should be better able to handle the244 * get_pages backends we should be better able to handle the
227 * cancellation of the async task in a more uniform manner.245 * cancellation of the async task in a more uniform manner.
228 */246 */
229 if (!pages && !i915_gem_object_needs_async_cancel(obj))247 if (!IS_ERR_OR_NULL(pages))
230 pages = ERR_PTR(-EINVAL);
231
232 if (!IS_ERR(pages))
233 obj->ops->put_pages(obj, pages);248 obj->ops->put_pages(obj, pages);
234 249
235 err = 0;250 return 0;
236unlock:
237 mutex_unlock(&obj->mm.lock);
238
239 return err;
240}251}
241 252
242/* The 'mapping' part of i915_gem_object_pin_map() below */253/* The 'mapping' part of i915_gem_object_pin_map() below */
@@ -333,18 +344,15 @@ void *i915_gem_object_pin_map(struct drm_i915_gem_object *obj, · 90 unmodified lines
333 enum i915_map_type type)344 enum i915_map_type type)
334{345{
335 enum i915_map_type has_type;346 enum i915_map_type has_type;
336 unsigned int flags;
337 bool pinned;347 bool pinned;
338 void *ptr;348 void *ptr;
339 int err;349 int err;
340 350
341 flags = I915_GEM_OBJECT_HAS_STRUCT_PAGE | I915_GEM_OBJECT_HAS_IOMEM;351 if (!i915_gem_object_has_struct_page(obj) &&
342 if (!i915_gem_object_type_has(obj, flags))352 !i915_gem_object_type_has(obj, I915_GEM_OBJECT_HAS_IOMEM))
343 return ERR_PTR(-ENXIO);353 return ERR_PTR(-ENXIO);
344 354
345 err = mutex_lock_interruptible_nested(&obj->mm.lock, I915_MM_GET_PAGES);355 assert_object_held(obj);
346 if (err)
347 return ERR_PTR(err);
348 356
349 pinned = !(type & I915_MAP_OVERRIDE);357 pinned = !(type & I915_MAP_OVERRIDE);
350 type &= ~I915_MAP_OVERRIDE;358 type &= ~I915_MAP_OVERRIDE;
@@ -354,10 +362,8 @@ void *i915_gem_object_pin_map(struct drm_i915_gem_object *obj, · 3 unmodified lines
354 GEM_BUG_ON(i915_gem_object_has_pinned_pages(obj));362 GEM_BUG_ON(i915_gem_object_has_pinned_pages(obj));
355 363
356 err = ____i915_gem_object_get_pages(obj);364 err = ____i915_gem_object_get_pages(obj);
357 if (err) {365 if (err)
358 ptr = ERR_PTR(err);366 return ERR_PTR(err);
359 goto out_unlock;
360 }
361 367
362 smp_mb__before_atomic();368 smp_mb__before_atomic();
363 }369 }
@@ -392,13 +398,23 @@ void *i915_gem_object_pin_map(struct drm_i915_gem_object *obj, · 28 unmodified lines
392 obj->mm.mapping = page_pack_bits(ptr, type);398 obj->mm.mapping = page_pack_bits(ptr, type);
393 }399 }
394 400
395out_unlock:
396 mutex_unlock(&obj->mm.lock);
397 return ptr;401 return ptr;
398 402
399err_unpin:403err_unpin:
400 atomic_dec(&obj->mm.pages_pin_count);404 atomic_dec(&obj->mm.pages_pin_count);
401 goto out_unlock;405 return ptr;
406}
407
408void *i915_gem_object_pin_map_unlocked(struct drm_i915_gem_object *obj,
409 enum i915_map_type type)
410{
411 void *ret;
412
413 i915_gem_object_lock(obj, NULL);
414 ret = i915_gem_object_pin_map(obj, type);
415 i915_gem_object_unlock(obj);
416
417 return ret;
402}418}
403 419
404void __i915_gem_object_flush_map(struct drm_i915_gem_object *obj,420void __i915_gem_object_flush_map(struct drm_i915_gem_object *obj,
@@ -448,7 +464,8 @@ struct scatterlist * · 43 unmodified lines
448__i915_gem_object_get_sg(struct drm_i915_gem_object *obj,464__i915_gem_object_get_sg(struct drm_i915_gem_object *obj,
449 struct i915_gem_object_page_iter *iter,465 struct i915_gem_object_page_iter *iter,
450 unsigned int n,466 unsigned int n,
451 unsigned int *offset)467 unsigned int *offset,
468 bool allow_alloc)
452{469{
453 const bool dma = iter == &obj->mm.get_dma_page;470 const bool dma = iter == &obj->mm.get_dma_page;
454 struct scatterlist *sg;471 struct scatterlist *sg;
@@ -470,6 +487,9 @@ __i915_gem_object_get_sg(struct drm_i915_gem_object *obj, · 15 unmodified lines
470 if (n < READ_ONCE(iter->sg_idx))487 if (n < READ_ONCE(iter->sg_idx))
471 goto lookup;488 goto lookup;
472 489
490 if (!allow_alloc)
491 goto manual_lookup;
492
473 mutex_lock(&iter->lock);493 mutex_lock(&iter->lock);
474 494
475 /* We prefer to reuse the last sg so that repeated lookup of this495 /* We prefer to reuse the last sg so that repeated lookup of this
@@ -519,7 +539,16 @@ scan: · 43 unmodified lines
519 if (unlikely(n < idx)) /* insertion completed by another thread */539 if (unlikely(n < idx)) /* insertion completed by another thread */
520 goto lookup;540 goto lookup;
521 541
522 /* In case we failed to insert the entry into the radixtree, we need542 goto manual_walk;
543
544manual_lookup:
545 idx = 0;
546 sg = obj->mm.pages->sgl;
547 count = __sg_page_count(sg);
548
549manual_walk:
550 /*
551 * In case we failed to insert the entry into the radixtree, we need
523 * to look beyond the current sg.552 * to look beyond the current sg.
524 */553 */
525 while (idx + count <= n) {554 while (idx + count <= n) {
@@ -566,7 +595,7 @@ i915_gem_object_get_page(struct drm_i915_gem_object *obj, unsigned int n) · 40 unmodified lines
566 595
567 GEM_BUG_ON(!i915_gem_object_has_struct_page(obj));596 GEM_BUG_ON(!i915_gem_object_has_struct_page(obj));
568 597
569 sg = i915_gem_object_get_sg(obj, n, &offset);598 sg = i915_gem_object_get_sg(obj, n, &offset, true);
570 return nth_page(sg_page(sg), offset);599 return nth_page(sg_page(sg), offset);
571}600}
572 601
@@ -592,7 +621,7 @@ i915_gem_object_get_dma_address_len(struct drm_i915_gem_object *obj, · 19 unmodified lines
592 struct scatterlist *sg;621 struct scatterlist *sg;
593 unsigned int offset;622 unsigned int offset;
594 623
595 sg = i915_gem_object_get_sg_dma(obj, n, &offset);624 sg = i915_gem_object_get_sg_dma(obj, n, &offset, true);
596 625
597 if (len)626 if (len)
598 *len = sg_dma_len(sg) - (offset << PAGE_SHIFT);627 *len = sg_dma_len(sg) - (offset << PAGE_SHIFT);
drivers/gpu/drm/i915/gem/i915_gem_phys.c+47−63
@@ -76,6 +76,8 @@ static int i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj) · 75 unmodified lines
76 76
77 intel_gt_chipset_flush(&to_i915(obj->base.dev)->gt);77 intel_gt_chipset_flush(&to_i915(obj->base.dev)->gt);
78 78
79 /* We're no longer struct page backed */
80 obj->flags &= ~I915_BO_ALLOC_STRUCT_PAGE;
79 __i915_gem_object_set_pages(obj, st, sg->length);81 __i915_gem_object_set_pages(obj, st, sg->length);
80 82
81 return 0;83 return 0;
@@ -89,7 +91,7 @@ err_pci: · 7 unmodified lines
89 return -ENOMEM;91 return -ENOMEM;
90}92}
91 93
92static void94void
93i915_gem_object_put_pages_phys(struct drm_i915_gem_object *obj,95i915_gem_object_put_pages_phys(struct drm_i915_gem_object *obj,
94 struct sg_table *pages)96 struct sg_table *pages)
95{97{
@@ -134,9 +136,8 @@ i915_gem_object_put_pages_phys(struct drm_i915_gem_object *obj, · 38 unmodified lines
134 vaddr, dma);136 vaddr, dma);
135}137}
136 138
137static int139int i915_gem_object_pwrite_phys(struct drm_i915_gem_object *obj,
138phys_pwrite(struct drm_i915_gem_object *obj,140 const struct drm_i915_gem_pwrite *args)
139 const struct drm_i915_gem_pwrite *args)
140{141{
141 void *vaddr = sg_page(obj->mm.pages->sgl) + args->offset;142 void *vaddr = sg_page(obj->mm.pages->sgl) + args->offset;
142 char __user *user_data = u64_to_user_ptr(args->data_ptr);143 char __user *user_data = u64_to_user_ptr(args->data_ptr);
@@ -165,9 +166,8 @@ phys_pwrite(struct drm_i915_gem_object *obj, · 22 unmodified lines
165 return 0;166 return 0;
166}167}
167 168
168static int169int i915_gem_object_pread_phys(struct drm_i915_gem_object *obj,
169phys_pread(struct drm_i915_gem_object *obj,170 const struct drm_i915_gem_pread *args)
170 const struct drm_i915_gem_pread *args)
171{171{
172 void *vaddr = sg_page(obj->mm.pages->sgl) + args->offset;172 void *vaddr = sg_page(obj->mm.pages->sgl) + args->offset;
173 char __user *user_data = u64_to_user_ptr(args->data_ptr);173 char __user *user_data = u64_to_user_ptr(args->data_ptr);
@@ -186,62 +186,14 @@ phys_pread(struct drm_i915_gem_object *obj, · 12 unmodified lines
186 return 0;186 return 0;
187}187}
188 188
189static void phys_release(struct drm_i915_gem_object *obj)189static int i915_gem_object_shmem_to_phys(struct drm_i915_gem_object *obj)
190{
191 fput(obj->base.filp);
192}
193
194static const struct drm_i915_gem_object_ops i915_gem_phys_ops = {
195 .name = "i915_gem_object_phys",
196 .get_pages = i915_gem_object_get_pages_phys,
197 .put_pages = i915_gem_object_put_pages_phys,
198
199 .pread = phys_pread,
200 .pwrite = phys_pwrite,
201
202 .release = phys_release,
203};
204
205int i915_gem_object_attach_phys(struct drm_i915_gem_object *obj, int align)
206{190{
207 struct sg_table *pages;191 struct sg_table *pages;
208 int err;192 int err;
209 193
210 if (align > obj->base.size)
211 return -EINVAL;
212
213 if (obj->ops == &i915_gem_phys_ops)
214 return 0;
215
216 if (!i915_gem_object_is_shmem(obj))
217 return -EINVAL;
218
219 err = i915_gem_object_unbind(obj, I915_GEM_OBJECT_UNBIND_ACTIVE);
220 if (err)
221 return err;
222
223 mutex_lock_nested(&obj->mm.lock, I915_MM_GET_PAGES);
224
225 if (obj->mm.madv != I915_MADV_WILLNEED) {
226 err = -EFAULT;
227 goto err_unlock;
228 }
229
230 if (i915_gem_object_has_tiling_quirk(obj)) {
231 err = -EFAULT;
232 goto err_unlock;
233 }
234
235 if (obj->mm.mapping) {
236 err = -EBUSY;
237 goto err_unlock;
238 }
239
240 pages = __i915_gem_object_unset_pages(obj);194 pages = __i915_gem_object_unset_pages(obj);
241 195
242 obj->ops = &i915_gem_phys_ops;196 err = i915_gem_object_get_pages_phys(obj);
243
244 err = ____i915_gem_object_get_pages(obj);
245 if (err)197 if (err)
246 goto err_xfer;198 goto err_xfer;
247 199
@@ -249,25 +201,57 @@ int i915_gem_object_attach_phys(struct drm_i915_gem_object *obj, int align) · 1 unmodified line
249 __i915_gem_object_pin_pages(obj);201 __i915_gem_object_pin_pages(obj);
250 202
251 if (!IS_ERR_OR_NULL(pages))203 if (!IS_ERR_OR_NULL(pages))
252 i915_gem_shmem_ops.put_pages(obj, pages);204 i915_gem_object_put_pages_shmem(obj, pages);
253 205
254 i915_gem_object_release_memory_region(obj);206 i915_gem_object_release_memory_region(obj);
255
256 mutex_unlock(&obj->mm.lock);
257 return 0;207 return 0;
258 208
259err_xfer:209err_xfer:
260 obj->ops = &i915_gem_shmem_ops;
261 if (!IS_ERR_OR_NULL(pages)) {210 if (!IS_ERR_OR_NULL(pages)) {
262 unsigned int sg_page_sizes = i915_sg_page_sizes(pages->sgl);211 unsigned int sg_page_sizes = i915_sg_page_sizes(pages->sgl);
263 212
264 __i915_gem_object_set_pages(obj, pages, sg_page_sizes);213 __i915_gem_object_set_pages(obj, pages, sg_page_sizes);
265 }214 }
266err_unlock:
267 mutex_unlock(&obj->mm.lock);
268 return err;215 return err;
269}216}
270 217
218int i915_gem_object_attach_phys(struct drm_i915_gem_object *obj, int align)
219{
220 int err;
221
222 assert_object_held(obj);
223
224 if (align > obj->base.size)
225 return -EINVAL;
226
227 if (!i915_gem_object_is_shmem(obj))
228 return -EINVAL;
229
230 if (!i915_gem_object_has_struct_page(obj))
231 return 0;
232
233 err = i915_gem_object_unbind(obj, I915_GEM_OBJECT_UNBIND_ACTIVE);
234 if (err)
235 return err;
236
237 if (obj->mm.madv != I915_MADV_WILLNEED)
238 return -EFAULT;
239
240 if (i915_gem_object_has_tiling_quirk(obj))
241 return -EFAULT;
242
243 if (obj->mm.mapping || i915_gem_object_has_pinned_pages(obj))
244 return -EBUSY;
245
246 if (unlikely(obj->mm.madv != I915_MADV_WILLNEED)) {
247 drm_dbg(obj->base.dev,
248 "Attempting to obtain a purgeable object\n");
249 return -EFAULT;
250 }
251
252 return i915_gem_object_shmem_to_phys(obj);
253}
254
271#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)255#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
272#include "selftests/i915_gem_phys.c"256#include "selftests/i915_gem_phys.c"
273#endif257#endif
drivers/gpu/drm/i915/gem/i915_gem_pm.c+1−1
@@ -116,7 +116,7 @@ int i915_gem_freeze_late(struct drm_i915_private *i915) · 115 unmodified lines
116 */116 */
117 117
118 with_intel_runtime_pm(&i915->runtime_pm, wakeref)118 with_intel_runtime_pm(&i915->runtime_pm, wakeref)
119 i915_gem_shrink(i915, -1UL, NULL, ~0);119 i915_gem_shrink(NULL, i915, -1UL, NULL, ~0);
120 i915_gem_drain_freed_objects(i915);120 i915_gem_drain_freed_objects(i915);
121 121
122 wbinvd_on_all_cpus();122 wbinvd_on_all_cpus();
drivers/gpu/drm/i915/gem/i915_gem_region.c+1−3
@@ -106,13 +106,11 @@ err_free_sg: · 105 unmodified lines
106}106}
107 107
108void i915_gem_object_init_memory_region(struct drm_i915_gem_object *obj,108void i915_gem_object_init_memory_region(struct drm_i915_gem_object *obj,
109 struct intel_memory_region *mem,109 struct intel_memory_region *mem)
110 unsigned long flags)
111{110{
112 INIT_LIST_HEAD(&obj->mm.blocks);111 INIT_LIST_HEAD(&obj->mm.blocks);
113 obj->mm.region = intel_memory_region_get(mem);112 obj->mm.region = intel_memory_region_get(mem);
114 113
115 obj->flags |= flags;
116 if (obj->base.size <= mem->min_page_size)114 if (obj->base.size <= mem->min_page_size)
117 obj->flags |= I915_BO_ALLOC_CONTIGUOUS;115 obj->flags |= I915_BO_ALLOC_CONTIGUOUS;
118 116
drivers/gpu/drm/i915/gem/i915_gem_region.h+1−2
@@ -17,8 +17,7 @@ void i915_gem_object_put_pages_buddy(struct drm_i915_gem_object *obj, · 16 unmodified lines
17 struct sg_table *pages);17 struct sg_table *pages);
18 18
19void i915_gem_object_init_memory_region(struct drm_i915_gem_object *obj,19void i915_gem_object_init_memory_region(struct drm_i915_gem_object *obj,
20 struct intel_memory_region *mem,20 struct intel_memory_region *mem);
21 unsigned long flags);
22void i915_gem_object_release_memory_region(struct drm_i915_gem_object *obj);21void i915_gem_object_release_memory_region(struct drm_i915_gem_object *obj);
23 22
24struct drm_i915_gem_object *23struct drm_i915_gem_object *
drivers/gpu/drm/i915/gem/i915_gem_shmem.c+31−8
@@ -99,7 +99,7 @@ rebuild_st: · 98 unmodified lines
99 goto err_sg;99 goto err_sg;
100 }100 }
101 101
102 i915_gem_shrink(i915, 2 * page_count, NULL, *s++);102 i915_gem_shrink(NULL, i915, 2 * page_count, NULL, *s++);
103 103
104 /*104 /*
105 * We've tried hard to allocate the memory by reaping105 * We've tried hard to allocate the memory by reaping
@@ -296,8 +296,7 @@ __i915_gem_object_release_shmem(struct drm_i915_gem_object *obj, · 190 unmodified lines
296 __start_cpu_write(obj);296 __start_cpu_write(obj);
297}297}
298 298
299static void299void i915_gem_object_put_pages_shmem(struct drm_i915_gem_object *obj, struct sg_table *pages)
300shmem_put_pages(struct drm_i915_gem_object *obj, struct sg_table *pages)
301{300{
302 struct sgt_iter sgt_iter;301 struct sgt_iter sgt_iter;
303 struct pagevec pvec;302 struct pagevec pvec;
@@ -331,6 +330,15 @@ shmem_put_pages(struct drm_i915_gem_object *obj, struct sg_table *pages) · 27 unmodified lines
331 kfree(pages);330 kfree(pages);
332}331}
333 332
333static void
334shmem_put_pages(struct drm_i915_gem_object *obj, struct sg_table *pages)
335{
336 if (likely(i915_gem_object_has_struct_page(obj)))
337 i915_gem_object_put_pages_shmem(obj, pages);
338 else
339 i915_gem_object_put_pages_phys(obj, pages);
340}
341
334static int342static int
335shmem_pwrite(struct drm_i915_gem_object *obj,343shmem_pwrite(struct drm_i915_gem_object *obj,
336 const struct drm_i915_gem_pwrite *arg)344 const struct drm_i915_gem_pwrite *arg)
@@ -343,6 +351,9 @@ shmem_pwrite(struct drm_i915_gem_object *obj, · 6 unmodified lines
343 /* Caller already validated user args */351 /* Caller already validated user args */
344 GEM_BUG_ON(!access_ok(user_data, arg->size));352 GEM_BUG_ON(!access_ok(user_data, arg->size));
345 353
354 if (!i915_gem_object_has_struct_page(obj))
355 return i915_gem_object_pwrite_phys(obj, arg);
356
346 /*357 /*
347 * Before we instantiate/pin the backing store for our use, we358 * Before we instantiate/pin the backing store for our use, we
348 * can prepopulate the shmemfs filp efficiently using a write into359 * can prepopulate the shmemfs filp efficiently using a write into
@@ -421,17 +432,27 @@ shmem_pwrite(struct drm_i915_gem_object *obj, · 72 unmodified lines
421 return 0;432 return 0;
422}433}
423 434
435static int
436shmem_pread(struct drm_i915_gem_object *obj,
437 const struct drm_i915_gem_pread *arg)
438{
439 if (!i915_gem_object_has_struct_page(obj))
440 return i915_gem_object_pread_phys(obj, arg);
441
442 return -ENODEV;
443}
444
424static void shmem_release(struct drm_i915_gem_object *obj)445static void shmem_release(struct drm_i915_gem_object *obj)
425{446{
426 i915_gem_object_release_memory_region(obj);447 if (obj->flags & I915_BO_ALLOC_STRUCT_PAGE)
448 i915_gem_object_release_memory_region(obj);
427 449
428 fput(obj->base.filp);450 fput(obj->base.filp);
429}451}
430 452
431const struct drm_i915_gem_object_ops i915_gem_shmem_ops = {453const struct drm_i915_gem_object_ops i915_gem_shmem_ops = {
432 .name = "i915_gem_object_shmem",454 .name = "i915_gem_object_shmem",
433 .flags = I915_GEM_OBJECT_HAS_STRUCT_PAGE |455 .flags = I915_GEM_OBJECT_IS_SHRINKABLE,
434 I915_GEM_OBJECT_IS_SHRINKABLE,
435 456
436 .get_pages = shmem_get_pages,457 .get_pages = shmem_get_pages,
437 .put_pages = shmem_put_pages,458 .put_pages = shmem_put_pages,
@@ -439,6 +460,7 @@ const struct drm_i915_gem_object_ops i915_gem_shmem_ops = { · 1 unmodified line
439 .writeback = shmem_writeback,460 .writeback = shmem_writeback,
440 461
441 .pwrite = shmem_pwrite,462 .pwrite = shmem_pwrite,
463 .pread = shmem_pread,
442 464
443 .release = shmem_release,465 .release = shmem_release,
444};466};
@@ -491,7 +513,8 @@ static int shmem_object_init(struct intel_memory_region *mem, · 46 unmodified lines
491 mapping_set_gfp_mask(mapping, mask);513 mapping_set_gfp_mask(mapping, mask);
492 GEM_BUG_ON(!(mapping_gfp_mask(mapping) & __GFP_RECLAIM));514 GEM_BUG_ON(!(mapping_gfp_mask(mapping) & __GFP_RECLAIM));
493 515
494 i915_gem_object_init(obj, &i915_gem_shmem_ops, &lock_class);516 i915_gem_object_init(obj, &i915_gem_shmem_ops, &lock_class,
517 I915_BO_ALLOC_STRUCT_PAGE);
495 518
496 obj->write_domain = I915_GEM_DOMAIN_CPU;519 obj->write_domain = I915_GEM_DOMAIN_CPU;
497 obj->read_domains = I915_GEM_DOMAIN_CPU;520 obj->read_domains = I915_GEM_DOMAIN_CPU;
@@ -515,7 +538,7 @@ static int shmem_object_init(struct intel_memory_region *mem, · 17 unmodified lines
515 538
516 i915_gem_object_set_cache_coherency(obj, cache_level);539 i915_gem_object_set_cache_coherency(obj, cache_level);
517 540
518 i915_gem_object_init_memory_region(obj, mem, 0);541 i915_gem_object_init_memory_region(obj, mem);
519 542
520 return 0;543 return 0;
521}544}
drivers/gpu/drm/i915/gem/i915_gem_shrinker.c+28−11
@@ -49,9 +49,9 @@ static bool unsafe_drop_pages(struct drm_i915_gem_object *obj, · 48 unmodified lines
49 flags = I915_GEM_OBJECT_UNBIND_TEST;49 flags = I915_GEM_OBJECT_UNBIND_TEST;
50 50
51 if (i915_gem_object_unbind(obj, flags) == 0)51 if (i915_gem_object_unbind(obj, flags) == 0)
52 __i915_gem_object_put_pages(obj);52 return true;
53 53
54 return !i915_gem_object_has_pages(obj);54 return false;
55}55}
56 56
57static void try_to_writeback(struct drm_i915_gem_object *obj,57static void try_to_writeback(struct drm_i915_gem_object *obj,
@@ -94,7 +94,8 @@ static void try_to_writeback(struct drm_i915_gem_object *obj, · 36 unmodified lines
94 * The number of pages of backing storage actually released.94 * The number of pages of backing storage actually released.
95 */95 */
96unsigned long96unsigned long
97i915_gem_shrink(struct drm_i915_private *i915,97i915_gem_shrink(struct i915_gem_ww_ctx *ww,
98 struct drm_i915_private *i915,
98 unsigned long target,99 unsigned long target,
99 unsigned long *nr_scanned,100 unsigned long *nr_scanned,
100 unsigned int shrink)101 unsigned int shrink)
@@ -113,6 +114,7 @@ i915_gem_shrink(struct drm_i915_private *i915, · 12 unmodified lines
113 intel_wakeref_t wakeref = 0;114 intel_wakeref_t wakeref = 0;
114 unsigned long count = 0;115 unsigned long count = 0;
115 unsigned long scanned = 0;116 unsigned long scanned = 0;
117 int err;
116 118
117 trace_i915_gem_shrink(i915, target, shrink);119 trace_i915_gem_shrink(i915, target, shrink);
118 120
@@ -200,25 +202,40 @@ i915_gem_shrink(struct drm_i915_private *i915, · 81 unmodified lines
200 202
201 spin_unlock_irqrestore(&i915->mm.obj_lock, flags);203 spin_unlock_irqrestore(&i915->mm.obj_lock, flags);
202 204
205 err = 0;
203 if (unsafe_drop_pages(obj, shrink)) {206 if (unsafe_drop_pages(obj, shrink)) {
204 /* May arrive from get_pages on another bo */207 /* May arrive from get_pages on another bo */
205 mutex_lock(&obj->mm.lock);208 if (!ww) {
206 if (!i915_gem_object_has_pages(obj)) {209 if (!i915_gem_object_trylock(obj))
210 goto skip;
211 } else {
212 err = i915_gem_object_lock(obj, ww);
213 if (err)
214 goto skip;
215 }
216
217 if (!__i915_gem_object_put_pages(obj)) {
207 try_to_writeback(obj, shrink);218 try_to_writeback(obj, shrink);
208 count += obj->base.size >> PAGE_SHIFT;219 count += obj->base.size >> PAGE_SHIFT;
209 }220 }
210 mutex_unlock(&obj->mm.lock);221 if (!ww)
222 i915_gem_object_unlock(obj);
211 }223 }
212 224
213 dma_resv_prune(obj->base.resv);225 dma_resv_prune(obj->base.resv);
214 226
215 scanned += obj->base.size >> PAGE_SHIFT;227 scanned += obj->base.size >> PAGE_SHIFT;
228skip:
216 i915_gem_object_put(obj);229 i915_gem_object_put(obj);
217 230
218 spin_lock_irqsave(&i915->mm.obj_lock, flags);231 spin_lock_irqsave(&i915->mm.obj_lock, flags);
232 if (err)
233 break;
219 }234 }
220 list_splice_tail(&still_in_list, phase->list);235 list_splice_tail(&still_in_list, phase->list);
221 spin_unlock_irqrestore(&i915->mm.obj_lock, flags);236 spin_unlock_irqrestore(&i915->mm.obj_lock, flags);
237 if (err)
238 return err;
222 }239 }
223 240
224 if (shrink & I915_SHRINK_BOUND)241 if (shrink & I915_SHRINK_BOUND)
@@ -249,7 +266,7 @@ unsigned long i915_gem_shrink_all(struct drm_i915_private *i915) · 24 unmodified lines
249 unsigned long freed = 0;266 unsigned long freed = 0;
250 267
251 with_intel_runtime_pm(&i915->runtime_pm, wakeref) {268 with_intel_runtime_pm(&i915->runtime_pm, wakeref) {
252 freed = i915_gem_shrink(i915, -1UL, NULL,269 freed = i915_gem_shrink(NULL, i915, -1UL, NULL,
253 I915_SHRINK_BOUND |270 I915_SHRINK_BOUND |
254 I915_SHRINK_UNBOUND);271 I915_SHRINK_UNBOUND);
255 }272 }
@@ -295,7 +312,7 @@ i915_gem_shrinker_scan(struct shrinker *shrinker, struct shrink_control *sc) · 39 unmodified lines
295 312
296 sc->nr_scanned = 0;313 sc->nr_scanned = 0;
297 314
298 freed = i915_gem_shrink(i915,315 freed = i915_gem_shrink(NULL, i915,
299 sc->nr_to_scan,316 sc->nr_to_scan,
300 &sc->nr_scanned,317 &sc->nr_scanned,
301 I915_SHRINK_BOUND |318 I915_SHRINK_BOUND |
@@ -304,7 +321,7 @@ i915_gem_shrinker_scan(struct shrinker *shrinker, struct shrink_control *sc) · 2 unmodified lines
304 intel_wakeref_t wakeref;321 intel_wakeref_t wakeref;
305 322
306 with_intel_runtime_pm(&i915->runtime_pm, wakeref) {323 with_intel_runtime_pm(&i915->runtime_pm, wakeref) {
307 freed += i915_gem_shrink(i915,324 freed += i915_gem_shrink(NULL, i915,
308 sc->nr_to_scan - sc->nr_scanned,325 sc->nr_to_scan - sc->nr_scanned,
309 &sc->nr_scanned,326 &sc->nr_scanned,
310 I915_SHRINK_ACTIVE |327 I915_SHRINK_ACTIVE |
@@ -329,7 +346,7 @@ i915_gem_shrinker_oom(struct notifier_block *nb, unsigned long event, void *ptr) · 18 unmodified lines
329 346
330 freed_pages = 0;347 freed_pages = 0;
331 with_intel_runtime_pm(&i915->runtime_pm, wakeref)348 with_intel_runtime_pm(&i915->runtime_pm, wakeref)
332 freed_pages += i915_gem_shrink(i915, -1UL, NULL,349 freed_pages += i915_gem_shrink(NULL, i915, -1UL, NULL,
333 I915_SHRINK_BOUND |350 I915_SHRINK_BOUND |
334 I915_SHRINK_UNBOUND |351 I915_SHRINK_UNBOUND |
335 I915_SHRINK_WRITEBACK);352 I915_SHRINK_WRITEBACK);
@@ -367,7 +384,7 @@ i915_gem_shrinker_vmap(struct notifier_block *nb, unsigned long event, void *ptr · 31 unmodified lines
367 intel_wakeref_t wakeref;384 intel_wakeref_t wakeref;
368 385
369 with_intel_runtime_pm(&i915->runtime_pm, wakeref)386 with_intel_runtime_pm(&i915->runtime_pm, wakeref)
370 freed_pages += i915_gem_shrink(i915, -1UL, NULL,387 freed_pages += i915_gem_shrink(NULL, i915, -1UL, NULL,
371 I915_SHRINK_BOUND |388 I915_SHRINK_BOUND |
372 I915_SHRINK_UNBOUND |389 I915_SHRINK_UNBOUND |
373 I915_SHRINK_VMAPS);390 I915_SHRINK_VMAPS);
drivers/gpu/drm/i915/gem/i915_gem_shrinker.h+3−1
@@ -9,10 +9,12 @@ · 8 unmodified lines
9#include <linux/bits.h>9#include <linux/bits.h>
10 10
11struct drm_i915_private;11struct drm_i915_private;
12struct i915_gem_ww_ctx;
12struct mutex;13struct mutex;
13 14
14/* i915_gem_shrinker.c */15/* i915_gem_shrinker.c */
15unsigned long i915_gem_shrink(struct drm_i915_private *i915,16unsigned long i915_gem_shrink(struct i915_gem_ww_ctx *ww,
17 struct drm_i915_private *i915,
16 unsigned long target,18 unsigned long target,
17 unsigned long *nr_scanned,19 unsigned long *nr_scanned,
18 unsigned flags);20 unsigned flags);
drivers/gpu/drm/i915/gem/i915_gem_stolen.c+8−6
@@ -630,20 +630,22 @@ static int __i915_gem_object_create_stolen(struct intel_memory_region *mem, · 629 unmodified lines
630 int err;630 int err;
631 631
632 drm_gem_private_object_init(&mem->i915->drm, &obj->base, stolen->size);632 drm_gem_private_object_init(&mem->i915->drm, &obj->base, stolen->size);
633 i915_gem_object_init(obj, &i915_gem_object_stolen_ops, &lock_class);633 i915_gem_object_init(obj, &i915_gem_object_stolen_ops, &lock_class, 0);
634 634
635 obj->stolen = stolen;635 obj->stolen = stolen;
636 obj->read_domains = I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT;636 obj->read_domains = I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT;
637 cache_level = HAS_LLC(mem->i915) ? I915_CACHE_LLC : I915_CACHE_NONE;637 cache_level = HAS_LLC(mem->i915) ? I915_CACHE_LLC : I915_CACHE_NONE;
638 i915_gem_object_set_cache_coherency(obj, cache_level);638 i915_gem_object_set_cache_coherency(obj, cache_level);
639 639
640 err = i915_gem_object_pin_pages(obj);640 if (WARN_ON(!i915_gem_object_trylock(obj)))
641 if (err)641 return -EBUSY;
642 return err;
643 642
644 i915_gem_object_init_memory_region(obj, mem, 0);643 err = i915_gem_object_pin_pages(obj);
644 if (!err)
645 i915_gem_object_init_memory_region(obj, mem);
646 i915_gem_object_unlock(obj);
645 647
646 return 0;648 return err;
647}649}
648 650
649static int _i915_gem_object_stolen_init(struct intel_memory_region *mem,651static int _i915_gem_object_stolen_init(struct intel_memory_region *mem,
drivers/gpu/drm/i915/gem/i915_gem_tiling.c+0−2
@@ -265,7 +265,6 @@ i915_gem_object_set_tiling(struct drm_i915_gem_object *obj, · 264 unmodified lines
265 * pages to prevent them being swapped out and causing corruption265 * pages to prevent them being swapped out and causing corruption
266 * due to the change in swizzling.266 * due to the change in swizzling.
267 */267 */
268 mutex_lock(&obj->mm.lock);
269 if (i915_gem_object_has_pages(obj) &&268 if (i915_gem_object_has_pages(obj) &&
270 obj->mm.madv == I915_MADV_WILLNEED &&269 obj->mm.madv == I915_MADV_WILLNEED &&
271 i915->quirks & QUIRK_PIN_SWIZZLED_PAGES) {270 i915->quirks & QUIRK_PIN_SWIZZLED_PAGES) {
@@ -280,7 +279,6 @@ i915_gem_object_set_tiling(struct drm_i915_gem_object *obj, · 8 unmodified lines
280 i915_gem_object_set_tiling_quirk(obj);279 i915_gem_object_set_tiling_quirk(obj);
281 }280 }
282 }281 }
283 mutex_unlock(&obj->mm.lock);
284 282
285 spin_lock(&obj->vma.lock);283 spin_lock(&obj->vma.lock);
286 for_each_ggtt_vma(vma, obj) {284 for_each_ggtt_vma(vma, obj) {
drivers/gpu/drm/i915/gem/i915_gem_userptr.c+320−582
@@ -2,10 +2,39 @@ · 1 unmodified line
2 * SPDX-License-Identifier: MIT2 * SPDX-License-Identifier: MIT
3 *3 *
4 * Copyright © 2012-2014 Intel Corporation4 * Copyright © 2012-2014 Intel Corporation
5 *
6 * Based on amdgpu_mn, which bears the following notice:
7 *
8 * Copyright 2014 Advanced Micro Devices, Inc.
9 * All Rights Reserved.
10 *
11 * Permission is hereby granted, free of charge, to any person obtaining a
12 * copy of this software and associated documentation files (the
13 * "Software"), to deal in the Software without restriction, including
14 * without limitation the rights to use, copy, modify, merge, publish,
15 * distribute, sub license, and/or sell copies of the Software, and to
16 * permit persons to whom the Software is furnished to do so, subject to
17 * the following conditions:
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
22 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
23 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
24 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
25 * USE OR OTHER DEALINGS IN THE SOFTWARE.
26 *
27 * The above copyright notice and this permission notice (including the
28 * next paragraph) shall be included in all copies or substantial portions
29 * of the Software.
30 *
31 */
32/*
33 * Authors:
34 * Christian König <christian.koenig@amd.com>
5 */35 */
6 36
7#include <linux/mmu_context.h>37#include <linux/mmu_context.h>
8#include <linux/mmu_notifier.h>
9#include <linux/mempolicy.h>38#include <linux/mempolicy.h>
10#include <linux/swap.h>39#include <linux/swap.h>
11#include <linux/sched/mm.h>40#include <linux/sched/mm.h>
@@ -15,408 +44,121 @@ · 3 unmodified lines
15#include "i915_gem_object.h"44#include "i915_gem_object.h"
16#include "i915_scatterlist.h"45#include "i915_scatterlist.h"
17 46
18struct i915_mm_struct {47#ifdef CONFIG_MMU_NOTIFIER
19 struct mm_struct *mm;
20 struct drm_i915_private *i915;
21 struct i915_mmu_notifier *mn;
22 struct hlist_node node;
23 struct kref kref;
24 struct rcu_work work;
25};
26
27#if defined(CONFIG_MMU_NOTIFIER)
28#include <linux/interval_tree.h>
29 48
30struct i915_mmu_notifier {49/**
31 spinlock_t lock;50 * i915_gem_userptr_invalidate - callback to notify about mm change
32 struct hlist_node node;51 *
33 struct mmu_notifier mn;52 * @mni: the range (mm) is about to update
34 struct rb_root_cached objects;53 * @range: details on the invalidation
35 struct i915_mm_struct *mm;54 * @cur_seq: Value to pass to mmu_interval_set_seq()
36};55 *
37 56 * Block for operations on BOs to finish and mark pages as accessed and
38struct i915_mmu_object {57 * potentially dirty.
39 struct i915_mmu_notifier *mn;58 */
40 struct drm_i915_gem_object *obj;59static bool i915_gem_userptr_invalidate(struct mmu_interval_notifier *mni,
41 struct interval_tree_node it;60 const struct mmu_notifier_range *range,
42};61 unsigned long cur_seq)
43
44static void add_object(struct i915_mmu_object *mo)
45{62{
46 GEM_BUG_ON(!RB_EMPTY_NODE(&mo->it.rb));63 struct drm_i915_gem_object *obj = container_of(mni, struct drm_i915_gem_object, userptr.notifier);
47 interval_tree_insert(&mo->it, &mo->mn->objects);64 struct drm_i915_private *i915 = to_i915(obj->base.dev);
48}65 long r;
49 66
50static void del_object(struct i915_mmu_object *mo)67 if (!mmu_notifier_range_blockable(range))
51{68 return false;
52 if (RB_EMPTY_NODE(&mo->it.rb))
53 return;
54 69
55 interval_tree_remove(&mo->it, &mo->mn->objects);70 spin_lock(&i915->mm.notifier_lock);
56 RB_CLEAR_NODE(&mo->it.rb);
57}
58 71
59static void72 mmu_interval_set_seq(mni, cur_seq);
60__i915_gem_userptr_set_active(struct drm_i915_gem_object *obj, bool value)73
61{74 spin_unlock(&i915->mm.notifier_lock);
62 struct i915_mmu_object *mo = obj->userptr.mmu_object;
63 75
64 /*76 /*
65 * During mm_invalidate_range we need to cancel any userptr that77 * We don't wait when the process is exiting. This is valid
66 * overlaps the range being invalidated. Doing so requires the78 * because the object will be cleaned up anyway.
67 * struct_mutex, and that risks recursion. In order to cause79 *
68 * recursion, the user must alias the userptr address space with80 * This is also temporarily required as a hack, because we
69 * a GTT mmapping (possible with a MAP_FIXED) - then when we have81 * cannot currently force non-consistent batch buffers to preempt
70 * to invalidate that mmaping, mm_invalidate_range is called with82 * and reschedule by waiting on it, hanging processes on exit.
71 * the userptr address *and* the struct_mutex held. To prevent that
72 * we set a flag under the i915_mmu_notifier spinlock to indicate
73 * whether this object is valid.
74 */83 */
75 if (!mo)84 if (current->flags & PF_EXITING)
76 return;85 return true;
77 86
78 spin_lock(&mo->mn->lock);87 /* we will unbind on next submission, still have userptr pins */
79 if (value)88 r = dma_resv_wait_timeout_rcu(obj->base.resv, true, false,
80 add_object(mo);89 MAX_SCHEDULE_TIMEOUT);
81 else90 if (r <= 0)
82 del_object(mo);91 drm_err(&i915->drm, "(%ld) failed to wait for idle\n", r);
83 spin_unlock(&mo->mn->lock);
84}
85
86static int
87userptr_mn_invalidate_range_start(struct mmu_notifier *_mn,
88 const struct mmu_notifier_range *range)
89{
90 struct i915_mmu_notifier *mn =
91 container_of(_mn, struct i915_mmu_notifier, mn);
92 struct interval_tree_node *it;
93 unsigned long end;
94 int ret = 0;
95
96 if (RB_EMPTY_ROOT(&mn->objects.rb_root))
97 return 0;
98
99 /* interval ranges are inclusive, but invalidate range is exclusive */
100 end = range->end - 1;
101
102 spin_lock(&mn->lock);
103 it = interval_tree_iter_first(&mn->objects, range->start, end);
104 while (it) {
105 struct drm_i915_gem_object *obj;
106
107 if (!mmu_notifier_range_blockable(range)) {
108 ret = -EAGAIN;
109 break;
110 }
111
112 /*
113 * The mmu_object is released late when destroying the
114 * GEM object so it is entirely possible to gain a
115 * reference on an object in the process of being freed
116 * since our serialisation is via the spinlock and not
117 * the struct_mutex - and consequently use it after it
118 * is freed and then double free it. To prevent that
119 * use-after-free we only acquire a reference on the
120 * object if it is not in the process of being destroyed.
121 */
122 obj = container_of(it, struct i915_mmu_object, it)->obj;
123 if (!kref_get_unless_zero(&obj->base.refcount)) {
124 it = interval_tree_iter_next(it, range->start, end);
125 continue;
126 }
127 spin_unlock(&mn->lock);
128
129 ret = i915_gem_object_unbind(obj,
130 I915_GEM_OBJECT_UNBIND_ACTIVE |
131 I915_GEM_OBJECT_UNBIND_BARRIER);
132 if (ret == 0)
133 ret = __i915_gem_object_put_pages(obj);
134 i915_gem_object_put(obj);
135 if (ret)
136 return ret;
137
138 spin_lock(&mn->lock);
139
140 /*
141 * As we do not (yet) protect the mmu from concurrent insertion
142 * over this range, there is no guarantee that this search will
143 * terminate given a pathologic workload.
144 */
145 it = interval_tree_iter_first(&mn->objects, range->start, end);
146 }
147 spin_unlock(&mn->lock);
148
149 return ret;
150 92
93 return true;
151}94}
152 95
153static const struct mmu_notifier_ops i915_gem_userptr_notifier = {96static const struct mmu_interval_notifier_ops i915_gem_userptr_notifier_ops = {
154 .invalidate_range_start = userptr_mn_invalidate_range_start,97 .invalidate = i915_gem_userptr_invalidate,
155};98};
156 99
157static struct i915_mmu_notifier *
158i915_mmu_notifier_create(struct i915_mm_struct *mm)
159{
160 struct i915_mmu_notifier *mn;
161
162 mn = kmalloc(sizeof(*mn), GFP_KERNEL);
163 if (mn == NULL)
164 return ERR_PTR(-ENOMEM);
165
166 spin_lock_init(&mn->lock);
167 mn->mn.ops = &i915_gem_userptr_notifier;
168 mn->objects = RB_ROOT_CACHED;
169 mn->mm = mm;
170
171 return mn;
172}
173
174static void
175i915_gem_userptr_release__mmu_notifier(struct drm_i915_gem_object *obj)
176{
177 struct i915_mmu_object *mo;
178
179 mo = fetch_and_zero(&obj->userptr.mmu_object);
180 if (!mo)
181 return;
182
183 spin_lock(&mo->mn->lock);
184 del_object(mo);
185 spin_unlock(&mo->mn->lock);
186 kfree(mo);
187}
188
189static struct i915_mmu_notifier *
190i915_mmu_notifier_find(struct i915_mm_struct *mm)
191{
192 struct i915_mmu_notifier *mn, *old;
193 int err;
194
195 mn = READ_ONCE(mm->mn);
196 if (likely(mn))
197 return mn;
198
199 mn = i915_mmu_notifier_create(mm);
200 if (IS_ERR(mn))
201 return mn;
202
203 err = mmu_notifier_register(&mn->mn, mm->mm);
204 if (err) {
205 kfree(mn);
206 return ERR_PTR(err);
207 }
208
209 old = cmpxchg(&mm->mn, NULL, mn);
210 if (old) {
211 mmu_notifier_unregister(&mn->mn, mm->mm);
212 kfree(mn);
213 mn = old;
214 }
215
216 return mn;
217}
218
219static int
220i915_gem_userptr_init__mmu_notifier(struct drm_i915_gem_object *obj,
221 unsigned flags)
222{
223 struct i915_mmu_notifier *mn;
224 struct i915_mmu_object *mo;
225
226 if (flags & I915_USERPTR_UNSYNCHRONIZED)
227 return capable(CAP_SYS_ADMIN) ? 0 : -EPERM;
228
229 if (GEM_WARN_ON(!obj->userptr.mm))
230 return -EINVAL;
231
232 mn = i915_mmu_notifier_find(obj->userptr.mm);
233 if (IS_ERR(mn))
234 return PTR_ERR(mn);
235
236 mo = kzalloc(sizeof(*mo), GFP_KERNEL);
237 if (!mo)
238 return -ENOMEM;
239
240 mo->mn = mn;
241 mo->obj = obj;
242 mo->it.start = obj->userptr.ptr;
243 mo->it.last = obj->userptr.ptr + obj->base.size - 1;
244 RB_CLEAR_NODE(&mo->it.rb);
245
246 obj->userptr.mmu_object = mo;
247 return 0;
248}
249
250static void
251i915_mmu_notifier_free(struct i915_mmu_notifier *mn,
252 struct mm_struct *mm)
253{
254 if (mn == NULL)
255 return;
256
257 mmu_notifier_unregister(&mn->mn, mm);
258 kfree(mn);
259}
260
261#else
262
263static void
264__i915_gem_userptr_set_active(struct drm_i915_gem_object *obj, bool value)
265{
266}
267
268static void
269i915_gem_userptr_release__mmu_notifier(struct drm_i915_gem_object *obj)
270{
271}
272
273static int100static int
274i915_gem_userptr_init__mmu_notifier(struct drm_i915_gem_object *obj,101i915_gem_userptr_init__mmu_notifier(struct drm_i915_gem_object *obj)
275 unsigned flags)
276{102{
277 if ((flags & I915_USERPTR_UNSYNCHRONIZED) == 0)103 return mmu_interval_notifier_insert(&obj->userptr.notifier, current->mm,
278 return -ENODEV;104 obj->userptr.ptr, obj->base.size,
279 105 &i915_gem_userptr_notifier_ops);
280 if (!capable(CAP_SYS_ADMIN))
281 return -EPERM;
282
283 return 0;
284}106}
285 107
286static void108static void i915_gem_object_userptr_drop_ref(struct drm_i915_gem_object *obj)
287i915_mmu_notifier_free(struct i915_mmu_notifier *mn,
288 struct mm_struct *mm)
289{
290}
291
292#endif
293
294static struct i915_mm_struct *
295__i915_mm_struct_find(struct drm_i915_private *i915, struct mm_struct *real)
296{
297 struct i915_mm_struct *it, *mm = NULL;
298
299 rcu_read_lock();
300 hash_for_each_possible_rcu(i915->mm_structs,
301 it, node,
302 (unsigned long)real)
303 if (it->mm == real && kref_get_unless_zero(&it->kref)) {
304 mm = it;
305 break;
306 }
307 rcu_read_unlock();
308
309 return mm;
310}
311
312static int
313i915_gem_userptr_init__mm_struct(struct drm_i915_gem_object *obj)
314{109{
315 struct drm_i915_private *i915 = to_i915(obj->base.dev);110 struct drm_i915_private *i915 = to_i915(obj->base.dev);
316 struct i915_mm_struct *mm, *new;111 struct page **pvec = NULL;
317 int ret = 0;
318
319 /* During release of the GEM object we hold the struct_mutex. This
320 * precludes us from calling mmput() at that time as that may be
321 * the last reference and so call exit_mmap(). exit_mmap() will
322 * attempt to reap the vma, and if we were holding a GTT mmap
323 * would then call drm_gem_vm_close() and attempt to reacquire
324 * the struct mutex. So in order to avoid that recursion, we have
325 * to defer releasing the mm reference until after we drop the
326 * struct_mutex, i.e. we need to schedule a worker to do the clean
327 * up.
328 */
329 mm = __i915_mm_struct_find(i915, current->mm);
330 if (mm)
331 goto out;
332
333 new = kmalloc(sizeof(*mm), GFP_KERNEL);
334 if (!new)
335 return -ENOMEM;
336 112
337 kref_init(&new->kref);113 spin_lock(&i915->mm.notifier_lock);
338 new->i915 = to_i915(obj->base.dev);114 if (!--obj->userptr.page_ref) {
339 new->mm = current->mm;115 pvec = obj->userptr.pvec;
340 new->mn = NULL;116 obj->userptr.pvec = NULL;
341
342 spin_lock(&i915->mm_lock);
343 mm = __i915_mm_struct_find(i915, current->mm);
344 if (!mm) {
345 hash_add_rcu(i915->mm_structs,
346 &new->node,
347 (unsigned long)new->mm);
348 mmgrab(current->mm);
349 mm = new;
350 }117 }
351 spin_unlock(&i915->mm_lock);118 GEM_BUG_ON(obj->userptr.page_ref < 0);
352 if (mm != new)119 spin_unlock(&i915->mm.notifier_lock);
353 kfree(new);
354 120
355out:121 if (pvec) {
356 obj->userptr.mm = mm;122 const unsigned long num_pages = obj->base.size >> PAGE_SHIFT;
357 return ret;
358}
359
360static void
361__i915_mm_struct_free__worker(struct work_struct *work)
362{
363 struct i915_mm_struct *mm = container_of(work, typeof(*mm), work.work);
364
365 i915_mmu_notifier_free(mm->mn, mm->mm);
366 mmdrop(mm->mm);
367 kfree(mm);
368}
369
370static void
371__i915_mm_struct_free(struct kref *kref)
372{
373 struct i915_mm_struct *mm = container_of(kref, typeof(*mm), kref);
374 123
375 spin_lock(&mm->i915->mm_lock);124 unpin_user_pages(pvec, num_pages);
376 hash_del_rcu(&mm->node);125 kvfree(pvec);
377 spin_unlock(&mm->i915->mm_lock);126 }
378
379 INIT_RCU_WORK(&mm->work, __i915_mm_struct_free__worker);
380 queue_rcu_work(system_wq, &mm->work);
381}
382
383static void
384i915_gem_userptr_release__mm_struct(struct drm_i915_gem_object *obj)
385{
386 if (obj->userptr.mm == NULL)
387 return;
388
389 kref_put(&obj->userptr.mm->kref, __i915_mm_struct_free);
390 obj->userptr.mm = NULL;
391}127}
392 128
393struct get_pages_work {129static int i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj)
394 struct work_struct work;
395 struct drm_i915_gem_object *obj;
396 struct task_struct *task;
397};
398
399static struct sg_table *
400__i915_gem_userptr_alloc_pages(struct drm_i915_gem_object *obj,
401 struct page **pvec, unsigned long num_pages)
402{130{
131 struct drm_i915_private *i915 = to_i915(obj->base.dev);
132 const unsigned long num_pages = obj->base.size >> PAGE_SHIFT;
403 unsigned int max_segment = i915_sg_segment_size();133 unsigned int max_segment = i915_sg_segment_size();
404 struct sg_table *st;134 struct sg_table *st;
405 unsigned int sg_page_sizes;135 unsigned int sg_page_sizes;
406 struct scatterlist *sg;136 struct scatterlist *sg;
137 struct page **pvec;
407 int ret;138 int ret;
408 139
409 st = kmalloc(sizeof(*st), GFP_KERNEL);140 st = kmalloc(sizeof(*st), GFP_KERNEL);
410 if (!st)141 if (!st)
411 return ERR_PTR(-ENOMEM);142 return -ENOMEM;
143
144 spin_lock(&i915->mm.notifier_lock);
145 if (GEM_WARN_ON(!obj->userptr.page_ref)) {
146 spin_unlock(&i915->mm.notifier_lock);
147 ret = -EFAULT;
148 goto err_free;
149 }
150
151 obj->userptr.page_ref++;
152 pvec = obj->userptr.pvec;
153 spin_unlock(&i915->mm.notifier_lock);
412 154
413alloc_table:155alloc_table:
414 sg = __sg_alloc_table_from_pages(st, pvec, num_pages, 0,156 sg = __sg_alloc_table_from_pages(st, pvec, num_pages, 0,
415 num_pages << PAGE_SHIFT, max_segment,157 num_pages << PAGE_SHIFT, max_segment,
416 NULL, 0, GFP_KERNEL);158 NULL, 0, GFP_KERNEL);
417 if (IS_ERR(sg)) {159 if (IS_ERR(sg)) {
418 kfree(st);160 ret = PTR_ERR(sg);
419 return ERR_CAST(sg);161 goto err;
420 }162 }
421 163
422 ret = i915_gem_gtt_prepare_pages(obj, st);164 ret = i915_gem_gtt_prepare_pages(obj, st);
@@ -428,203 +170,20 @@ alloc_table: · 5 unmodified lines
428 goto alloc_table;170 goto alloc_table;
429 }171 }
430 172
431 kfree(st);173 goto err;
432 return ERR_PTR(ret);
433 }174 }
434 175
435 sg_page_sizes = i915_sg_page_sizes(st->sgl);176 sg_page_sizes = i915_sg_page_sizes(st->sgl);
436 177
437 __i915_gem_object_set_pages(obj, st, sg_page_sizes);178 __i915_gem_object_set_pages(obj, st, sg_page_sizes);
438 179
439 return st;180 return 0;
440}
441
442static void
443__i915_gem_userptr_get_pages_worker(struct work_struct *_work)
444{
445 struct get_pages_work *work = container_of(_work, typeof(*work), work);
446 struct drm_i915_gem_object *obj = work->obj;
447 const unsigned long npages = obj->base.size >> PAGE_SHIFT;
448 unsigned long pinned;
449 struct page **pvec;
450 int ret;
451
452 ret = -ENOMEM;
453 pinned = 0;
454
455 pvec = kvmalloc_array(npages, sizeof(struct page *), GFP_KERNEL);
456 if (pvec != NULL) {
457 struct mm_struct *mm = obj->userptr.mm->mm;
458 unsigned int flags = 0;
459 int locked = 0;
460
461 if (!i915_gem_object_is_readonly(obj))
462 flags |= FOLL_WRITE;
463
464 ret = -EFAULT;
465 if (mmget_not_zero(mm)) {
466 while (pinned < npages) {
467 if (!locked) {
468 mmap_read_lock(mm);
469 locked = 1;
470 }
471 ret = pin_user_pages_remote
472 (mm,
473 obj->userptr.ptr + pinned * PAGE_SIZE,
474 npages - pinned,
475 flags,
476 pvec + pinned, NULL, &locked);
477 if (ret < 0)
478 break;
479
480 pinned += ret;
481 }
482 if (locked)
483 mmap_read_unlock(mm);
484 mmput(mm);
485 }
486 }
487
488 mutex_lock_nested(&obj->mm.lock, I915_MM_GET_PAGES);
489 if (obj->userptr.work == &work->work) {
490 struct sg_table *pages = ERR_PTR(ret);
491
492 if (pinned == npages) {
493 pages = __i915_gem_userptr_alloc_pages(obj, pvec,
494 npages);
495 if (!IS_ERR(pages)) {
496 pinned = 0;
497 pages = NULL;
498 }
499 }
500
501 obj->userptr.work = ERR_CAST(pages);
502 if (IS_ERR(pages))
503 __i915_gem_userptr_set_active(obj, false);
504 }
505 mutex_unlock(&obj->mm.lock);
506
507 unpin_user_pages(pvec, pinned);
508 kvfree(pvec);
509
510 i915_gem_object_put(obj);
511 put_task_struct(work->task);
512 kfree(work);
513}
514
515static struct sg_table *
516__i915_gem_userptr_get_pages_schedule(struct drm_i915_gem_object *obj)
517{
518 struct get_pages_work *work;
519
520 /* Spawn a worker so that we can acquire the
521 * user pages without holding our mutex. Access
522 * to the user pages requires mmap_lock, and we have
523 * a strict lock ordering of mmap_lock, struct_mutex -
524 * we already hold struct_mutex here and so cannot
525 * call gup without encountering a lock inversion.
526 *
527 * Userspace will keep on repeating the operation
528 * (thanks to EAGAIN) until either we hit the fast
529 * path or the worker completes. If the worker is
530 * cancelled or superseded, the task is still run
531 * but the results ignored. (This leads to
532 * complications that we may have a stray object
533 * refcount that we need to be wary of when
534 * checking for existing objects during creation.)
535 * If the worker encounters an error, it reports
536 * that error back to this function through
537 * obj->userptr.work = ERR_PTR.
538 */
539 work = kmalloc(sizeof(*work), GFP_KERNEL);
540 if (work == NULL)
541 return ERR_PTR(-ENOMEM);
542
543 obj->userptr.work = &work->work;
544
545 work->obj = i915_gem_object_get(obj);
546
547 work->task = current;
548 get_task_struct(work->task);
549
550 INIT_WORK(&work->work, __i915_gem_userptr_get_pages_worker);
551 queue_work(to_i915(obj->base.dev)->mm.userptr_wq, &work->work);
552
553 return ERR_PTR(-EAGAIN);
554}
555
556static int i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj)
557{
558 const unsigned long num_pages = obj->base.size >> PAGE_SHIFT;
559 struct mm_struct *mm = obj->userptr.mm->mm;
560 struct page **pvec;
561 struct sg_table *pages;
562 bool active;
563 int pinned;
564 unsigned int gup_flags = 0;
565
566 /* If userspace should engineer that these pages are replaced in
567 * the vma between us binding this page into the GTT and completion
568 * of rendering... Their loss. If they change the mapping of their
569 * pages they need to create a new bo to point to the new vma.
570 *
571 * However, that still leaves open the possibility of the vma
572 * being copied upon fork. Which falls under the same userspace
573 * synchronisation issue as a regular bo, except that this time
574 * the process may not be expecting that a particular piece of
575 * memory is tied to the GPU.
576 *
577 * Fortunately, we can hook into the mmu_notifier in order to
578 * discard the page references prior to anything nasty happening
579 * to the vma (discard or cloning) which should prevent the more
580 * egregious cases from causing harm.
581 */
582
583 if (obj->userptr.work) {
584 /* active flag should still be held for the pending work */
585 if (IS_ERR(obj->userptr.work))
586 return PTR_ERR(obj->userptr.work);
587 else
588 return -EAGAIN;
589 }
590
591 pvec = NULL;
592 pinned = 0;
593
594 if (mm == current->mm) {
595 pvec = kvmalloc_array(num_pages, sizeof(struct page *),
596 GFP_KERNEL |
597 __GFP_NORETRY |
598 __GFP_NOWARN);
599 if (pvec) {
600 /* defer to worker if malloc fails */
601 if (!i915_gem_object_is_readonly(obj))
602 gup_flags |= FOLL_WRITE;
603 pinned = pin_user_pages_fast_only(obj->userptr.ptr,
604 num_pages, gup_flags,
605 pvec);
606 }
607 }
608
609 active = false;
610 if (pinned < 0) {
611 pages = ERR_PTR(pinned);
612 pinned = 0;
613 } else if (pinned < num_pages) {
614 pages = __i915_gem_userptr_get_pages_schedule(obj);
615 active = pages == ERR_PTR(-EAGAIN);
616 } else {
617 pages = __i915_gem_userptr_alloc_pages(obj, pvec, num_pages);
618 active = !IS_ERR(pages);
619 }
620 if (active)
621 __i915_gem_userptr_set_active(obj, true);
622
623 if (IS_ERR(pages))
624 unpin_user_pages(pvec, pinned);
625 kvfree(pvec);
626 181
627 return PTR_ERR_OR_ZERO(pages);182err:
183 i915_gem_object_userptr_drop_ref(obj);
184err_free:
185 kfree(st);
186 return ret;
628}187}
629 188
630static void189static void
@@ -634,9 +193,6 @@ i915_gem_userptr_put_pages(struct drm_i915_gem_object *obj, · 3 unmodified lines
634 struct sgt_iter sgt_iter;193 struct sgt_iter sgt_iter;
635 struct page *page;194 struct page *page;
636 195
637 /* Cancel any inflight work and force them to restart their gup */
638 obj->userptr.work = NULL;
639 __i915_gem_userptr_set_active(obj, false);
640 if (!pages)196 if (!pages)
641 return;197 return;
642 198
@@ -676,42 +232,224 @@ i915_gem_userptr_put_pages(struct drm_i915_gem_object *obj, · 33 unmodified lines
676 }232 }
677 233
678 mark_page_accessed(page);234 mark_page_accessed(page);
679 unpin_user_page(page);
680 }235 }
681 obj->mm.dirty = false;236 obj->mm.dirty = false;
682 237
683 sg_free_table(pages);238 sg_free_table(pages);
684 kfree(pages);239 kfree(pages);
240
241 i915_gem_object_userptr_drop_ref(obj);
242}
243
244static int i915_gem_object_userptr_unbind(struct drm_i915_gem_object *obj, bool get_pages)
245{
246 struct sg_table *pages;
247 int err;
248
249 err = i915_gem_object_unbind(obj, I915_GEM_OBJECT_UNBIND_ACTIVE);
250 if (err)
251 return err;
252
253 if (GEM_WARN_ON(i915_gem_object_has_pinned_pages(obj)))
254 return -EBUSY;
255
256 assert_object_held(obj);
257
258 pages = __i915_gem_object_unset_pages(obj);
259 if (!IS_ERR_OR_NULL(pages))
260 i915_gem_userptr_put_pages(obj, pages);
261
262 if (get_pages)
263 err = ____i915_gem_object_get_pages(obj);
264
265 return err;
266}
267
268int i915_gem_object_userptr_submit_init(struct drm_i915_gem_object *obj)
269{
270 struct drm_i915_private *i915 = to_i915(obj->base.dev);
271 const unsigned long num_pages = obj->base.size >> PAGE_SHIFT;
272 struct page **pvec;
273 unsigned int gup_flags = 0;
274 unsigned long notifier_seq;
275 int pinned, ret;
276
277 if (obj->userptr.notifier.mm != current->mm)
278 return -EFAULT;
279
280 ret = i915_gem_object_lock_interruptible(obj, NULL);
281 if (ret)
282 return ret;
283
284 /* optimistically try to preserve current pages while unlocked */
285 if (i915_gem_object_has_pages(obj) &&
286 !mmu_interval_check_retry(&obj->userptr.notifier,
287 obj->userptr.notifier_seq)) {
288 spin_lock(&i915->mm.notifier_lock);
289 if (obj->userptr.pvec &&
290 !mmu_interval_read_retry(&obj->userptr.notifier,
291 obj->userptr.notifier_seq)) {
292 obj->userptr.page_ref++;
293
294 /* We can keep using the current binding, this is the fastpath */
295 ret = 1;
296 }
297 spin_unlock(&i915->mm.notifier_lock);
298 }
299
300 if (!ret) {
301 /* Make sure userptr is unbound for next attempt, so we don't use stale pages. */
302 ret = i915_gem_object_userptr_unbind(obj, false);
303 }
304 i915_gem_object_unlock(obj);
305 if (ret < 0)
306 return ret;
307
308 if (ret > 0)
309 return 0;
310
311 notifier_seq = mmu_interval_read_begin(&obj->userptr.notifier);
312
313 pvec = kvmalloc_array(num_pages, sizeof(struct page *), GFP_KERNEL);
314 if (!pvec)
315 return -ENOMEM;
316
317 if (!i915_gem_object_is_readonly(obj))
318 gup_flags |= FOLL_WRITE;
319
320 pinned = ret = 0;
321 while (pinned < num_pages) {
322 ret = pin_user_pages_fast(obj->userptr.ptr + pinned * PAGE_SIZE,
323 num_pages - pinned, gup_flags,
324 &pvec[pinned]);
325 if (ret < 0)
326 goto out;
327
328 pinned += ret;
329 }
330 ret = 0;
331
332 spin_lock(&i915->mm.notifier_lock);
333
334 if (mmu_interval_read_retry(&obj->userptr.notifier,
335 !obj->userptr.page_ref ? notifier_seq :
336 obj->userptr.notifier_seq)) {
337 ret = -EAGAIN;
338 goto out_unlock;
339 }
340
341 if (!obj->userptr.page_ref++) {
342 obj->userptr.pvec = pvec;
343 obj->userptr.notifier_seq = notifier_seq;
344
345 pvec = NULL;
346 }
347
348out_unlock:
349 spin_unlock(&i915->mm.notifier_lock);
350
351out:
352 if (pvec) {
353 unpin_user_pages(pvec, pinned);
354 kvfree(pvec);
355 }
356
357 return ret;
358}
359
360int i915_gem_object_userptr_submit_done(struct drm_i915_gem_object *obj)
361{
362 if (mmu_interval_read_retry(&obj->userptr.notifier,
363 obj->userptr.notifier_seq)) {
364 /* We collided with the mmu notifier, need to retry */
365
366 return -EAGAIN;
367 }
368
369 return 0;
370}
371
372void i915_gem_object_userptr_submit_fini(struct drm_i915_gem_object *obj)
373{
374 i915_gem_object_userptr_drop_ref(obj);
375}
376
377int i915_gem_object_userptr_validate(struct drm_i915_gem_object *obj)
378{
379 int err;
380
381 err = i915_gem_object_userptr_submit_init(obj);
382 if (err)
383 return err;
384
385 err = i915_gem_object_lock_interruptible(obj, NULL);
386 if (!err) {
387 /*
388 * Since we only check validity, not use the pages,
389 * it doesn't matter if we collide with the mmu notifier,
390 * and -EAGAIN handling is not required.
391 */
392 err = i915_gem_object_pin_pages(obj);
393 if (!err)
394 i915_gem_object_unpin_pages(obj);
395
396 i915_gem_object_unlock(obj);
397 }
398
399 i915_gem_object_userptr_submit_fini(obj);
400 return err;
685}401}
686 402
687static void403static void
688i915_gem_userptr_release(struct drm_i915_gem_object *obj)404i915_gem_userptr_release(struct drm_i915_gem_object *obj)
689{405{
690 i915_gem_userptr_release__mmu_notifier(obj);406 GEM_WARN_ON(obj->userptr.page_ref);
691 i915_gem_userptr_release__mm_struct(obj);407
408 mmu_interval_notifier_remove(&obj->userptr.notifier);
409 obj->userptr.notifier.mm = NULL;
692}410}
693 411
694static int412static int
695i915_gem_userptr_dmabuf_export(struct drm_i915_gem_object *obj)413i915_gem_userptr_dmabuf_export(struct drm_i915_gem_object *obj)
696{414{
697 if (obj->userptr.mmu_object)415 drm_dbg(obj->base.dev, "Exporting userptr no longer allowed\n");
698 return 0;
699 416
700 return i915_gem_userptr_init__mmu_notifier(obj, 0);417 return -EINVAL;
418}
419
420static int
421i915_gem_userptr_pwrite(struct drm_i915_gem_object *obj,
422 const struct drm_i915_gem_pwrite *args)
423{
424 drm_dbg(obj->base.dev, "pwrite to userptr no longer allowed\n");
425
426 return -EINVAL;
427}
428
429static int
430i915_gem_userptr_pread(struct drm_i915_gem_object *obj,
431 const struct drm_i915_gem_pread *args)
432{
433 drm_dbg(obj->base.dev, "pread from userptr no longer allowed\n");
434
435 return -EINVAL;
701}436}
702 437
703static const struct drm_i915_gem_object_ops i915_gem_userptr_ops = {438static const struct drm_i915_gem_object_ops i915_gem_userptr_ops = {
704 .name = "i915_gem_object_userptr",439 .name = "i915_gem_object_userptr",
705 .flags = I915_GEM_OBJECT_HAS_STRUCT_PAGE |440 .flags = I915_GEM_OBJECT_IS_SHRINKABLE |
706 I915_GEM_OBJECT_IS_SHRINKABLE |
707 I915_GEM_OBJECT_NO_MMAP |441 I915_GEM_OBJECT_NO_MMAP |
708 I915_GEM_OBJECT_ASYNC_CANCEL,442 I915_GEM_OBJECT_IS_PROXY,
709 .get_pages = i915_gem_userptr_get_pages,443 .get_pages = i915_gem_userptr_get_pages,
710 .put_pages = i915_gem_userptr_put_pages,444 .put_pages = i915_gem_userptr_put_pages,
711 .dmabuf_export = i915_gem_userptr_dmabuf_export,445 .dmabuf_export = i915_gem_userptr_dmabuf_export,
446 .pwrite = i915_gem_userptr_pwrite,
447 .pread = i915_gem_userptr_pread,
712 .release = i915_gem_userptr_release,448 .release = i915_gem_userptr_release,
713};449};
714 450
451#endif
452
715/*453/*
716 * Creates a new mm object that wraps some normal memory from the process454 * Creates a new mm object that wraps some normal memory from the process
717 * context - user memory.455 * context - user memory.
@@ -752,12 +490,12 @@ i915_gem_userptr_ioctl(struct drm_device *dev, · 34 unmodified lines
752 void *data,490 void *data,
753 struct drm_file *file)491 struct drm_file *file)
754{492{
755 static struct lock_class_key lock_class;493 static struct lock_class_key __maybe_unused lock_class;
756 struct drm_i915_private *dev_priv = to_i915(dev);494 struct drm_i915_private *dev_priv = to_i915(dev);
757 struct drm_i915_gem_userptr *args = data;495 struct drm_i915_gem_userptr *args = data;
758 struct drm_i915_gem_object *obj;496 struct drm_i915_gem_object __maybe_unused *obj;
759 int ret;497 int __maybe_unused ret;
760 u32 handle;498 u32 __maybe_unused handle;
761 499
762 if (!HAS_LLC(dev_priv) && !HAS_SNOOP(dev_priv)) {500 if (!HAS_LLC(dev_priv) && !HAS_SNOOP(dev_priv)) {
763 /* We cannot support coherent userptr objects on hw without501 /* We cannot support coherent userptr objects on hw without
@@ -796,6 +534,9 @@ i915_gem_userptr_ioctl(struct drm_device *dev, · 32 unmodified lines
796 if (!access_ok((char __user *)(unsigned long)args->user_ptr, args->user_size))534 if (!access_ok((char __user *)(unsigned long)args->user_ptr, args->user_size))
797 return -EFAULT;535 return -EFAULT;
798 536
537 if (args->flags & I915_USERPTR_UNSYNCHRONIZED)
538 return -ENODEV;
539
799 if (args->flags & I915_USERPTR_READ_ONLY) {540 if (args->flags & I915_USERPTR_READ_ONLY) {
800 /*541 /*
801 * On almost all of the older hw, we cannot tell the GPU that542 * On almost all of the older hw, we cannot tell the GPU that
@@ -805,17 +546,20 @@ i915_gem_userptr_ioctl(struct drm_device *dev, · 3 unmodified lines
805 return -ENODEV;546 return -ENODEV;
806 }547 }
807 548
549#ifdef CONFIG_MMU_NOTIFIER
808 obj = i915_gem_object_alloc();550 obj = i915_gem_object_alloc();
809 if (obj == NULL)551 if (obj == NULL)
810 return -ENOMEM;552 return -ENOMEM;
811 553
812 drm_gem_private_object_init(dev, &obj->base, args->user_size);554 drm_gem_private_object_init(dev, &obj->base, args->user_size);
813 i915_gem_object_init(obj, &i915_gem_userptr_ops, &lock_class);555 i915_gem_object_init(obj, &i915_gem_userptr_ops, &lock_class,
556 I915_BO_ALLOC_STRUCT_PAGE);
814 obj->read_domains = I915_GEM_DOMAIN_CPU;557 obj->read_domains = I915_GEM_DOMAIN_CPU;
815 obj->write_domain = I915_GEM_DOMAIN_CPU;558 obj->write_domain = I915_GEM_DOMAIN_CPU;
816 i915_gem_object_set_cache_coherency(obj, I915_CACHE_LLC);559 i915_gem_object_set_cache_coherency(obj, I915_CACHE_LLC);
817 560
818 obj->userptr.ptr = args->user_ptr;561 obj->userptr.ptr = args->user_ptr;
562 obj->userptr.notifier_seq = ULONG_MAX;
819 if (args->flags & I915_USERPTR_READ_ONLY)563 if (args->flags & I915_USERPTR_READ_ONLY)
820 i915_gem_object_set_readonly(obj);564 i915_gem_object_set_readonly(obj);
821 565
@@ -823,9 +567,7 @@ i915_gem_userptr_ioctl(struct drm_device *dev, · 1 unmodified line
823 * at binding. This means that we need to hook into the mmu_notifier567 * at binding. This means that we need to hook into the mmu_notifier
824 * in order to detect if the mmu is destroyed.568 * in order to detect if the mmu is destroyed.
825 */569 */
826 ret = i915_gem_userptr_init__mm_struct(obj);570 ret = i915_gem_userptr_init__mmu_notifier(obj);
827 if (ret == 0)
828 ret = i915_gem_userptr_init__mmu_notifier(obj, args->flags);
829 if (ret == 0)571 if (ret == 0)
830 ret = drm_gem_handle_create(file, &obj->base, &handle);572 ret = drm_gem_handle_create(file, &obj->base, &handle);
831 573
@@ -836,24 +578,20 @@ i915_gem_userptr_ioctl(struct drm_device *dev, · 4 unmodified lines
836 578
837 args->handle = handle;579 args->handle = handle;
838 return 0;580 return 0;
581#else
582 return -ENODEV;
583#endif
839}584}
840 585
841int i915_gem_init_userptr(struct drm_i915_private *dev_priv)586int i915_gem_init_userptr(struct drm_i915_private *dev_priv)
842{587{
843 spin_lock_init(&dev_priv->mm_lock);588#ifdef CONFIG_MMU_NOTIFIER
844 hash_init(dev_priv->mm_structs);589 spin_lock_init(&dev_priv->mm.notifier_lock);
845 590#endif
846 dev_priv->mm.userptr_wq =
847 alloc_workqueue("i915-userptr-acquire",
848 WQ_HIGHPRI | WQ_UNBOUND,
849 0);
850 if (!dev_priv->mm.userptr_wq)
851 return -ENOMEM;
852 591
853 return 0;592 return 0;
854}593}
855 594
856void i915_gem_cleanup_userptr(struct drm_i915_private *dev_priv)595void i915_gem_cleanup_userptr(struct drm_i915_private *dev_priv)
857{596{
858 destroy_workqueue(dev_priv->mm.userptr_wq);
859}597}
drivers/gpu/drm/i915/gem/selftests/huge_gem_object.c+2−2
@@ -89,7 +89,6 @@ static void huge_put_pages(struct drm_i915_gem_object *obj, · 88 unmodified lines
89 89
90static const struct drm_i915_gem_object_ops huge_ops = {90static const struct drm_i915_gem_object_ops huge_ops = {
91 .name = "huge-gem",91 .name = "huge-gem",
92 .flags = I915_GEM_OBJECT_HAS_STRUCT_PAGE,
93 .get_pages = huge_get_pages,92 .get_pages = huge_get_pages,
94 .put_pages = huge_put_pages,93 .put_pages = huge_put_pages,
95};94};
@@ -115,7 +114,8 @@ huge_gem_object(struct drm_i915_private *i915, · 19 unmodified lines
115 return ERR_PTR(-ENOMEM);114 return ERR_PTR(-ENOMEM);
116 115
117 drm_gem_private_object_init(&i915->drm, &obj->base, dma_size);116 drm_gem_private_object_init(&i915->drm, &obj->base, dma_size);
118 i915_gem_object_init(obj, &huge_ops, &lock_class);117 i915_gem_object_init(obj, &huge_ops, &lock_class,
118 I915_BO_ALLOC_STRUCT_PAGE);
119 119
120 obj->read_domains = I915_GEM_DOMAIN_CPU;120 obj->read_domains = I915_GEM_DOMAIN_CPU;
121 obj->write_domain = I915_GEM_DOMAIN_CPU;121 obj->write_domain = I915_GEM_DOMAIN_CPU;
drivers/gpu/drm/i915/gem/selftests/huge_pages.c+26−12
@@ -140,8 +140,7 @@ static void put_huge_pages(struct drm_i915_gem_object *obj, · 139 unmodified lines
140 140
141static const struct drm_i915_gem_object_ops huge_page_ops = {141static const struct drm_i915_gem_object_ops huge_page_ops = {
142 .name = "huge-gem",142 .name = "huge-gem",
143 .flags = I915_GEM_OBJECT_HAS_STRUCT_PAGE |143 .flags = I915_GEM_OBJECT_IS_SHRINKABLE,
144 I915_GEM_OBJECT_IS_SHRINKABLE,
145 .get_pages = get_huge_pages,144 .get_pages = get_huge_pages,
146 .put_pages = put_huge_pages,145 .put_pages = put_huge_pages,
147};146};
@@ -168,7 +167,8 @@ huge_pages_object(struct drm_i915_private *i915, · 20 unmodified lines
168 return ERR_PTR(-ENOMEM);167 return ERR_PTR(-ENOMEM);
169 168
170 drm_gem_private_object_init(&i915->drm, &obj->base, size);169 drm_gem_private_object_init(&i915->drm, &obj->base, size);
171 i915_gem_object_init(obj, &huge_page_ops, &lock_class);170 i915_gem_object_init(obj, &huge_page_ops, &lock_class,
171 I915_BO_ALLOC_STRUCT_PAGE);
172 172
173 i915_gem_object_set_volatile(obj);173 i915_gem_object_set_volatile(obj);
174 174
@@ -319,9 +319,9 @@ fake_huge_pages_object(struct drm_i915_private *i915, u64 size, bool single) · 144 unmodified lines
319 drm_gem_private_object_init(&i915->drm, &obj->base, size);319 drm_gem_private_object_init(&i915->drm, &obj->base, size);
320 320
321 if (single)321 if (single)
322 i915_gem_object_init(obj, &fake_ops_single, &lock_class);322 i915_gem_object_init(obj, &fake_ops_single, &lock_class, 0);
323 else323 else
324 i915_gem_object_init(obj, &fake_ops, &lock_class);324 i915_gem_object_init(obj, &fake_ops, &lock_class, 0);
325 325
326 i915_gem_object_set_volatile(obj);326 i915_gem_object_set_volatile(obj);
327 327
@@ -589,7 +589,7 @@ static int igt_mock_ppgtt_misaligned_dma(void *arg) · 261 unmodified lines
589 goto out_put;589 goto out_put;
590 }590 }
591 591
592 err = i915_gem_object_pin_pages(obj);592 err = i915_gem_object_pin_pages_unlocked(obj);
593 if (err)593 if (err)
594 goto out_put;594 goto out_put;
595 595
@@ -653,15 +653,19 @@ static int igt_mock_ppgtt_misaligned_dma(void *arg) · 57 unmodified lines
653 break;653 break;
654 }654 }
655 655
656 i915_gem_object_lock(obj, NULL);
656 i915_gem_object_unpin_pages(obj);657 i915_gem_object_unpin_pages(obj);
657 __i915_gem_object_put_pages(obj);658 __i915_gem_object_put_pages(obj);
659 i915_gem_object_unlock(obj);
658 i915_gem_object_put(obj);660 i915_gem_object_put(obj);
659 }661 }
660 662
661 return 0;663 return 0;
662 664
663out_unpin:665out_unpin:
666 i915_gem_object_lock(obj, NULL);
664 i915_gem_object_unpin_pages(obj);667 i915_gem_object_unpin_pages(obj);
668 i915_gem_object_unlock(obj);
665out_put:669out_put:
666 i915_gem_object_put(obj);670 i915_gem_object_put(obj);
667 671
@@ -675,8 +679,10 @@ static void close_object_list(struct list_head *objects, · 7 unmodified lines
675 679
676 list_for_each_entry_safe(obj, on, objects, st_link) {680 list_for_each_entry_safe(obj, on, objects, st_link) {
677 list_del(&obj->st_link);681 list_del(&obj->st_link);
682 i915_gem_object_lock(obj, NULL);
678 i915_gem_object_unpin_pages(obj);683 i915_gem_object_unpin_pages(obj);
679 __i915_gem_object_put_pages(obj);684 __i915_gem_object_put_pages(obj);
685 i915_gem_object_unlock(obj);
680 i915_gem_object_put(obj);686 i915_gem_object_put(obj);
681 }687 }
682}688}
@@ -713,7 +719,7 @@ static int igt_mock_ppgtt_huge_fill(void *arg) · 30 unmodified lines
713 break;719 break;
714 }720 }
715 721
716 err = i915_gem_object_pin_pages(obj);722 err = i915_gem_object_pin_pages_unlocked(obj);
717 if (err) {723 if (err) {
718 i915_gem_object_put(obj);724 i915_gem_object_put(obj);
719 break;725 break;
@@ -889,7 +895,7 @@ static int igt_mock_ppgtt_64K(void *arg) · 169 unmodified lines
889 if (IS_ERR(obj))895 if (IS_ERR(obj))
890 return PTR_ERR(obj);896 return PTR_ERR(obj);
891 897
892 err = i915_gem_object_pin_pages(obj);898 err = i915_gem_object_pin_pages_unlocked(obj);
893 if (err)899 if (err)
894 goto out_object_put;900 goto out_object_put;
895 901
@@ -943,8 +949,10 @@ static int igt_mock_ppgtt_64K(void *arg) · 47 unmodified lines
943 }949 }
944 950
945 i915_vma_unpin(vma);951 i915_vma_unpin(vma);
952 i915_gem_object_lock(obj, NULL);
946 i915_gem_object_unpin_pages(obj);953 i915_gem_object_unpin_pages(obj);
947 __i915_gem_object_put_pages(obj);954 __i915_gem_object_put_pages(obj);
955 i915_gem_object_unlock(obj);
948 i915_gem_object_put(obj);956 i915_gem_object_put(obj);
949 }957 }
950 }958 }
@@ -954,7 +962,9 @@ static int igt_mock_ppgtt_64K(void *arg) · 3 unmodified lines
954out_vma_unpin:962out_vma_unpin:
955 i915_vma_unpin(vma);963 i915_vma_unpin(vma);
956out_object_unpin:964out_object_unpin:
965 i915_gem_object_lock(obj, NULL);
957 i915_gem_object_unpin_pages(obj);966 i915_gem_object_unpin_pages(obj);
967 i915_gem_object_unlock(obj);
958out_object_put:968out_object_put:
959 i915_gem_object_put(obj);969 i915_gem_object_put(obj);
960 970
@@ -1024,7 +1034,7 @@ static int __cpu_check_vmap(struct drm_i915_gem_object *obj, u32 dword, u32 val) · 63 unmodified lines
1024 if (err)1034 if (err)
1025 return err;1035 return err;
1026 1036
1027 ptr = i915_gem_object_pin_map(obj, I915_MAP_WC);1037 ptr = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WC);
1028 if (IS_ERR(ptr))1038 if (IS_ERR(ptr))
1029 return PTR_ERR(ptr);1039 return PTR_ERR(ptr);
1030 1040
@@ -1304,7 +1314,7 @@ try_again: · 273 unmodified lines
1304 return err;1314 return err;
1305 }1315 }
1306 1316
1307 err = i915_gem_object_pin_pages(obj);1317 err = i915_gem_object_pin_pages_unlocked(obj);
1308 if (err) {1318 if (err) {
1309 if (err == -ENXIO || err == -E2BIG) {1319 if (err == -ENXIO || err == -E2BIG) {
1310 i915_gem_object_put(obj);1320 i915_gem_object_put(obj);
@@ -1327,8 +1337,10 @@ try_again: · 16 unmodified lines
1327 __func__, size, i);1337 __func__, size, i);
1328 }1338 }
1329out_unpin:1339out_unpin:
1340 i915_gem_object_lock(obj, NULL);
1330 i915_gem_object_unpin_pages(obj);1341 i915_gem_object_unpin_pages(obj);
1331 __i915_gem_object_put_pages(obj);1342 __i915_gem_object_put_pages(obj);
1343 i915_gem_object_unlock(obj);
1332out_put:1344out_put:
1333 i915_gem_object_put(obj);1345 i915_gem_object_put(obj);
1334 1346
@@ -1402,7 +1414,7 @@ static int igt_ppgtt_sanity_check(void *arg) · 67 unmodified lines
1402 return err;1414 return err;
1403 }1415 }
1404 1416
1405 err = i915_gem_object_pin_pages(obj);1417 err = i915_gem_object_pin_pages_unlocked(obj);
1406 if (err) {1418 if (err) {
1407 i915_gem_object_put(obj);1419 i915_gem_object_put(obj);
1408 goto out;1420 goto out;
@@ -1416,8 +1428,10 @@ static int igt_ppgtt_sanity_check(void *arg) · 7 unmodified lines
1416 1428
1417 err = igt_write_huge(ctx, obj);1429 err = igt_write_huge(ctx, obj);
1418 1430
1431 i915_gem_object_lock(obj, NULL);
1419 i915_gem_object_unpin_pages(obj);1432 i915_gem_object_unpin_pages(obj);
1420 __i915_gem_object_put_pages(obj);1433 __i915_gem_object_put_pages(obj);
1434 i915_gem_object_unlock(obj);
1421 i915_gem_object_put(obj);1435 i915_gem_object_put(obj);
1422 1436
1423 if (err) {1437 if (err) {
@@ -1462,7 +1476,7 @@ static int igt_tmpfs_fallback(void *arg) · 38 unmodified lines
1462 goto out_restore;1476 goto out_restore;
1463 }1477 }
1464 1478
1465 vaddr = i915_gem_object_pin_map(obj, I915_MAP_WB);1479 vaddr = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WB);
1466 if (IS_ERR(vaddr)) {1480 if (IS_ERR(vaddr)) {
1467 err = PTR_ERR(vaddr);1481 err = PTR_ERR(vaddr);
1468 goto out_put;1482 goto out_put;
drivers/gpu/drm/i915/gem/selftests/i915_gem_client_blt.c+4−4
@@ -45,7 +45,7 @@ static int __igt_client_fill(struct intel_engine_cs *engine) · 44 unmodified lines
45 goto err_flush;45 goto err_flush;
46 }46 }
47 47
48 vaddr = i915_gem_object_pin_map(obj, I915_MAP_WB);48 vaddr = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WB);
49 if (IS_ERR(vaddr)) {49 if (IS_ERR(vaddr)) {
50 err = PTR_ERR(vaddr);50 err = PTR_ERR(vaddr);
51 goto err_put;51 goto err_put;
@@ -157,7 +157,7 @@ static int prepare_blit(const struct tiled_blits *t, · 105 unmodified lines
157 u32 src_pitch, dst_pitch;157 u32 src_pitch, dst_pitch;
158 u32 cmd, *cs;158 u32 cmd, *cs;
159 159
160 cs = i915_gem_object_pin_map(batch, I915_MAP_WC);160 cs = i915_gem_object_pin_map_unlocked(batch, I915_MAP_WC);
161 if (IS_ERR(cs))161 if (IS_ERR(cs))
162 return PTR_ERR(cs);162 return PTR_ERR(cs);
163 163
@@ -377,7 +377,7 @@ static int verify_buffer(const struct tiled_blits *t, · 213 unmodified lines
377 y = i915_prandom_u32_max_state(t->height, prng);377 y = i915_prandom_u32_max_state(t->height, prng);
378 p = y * t->width + x;378 p = y * t->width + x;
379 379
380 vaddr = i915_gem_object_pin_map(buf->vma->obj, I915_MAP_WC);380 vaddr = i915_gem_object_pin_map_unlocked(buf->vma->obj, I915_MAP_WC);
381 if (IS_ERR(vaddr))381 if (IS_ERR(vaddr))
382 return PTR_ERR(vaddr);382 return PTR_ERR(vaddr);
383 383
@@ -564,7 +564,7 @@ static int tiled_blits_prepare(struct tiled_blits *t, · 180 unmodified lines
564 int err;564 int err;
565 int i;565 int i;
566 566
567 map = i915_gem_object_pin_map(t->scratch.vma->obj, I915_MAP_WC);567 map = i915_gem_object_pin_map_unlocked(t->scratch.vma->obj, I915_MAP_WC);
568 if (IS_ERR(map))568 if (IS_ERR(map))
569 return PTR_ERR(map);569 return PTR_ERR(map);
570 570
drivers/gpu/drm/i915/gem/selftests/i915_gem_coherency.c+6−8
@@ -160,7 +160,7 @@ static int wc_set(struct context *ctx, unsigned long offset, u32 v) · 159 unmodified lines
160 if (err)160 if (err)
161 return err;161 return err;
162 162
163 map = i915_gem_object_pin_map(ctx->obj, I915_MAP_WC);163 map = i915_gem_object_pin_map_unlocked(ctx->obj, I915_MAP_WC);
164 if (IS_ERR(map))164 if (IS_ERR(map))
165 return PTR_ERR(map);165 return PTR_ERR(map);
166 166
@@ -183,7 +183,7 @@ static int wc_get(struct context *ctx, unsigned long offset, u32 *v) · 16 unmodified lines
183 if (err)183 if (err)
184 return err;184 return err;
185 185
186 map = i915_gem_object_pin_map(ctx->obj, I915_MAP_WC);186 map = i915_gem_object_pin_map_unlocked(ctx->obj, I915_MAP_WC);
187 if (IS_ERR(map))187 if (IS_ERR(map))
188 return PTR_ERR(map);188 return PTR_ERR(map);
189 189
@@ -200,17 +200,15 @@ static int gpu_set(struct context *ctx, unsigned long offset, u32 v) · 10 unmodified lines
200 u32 *cs;200 u32 *cs;
201 int err;201 int err;
202 202
203 vma = i915_gem_object_ggtt_pin(ctx->obj, NULL, 0, 0, 0);
204 if (IS_ERR(vma))
205 return PTR_ERR(vma);
206
203 i915_gem_object_lock(ctx->obj, NULL);207 i915_gem_object_lock(ctx->obj, NULL);
204 err = i915_gem_object_set_to_gtt_domain(ctx->obj, true);208 err = i915_gem_object_set_to_gtt_domain(ctx->obj, true);
205 if (err)209 if (err)
206 goto out_unlock;210 goto out_unlock;
207 211
208 vma = i915_gem_object_ggtt_pin(ctx->obj, NULL, 0, 0, 0);
209 if (IS_ERR(vma)) {
210 err = PTR_ERR(vma);
211 goto out_unlock;
212 }
213
214 rq = intel_engine_create_kernel_request(ctx->engine);212 rq = intel_engine_create_kernel_request(ctx->engine);
215 if (IS_ERR(rq)) {213 if (IS_ERR(rq)) {
216 err = PTR_ERR(rq);214 err = PTR_ERR(rq);
drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c+5−5
@@ -1094,7 +1094,7 @@ __read_slice_count(struct intel_context *ce, · 1093 unmodified lines
1094 if (ret < 0)1094 if (ret < 0)
1095 return ret;1095 return ret;
1096 1096
1097 buf = i915_gem_object_pin_map(obj, I915_MAP_WB);1097 buf = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WB);
1098 if (IS_ERR(buf)) {1098 if (IS_ERR(buf)) {
1099 ret = PTR_ERR(buf);1099 ret = PTR_ERR(buf);
1100 return ret;1100 return ret;
@@ -1511,7 +1511,7 @@ static int write_to_scratch(struct i915_gem_context *ctx, · 410 unmodified lines
1511 if (IS_ERR(obj))1511 if (IS_ERR(obj))
1512 return PTR_ERR(obj);1512 return PTR_ERR(obj);
1513 1513
1514 cmd = i915_gem_object_pin_map(obj, I915_MAP_WB);1514 cmd = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WB);
1515 if (IS_ERR(cmd)) {1515 if (IS_ERR(cmd)) {
1516 err = PTR_ERR(cmd);1516 err = PTR_ERR(cmd);
1517 goto out;1517 goto out;
@@ -1622,7 +1622,7 @@ static int read_from_scratch(struct i915_gem_context *ctx, · 104 unmodified lines
1622 if (err)1622 if (err)
1623 goto out_vm;1623 goto out_vm;
1624 1624
1625 cmd = i915_gem_object_pin_map(obj, I915_MAP_WB);1625 cmd = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WB);
1626 if (IS_ERR(cmd)) {1626 if (IS_ERR(cmd)) {
1627 err = PTR_ERR(cmd);1627 err = PTR_ERR(cmd);
1628 goto out;1628 goto out;
@@ -1658,7 +1658,7 @@ static int read_from_scratch(struct i915_gem_context *ctx, · 29 unmodified lines
1658 if (err)1658 if (err)
1659 goto out_vm;1659 goto out_vm;
1660 1660
1661 cmd = i915_gem_object_pin_map(obj, I915_MAP_WB);1661 cmd = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WB);
1662 if (IS_ERR(cmd)) {1662 if (IS_ERR(cmd)) {
1663 err = PTR_ERR(cmd);1663 err = PTR_ERR(cmd);
1664 goto out;1664 goto out;
@@ -1715,7 +1715,7 @@ static int read_from_scratch(struct i915_gem_context *ctx, · 50 unmodified lines
1715 if (err)1715 if (err)
1716 goto out_vm;1716 goto out_vm;
1717 1717
1718 cmd = i915_gem_object_pin_map(obj, I915_MAP_WB);1718 cmd = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WB);
1719 if (IS_ERR(cmd)) {1719 if (IS_ERR(cmd)) {
1720 err = PTR_ERR(cmd);1720 err = PTR_ERR(cmd);
1721 goto out_vm;1721 goto out_vm;
drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c+1−1
@@ -194,7 +194,7 @@ static int igt_dmabuf_import_ownership(void *arg) · 193 unmodified lines
194 194
195 dma_buf_put(dmabuf);195 dma_buf_put(dmabuf);
196 196
197 err = i915_gem_object_pin_pages(obj);197 err = i915_gem_object_pin_pages_unlocked(obj);
198 if (err) {198 if (err) {
199 pr_err("i915_gem_object_pin_pages failed with err=%d\n", err);199 pr_err("i915_gem_object_pin_pages failed with err=%d\n", err);
200 goto out_obj;200 goto out_obj;
drivers/gpu/drm/i915/gem/selftests/i915_gem_execbuffer.c+1−1
@@ -116,7 +116,7 @@ static int igt_gpu_reloc(void *arg) · 115 unmodified lines
116 if (IS_ERR(scratch))116 if (IS_ERR(scratch))
117 return PTR_ERR(scratch);117 return PTR_ERR(scratch);
118 118
119 map = i915_gem_object_pin_map(scratch, I915_MAP_WC);119 map = i915_gem_object_pin_map_unlocked(scratch, I915_MAP_WC);
120 if (IS_ERR(map)) {120 if (IS_ERR(map)) {
121 err = PTR_ERR(map);121 err = PTR_ERR(map);
122 goto err_scratch;122 goto err_scratch;
drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c+10−11
@@ -322,7 +322,7 @@ static int igt_partial_tiling(void *arg) · 321 unmodified lines
322 if (IS_ERR(obj))322 if (IS_ERR(obj))
323 return PTR_ERR(obj);323 return PTR_ERR(obj);
324 324
325 err = i915_gem_object_pin_pages(obj);325 err = i915_gem_object_pin_pages_unlocked(obj);
326 if (err) {326 if (err) {
327 pr_err("Failed to allocate %u pages (%lu total), err=%d\n",327 pr_err("Failed to allocate %u pages (%lu total), err=%d\n",
328 nreal, obj->base.size / PAGE_SIZE, err);328 nreal, obj->base.size / PAGE_SIZE, err);
@@ -459,7 +459,7 @@ static int igt_smoke_tiling(void *arg) · 130 unmodified lines
459 if (IS_ERR(obj))459 if (IS_ERR(obj))
460 return PTR_ERR(obj);460 return PTR_ERR(obj);
461 461
462 err = i915_gem_object_pin_pages(obj);462 err = i915_gem_object_pin_pages_unlocked(obj);
463 if (err) {463 if (err) {
464 pr_err("Failed to allocate %u pages (%lu total), err=%d\n",464 pr_err("Failed to allocate %u pages (%lu total), err=%d\n",
465 nreal, obj->base.size / PAGE_SIZE, err);465 nreal, obj->base.size / PAGE_SIZE, err);
@@ -798,7 +798,7 @@ static int wc_set(struct drm_i915_gem_object *obj) · 332 unmodified lines
798{798{
799 void *vaddr;799 void *vaddr;
800 800
801 vaddr = i915_gem_object_pin_map(obj, I915_MAP_WC);801 vaddr = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WC);
802 if (IS_ERR(vaddr))802 if (IS_ERR(vaddr))
803 return PTR_ERR(vaddr);803 return PTR_ERR(vaddr);
804 804
@@ -814,7 +814,7 @@ static int wc_check(struct drm_i915_gem_object *obj) · 9 unmodified lines
814 void *vaddr;814 void *vaddr;
815 int err = 0;815 int err = 0;
816 816
817 vaddr = i915_gem_object_pin_map(obj, I915_MAP_WC);817 vaddr = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WC);
818 if (IS_ERR(vaddr))818 if (IS_ERR(vaddr))
819 return PTR_ERR(vaddr);819 return PTR_ERR(vaddr);
820 820
@@ -835,9 +835,8 @@ static bool can_mmap(struct drm_i915_gem_object *obj, enum i915_mmap_type type) · 14 unmodified lines
835 return false;835 return false;
836 836
837 if (type != I915_MMAP_TYPE_GTT &&837 if (type != I915_MMAP_TYPE_GTT &&
838 !i915_gem_object_type_has(obj,838 !i915_gem_object_has_struct_page(obj) &&
839 I915_GEM_OBJECT_HAS_STRUCT_PAGE |839 !i915_gem_object_type_has(obj, I915_GEM_OBJECT_HAS_IOMEM))
840 I915_GEM_OBJECT_HAS_IOMEM))
841 return false;840 return false;
842 841
843 return true;842 return true;
@@ -977,10 +976,8 @@ static const char *repr_mmap_type(enum i915_mmap_type type) · 133 unmodified lines
977 976
978static bool can_access(const struct drm_i915_gem_object *obj)977static bool can_access(const struct drm_i915_gem_object *obj)
979{978{
980 unsigned int flags =979 return i915_gem_object_has_struct_page(obj) ||
981 I915_GEM_OBJECT_HAS_STRUCT_PAGE | I915_GEM_OBJECT_HAS_IOMEM;980 i915_gem_object_type_has(obj, I915_GEM_OBJECT_HAS_IOMEM);
982
983 return i915_gem_object_type_has(obj, flags);
984}981}
985 982
986static int __igt_mmap_access(struct drm_i915_private *i915,983static int __igt_mmap_access(struct drm_i915_private *i915,
@@ -1319,7 +1316,9 @@ static int __igt_mmap_revoke(struct drm_i915_private *i915, · 332 unmodified lines
1319 }1316 }
1320 1317
1321 if (type != I915_MMAP_TYPE_GTT) {1318 if (type != I915_MMAP_TYPE_GTT) {
1319 i915_gem_object_lock(obj, NULL);
1322 __i915_gem_object_put_pages(obj);1320 __i915_gem_object_put_pages(obj);
1321 i915_gem_object_unlock(obj);
1323 if (i915_gem_object_has_pages(obj)) {1322 if (i915_gem_object_has_pages(obj)) {
1324 pr_err("Failed to put-pages object!\n");1323 pr_err("Failed to put-pages object!\n");
1325 err = -EINVAL;1324 err = -EINVAL;
drivers/gpu/drm/i915/gem/selftests/i915_gem_object.c+1−1
@@ -47,7 +47,7 @@ static int igt_gem_huge(void *arg) · 46 unmodified lines
47 if (IS_ERR(obj))47 if (IS_ERR(obj))
48 return PTR_ERR(obj);48 return PTR_ERR(obj);
49 49
50 err = i915_gem_object_pin_pages(obj);50 err = i915_gem_object_pin_pages_unlocked(obj);
51 if (err) {51 if (err) {
52 pr_err("Failed to allocate %u pages (%lu total), err=%d\n",52 pr_err("Failed to allocate %u pages (%lu total), err=%d\n",
53 nreal, obj->base.size / PAGE_SIZE, err);53 nreal, obj->base.size / PAGE_SIZE, err);
drivers/gpu/drm/i915/gem/selftests/i915_gem_object_blt.c+3−3
@@ -262,7 +262,7 @@ static int igt_fill_blt_thread(void *arg) · 261 unmodified lines
262 goto err_flush;262 goto err_flush;
263 }263 }
264 264
265 vaddr = i915_gem_object_pin_map(obj, I915_MAP_WB);265 vaddr = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WB);
266 if (IS_ERR(vaddr)) {266 if (IS_ERR(vaddr)) {
267 err = PTR_ERR(vaddr);267 err = PTR_ERR(vaddr);
268 goto err_put;268 goto err_put;
@@ -380,7 +380,7 @@ static int igt_copy_blt_thread(void *arg) · 111 unmodified lines
380 goto err_flush;380 goto err_flush;
381 }381 }
382 382
383 vaddr = i915_gem_object_pin_map(src, I915_MAP_WB);383 vaddr = i915_gem_object_pin_map_unlocked(src, I915_MAP_WB);
384 if (IS_ERR(vaddr)) {384 if (IS_ERR(vaddr)) {
385 err = PTR_ERR(vaddr);385 err = PTR_ERR(vaddr);
386 goto err_put_src;386 goto err_put_src;
@@ -400,7 +400,7 @@ static int igt_copy_blt_thread(void *arg) · 13 unmodified lines
400 goto err_put_src;400 goto err_put_src;
401 }401 }
402 402
403 vaddr = i915_gem_object_pin_map(dst, I915_MAP_WB);403 vaddr = i915_gem_object_pin_map_unlocked(dst, I915_MAP_WB);
404 if (IS_ERR(vaddr)) {404 if (IS_ERR(vaddr)) {
405 err = PTR_ERR(vaddr);405 err = PTR_ERR(vaddr);
406 goto err_put_dst;406 goto err_put_dst;
drivers/gpu/drm/i915/gem/selftests/i915_gem_phys.c+9−1
@@ -25,13 +25,21 @@ static int mock_phys_object(void *arg) · 24 unmodified lines
25 goto out;25 goto out;
26 }26 }
27 27
28 if (!i915_gem_object_has_struct_page(obj)) {
29 err = -EINVAL;
30 pr_err("shmem has no struct page\n");
31 goto out_obj;
32 }
33
34 i915_gem_object_lock(obj, NULL);
28 err = i915_gem_object_attach_phys(obj, PAGE_SIZE);35 err = i915_gem_object_attach_phys(obj, PAGE_SIZE);
36 i915_gem_object_unlock(obj);
29 if (err) {37 if (err) {
30 pr_err("i915_gem_object_attach_phys failed, err=%d\n", err);38 pr_err("i915_gem_object_attach_phys failed, err=%d\n", err);
31 goto out_obj;39 goto out_obj;
32 }40 }
33 41
34 if (obj->ops != &i915_gem_phys_ops) {42 if (i915_gem_object_has_struct_page(obj)) {
35 pr_err("i915_gem_object_attach_phys did not create a phys object\n");43 pr_err("i915_gem_object_attach_phys did not create a phys object\n");
36 err = -EINVAL;44 err = -EINVAL;
37 goto out_obj;45 goto out_obj;
drivers/gpu/drm/i915/gem/selftests/igt_gem_utils.c+1−1
@@ -55,7 +55,7 @@ igt_emit_store_dw(struct i915_vma *vma, · 54 unmodified lines
55 if (IS_ERR(obj))55 if (IS_ERR(obj))
56 return ERR_CAST(obj);56 return ERR_CAST(obj);
57 57
58 cmd = i915_gem_object_pin_map(obj, I915_MAP_WC);58 cmd = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WC);
59 if (IS_ERR(cmd)) {59 if (IS_ERR(cmd)) {
60 err = PTR_ERR(cmd);60 err = PTR_ERR(cmd);
61 goto err;61 goto err;
drivers/gpu/drm/i915/gt/gen2_engine_cs.c+1−1
@@ -143,7 +143,7 @@ static u32 *__gen2_emit_breadcrumb(struct i915_request *rq, u32 *cs, · 142 unmodified lines
143 int flush, int post)143 int flush, int post)
144{144{
145 GEM_BUG_ON(i915_request_active_timeline(rq)->hwsp_ggtt != rq->engine->status_page.vma);145 GEM_BUG_ON(i915_request_active_timeline(rq)->hwsp_ggtt != rq->engine->status_page.vma);
146 GEM_BUG_ON(offset_in_page(i915_request_active_timeline(rq)->hwsp_offset) != I915_GEM_HWS_SEQNO_ADDR);146 GEM_BUG_ON(offset_in_page(rq->hwsp_seqno) != I915_GEM_HWS_SEQNO_ADDR);
147 147
148 *cs++ = MI_FLUSH;148 *cs++ = MI_FLUSH;
149 149
drivers/gpu/drm/i915/gt/gen6_engine_cs.c+4−4
@@ -161,7 +161,7 @@ u32 *gen6_emit_breadcrumb_rcs(struct i915_request *rq, u32 *cs) · 160 unmodified lines
161 PIPE_CONTROL_DC_FLUSH_ENABLE |161 PIPE_CONTROL_DC_FLUSH_ENABLE |
162 PIPE_CONTROL_QW_WRITE |162 PIPE_CONTROL_QW_WRITE |
163 PIPE_CONTROL_CS_STALL);163 PIPE_CONTROL_CS_STALL);
164 *cs++ = i915_request_active_timeline(rq)->hwsp_offset |164 *cs++ = i915_request_active_seqno(rq) |
165 PIPE_CONTROL_GLOBAL_GTT;165 PIPE_CONTROL_GLOBAL_GTT;
166 *cs++ = rq->fence.seqno;166 *cs++ = rq->fence.seqno;
167 167
@@ -359,7 +359,7 @@ u32 *gen7_emit_breadcrumb_rcs(struct i915_request *rq, u32 *cs) · 191 unmodified lines
359 PIPE_CONTROL_QW_WRITE |359 PIPE_CONTROL_QW_WRITE |
360 PIPE_CONTROL_GLOBAL_GTT_IVB |360 PIPE_CONTROL_GLOBAL_GTT_IVB |
361 PIPE_CONTROL_CS_STALL);361 PIPE_CONTROL_CS_STALL);
362 *cs++ = i915_request_active_timeline(rq)->hwsp_offset;362 *cs++ = i915_request_active_seqno(rq);
363 *cs++ = rq->fence.seqno;363 *cs++ = rq->fence.seqno;
364 364
365 *cs++ = MI_USER_INTERRUPT;365 *cs++ = MI_USER_INTERRUPT;
@@ -374,7 +374,7 @@ u32 *gen7_emit_breadcrumb_rcs(struct i915_request *rq, u32 *cs) · 8 unmodified lines
374u32 *gen6_emit_breadcrumb_xcs(struct i915_request *rq, u32 *cs)374u32 *gen6_emit_breadcrumb_xcs(struct i915_request *rq, u32 *cs)
375{375{
376 GEM_BUG_ON(i915_request_active_timeline(rq)->hwsp_ggtt != rq->engine->status_page.vma);376 GEM_BUG_ON(i915_request_active_timeline(rq)->hwsp_ggtt != rq->engine->status_page.vma);
377 GEM_BUG_ON(offset_in_page(i915_request_active_timeline(rq)->hwsp_offset) != I915_GEM_HWS_SEQNO_ADDR);377 GEM_BUG_ON(offset_in_page(rq->hwsp_seqno) != I915_GEM_HWS_SEQNO_ADDR);
378 378
379 *cs++ = MI_FLUSH_DW | MI_FLUSH_DW_OP_STOREDW | MI_FLUSH_DW_STORE_INDEX;379 *cs++ = MI_FLUSH_DW | MI_FLUSH_DW_OP_STOREDW | MI_FLUSH_DW_STORE_INDEX;
380 *cs++ = I915_GEM_HWS_SEQNO_ADDR | MI_FLUSH_DW_USE_GTT;380 *cs++ = I915_GEM_HWS_SEQNO_ADDR | MI_FLUSH_DW_USE_GTT;
@@ -394,7 +394,7 @@ u32 *gen7_emit_breadcrumb_xcs(struct i915_request *rq, u32 *cs) · 13 unmodified lines
394 int i;394 int i;
395 395
396 GEM_BUG_ON(i915_request_active_timeline(rq)->hwsp_ggtt != rq->engine->status_page.vma);396 GEM_BUG_ON(i915_request_active_timeline(rq)->hwsp_ggtt != rq->engine->status_page.vma);
397 GEM_BUG_ON(offset_in_page(i915_request_active_timeline(rq)->hwsp_offset) != I915_GEM_HWS_SEQNO_ADDR);397 GEM_BUG_ON(offset_in_page(rq->hwsp_seqno) != I915_GEM_HWS_SEQNO_ADDR);
398 398
399 *cs++ = MI_FLUSH_DW | MI_INVALIDATE_TLB |399 *cs++ = MI_FLUSH_DW | MI_INVALIDATE_TLB |
400 MI_FLUSH_DW_OP_STOREDW | MI_FLUSH_DW_STORE_INDEX;400 MI_FLUSH_DW_OP_STOREDW | MI_FLUSH_DW_STORE_INDEX;
drivers/gpu/drm/i915/gt/gen8_engine_cs.c+6−7
@@ -338,15 +338,14 @@ static u32 preempt_address(struct intel_engine_cs *engine) · 337 unmodified lines
338 338
339static u32 hwsp_offset(const struct i915_request *rq)339static u32 hwsp_offset(const struct i915_request *rq)
340{340{
341 const struct intel_timeline_cacheline *cl;341 const struct intel_timeline *tl;
342 342
343 /* Before the request is executed, the timeline/cachline is fixed */343 /* Before the request is executed, the timeline is fixed */
344 tl = rcu_dereference_protected(rq->timeline,
345 !i915_request_signaled(rq));
344 346
345 cl = rcu_dereference_protected(rq->hwsp_cacheline, 1);347 /* See the comment in i915_request_active_seqno(). */
346 if (cl)348 return page_mask_bits(tl->hwsp_offset) + offset_in_page(rq->hwsp_seqno);
347 return cl->ggtt_offset;
348
349 return rcu_dereference_protected(rq->timeline, 1)->hwsp_offset;
350}349}
351 350
352int gen8_emit_init_breadcrumb(struct i915_request *rq)351int gen8_emit_init_breadcrumb(struct i915_request *rq)
drivers/gpu/drm/i915/gt/intel_context_param.h+10−1
@@ -6,9 +6,18 @@ · 5 unmodified lines
6#ifndef INTEL_CONTEXT_PARAM_H6#ifndef INTEL_CONTEXT_PARAM_H
7#define INTEL_CONTEXT_PARAM_H7#define INTEL_CONTEXT_PARAM_H
8 8
9struct intel_context;9#include <linux/types.h>
10
11#include "intel_context.h"
10 12
11int intel_context_set_ring_size(struct intel_context *ce, long sz);13int intel_context_set_ring_size(struct intel_context *ce, long sz);
12long intel_context_get_ring_size(struct intel_context *ce);14long intel_context_get_ring_size(struct intel_context *ce);
13 15
16static inline int
17intel_context_set_watchdog_us(struct intel_context *ce, u64 timeout_us)
18{
19 ce->watchdog.timeout_us = timeout_us;
20 return 0;
21}
22
14#endif /* INTEL_CONTEXT_PARAM_H */23#endif /* INTEL_CONTEXT_PARAM_H */
drivers/gpu/drm/i915/gt/intel_context_types.h+4−0
@@ -97,6 +97,10 @@ struct intel_context { · 96 unmodified lines
97#define CONTEXT_FORCE_SINGLE_SUBMISSION 797#define CONTEXT_FORCE_SINGLE_SUBMISSION 7
98#define CONTEXT_NOPREEMPT 898#define CONTEXT_NOPREEMPT 8
99 99
100 struct {
101 u64 timeout_us;
102 } watchdog;
103
100 u32 *lrc_reg_state;104 u32 *lrc_reg_state;
101 union {105 union {
102 struct {106 struct {
drivers/gpu/drm/i915/gt/intel_engine_cs.c+25−13
@@ -619,6 +619,7 @@ static void cleanup_status_page(struct intel_engine_cs *engine) · 618 unmodified lines
619}619}
620 620
621static int pin_ggtt_status_page(struct intel_engine_cs *engine,621static int pin_ggtt_status_page(struct intel_engine_cs *engine,
622 struct i915_gem_ww_ctx *ww,
622 struct i915_vma *vma)623 struct i915_vma *vma)
623{624{
624 unsigned int flags;625 unsigned int flags;
@@ -639,12 +640,13 @@ static int pin_ggtt_status_page(struct intel_engine_cs *engine, · 14 unmodified lines
639 else640 else
640 flags = PIN_HIGH;641 flags = PIN_HIGH;
641 642
642 return i915_ggtt_pin(vma, NULL, 0, flags);643 return i915_ggtt_pin(vma, ww, 0, flags);
643}644}
644 645
645static int init_status_page(struct intel_engine_cs *engine)646static int init_status_page(struct intel_engine_cs *engine)
646{647{
647 struct drm_i915_gem_object *obj;648 struct drm_i915_gem_object *obj;
649 struct i915_gem_ww_ctx ww;
648 struct i915_vma *vma;650 struct i915_vma *vma;
649 void *vaddr;651 void *vaddr;
650 int ret;652 int ret;
@@ -670,30 +672,39 @@ static int init_status_page(struct intel_engine_cs *engine) · 19 unmodified lines
670 vma = i915_vma_instance(obj, &engine->gt->ggtt->vm, NULL);672 vma = i915_vma_instance(obj, &engine->gt->ggtt->vm, NULL);
671 if (IS_ERR(vma)) {673 if (IS_ERR(vma)) {
672 ret = PTR_ERR(vma);674 ret = PTR_ERR(vma);
673 goto err;675 goto err_put;
674 }676 }
675 677
678 i915_gem_ww_ctx_init(&ww, true);
679retry:
680 ret = i915_gem_object_lock(obj, &ww);
681 if (!ret && !HWS_NEEDS_PHYSICAL(engine->i915))
682 ret = pin_ggtt_status_page(engine, &ww, vma);
683 if (ret)
684 goto err;
685
676 vaddr = i915_gem_object_pin_map(obj, I915_MAP_WB);686 vaddr = i915_gem_object_pin_map(obj, I915_MAP_WB);
677 if (IS_ERR(vaddr)) {687 if (IS_ERR(vaddr)) {
678 ret = PTR_ERR(vaddr);688 ret = PTR_ERR(vaddr);
679 goto err;689 goto err_unpin;
680 }690 }
681 691
682 engine->status_page.addr = memset(vaddr, 0, PAGE_SIZE);692 engine->status_page.addr = memset(vaddr, 0, PAGE_SIZE);
683 engine->status_page.vma = vma;693 engine->status_page.vma = vma;
684 694
685 if (!HWS_NEEDS_PHYSICAL(engine->i915)) {
686 ret = pin_ggtt_status_page(engine, vma);
687 if (ret)
688 goto err_unpin;
689 }
690
691 return 0;
692
693err_unpin:695err_unpin:
694 i915_gem_object_unpin_map(obj);696 if (ret)
697 i915_vma_unpin(vma);
695err:698err:
696 i915_gem_object_put(obj);699 if (ret == -EDEADLK) {
700 ret = i915_gem_ww_ctx_backoff(&ww);
701 if (!ret)
702 goto retry;
703 }
704 i915_gem_ww_ctx_fini(&ww);
705err_put:
706 if (ret)
707 i915_gem_object_put(obj);
697 return ret;708 return ret;
698}709}
699 710
@@ -763,6 +774,7 @@ static int measure_breadcrumb_dw(struct intel_context *ce) · 63 unmodified lines
763 frame->rq.engine = engine;774 frame->rq.engine = engine;
764 frame->rq.context = ce;775 frame->rq.context = ce;
765 rcu_assign_pointer(frame->rq.timeline, ce->timeline);776 rcu_assign_pointer(frame->rq.timeline, ce->timeline);
777 frame->rq.hwsp_seqno = ce->timeline->hwsp_seqno;
766 778
767 frame->ring.vaddr = frame->cs;779 frame->ring.vaddr = frame->cs;
768 frame->ring.size = sizeof(frame->cs);780 frame->ring.size = sizeof(frame->cs);
drivers/gpu/drm/i915/gt/intel_engine_heartbeat.c+1−0
@@ -279,6 +279,7 @@ int intel_engine_pulse(struct intel_engine_cs *engine) · 278 unmodified lines
279 mutex_unlock(&ce->timeline->mutex);279 mutex_unlock(&ce->timeline->mutex);
280 }280 }
281 281
282 intel_engine_flush_submission(engine);
282 intel_engine_pm_put(engine);283 intel_engine_pm_put(engine);
283 return err;284 return err;
284}285}
drivers/gpu/drm/i915/gt/intel_engine_pm.c+4−0
@@ -27,12 +27,16 @@ static void dbg_poison_ce(struct intel_context *ce) · 26 unmodified lines
27 int type = i915_coherent_map_type(ce->engine->i915);27 int type = i915_coherent_map_type(ce->engine->i915);
28 void *map;28 void *map;
29 29
30 if (!i915_gem_object_trylock(obj))
31 return;
32
30 map = i915_gem_object_pin_map(obj, type);33 map = i915_gem_object_pin_map(obj, type);
31 if (!IS_ERR(map)) {34 if (!IS_ERR(map)) {
32 memset(map, CONTEXT_REDZONE, obj->base.size);35 memset(map, CONTEXT_REDZONE, obj->base.size);
33 i915_gem_object_flush_map(obj);36 i915_gem_object_flush_map(obj);
34 i915_gem_object_unpin_map(obj);37 i915_gem_object_unpin_map(obj);
35 }38 }
39 i915_gem_object_unlock(obj);
36 }40 }
37}41}
38 42
drivers/gpu/drm/i915/gt/intel_execlists_submission.c+39−10
@@ -470,6 +470,11 @@ static void reset_active(struct i915_request *rq, · 469 unmodified lines
470 ce->lrc.lrca = lrc_update_regs(ce, engine, head);470 ce->lrc.lrca = lrc_update_regs(ce, engine, head);
471}471}
472 472
473static bool bad_request(const struct i915_request *rq)
474{
475 return rq->fence.error && i915_request_started(rq);
476}
477
473static struct intel_engine_cs *478static struct intel_engine_cs *
474__execlists_schedule_in(struct i915_request *rq)479__execlists_schedule_in(struct i915_request *rq)
475{480{
@@ -482,7 +487,7 @@ __execlists_schedule_in(struct i915_request *rq) · 6 unmodified lines
482 !intel_engine_has_heartbeat(engine)))487 !intel_engine_has_heartbeat(engine)))
483 intel_context_set_banned(ce);488 intel_context_set_banned(ce);
484 489
485 if (unlikely(intel_context_is_banned(ce)))490 if (unlikely(intel_context_is_banned(ce) || bad_request(rq)))
486 reset_active(rq, engine);491 reset_active(rq, engine);
487 492
488 if (IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM))493 if (IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM))
@@ -752,9 +757,8 @@ assert_pending_valid(const struct intel_engine_execlists *execlists, · 263 unmodified lines
752{757{
753 struct intel_engine_cs *engine =758 struct intel_engine_cs *engine =
754 container_of(execlists, typeof(*engine), execlists);759 container_of(execlists, typeof(*engine), execlists);
755 struct i915_request * const *port, *rq;760 struct i915_request * const *port, *rq, *prev = NULL;
756 struct intel_context *ce = NULL;761 struct intel_context *ce = NULL;
757 bool sentinel = false;
758 u32 ccid = -1;762 u32 ccid = -1;
759 763
760 trace_ports(execlists, msg, execlists->pending);764 trace_ports(execlists, msg, execlists->pending);
@@ -804,15 +808,20 @@ assert_pending_valid(const struct intel_engine_execlists *execlists, · 43 unmodified lines
804 * Sentinels are supposed to be the last request so they flush808 * Sentinels are supposed to be the last request so they flush
805 * the current execution off the HW. Check that they are the only809 * the current execution off the HW. Check that they are the only
806 * request in the pending submission.810 * request in the pending submission.
811 *
812 * NB: Due to the async nature of preempt-to-busy and request
813 * cancellation we need to handle the case where request
814 * becomes a sentinel in parallel to CSB processing.
807 */815 */
808 if (sentinel) {816 if (prev && i915_request_has_sentinel(prev) &&
817 !READ_ONCE(prev->fence.error)) {
809 GEM_TRACE_ERR("%s: context:%llx after sentinel in pending[%zd]\n",818 GEM_TRACE_ERR("%s: context:%llx after sentinel in pending[%zd]\n",
810 engine->name,819 engine->name,
811 ce->timeline->fence_context,820 ce->timeline->fence_context,
812 port - execlists->pending);821 port - execlists->pending);
813 return false;822 return false;
814 }823 }
815 sentinel = i915_request_has_sentinel(rq);824 prev = rq;
816 825
817 /*826 /*
818 * We want virtual requests to only be in the first slot so827 * We want virtual requests to only be in the first slot so
@@ -948,7 +957,7 @@ static bool can_merge_rq(const struct i915_request *prev, · 129 unmodified lines
948 if (__i915_request_is_complete(next))957 if (__i915_request_is_complete(next))
949 return true;958 return true;
950 959
951 if (unlikely((i915_request_flags(prev) ^ i915_request_flags(next)) &960 if (unlikely((i915_request_flags(prev) | i915_request_flags(next)) &
952 (BIT(I915_FENCE_FLAG_NOPREEMPT) |961 (BIT(I915_FENCE_FLAG_NOPREEMPT) |
953 BIT(I915_FENCE_FLAG_SENTINEL))))962 BIT(I915_FENCE_FLAG_SENTINEL))))
954 return false;963 return false;
@@ -1208,7 +1217,7 @@ static unsigned long active_preempt_timeout(struct intel_engine_cs *engine, · 253 unmodified lines
1208 return 0;1217 return 0;
1209 1218
1210 /* Force a fast reset for terminated contexts (ignoring sysfs!) */1219 /* Force a fast reset for terminated contexts (ignoring sysfs!) */
1211 if (unlikely(intel_context_is_banned(rq->context)))1220 if (unlikely(intel_context_is_banned(rq->context) || bad_request(rq)))
1212 return 1;1221 return 1;
1213 1222
1214 return READ_ONCE(engine->props.preempt_timeout_ms);1223 return READ_ONCE(engine->props.preempt_timeout_ms);
@@ -2457,11 +2466,31 @@ static void execlists_submit_request(struct i915_request *request) · 1242 unmodified lines
2457 spin_unlock_irqrestore(&engine->active.lock, flags);2466 spin_unlock_irqrestore(&engine->active.lock, flags);
2458}2467}
2459 2468
2469static int
2470__execlists_context_pre_pin(struct intel_context *ce,
2471 struct intel_engine_cs *engine,
2472 struct i915_gem_ww_ctx *ww, void **vaddr)
2473{
2474 int err;
2475
2476 err = lrc_pre_pin(ce, engine, ww, vaddr);
2477 if (err)
2478 return err;
2479
2480 if (!__test_and_set_bit(CONTEXT_INIT_BIT, &ce->flags)) {
2481 lrc_init_state(ce, engine, *vaddr);
2482
2483 __i915_gem_object_flush_map(ce->state->obj, 0, engine->context_size);
2484 }
2485
2486 return 0;
2487}
2488
2460static int execlists_context_pre_pin(struct intel_context *ce,2489static int execlists_context_pre_pin(struct intel_context *ce,
2461 struct i915_gem_ww_ctx *ww,2490 struct i915_gem_ww_ctx *ww,
2462 void **vaddr)2491 void **vaddr)
2463{2492{
2464 return lrc_pre_pin(ce, ce->engine, ww, vaddr);2493 return __execlists_context_pre_pin(ce, ce->engine, ww, vaddr);
2465}2494}
2466 2495
2467static int execlists_context_pin(struct intel_context *ce, void *vaddr)2496static int execlists_context_pin(struct intel_context *ce, void *vaddr)
@@ -3365,8 +3394,8 @@ static int virtual_context_pre_pin(struct intel_context *ce, · 897 unmodified lines
3365{3394{
3366 struct virtual_engine *ve = container_of(ce, typeof(*ve), context);3395 struct virtual_engine *ve = container_of(ce, typeof(*ve), context);
3367 3396
3368 /* Note: we must use a real engine class for setting up reg state */3397 /* Note: we must use a real engine class for setting up reg state */
3369 return lrc_pre_pin(ce, ve->siblings[0], ww, vaddr);3398 return __execlists_context_pre_pin(ce, ve->siblings[0], ww, vaddr);
3370}3399}
3371 3400
3372static int virtual_context_pin(struct intel_context *ce, void *vaddr)3401static int virtual_context_pin(struct intel_context *ce, void *vaddr)
drivers/gpu/drm/i915/gt/intel_execlists_submission.h+2−0
@@ -6,6 +6,7 @@ · 5 unmodified lines
6#ifndef __INTEL_EXECLISTS_SUBMISSION_H__6#ifndef __INTEL_EXECLISTS_SUBMISSION_H__
7#define __INTEL_EXECLISTS_SUBMISSION_H__7#define __INTEL_EXECLISTS_SUBMISSION_H__
8 8
9#include <linux/llist.h>
9#include <linux/types.h>10#include <linux/types.h>
10 11
11struct drm_printer;12struct drm_printer;
@@ -13,6 +14,7 @@ struct drm_printer; · 1 unmodified line
13struct i915_request;14struct i915_request;
14struct intel_context;15struct intel_context;
15struct intel_engine_cs;16struct intel_engine_cs;
17struct intel_gt;
16 18
17enum {19enum {
18 INTEL_CONTEXT_SCHEDULE_IN = 0,20 INTEL_CONTEXT_SCHEDULE_IN = 0,
drivers/gpu/drm/i915/gt/intel_ggtt.c+8−2
@@ -647,7 +647,9 @@ static int init_aliasing_ppgtt(struct i915_ggtt *ggtt) · 646 unmodified lines
647 if (err)647 if (err)
648 goto err_ppgtt;648 goto err_ppgtt;
649 649
650 i915_gem_object_lock(ppgtt->vm.scratch[0], NULL);
650 err = i915_vm_pin_pt_stash(&ppgtt->vm, &stash);651 err = i915_vm_pin_pt_stash(&ppgtt->vm, &stash);
652 i915_gem_object_unlock(ppgtt->vm.scratch[0]);
651 if (err)653 if (err)
652 goto err_stash;654 goto err_stash;
653 655
@@ -734,6 +736,7 @@ static void ggtt_cleanup_hw(struct i915_ggtt *ggtt) · 80 unmodified lines
734 736
735 mutex_unlock(&ggtt->vm.mutex);737 mutex_unlock(&ggtt->vm.mutex);
736 i915_address_space_fini(&ggtt->vm);738 i915_address_space_fini(&ggtt->vm);
739 dma_resv_fini(&ggtt->vm.resv);
737 740
738 arch_phys_wc_del(ggtt->mtrr);741 arch_phys_wc_del(ggtt->mtrr);
739 742
@@ -1115,6 +1118,7 @@ static int ggtt_probe_hw(struct i915_ggtt *ggtt, struct intel_gt *gt) · 375 unmodified lines
1115 ggtt->vm.gt = gt;1118 ggtt->vm.gt = gt;
1116 ggtt->vm.i915 = i915;1119 ggtt->vm.i915 = i915;
1117 ggtt->vm.dma = i915->drm.dev;1120 ggtt->vm.dma = i915->drm.dev;
1121 dma_resv_init(&ggtt->vm.resv);
1118 1122
1119 if (INTEL_GEN(i915) <= 5)1123 if (INTEL_GEN(i915) <= 5)
1120 ret = i915_gmch_probe(ggtt);1124 ret = i915_gmch_probe(ggtt);
@@ -1122,8 +1126,10 @@ static int ggtt_probe_hw(struct i915_ggtt *ggtt, struct intel_gt *gt) · 1 unmodified line
1122 ret = gen6_gmch_probe(ggtt);1126 ret = gen6_gmch_probe(ggtt);
1123 else1127 else
1124 ret = gen8_gmch_probe(ggtt);1128 ret = gen8_gmch_probe(ggtt);
1125 if (ret)1129 if (ret) {
1130 dma_resv_fini(&ggtt->vm.resv);
1126 return ret;1131 return ret;
1132 }
1127 1133
1128 if ((ggtt->vm.total - 1) >> 32) {1134 if ((ggtt->vm.total - 1) >> 32) {
1129 drm_err(&i915->drm,1135 drm_err(&i915->drm,
@@ -1420,7 +1426,7 @@ intel_partial_pages(const struct i915_ggtt_view *view, · 290 unmodified lines
1420 if (ret)1426 if (ret)
1421 goto err_sg_alloc;1427 goto err_sg_alloc;
1422 1428
1423 iter = i915_gem_object_get_sg_dma(obj, view->partial.offset, &offset);1429 iter = i915_gem_object_get_sg_dma(obj, view->partial.offset, &offset, true);
1424 GEM_BUG_ON(!iter);1430 GEM_BUG_ON(!iter);
1425 1431
1426 sg = st->sgl;1432 sg = st->sgl;
drivers/gpu/drm/i915/gt/intel_gt.c+3−0
@@ -29,6 +29,9 @@ void intel_gt_init_early(struct intel_gt *gt, struct drm_i915_private *i915) · 28 unmodified lines
29 INIT_LIST_HEAD(&gt->closed_vma);29 INIT_LIST_HEAD(&gt->closed_vma);
30 spin_lock_init(&gt->closed_lock);30 spin_lock_init(&gt->closed_lock);
31 31
32 init_llist_head(&gt->watchdog.list);
33 INIT_WORK(&gt->watchdog.work, intel_gt_watchdog_work);
34
32 intel_gt_init_buffer_pool(gt);35 intel_gt_init_buffer_pool(gt);
33 intel_gt_init_reset(gt);36 intel_gt_init_reset(gt);
34 intel_gt_init_requests(gt);37 intel_gt_init_requests(gt);
drivers/gpu/drm/i915/gt/intel_gt.h+2−0
@@ -77,4 +77,6 @@ static inline bool intel_gt_is_wedged(const struct intel_gt *gt) · 76 unmodified lines
77void intel_gt_info_print(const struct intel_gt_info *info,77void intel_gt_info_print(const struct intel_gt_info *info,
78 struct drm_printer *p);78 struct drm_printer *p);
79 79
80void intel_gt_watchdog_work(struct work_struct *work);
81
80#endif /* __INTEL_GT_H__ */82#endif /* __INTEL_GT_H__ */
drivers/gpu/drm/i915/gt/intel_gt_buffer_pool.c+21−26
@@ -98,28 +98,6 @@ static void pool_free_work(struct work_struct *wrk) · 97 unmodified lines
98 round_jiffies_up_relative(HZ));98 round_jiffies_up_relative(HZ));
99}99}
100 100
101static int pool_active(struct i915_active *ref)
102{
103 struct intel_gt_buffer_pool_node *node =
104 container_of(ref, typeof(*node), active);
105 struct dma_resv *resv = node->obj->base.resv;
106 int err;
107
108 if (dma_resv_trylock(resv)) {
109 dma_resv_add_excl_fence(resv, NULL);
110 dma_resv_unlock(resv);
111 }
112
113 err = i915_gem_object_pin_pages(node->obj);
114 if (err)
115 return err;
116
117 /* Hide this pinned object from the shrinker until retired */
118 i915_gem_object_make_unshrinkable(node->obj);
119
120 return 0;
121}
122
123__i915_active_call101__i915_active_call
124static void pool_retire(struct i915_active *ref)102static void pool_retire(struct i915_active *ref)
125{103{
@@ -129,10 +107,13 @@ static void pool_retire(struct i915_active *ref) · 3 unmodified lines
129 struct list_head *list = bucket_for_size(pool, node->obj->base.size);107 struct list_head *list = bucket_for_size(pool, node->obj->base.size);
130 unsigned long flags;108 unsigned long flags;
131 109
132 i915_gem_object_unpin_pages(node->obj);110 if (node->pinned) {
111 i915_gem_object_unpin_pages(node->obj);
133 112
134 /* Return this object to the shrinker pool */113 /* Return this object to the shrinker pool */
135 i915_gem_object_make_purgeable(node->obj);114 i915_gem_object_make_purgeable(node->obj);
115 node->pinned = false;
116 }
136 117
137 GEM_BUG_ON(node->age);118 GEM_BUG_ON(node->age);
138 spin_lock_irqsave(&pool->lock, flags);119 spin_lock_irqsave(&pool->lock, flags);
@@ -144,6 +125,19 @@ static void pool_retire(struct i915_active *ref) · 5 unmodified lines
144 round_jiffies_up_relative(HZ));125 round_jiffies_up_relative(HZ));
145}126}
146 127
128void intel_gt_buffer_pool_mark_used(struct intel_gt_buffer_pool_node *node)
129{
130 assert_object_held(node->obj);
131
132 if (node->pinned)
133 return;
134
135 __i915_gem_object_pin_pages(node->obj);
136 /* Hide this pinned object from the shrinker until retired */
137 i915_gem_object_make_unshrinkable(node->obj);
138 node->pinned = true;
139}
140
147static struct intel_gt_buffer_pool_node *141static struct intel_gt_buffer_pool_node *
148node_create(struct intel_gt_buffer_pool *pool, size_t sz,142node_create(struct intel_gt_buffer_pool *pool, size_t sz,
149 enum i915_map_type type)143 enum i915_map_type type)
@@ -159,7 +153,8 @@ node_create(struct intel_gt_buffer_pool *pool, size_t sz, · 9 unmodified lines
159 153
160 node->age = 0;154 node->age = 0;
161 node->pool = pool;155 node->pool = pool;
162 i915_active_init(&node->active, pool_active, pool_retire);156 node->pinned = false;
157 i915_active_init(&node->active, NULL, pool_retire);
163 158
164 obj = i915_gem_object_create_internal(gt->i915, sz);159 obj = i915_gem_object_create_internal(gt->i915, sz);
165 if (IS_ERR(obj)) {160 if (IS_ERR(obj)) {
drivers/gpu/drm/i915/gt/intel_gt_buffer_pool.h+5−0
@@ -18,10 +18,15 @@ struct intel_gt_buffer_pool_node * · 17 unmodified lines
18intel_gt_get_buffer_pool(struct intel_gt *gt, size_t size,18intel_gt_get_buffer_pool(struct intel_gt *gt, size_t size,
19 enum i915_map_type type);19 enum i915_map_type type);
20 20
21void intel_gt_buffer_pool_mark_used(struct intel_gt_buffer_pool_node *node);
22
21static inline int23static inline int
22intel_gt_buffer_pool_mark_active(struct intel_gt_buffer_pool_node *node,24intel_gt_buffer_pool_mark_active(struct intel_gt_buffer_pool_node *node,
23 struct i915_request *rq)25 struct i915_request *rq)
24{26{
27 /* did we call mark_used? */
28 GEM_WARN_ON(!node->pinned);
29
25 return i915_active_add_request(&node->active, rq);30 return i915_active_add_request(&node->active, rq);
26}31}
27 32
drivers/gpu/drm/i915/gt/intel_gt_buffer_pool_types.h+1−0
@@ -31,6 +31,7 @@ struct intel_gt_buffer_pool_node { · 30 unmodified lines
31 };31 };
32 unsigned long age;32 unsigned long age;
33 enum i915_map_type type;33 enum i915_map_type type;
34 u32 pinned;
34};35};
35 36
36#endif /* INTEL_GT_BUFFER_POOL_TYPES_H */37#endif /* INTEL_GT_BUFFER_POOL_TYPES_H */
drivers/gpu/drm/i915/gt/intel_gt_requests.c+28−0
@@ -9,6 +9,7 @@ · 8 unmodified lines
9#include "i915_drv.h" /* for_each_engine() */9#include "i915_drv.h" /* for_each_engine() */
10#include "i915_request.h"10#include "i915_request.h"
11#include "intel_engine_heartbeat.h"11#include "intel_engine_heartbeat.h"
12#include "intel_execlists_submission.h"
12#include "intel_gt.h"13#include "intel_gt.h"
13#include "intel_gt_pm.h"14#include "intel_gt_pm.h"
14#include "intel_gt_requests.h"15#include "intel_gt_requests.h"
@@ -243,4 +244,31 @@ void intel_gt_fini_requests(struct intel_gt *gt) · 228 unmodified lines
243{244{
244 /* Wait until the work is marked as finished before unloading! */245 /* Wait until the work is marked as finished before unloading! */
245 cancel_delayed_work_sync(&gt->requests.retire_work);246 cancel_delayed_work_sync(&gt->requests.retire_work);
247
248 flush_work(&gt->watchdog.work);
249}
250
251void intel_gt_watchdog_work(struct work_struct *work)
252{
253 struct intel_gt *gt =
254 container_of(work, typeof(*gt), watchdog.work);
255 struct i915_request *rq, *rn;
256 struct llist_node *first;
257
258 first = llist_del_all(&gt->watchdog.list);
259 if (!first)
260 return;
261
262 llist_for_each_entry_safe(rq, rn, first, watchdog.link) {
263 if (!i915_request_completed(rq)) {
264 struct dma_fence *f = &rq->fence;
265
266 pr_notice("Fence expiration time out i915-%s:%s:%llx!\n",
267 f->ops->get_driver_name(f),
268 f->ops->get_timeline_name(f),
269 f->seqno);
270 i915_request_cancel(rq, -EINTR);
271 }
272 i915_request_put(rq);
273 }
246}274}
drivers/gpu/drm/i915/gt/intel_gt_types.h+7−4
@@ -8,10 +8,12 @@ · 7 unmodified lines
8 8
9#include <linux/ktime.h>9#include <linux/ktime.h>
10#include <linux/list.h>10#include <linux/list.h>
11#include <linux/llist.h>
11#include <linux/mutex.h>12#include <linux/mutex.h>
12#include <linux/notifier.h>13#include <linux/notifier.h>
13#include <linux/spinlock.h>14#include <linux/spinlock.h>
14#include <linux/types.h>15#include <linux/types.h>
16#include <linux/workqueue.h>
15 17
16#include "uc/intel_uc.h"18#include "uc/intel_uc.h"
17 19
@@ -39,10 +41,6 @@ struct intel_gt { · 21 unmodified lines
39 struct intel_gt_timelines {41 struct intel_gt_timelines {
40 spinlock_t lock; /* protects active_list */42 spinlock_t lock; /* protects active_list */
41 struct list_head active_list;43 struct list_head active_list;
42
43 /* Pack multiple timelines' seqnos into the same page */
44 spinlock_t hwsp_lock;
45 struct list_head hwsp_free_list;
46 } timelines;44 } timelines;
47 45
48 struct intel_gt_requests {46 struct intel_gt_requests {
@@ -56,6 +54,11 @@ struct intel_gt { · 7 unmodified lines
56 struct delayed_work retire_work;54 struct delayed_work retire_work;
57 } requests;55 } requests;
58 56
57 struct {
58 struct llist_head list;
59 struct work_struct work;
60 } watchdog;
61
59 struct intel_wakeref wakeref;62 struct intel_wakeref wakeref;
60 atomic_t user_wakeref;63 atomic_t user_wakeref;
61 64
drivers/gpu/drm/i915/gt/intel_gtt.c+50−2
@@ -13,16 +13,36 @@ · 12 unmodified lines
13 13
14struct drm_i915_gem_object *alloc_pt_dma(struct i915_address_space *vm, int sz)14struct drm_i915_gem_object *alloc_pt_dma(struct i915_address_space *vm, int sz)
15{15{
16 struct drm_i915_gem_object *obj;
17
16 if (I915_SELFTEST_ONLY(should_fail(&vm->fault_attr, 1)))18 if (I915_SELFTEST_ONLY(should_fail(&vm->fault_attr, 1)))
17 i915_gem_shrink_all(vm->i915);19 i915_gem_shrink_all(vm->i915);
18 20
19 return i915_gem_object_create_internal(vm->i915, sz);21 obj = i915_gem_object_create_internal(vm->i915, sz);
22 /* ensure all dma objects have the same reservation class */
23 if (!IS_ERR(obj))
24 obj->base.resv = &vm->resv;
25 return obj;
20}26}
21 27
22int pin_pt_dma(struct i915_address_space *vm, struct drm_i915_gem_object *obj)28int pin_pt_dma(struct i915_address_space *vm, struct drm_i915_gem_object *obj)
23{29{
24 int err;30 int err;
25 31
32 i915_gem_object_lock(obj, NULL);
33 err = i915_gem_object_pin_pages(obj);
34 i915_gem_object_unlock(obj);
35 if (err)
36 return err;
37
38 i915_gem_object_make_unshrinkable(obj);
39 return 0;
40}
41
42int pin_pt_dma_locked(struct i915_address_space *vm, struct drm_i915_gem_object *obj)
43{
44 int err;
45
26 err = i915_gem_object_pin_pages(obj);46 err = i915_gem_object_pin_pages(obj);
27 if (err)47 if (err)
28 return err;48 return err;
@@ -56,6 +76,20 @@ void __i915_vm_close(struct i915_address_space *vm) · 27 unmodified lines
56 mutex_unlock(&vm->mutex);76 mutex_unlock(&vm->mutex);
57}77}
58 78
79/* lock the vm into the current ww, if we lock one, we lock all */
80int i915_vm_lock_objects(struct i915_address_space *vm,
81 struct i915_gem_ww_ctx *ww)
82{
83 if (vm->scratch[0]->base.resv == &vm->resv) {
84 return i915_gem_object_lock(vm->scratch[0], ww);
85 } else {
86 struct i915_ppgtt *ppgtt = i915_vm_to_ppgtt(vm);
87
88 /* We borrowed the scratch page from ggtt, take the top level object */
89 return i915_gem_object_lock(ppgtt->pd->pt.base, ww);
90 }
91}
92
59void i915_address_space_fini(struct i915_address_space *vm)93void i915_address_space_fini(struct i915_address_space *vm)
60{94{
61 drm_mm_takedown(&vm->mm);95 drm_mm_takedown(&vm->mm);
@@ -69,6 +103,7 @@ static void __i915_vm_release(struct work_struct *work) · 7 unmodified lines
69 103
70 vm->cleanup(vm);104 vm->cleanup(vm);
71 i915_address_space_fini(vm);105 i915_address_space_fini(vm);
106 dma_resv_fini(&vm->resv);
72 107
73 kfree(vm);108 kfree(vm);
74}109}
@@ -98,6 +133,7 @@ void i915_address_space_init(struct i915_address_space *vm, int subclass) · 23 unmodified lines
98 mutex_init(&vm->mutex);133 mutex_init(&vm->mutex);
99 lockdep_set_subclass(&vm->mutex, subclass);134 lockdep_set_subclass(&vm->mutex, subclass);
100 i915_gem_shrinker_taints_mutex(vm->i915, &vm->mutex);135 i915_gem_shrinker_taints_mutex(vm->i915, &vm->mutex);
136 dma_resv_init(&vm->resv);
101 137
102 GEM_BUG_ON(!vm->total);138 GEM_BUG_ON(!vm->total);
103 drm_mm_init(&vm->mm, 0, vm->total);139 drm_mm_init(&vm->mm, 0, vm->total);
@@ -427,7 +463,6 @@ __vm_create_scratch_for_read(struct i915_address_space *vm, unsigned long size) · 323 unmodified lines
427{463{
428 struct drm_i915_gem_object *obj;464 struct drm_i915_gem_object *obj;
429 struct i915_vma *vma;465 struct i915_vma *vma;
430 int err;
431 466
432 obj = i915_gem_object_create_internal(vm->i915, PAGE_ALIGN(size));467 obj = i915_gem_object_create_internal(vm->i915, PAGE_ALIGN(size));
433 if (IS_ERR(obj))468 if (IS_ERR(obj))
@@ -441,6 +476,19 @@ __vm_create_scratch_for_read(struct i915_address_space *vm, unsigned long size) · 7 unmodified lines
441 return vma;476 return vma;
442 }477 }
443 478
479 return vma;
480}
481
482struct i915_vma *
483__vm_create_scratch_for_read_pinned(struct i915_address_space *vm, unsigned long size)
484{
485 struct i915_vma *vma;
486 int err;
487
488 vma = __vm_create_scratch_for_read(vm, size);
489 if (IS_ERR(vma))
490 return vma;
491
444 err = i915_vma_pin(vma, 0, 0,492 err = i915_vma_pin(vma, 0, 0,
445 i915_vma_is_ggtt(vma) ? PIN_GLOBAL : PIN_USER);493 i915_vma_is_ggtt(vma) ? PIN_GLOBAL : PIN_USER);
446 if (err) {494 if (err) {
drivers/gpu/drm/i915/gt/intel_gtt.h+8−0
@@ -238,6 +238,7 @@ struct i915_address_space { · 237 unmodified lines
238 atomic_t open;238 atomic_t open;
239 239
240 struct mutex mutex; /* protects vma and our lists */240 struct mutex mutex; /* protects vma and our lists */
241 struct dma_resv resv; /* reservation lock for all pd objects, and buffer pool */
241#define VM_CLASS_GGTT 0242#define VM_CLASS_GGTT 0
242#define VM_CLASS_PPGTT 1243#define VM_CLASS_PPGTT 1
243 244
@@ -346,6 +347,9 @@ struct i915_ppgtt { · 102 unmodified lines
346 347
347#define i915_is_ggtt(vm) ((vm)->is_ggtt)348#define i915_is_ggtt(vm) ((vm)->is_ggtt)
348 349
350int __must_check
351i915_vm_lock_objects(struct i915_address_space *vm, struct i915_gem_ww_ctx *ww);
352
349static inline bool353static inline bool
350i915_vm_is_4lvl(const struct i915_address_space *vm)354i915_vm_is_4lvl(const struct i915_address_space *vm)
351{355{
@@ -522,6 +526,7 @@ struct i915_page_directory *alloc_pd(struct i915_address_space *vm); · 170 unmodified lines
522struct i915_page_directory *__alloc_pd(int npde);526struct i915_page_directory *__alloc_pd(int npde);
523 527
524int pin_pt_dma(struct i915_address_space *vm, struct drm_i915_gem_object *obj);528int pin_pt_dma(struct i915_address_space *vm, struct drm_i915_gem_object *obj);
529int pin_pt_dma_locked(struct i915_address_space *vm, struct drm_i915_gem_object *obj);
525 530
526void free_px(struct i915_address_space *vm,531void free_px(struct i915_address_space *vm,
527 struct i915_page_table *pt, int lvl);532 struct i915_page_table *pt, int lvl);
@@ -576,6 +581,9 @@ void i915_vm_free_pt_stash(struct i915_address_space *vm, · 48 unmodified lines
576struct i915_vma *581struct i915_vma *
577__vm_create_scratch_for_read(struct i915_address_space *vm, unsigned long size);582__vm_create_scratch_for_read(struct i915_address_space *vm, unsigned long size);
578 583
584struct i915_vma *
585__vm_create_scratch_for_read_pinned(struct i915_address_space *vm, unsigned long size);
586
579static inline struct sgt_dma {587static inline struct sgt_dma {
580 struct scatterlist *sg;588 struct scatterlist *sg;
581 dma_addr_t dma, max;589 dma_addr_t dma, max;
drivers/gpu/drm/i915/gt/intel_lrc.c+38−11
@@ -1417,7 +1417,7 @@ gen10_init_indirectctx_bb(struct intel_engine_cs *engine, u32 *batch) · 1416 unmodified lines
1417 1417
1418#define CTX_WA_BB_SIZE (PAGE_SIZE)1418#define CTX_WA_BB_SIZE (PAGE_SIZE)
1419 1419
1420static int lrc_setup_wa_ctx(struct intel_engine_cs *engine)1420static int lrc_create_wa_ctx(struct intel_engine_cs *engine)
1421{1421{
1422 struct drm_i915_gem_object *obj;1422 struct drm_i915_gem_object *obj;
1423 struct i915_vma *vma;1423 struct i915_vma *vma;
@@ -1433,10 +1433,6 @@ static int lrc_setup_wa_ctx(struct intel_engine_cs *engine) · 9 unmodified lines
1433 goto err;1433 goto err;
1434 }1434 }
1435 1435
1436 err = i915_ggtt_pin(vma, NULL, 0, PIN_HIGH);
1437 if (err)
1438 goto err;
1439
1440 engine->wa_ctx.vma = vma;1436 engine->wa_ctx.vma = vma;
1441 return 0;1437 return 0;
1442 1438
@@ -1448,9 +1444,6 @@ err: · 5 unmodified lines
1448void lrc_fini_wa_ctx(struct intel_engine_cs *engine)1444void lrc_fini_wa_ctx(struct intel_engine_cs *engine)
1449{1445{
1450 i915_vma_unpin_and_release(&engine->wa_ctx.vma, 0);1446 i915_vma_unpin_and_release(&engine->wa_ctx.vma, 0);
1451
1452 /* Called on error unwind, clear all flags to prevent further use */
1453 memset(&engine->wa_ctx, 0, sizeof(engine->wa_ctx));
1454}1447}
1455 1448
1456typedef u32 *(*wa_bb_func_t)(struct intel_engine_cs *engine, u32 *batch);1449typedef u32 *(*wa_bb_func_t)(struct intel_engine_cs *engine, u32 *batch);
@@ -1462,6 +1455,7 @@ void lrc_init_wa_ctx(struct intel_engine_cs *engine) · 5 unmodified lines
1462 &wa_ctx->indirect_ctx, &wa_ctx->per_ctx1455 &wa_ctx->indirect_ctx, &wa_ctx->per_ctx
1463 };1456 };
1464 wa_bb_func_t wa_bb_fn[ARRAY_SIZE(wa_bb)];1457 wa_bb_func_t wa_bb_fn[ARRAY_SIZE(wa_bb)];
1458 struct i915_gem_ww_ctx ww;
1465 void *batch, *batch_ptr;1459 void *batch, *batch_ptr;
1466 unsigned int i;1460 unsigned int i;
1467 int err;1461 int err;
@@ -1490,7 +1484,7 @@ void lrc_init_wa_ctx(struct intel_engine_cs *engine) · 22 unmodified lines
1490 return;1484 return;
1491 }1485 }
1492 1486
1493 err = lrc_setup_wa_ctx(engine);1487 err = lrc_create_wa_ctx(engine);
1494 if (err) {1488 if (err) {
1495 /*1489 /*
1496 * We continue even if we fail to initialize WA batch1490 * We continue even if we fail to initialize WA batch
@@ -1503,7 +1497,22 @@ void lrc_init_wa_ctx(struct intel_engine_cs *engine) · 6 unmodified lines
1503 return;1497 return;
1504 }1498 }
1505 1499
1500 if (!engine->wa_ctx.vma)
1501 return;
1502
1503 i915_gem_ww_ctx_init(&ww, true);
1504retry:
1505 err = i915_gem_object_lock(wa_ctx->vma->obj, &ww);
1506 if (!err)
1507 err = i915_ggtt_pin(wa_ctx->vma, &ww, 0, PIN_HIGH);
1508 if (err)
1509 goto err;
1510
1506 batch = i915_gem_object_pin_map(wa_ctx->vma->obj, I915_MAP_WB);1511 batch = i915_gem_object_pin_map(wa_ctx->vma->obj, I915_MAP_WB);
1512 if (IS_ERR(batch)) {
1513 err = PTR_ERR(batch);
1514 goto err_unpin;
1515 }
1507 1516
1508 /*1517 /*
1509 * Emit the two workaround batch buffers, recording the offset from the1518 * Emit the two workaround batch buffers, recording the offset from the
@@ -1528,8 +1537,26 @@ void lrc_init_wa_ctx(struct intel_engine_cs *engine) · 18 unmodified lines
1528 __i915_gem_object_release_map(wa_ctx->vma->obj);1537 __i915_gem_object_release_map(wa_ctx->vma->obj);
1529 1538
1530 /* Verify that we can handle failure to setup the wa_ctx */1539 /* Verify that we can handle failure to setup the wa_ctx */
1531 if (err || i915_inject_probe_error(engine->i915, -ENODEV))1540 if (!err)
1532 lrc_fini_wa_ctx(engine);1541 err = i915_inject_probe_error(engine->i915, -ENODEV);
1542
1543err_unpin:
1544 if (err)
1545 i915_vma_unpin(wa_ctx->vma);
1546err:
1547 if (err == -EDEADLK) {
1548 err = i915_gem_ww_ctx_backoff(&ww);
1549 if (!err)
1550 goto retry;
1551 }
1552 i915_gem_ww_ctx_fini(&ww);
1553
1554 if (err) {
1555 i915_vma_put(engine->wa_ctx.vma);
1556
1557 /* Clear all flags to prevent further use */
1558 memset(wa_ctx, 0, sizeof(*wa_ctx));
1559 }
1533}1560}
1534 1561
1535static void st_update_runtime_underflow(struct intel_context *ce, s32 dt)1562static void st_update_runtime_underflow(struct intel_context *ce, s32 dt)
drivers/gpu/drm/i915/gt/intel_ppgtt.c+2−1
@@ -262,7 +262,7 @@ int i915_vm_pin_pt_stash(struct i915_address_space *vm, · 261 unmodified lines
262 262
263 for (n = 0; n < ARRAY_SIZE(stash->pt); n++) {263 for (n = 0; n < ARRAY_SIZE(stash->pt); n++) {
264 for (pt = stash->pt[n]; pt; pt = pt->stash) {264 for (pt = stash->pt[n]; pt; pt = pt->stash) {
265 err = pin_pt_dma(vm, pt->base);265 err = pin_pt_dma_locked(vm, pt->base);
266 if (err)266 if (err)
267 return err;267 return err;
268 }268 }
@@ -304,6 +304,7 @@ void ppgtt_init(struct i915_ppgtt *ppgtt, struct intel_gt *gt) · 35 unmodified lines
304 ppgtt->vm.dma = i915->drm.dev;304 ppgtt->vm.dma = i915->drm.dev;
305 ppgtt->vm.total = BIT_ULL(INTEL_INFO(i915)->ppgtt_size);305 ppgtt->vm.total = BIT_ULL(INTEL_INFO(i915)->ppgtt_size);
306 306
307 dma_resv_init(&ppgtt->vm.resv);
307 i915_address_space_init(&ppgtt->vm, VM_CLASS_PPGTT);308 i915_address_space_init(&ppgtt->vm, VM_CLASS_PPGTT);
308 309
309 ppgtt->vm.vma_ops.bind_vma = ppgtt_bind_vma;310 ppgtt->vm.vma_ops.bind_vma = ppgtt_bind_vma;
drivers/gpu/drm/i915/gt/intel_renderstate.c+1−1
@@ -197,7 +197,7 @@ retry: · 196 unmodified lines
197 if (err)197 if (err)
198 goto err_context;198 goto err_context;
199 199
200 err = i915_vma_pin(so->vma, 0, 0, PIN_GLOBAL | PIN_HIGH);200 err = i915_vma_pin_ww(so->vma, &so->ww, 0, 0, PIN_GLOBAL | PIN_HIGH);
201 if (err)201 if (err)
202 goto err_context;202 goto err_context;
203 203
drivers/gpu/drm/i915/gt/intel_reset.c+7−2
@@ -974,8 +974,6 @@ static int do_reset(struct intel_gt *gt, intel_engine_mask_t stalled_mask) · 973 unmodified lines
974{974{
975 int err, i;975 int err, i;
976 976
977 gt_revoke(gt);
978
979 err = __intel_gt_reset(gt, ALL_ENGINES);977 err = __intel_gt_reset(gt, ALL_ENGINES);
980 for (i = 0; err && i < RESET_MAX_RETRIES; i++) {978 for (i = 0; err && i < RESET_MAX_RETRIES; i++) {
981 msleep(10 * (i + 1));979 msleep(10 * (i + 1));
@@ -1030,6 +1028,13 @@ void intel_gt_reset(struct intel_gt *gt, · 48 unmodified lines
1030 1028
1031 might_sleep();1029 might_sleep();
1032 GEM_BUG_ON(!test_bit(I915_RESET_BACKOFF, &gt->reset.flags));1030 GEM_BUG_ON(!test_bit(I915_RESET_BACKOFF, &gt->reset.flags));
1031
1032 /*
1033 * FIXME: Revoking cpu mmap ptes cannot be done from a dma_fence
1034 * critical section like gpu reset.
1035 */
1036 gt_revoke(gt);
1037
1033 mutex_lock(&gt->reset.mutex);1038 mutex_lock(&gt->reset.mutex);
1034 1039
1035 /* Clear any previous failed attempts at recovery. Time to try again. */1040 /* Clear any previous failed attempts at recovery. Time to try again. */
drivers/gpu/drm/i915/gt/intel_ring_submission.c+118−66
@@ -466,6 +466,26 @@ static void ring_context_destroy(struct kref *ref) · 465 unmodified lines
466 intel_context_free(ce);466 intel_context_free(ce);
467}467}
468 468
469static int ring_context_init_default_state(struct intel_context *ce,
470 struct i915_gem_ww_ctx *ww)
471{
472 struct drm_i915_gem_object *obj = ce->state->obj;
473 void *vaddr;
474
475 vaddr = i915_gem_object_pin_map(obj, I915_MAP_WB);
476 if (IS_ERR(vaddr))
477 return PTR_ERR(vaddr);
478
479 shmem_read(ce->engine->default_state, 0,
480 vaddr, ce->engine->context_size);
481
482 i915_gem_object_flush_map(obj);
483 __i915_gem_object_release_map(obj);
484
485 __set_bit(CONTEXT_VALID_BIT, &ce->flags);
486 return 0;
487}
488
469static int ring_context_pre_pin(struct intel_context *ce,489static int ring_context_pre_pin(struct intel_context *ce,
470 struct i915_gem_ww_ctx *ww,490 struct i915_gem_ww_ctx *ww,
471 void **unused)491 void **unused)
@@ -473,6 +493,13 @@ static int ring_context_pre_pin(struct intel_context *ce, · 1 unmodified line
473 struct i915_address_space *vm;493 struct i915_address_space *vm;
474 int err = 0;494 int err = 0;
475 495
496 if (ce->engine->default_state &&
497 !test_bit(CONTEXT_VALID_BIT, &ce->flags)) {
498 err = ring_context_init_default_state(ce, ww);
499 if (err)
500 return err;
501 }
502
476 vm = vm_alias(ce->vm);503 vm = vm_alias(ce->vm);
477 if (vm)504 if (vm)
478 err = gen6_ppgtt_pin(i915_vm_to_ppgtt((vm)), ww);505 err = gen6_ppgtt_pin(i915_vm_to_ppgtt((vm)), ww);
@@ -528,22 +555,6 @@ alloc_context_vma(struct intel_engine_cs *engine) · 49 unmodified lines
528 if (IS_IVYBRIDGE(i915))555 if (IS_IVYBRIDGE(i915))
529 i915_gem_object_set_cache_coherency(obj, I915_CACHE_L3_LLC);556 i915_gem_object_set_cache_coherency(obj, I915_CACHE_L3_LLC);
530 557
531 if (engine->default_state) {
532 void *vaddr;
533
534 vaddr = i915_gem_object_pin_map(obj, I915_MAP_WB);
535 if (IS_ERR(vaddr)) {
536 err = PTR_ERR(vaddr);
537 goto err_obj;
538 }
539
540 shmem_read(engine->default_state, 0,
541 vaddr, engine->context_size);
542
543 i915_gem_object_flush_map(obj);
544 __i915_gem_object_release_map(obj);
545 }
546
547 vma = i915_vma_instance(obj, &engine->gt->ggtt->vm, NULL);558 vma = i915_vma_instance(obj, &engine->gt->ggtt->vm, NULL);
548 if (IS_ERR(vma)) {559 if (IS_ERR(vma)) {
549 err = PTR_ERR(vma);560 err = PTR_ERR(vma);
@@ -575,8 +586,6 @@ static int ring_context_alloc(struct intel_context *ce) · 25 unmodified lines
575 return PTR_ERR(vma);586 return PTR_ERR(vma);
576 587
577 ce->state = vma;588 ce->state = vma;
578 if (engine->default_state)
579 __set_bit(CONTEXT_VALID_BIT, &ce->flags);
580 }589 }
581 590
582 return 0;591 return 0;
@@ -1176,37 +1185,15 @@ static int gen7_ctx_switch_bb_setup(struct intel_engine_cs * const engine, · 593 unmodified lines
1176 return gen7_setup_clear_gpr_bb(engine, vma);1185 return gen7_setup_clear_gpr_bb(engine, vma);
1177}1186}
1178 1187
1179static int gen7_ctx_switch_bb_init(struct intel_engine_cs *engine)1188static int gen7_ctx_switch_bb_init(struct intel_engine_cs *engine,
1189 struct i915_gem_ww_ctx *ww,
1190 struct i915_vma *vma)
1180{1191{
1181 struct drm_i915_gem_object *obj;
1182 struct i915_vma *vma;
1183 int size;
1184 int err;1192 int err;
1185 1193
1186 size = gen7_ctx_switch_bb_setup(engine, NULL /* probe size */);1194 err = i915_vma_pin_ww(vma, ww, 0, 0, PIN_USER | PIN_HIGH);
1187 if (size <= 0)
1188 return size;
1189
1190 size = ALIGN(size, PAGE_SIZE);
1191 obj = i915_gem_object_create_internal(engine->i915, size);
1192 if (IS_ERR(obj))
1193 return PTR_ERR(obj);
1194
1195 vma = i915_vma_instance(obj, engine->gt->vm, NULL);
1196 if (IS_ERR(vma)) {
1197 err = PTR_ERR(vma);
1198 goto err_obj;
1199 }
1200
1201 vma->private = intel_context_create(engine); /* dummy residuals */
1202 if (IS_ERR(vma->private)) {
1203 err = PTR_ERR(vma->private);
1204 goto err_obj;
1205 }
1206
1207 err = i915_vma_pin(vma, 0, 0, PIN_USER | PIN_HIGH);
1208 if (err)1195 if (err)
1209 goto err_private;1196 return err;
1210 1197
1211 err = i915_vma_sync(vma);1198 err = i915_vma_sync(vma);
1212 if (err)1199 if (err)
@@ -1221,17 +1208,53 @@ static int gen7_ctx_switch_bb_init(struct intel_engine_cs *engine) · 8 unmodified lines
1221 1208
1222err_unpin:1209err_unpin:
1223 i915_vma_unpin(vma);1210 i915_vma_unpin(vma);
1224err_private:
1225 intel_context_put(vma->private);
1226err_obj:
1227 i915_gem_object_put(obj);
1228 return err;1211 return err;
1229}1212}
1230 1213
1214static struct i915_vma *gen7_ctx_vma(struct intel_engine_cs *engine)
1215{
1216 struct drm_i915_gem_object *obj;
1217 struct i915_vma *vma;
1218 int size, err;
1219
1220 if (!IS_GEN(engine->i915, 7) || engine->class != RENDER_CLASS)
1221 return 0;
1222
1223 err = gen7_ctx_switch_bb_setup(engine, NULL /* probe size */);
1224 if (err < 0)
1225 return ERR_PTR(err);
1226 if (!err)
1227 return NULL;
1228
1229 size = ALIGN(err, PAGE_SIZE);
1230
1231 obj = i915_gem_object_create_internal(engine->i915, size);
1232 if (IS_ERR(obj))
1233 return ERR_CAST(obj);
1234
1235 vma = i915_vma_instance(obj, engine->gt->vm, NULL);
1236 if (IS_ERR(vma)) {
1237 i915_gem_object_put(obj);
1238 return ERR_CAST(vma);
1239 }
1240
1241 vma->private = intel_context_create(engine); /* dummy residuals */
1242 if (IS_ERR(vma->private)) {
1243 err = PTR_ERR(vma->private);
1244 vma->private = NULL;
1245 i915_gem_object_put(obj);
1246 return ERR_PTR(err);
1247 }
1248
1249 return vma;
1250}
1251
1231int intel_ring_submission_setup(struct intel_engine_cs *engine)1252int intel_ring_submission_setup(struct intel_engine_cs *engine)
1232{1253{
1254 struct i915_gem_ww_ctx ww;
1233 struct intel_timeline *timeline;1255 struct intel_timeline *timeline;
1234 struct intel_ring *ring;1256 struct intel_ring *ring;
1257 struct i915_vma *gen7_wa_vma;
1235 int err;1258 int err;
1236 1259
1237 setup_common(engine);1260 setup_common(engine);
@@ -1262,43 +1285,72 @@ int intel_ring_submission_setup(struct intel_engine_cs *engine) · 24 unmodified lines
1262 }1285 }
1263 GEM_BUG_ON(timeline->has_initial_breadcrumb);1286 GEM_BUG_ON(timeline->has_initial_breadcrumb);
1264 1287
1265 err = intel_timeline_pin(timeline, NULL);
1266 if (err)
1267 goto err_timeline;
1268
1269 ring = intel_engine_create_ring(engine, SZ_16K);1288 ring = intel_engine_create_ring(engine, SZ_16K);
1270 if (IS_ERR(ring)) {1289 if (IS_ERR(ring)) {
1271 err = PTR_ERR(ring);1290 err = PTR_ERR(ring);
1272 goto err_timeline_unpin;1291 goto err_timeline;
1273 }1292 }
1274 1293
1275 err = intel_ring_pin(ring, NULL);
1276 if (err)
1277 goto err_ring;
1278
1279 GEM_BUG_ON(engine->legacy.ring);1294 GEM_BUG_ON(engine->legacy.ring);
1280 engine->legacy.ring = ring;1295 engine->legacy.ring = ring;
1281 engine->legacy.timeline = timeline;1296 engine->legacy.timeline = timeline;
1282 1297
1283 GEM_BUG_ON(timeline->hwsp_ggtt != engine->status_page.vma);1298 gen7_wa_vma = gen7_ctx_vma(engine);
1299 if (IS_ERR(gen7_wa_vma)) {
1300 err = PTR_ERR(gen7_wa_vma);
1301 goto err_ring;
1302 }
1284 1303
1285 if (IS_GEN(engine->i915, 7) && engine->class == RENDER_CLASS) {1304 i915_gem_ww_ctx_init(&ww, false);
1286 err = gen7_ctx_switch_bb_init(engine);1305
1306retry:
1307 err = i915_gem_object_lock(timeline->hwsp_ggtt->obj, &ww);
1308 if (!err && gen7_wa_vma)
1309 err = i915_gem_object_lock(gen7_wa_vma->obj, &ww);
1310 if (!err && engine->legacy.ring->vma->obj)
1311 err = i915_gem_object_lock(engine->legacy.ring->vma->obj, &ww);
1312 if (!err)
1313 err = intel_timeline_pin(timeline, &ww);
1314 if (!err) {
1315 err = intel_ring_pin(ring, &ww);
1287 if (err)1316 if (err)
1288 goto err_ring_unpin;1317 intel_timeline_unpin(timeline);
1318 }
1319 if (err)
1320 goto out;
1321
1322 GEM_BUG_ON(timeline->hwsp_ggtt != engine->status_page.vma);
1323
1324 if (gen7_wa_vma) {
1325 err = gen7_ctx_switch_bb_init(engine, &ww, gen7_wa_vma);
1326 if (err) {
1327 intel_ring_unpin(ring);
1328 intel_timeline_unpin(timeline);
1329 }
1289 }1330 }
1290 1331
1332out:
1333 if (err == -EDEADLK) {
1334 err = i915_gem_ww_ctx_backoff(&ww);
1335 if (!err)
1336 goto retry;
1337 }
1338 i915_gem_ww_ctx_fini(&ww);
1339 if (err)
1340 goto err_gen7_put;
1341
1291 /* Finally, take ownership and responsibility for cleanup! */1342 /* Finally, take ownership and responsibility for cleanup! */
1292 engine->release = ring_release;1343 engine->release = ring_release;
1293 1344
1294 return 0;1345 return 0;
1295 1346
1296err_ring_unpin:1347err_gen7_put:
1297 intel_ring_unpin(ring);1348 if (gen7_wa_vma) {
1349 intel_context_put(gen7_wa_vma->private);
1350 i915_gem_object_put(gen7_wa_vma->obj);
1351 }
1298err_ring:1352err_ring:
1299 intel_ring_put(ring);1353 intel_ring_put(ring);
1300err_timeline_unpin:
1301 intel_timeline_unpin(timeline);
1302err_timeline:1354err_timeline:
1303 intel_timeline_put(timeline);1355 intel_timeline_put(timeline);
1304err:1356err:
drivers/gpu/drm/i915/gt/intel_timeline.c+94−332
@@ -12,21 +12,9 @@ · 11 unmodified lines
12#include "intel_ring.h"12#include "intel_ring.h"
13#include "intel_timeline.h"13#include "intel_timeline.h"
14 14
15#define ptr_set_bit(ptr, bit) ((typeof(ptr))((unsigned long)(ptr) | BIT(bit)))15#define TIMELINE_SEQNO_BYTES 8
16#define ptr_test_bit(ptr, bit) ((unsigned long)(ptr) & BIT(bit))
17 16
18#define CACHELINE_BITS 617static struct i915_vma *hwsp_alloc(struct intel_gt *gt)
19#define CACHELINE_FREE CACHELINE_BITS
20
21struct intel_timeline_hwsp {
22 struct intel_gt *gt;
23 struct intel_gt_timelines *gt_timelines;
24 struct list_head free_link;
25 struct i915_vma *vma;
26 u64 free_bitmap;
27};
28
29static struct i915_vma *__hwsp_alloc(struct intel_gt *gt)
30{18{
31 struct drm_i915_private *i915 = gt->i915;19 struct drm_i915_private *i915 = gt->i915;
32 struct drm_i915_gem_object *obj;20 struct drm_i915_gem_object *obj;
@@ -45,174 +33,42 @@ static struct i915_vma *__hwsp_alloc(struct intel_gt *gt) · 12 unmodified lines
45 return vma;33 return vma;
46}34}
47 35
48static struct i915_vma *
49hwsp_alloc(struct intel_timeline *timeline, unsigned int *cacheline)
50{
51 struct intel_gt_timelines *gt = &timeline->gt->timelines;
52 struct intel_timeline_hwsp *hwsp;
53
54 BUILD_BUG_ON(BITS_PER_TYPE(u64) * CACHELINE_BYTES > PAGE_SIZE);
55
56 spin_lock_irq(&gt->hwsp_lock);
57
58 /* hwsp_free_list only contains HWSP that have available cachelines */
59 hwsp = list_first_entry_or_null(&gt->hwsp_free_list,
60 typeof(*hwsp), free_link);
61 if (!hwsp) {
62 struct i915_vma *vma;
63
64 spin_unlock_irq(&gt->hwsp_lock);
65
66 hwsp = kmalloc(sizeof(*hwsp), GFP_KERNEL);
67 if (!hwsp)
68 return ERR_PTR(-ENOMEM);
69
70 vma = __hwsp_alloc(timeline->gt);
71 if (IS_ERR(vma)) {
72 kfree(hwsp);
73 return vma;
74 }
75
76 GT_TRACE(timeline->gt, "new HWSP allocated\n");
77
78 vma->private = hwsp;
79 hwsp->gt = timeline->gt;
80 hwsp->vma = vma;
81 hwsp->free_bitmap = ~0ull;
82 hwsp->gt_timelines = gt;
83
84 spin_lock_irq(&gt->hwsp_lock);
85 list_add(&hwsp->free_link, &gt->hwsp_free_list);
86 }
87
88 GEM_BUG_ON(!hwsp->free_bitmap);
89 *cacheline = __ffs64(hwsp->free_bitmap);
90 hwsp->free_bitmap &= ~BIT_ULL(*cacheline);
91 if (!hwsp->free_bitmap)
92 list_del(&hwsp->free_link);
93
94 spin_unlock_irq(&gt->hwsp_lock);
95
96 GEM_BUG_ON(hwsp->vma->private != hwsp);
97 return hwsp->vma;
98}
99
100static void __idle_hwsp_free(struct intel_timeline_hwsp *hwsp, int cacheline)
101{
102 struct intel_gt_timelines *gt = hwsp->gt_timelines;
103 unsigned long flags;
104
105 spin_lock_irqsave(&gt->hwsp_lock, flags);
106
107 /* As a cacheline becomes available, publish the HWSP on the freelist */
108 if (!hwsp->free_bitmap)
109 list_add_tail(&hwsp->free_link, &gt->hwsp_free_list);
110
111 GEM_BUG_ON(cacheline >= BITS_PER_TYPE(hwsp->free_bitmap));
112 hwsp->free_bitmap |= BIT_ULL(cacheline);
113
114 /* And if no one is left using it, give the page back to the system */
115 if (hwsp->free_bitmap == ~0ull) {
116 i915_vma_put(hwsp->vma);
117 list_del(&hwsp->free_link);
118 kfree(hwsp);
119 }
120
121 spin_unlock_irqrestore(&gt->hwsp_lock, flags);
122}
123
124static void __rcu_cacheline_free(struct rcu_head *rcu)
125{
126 struct intel_timeline_cacheline *cl =
127 container_of(rcu, typeof(*cl), rcu);
128
129 /* Must wait until after all *rq->hwsp are complete before removing */
130 i915_gem_object_unpin_map(cl->hwsp->vma->obj);
131 __idle_hwsp_free(cl->hwsp, ptr_unmask_bits(cl->vaddr, CACHELINE_BITS));
132
133 i915_active_fini(&cl->active);
134 kfree(cl);
135}
136
137static void __idle_cacheline_free(struct intel_timeline_cacheline *cl)
138{
139 GEM_BUG_ON(!i915_active_is_idle(&cl->active));
140 call_rcu(&cl->rcu, __rcu_cacheline_free);
141}
142
143__i915_active_call36__i915_active_call
144static void __cacheline_retire(struct i915_active *active)37static void __timeline_retire(struct i915_active *active)
145{38{
146 struct intel_timeline_cacheline *cl =39 struct intel_timeline *tl =
147 container_of(active, typeof(*cl), active);40 container_of(active, typeof(*tl), active);
148 41
149 i915_vma_unpin(cl->hwsp->vma);42 i915_vma_unpin(tl->hwsp_ggtt);
150 if (ptr_test_bit(cl->vaddr, CACHELINE_FREE))43 intel_timeline_put(tl);
151 __idle_cacheline_free(cl);
152}44}
153 45
154static int __cacheline_active(struct i915_active *active)46static int __timeline_active(struct i915_active *active)
155{47{
156 struct intel_timeline_cacheline *cl =48 struct intel_timeline *tl =
157 container_of(active, typeof(*cl), active);49 container_of(active, typeof(*tl), active);
158 50
159 __i915_vma_pin(cl->hwsp->vma);51 __i915_vma_pin(tl->hwsp_ggtt);
52 intel_timeline_get(tl);
160 return 0;53 return 0;
161}54}
162 55
163static struct intel_timeline_cacheline *56I915_SELFTEST_EXPORT int
164cacheline_alloc(struct intel_timeline_hwsp *hwsp, unsigned int cacheline)57intel_timeline_pin_map(struct intel_timeline *timeline)
165{58{
166 struct intel_timeline_cacheline *cl;59 struct drm_i915_gem_object *obj = timeline->hwsp_ggtt->obj;
60 u32 ofs = offset_in_page(timeline->hwsp_offset);
167 void *vaddr;61 void *vaddr;
168 62
169 GEM_BUG_ON(cacheline >= BIT(CACHELINE_BITS));63 vaddr = i915_gem_object_pin_map(obj, I915_MAP_WB);
170 64 if (IS_ERR(vaddr))
171 cl = kmalloc(sizeof(*cl), GFP_KERNEL);65 return PTR_ERR(vaddr);
172 if (!cl)
173 return ERR_PTR(-ENOMEM);
174
175 vaddr = i915_gem_object_pin_map(hwsp->vma->obj, I915_MAP_WB);
176 if (IS_ERR(vaddr)) {
177 kfree(cl);
178 return ERR_CAST(vaddr);
179 }
180
181 cl->hwsp = hwsp;
182 cl->vaddr = page_pack_bits(vaddr, cacheline);
183
184 i915_active_init(&cl->active, __cacheline_active, __cacheline_retire);
185
186 return cl;
187}
188
189static void cacheline_acquire(struct intel_timeline_cacheline *cl,
190 u32 ggtt_offset)
191{
192 if (!cl)
193 return;
194
195 cl->ggtt_offset = ggtt_offset;
196 i915_active_acquire(&cl->active);
197}
198
199static void cacheline_release(struct intel_timeline_cacheline *cl)
200{
201 if (cl)
202 i915_active_release(&cl->active);
203}
204
205static void cacheline_free(struct intel_timeline_cacheline *cl)
206{
207 if (!i915_active_acquire_if_busy(&cl->active)) {
208 __idle_cacheline_free(cl);
209 return;
210 }
211 66
212 GEM_BUG_ON(ptr_test_bit(cl->vaddr, CACHELINE_FREE));67 timeline->hwsp_map = vaddr;
213 cl->vaddr = ptr_set_bit(cl->vaddr, CACHELINE_FREE);68 timeline->hwsp_seqno = memset(vaddr + ofs, 0, TIMELINE_SEQNO_BYTES);
69 clflush(vaddr + ofs);
214 70
215 i915_active_release(&cl->active);71 return 0;
216}72}
217 73
218static int intel_timeline_init(struct intel_timeline *timeline,74static int intel_timeline_init(struct intel_timeline *timeline,
@@ -220,45 +76,25 @@ static int intel_timeline_init(struct intel_timeline *timeline, · 1 unmodified line
220 struct i915_vma *hwsp,76 struct i915_vma *hwsp,
221 unsigned int offset)77 unsigned int offset)
222{78{
223 void *vaddr;
224
225 kref_init(&timeline->kref);79 kref_init(&timeline->kref);
226 atomic_set(&timeline->pin_count, 0);80 atomic_set(&timeline->pin_count, 0);
227 81
228 timeline->gt = gt;82 timeline->gt = gt;
229 83
230 timeline->has_initial_breadcrumb = !hwsp;84 if (hwsp) {
231 timeline->hwsp_cacheline = NULL;85 timeline->hwsp_offset = offset;
232 86 timeline->hwsp_ggtt = i915_vma_get(hwsp);
233 if (!hwsp) {87 } else {
234 struct intel_timeline_cacheline *cl;88 timeline->has_initial_breadcrumb = true;
235 unsigned int cacheline;89 hwsp = hwsp_alloc(gt);
236
237 hwsp = hwsp_alloc(timeline, &cacheline);
238 if (IS_ERR(hwsp))90 if (IS_ERR(hwsp))
239 return PTR_ERR(hwsp);91 return PTR_ERR(hwsp);
240 92 timeline->hwsp_ggtt = hwsp;
241 cl = cacheline_alloc(hwsp->private, cacheline);
242 if (IS_ERR(cl)) {
243 __idle_hwsp_free(hwsp->private, cacheline);
244 return PTR_ERR(cl);
245 }
246
247 timeline->hwsp_cacheline = cl;
248 timeline->hwsp_offset = cacheline * CACHELINE_BYTES;
249
250 vaddr = page_mask_bits(cl->vaddr);
251 } else {
252 timeline->hwsp_offset = offset;
253 vaddr = i915_gem_object_pin_map(hwsp->obj, I915_MAP_WB);
254 if (IS_ERR(vaddr))
255 return PTR_ERR(vaddr);
256 }93 }
257 94
258 timeline->hwsp_seqno =95 timeline->hwsp_map = NULL;
259 memset(vaddr + timeline->hwsp_offset, 0, CACHELINE_BYTES);96 timeline->hwsp_seqno = (void *)(long)timeline->hwsp_offset;
260 97
261 timeline->hwsp_ggtt = i915_vma_get(hwsp);
262 GEM_BUG_ON(timeline->hwsp_offset >= hwsp->size);98 GEM_BUG_ON(timeline->hwsp_offset >= hwsp->size);
263 99
264 timeline->fence_context = dma_fence_context_alloc(1);100 timeline->fence_context = dma_fence_context_alloc(1);
@@ -269,6 +105,7 @@ static int intel_timeline_init(struct intel_timeline *timeline, · 4 unmodified lines
269 INIT_LIST_HEAD(&timeline->requests);105 INIT_LIST_HEAD(&timeline->requests);
270 106
271 i915_syncmap_init(&timeline->sync);107 i915_syncmap_init(&timeline->sync);
108 i915_active_init(&timeline->active, __timeline_active, __timeline_retire);
272 109
273 return 0;110 return 0;
274}111}
@@ -279,23 +116,19 @@ void intel_gt_init_timelines(struct intel_gt *gt) · 4 unmodified lines
279 116
280 spin_lock_init(&timelines->lock);117 spin_lock_init(&timelines->lock);
281 INIT_LIST_HEAD(&timelines->active_list);118 INIT_LIST_HEAD(&timelines->active_list);
282
283 spin_lock_init(&timelines->hwsp_lock);
284 INIT_LIST_HEAD(&timelines->hwsp_free_list);
285}119}
286 120
287static void intel_timeline_fini(struct intel_timeline *timeline)121static void intel_timeline_fini(struct rcu_head *rcu)
288{122{
289 GEM_BUG_ON(atomic_read(&timeline->pin_count));123 struct intel_timeline *timeline =
290 GEM_BUG_ON(!list_empty(&timeline->requests));124 container_of(rcu, struct intel_timeline, rcu);
291 GEM_BUG_ON(timeline->retire);
292 125
293 if (timeline->hwsp_cacheline)126 if (timeline->hwsp_map)
294 cacheline_free(timeline->hwsp_cacheline);
295 else
296 i915_gem_object_unpin_map(timeline->hwsp_ggtt->obj);127 i915_gem_object_unpin_map(timeline->hwsp_ggtt->obj);
297 128
298 i915_vma_put(timeline->hwsp_ggtt);129 i915_vma_put(timeline->hwsp_ggtt);
130 i915_active_fini(&timeline->active);
131 kfree(timeline);
299}132}
300 133
301struct intel_timeline *134struct intel_timeline *
@@ -351,6 +184,12 @@ int intel_timeline_pin(struct intel_timeline *tl, struct i915_gem_ww_ctx *ww) · 49 unmodified lines
351 if (atomic_add_unless(&tl->pin_count, 1, 0))184 if (atomic_add_unless(&tl->pin_count, 1, 0))
352 return 0;185 return 0;
353 186
187 if (!tl->hwsp_map) {
188 err = intel_timeline_pin_map(tl);
189 if (err)
190 return err;
191 }
192
354 err = i915_ggtt_pin(tl->hwsp_ggtt, ww, 0, PIN_HIGH);193 err = i915_ggtt_pin(tl->hwsp_ggtt, ww, 0, PIN_HIGH);
355 if (err)194 if (err)
356 return err;195 return err;
@@ -361,9 +200,9 @@ int intel_timeline_pin(struct intel_timeline *tl, struct i915_gem_ww_ctx *ww) · 4 unmodified lines
361 GT_TRACE(tl->gt, "timeline:%llx using HWSP offset:%x\n",200 GT_TRACE(tl->gt, "timeline:%llx using HWSP offset:%x\n",
362 tl->fence_context, tl->hwsp_offset);201 tl->fence_context, tl->hwsp_offset);
363 202
364 cacheline_acquire(tl->hwsp_cacheline, tl->hwsp_offset);203 i915_active_acquire(&tl->active);
365 if (atomic_fetch_inc(&tl->pin_count)) {204 if (atomic_fetch_inc(&tl->pin_count)) {
366 cacheline_release(tl->hwsp_cacheline);205 i915_active_release(&tl->active);
367 __i915_vma_unpin(tl->hwsp_ggtt);206 __i915_vma_unpin(tl->hwsp_ggtt);
368 }207 }
369 208
@@ -372,9 +211,13 @@ int intel_timeline_pin(struct intel_timeline *tl, struct i915_gem_ww_ctx *ww) · 2 unmodified lines
372 211
373void intel_timeline_reset_seqno(const struct intel_timeline *tl)212void intel_timeline_reset_seqno(const struct intel_timeline *tl)
374{213{
214 u32 *hwsp_seqno = (u32 *)tl->hwsp_seqno;
375 /* Must be pinned to be writable, and no requests in flight. */215 /* Must be pinned to be writable, and no requests in flight. */
376 GEM_BUG_ON(!atomic_read(&tl->pin_count));216 GEM_BUG_ON(!atomic_read(&tl->pin_count));
377 WRITE_ONCE(*(u32 *)tl->hwsp_seqno, tl->seqno);217
218 memset(hwsp_seqno + 1, 0, TIMELINE_SEQNO_BYTES - sizeof(*hwsp_seqno));
219 WRITE_ONCE(*hwsp_seqno, tl->seqno);
220 clflush(hwsp_seqno);
378}221}
379 222
380void intel_timeline_enter(struct intel_timeline *tl)223void intel_timeline_enter(struct intel_timeline *tl)
@@ -450,106 +293,23 @@ static u32 timeline_advance(struct intel_timeline *tl) · 69 unmodified lines
450 return tl->seqno += 1 + tl->has_initial_breadcrumb;293 return tl->seqno += 1 + tl->has_initial_breadcrumb;
451}294}
452 295
453static void timeline_rollback(struct intel_timeline *tl)
454{
455 tl->seqno -= 1 + tl->has_initial_breadcrumb;
456}
457
458static noinline int296static noinline int
459__intel_timeline_get_seqno(struct intel_timeline *tl,297__intel_timeline_get_seqno(struct intel_timeline *tl,
460 struct i915_request *rq,
461 u32 *seqno)298 u32 *seqno)
462{299{
463 struct intel_timeline_cacheline *cl;300 u32 next_ofs = offset_in_page(tl->hwsp_offset + TIMELINE_SEQNO_BYTES);
464 unsigned int cacheline;
465 struct i915_vma *vma;
466 void *vaddr;
467 int err;
468
469 might_lock(&tl->gt->ggtt->vm.mutex);
470 GT_TRACE(tl->gt, "timeline:%llx wrapped\n", tl->fence_context);
471
472 /*
473 * If there is an outstanding GPU reference to this cacheline,
474 * such as it being sampled by a HW semaphore on another timeline,
475 * we cannot wraparound our seqno value (the HW semaphore does
476 * a strict greater-than-or-equals compare, not i915_seqno_passed).
477 * So if the cacheline is still busy, we must detach ourselves
478 * from it and leave it inflight alongside its users.
479 *
480 * However, if nobody is watching and we can guarantee that nobody
481 * will, we could simply reuse the same cacheline.
482 *
483 * if (i915_active_request_is_signaled(&tl->last_request) &&
484 * i915_active_is_signaled(&tl->hwsp_cacheline->active))
485 * return 0;
486 *
487 * That seems unlikely for a busy timeline that needed to wrap in
488 * the first place, so just replace the cacheline.
489 */
490
491 vma = hwsp_alloc(tl, &cacheline);
492 if (IS_ERR(vma)) {
493 err = PTR_ERR(vma);
494 goto err_rollback;
495 }
496
497 err = i915_ggtt_pin(vma, NULL, 0, PIN_HIGH);
498 if (err) {
499 __idle_hwsp_free(vma->private, cacheline);
500 goto err_rollback;
501 }
502
503 cl = cacheline_alloc(vma->private, cacheline);
504 if (IS_ERR(cl)) {
505 err = PTR_ERR(cl);
506 __idle_hwsp_free(vma->private, cacheline);
507 goto err_unpin;
508 }
509 GEM_BUG_ON(cl->hwsp->vma != vma);
510
511 /*
512 * Attach the old cacheline to the current request, so that we only
513 * free it after the current request is retired, which ensures that
514 * all writes into the cacheline from previous requests are complete.
515 */
516 err = i915_active_ref(&tl->hwsp_cacheline->active,
517 tl->fence_context,
518 &rq->fence);
519 if (err)
520 goto err_cacheline;
521
522 cacheline_release(tl->hwsp_cacheline); /* ownership now xfered to rq */
523 cacheline_free(tl->hwsp_cacheline);
524
525 i915_vma_unpin(tl->hwsp_ggtt); /* binding kept alive by old cacheline */
526 i915_vma_put(tl->hwsp_ggtt);
527
528 tl->hwsp_ggtt = i915_vma_get(vma);
529 301
530 vaddr = page_mask_bits(cl->vaddr);302 /* w/a: bit 5 needs to be zero for MI_FLUSH_DW address. */
531 tl->hwsp_offset = cacheline * CACHELINE_BYTES;303 if (TIMELINE_SEQNO_BYTES <= BIT(5) && (next_ofs & BIT(5)))
532 tl->hwsp_seqno =304 next_ofs = offset_in_page(next_ofs + BIT(5));
533 memset(vaddr + tl->hwsp_offset, 0, CACHELINE_BYTES);
534 305
535 tl->hwsp_offset += i915_ggtt_offset(vma);306 tl->hwsp_offset = i915_ggtt_offset(tl->hwsp_ggtt) + next_ofs;
536 GT_TRACE(tl->gt, "timeline:%llx using HWSP offset:%x\n",307 tl->hwsp_seqno = tl->hwsp_map + next_ofs;
537 tl->fence_context, tl->hwsp_offset);308 intel_timeline_reset_seqno(tl);
538
539 cacheline_acquire(cl, tl->hwsp_offset);
540 tl->hwsp_cacheline = cl;
541 309
542 *seqno = timeline_advance(tl);310 *seqno = timeline_advance(tl);
543 GEM_BUG_ON(i915_seqno_passed(*tl->hwsp_seqno, *seqno));311 GEM_BUG_ON(i915_seqno_passed(*tl->hwsp_seqno, *seqno));
544 return 0;312 return 0;
545
546err_cacheline:
547 cacheline_free(cl);
548err_unpin:
549 i915_vma_unpin(vma);
550err_rollback:
551 timeline_rollback(tl);
552 return err;
553}313}
554 314
555int intel_timeline_get_seqno(struct intel_timeline *tl,315int intel_timeline_get_seqno(struct intel_timeline *tl,
@@ -559,51 +319,52 @@ int intel_timeline_get_seqno(struct intel_timeline *tl, · 3 unmodified lines
559 *seqno = timeline_advance(tl);319 *seqno = timeline_advance(tl);
560 320
561 /* Replace the HWSP on wraparound for HW semaphores */321 /* Replace the HWSP on wraparound for HW semaphores */
562 if (unlikely(!*seqno && tl->hwsp_cacheline))322 if (unlikely(!*seqno && tl->has_initial_breadcrumb))
563 return __intel_timeline_get_seqno(tl, rq, seqno);323 return __intel_timeline_get_seqno(tl, seqno);
564 324
565 return 0;325 return 0;
566}326}
567 327
568static int cacheline_ref(struct intel_timeline_cacheline *cl,
569 struct i915_request *rq)
570{
571 return i915_active_add_request(&cl->active, rq);
572}
573
574int intel_timeline_read_hwsp(struct i915_request *from,328int intel_timeline_read_hwsp(struct i915_request *from,
575 struct i915_request *to,329 struct i915_request *to,
576 u32 *hwsp)330 u32 *hwsp)
577{331{
578 struct intel_timeline_cacheline *cl;332 struct intel_timeline *tl;
579 int err;333 int err;
580 334
581 GEM_BUG_ON(!rcu_access_pointer(from->hwsp_cacheline));
582
583 rcu_read_lock();335 rcu_read_lock();
584 cl = rcu_dereference(from->hwsp_cacheline);336 tl = rcu_dereference(from->timeline);
585 if (i915_request_signaled(from)) /* confirm cacheline is valid */337 if (i915_request_signaled(from) ||
586 goto unlock;338 !i915_active_acquire_if_busy(&tl->active))
587 if (unlikely(!i915_active_acquire_if_busy(&cl->active)))339 tl = NULL;
588 goto unlock; /* seqno wrapped and completed! */340
589 if (unlikely(__i915_request_is_complete(from)))341 if (tl) {
590 goto release;342 /* hwsp_offset may wraparound, so use from->hwsp_seqno */
343 *hwsp = i915_ggtt_offset(tl->hwsp_ggtt) +
344 offset_in_page(from->hwsp_seqno);
345 }
346
347 /* ensure we wait on the right request, if not, we completed */
348 if (tl && __i915_request_is_complete(from)) {
349 i915_active_release(&tl->active);
350 tl = NULL;
351 }
591 rcu_read_unlock();352 rcu_read_unlock();
592 353
593 err = cacheline_ref(cl, to);354 if (!tl)
594 if (err)355 return 1;
356
357 /* Can't do semaphore waits on kernel context */
358 if (!tl->has_initial_breadcrumb) {
359 err = -EINVAL;
595 goto out;360 goto out;
361 }
362
363 err = i915_active_add_request(&tl->active, to);
596 364
597 *hwsp = cl->ggtt_offset;
598out:365out:
599 i915_active_release(&cl->active);366 i915_active_release(&tl->active);
600 return err;367 return err;
601
602release:
603 i915_active_release(&cl->active);
604unlock:
605 rcu_read_unlock();
606 return 1;
607}368}
608 369
609void intel_timeline_unpin(struct intel_timeline *tl)370void intel_timeline_unpin(struct intel_timeline *tl)
@@ -612,8 +373,7 @@ void intel_timeline_unpin(struct intel_timeline *tl) · 2 unmodified lines
612 if (!atomic_dec_and_test(&tl->pin_count))373 if (!atomic_dec_and_test(&tl->pin_count))
613 return;374 return;
614 375
615 cacheline_release(tl->hwsp_cacheline);376 i915_active_release(&tl->active);
616
617 __i915_vma_unpin(tl->hwsp_ggtt);377 __i915_vma_unpin(tl->hwsp_ggtt);
618}378}
619 379
@@ -622,8 +382,11 @@ void __intel_timeline_free(struct kref *kref) · 2 unmodified lines
622 struct intel_timeline *timeline =382 struct intel_timeline *timeline =
623 container_of(kref, typeof(*timeline), kref);383 container_of(kref, typeof(*timeline), kref);
624 384
625 intel_timeline_fini(timeline);385 GEM_BUG_ON(atomic_read(&timeline->pin_count));
626 kfree_rcu(timeline, rcu);386 GEM_BUG_ON(!list_empty(&timeline->requests));
387 GEM_BUG_ON(timeline->retire);
388
389 call_rcu(&timeline->rcu, intel_timeline_fini);
627}390}
628 391
629void intel_gt_fini_timelines(struct intel_gt *gt)392void intel_gt_fini_timelines(struct intel_gt *gt)
@@ -631,7 +394,6 @@ void intel_gt_fini_timelines(struct intel_gt *gt) · 1 unmodified line
631 struct intel_gt_timelines *timelines = &gt->timelines;394 struct intel_gt_timelines *timelines = &gt->timelines;
632 395
633 GEM_BUG_ON(!list_empty(&timelines->active_list));396 GEM_BUG_ON(!list_empty(&timelines->active_list));
634 GEM_BUG_ON(!list_empty(&timelines->hwsp_free_list));
635}397}
636 398
637void intel_gt_show_timelines(struct intel_gt *gt,399void intel_gt_show_timelines(struct intel_gt *gt,
drivers/gpu/drm/i915/gt/intel_timeline.h+2−0
@@ -117,4 +117,6 @@ intel_timeline_is_last(const struct intel_timeline *tl, · 116 unmodified lines
117 return list_is_last_rcu(&rq->link, &tl->requests);117 return list_is_last_rcu(&rq->link, &tl->requests);
118}118}
119 119
120I915_SELFTEST_DECLARE(int intel_timeline_pin_map(struct intel_timeline *tl));
121
120#endif122#endif
drivers/gpu/drm/i915/gt/intel_timeline_types.h+3−14
@@ -18,7 +18,6 @@ · 17 unmodified lines
18struct i915_vma;18struct i915_vma;
19struct i915_syncmap;19struct i915_syncmap;
20struct intel_gt;20struct intel_gt;
21struct intel_timeline_hwsp;
22 21
23struct intel_timeline {22struct intel_timeline {
24 u64 fence_context;23 u64 fence_context;
@@ -45,12 +44,11 @@ struct intel_timeline { · 20 unmodified lines
45 atomic_t pin_count;44 atomic_t pin_count;
46 atomic_t active_count;45 atomic_t active_count;
47 46
47 void *hwsp_map;
48 const u32 *hwsp_seqno;48 const u32 *hwsp_seqno;
49 struct i915_vma *hwsp_ggtt;49 struct i915_vma *hwsp_ggtt;
50 u32 hwsp_offset;50 u32 hwsp_offset;
51 51
52 struct intel_timeline_cacheline *hwsp_cacheline;
53
54 bool has_initial_breadcrumb;52 bool has_initial_breadcrumb;
55 53
56 /**54 /**
@@ -67,6 +65,8 @@ struct intel_timeline { · 10 unmodified lines
67 */65 */
68 struct i915_active_fence last_request;66 struct i915_active_fence last_request;
69 67
68 struct i915_active active;
69
70 /** A chain of completed timelines ready for early retirement. */70 /** A chain of completed timelines ready for early retirement. */
71 struct intel_timeline *retire;71 struct intel_timeline *retire;
72 72
@@ -90,15 +90,4 @@ struct intel_timeline { · 17 unmodified lines
90 struct rcu_head rcu;90 struct rcu_head rcu;
91};91};
92 92
93struct intel_timeline_cacheline {
94 struct i915_active active;
95
96 struct intel_timeline_hwsp *hwsp;
97 void *vaddr;
98
99 u32 ggtt_offset;
100
101 struct rcu_head rcu;
102};
103
104#endif /* __I915_TIMELINE_TYPES_H__ */93#endif /* __I915_TIMELINE_TYPES_H__ */
drivers/gpu/drm/i915/gt/intel_workarounds.c+8−2
@@ -2213,10 +2213,15 @@ retry: · 2212 unmodified lines
2213 if (err)2213 if (err)
2214 goto err_pm;2214 goto err_pm;
2215 2215
2216 err = i915_vma_pin_ww(vma, &ww, 0, 0,
2217 i915_vma_is_ggtt(vma) ? PIN_GLOBAL : PIN_USER);
2218 if (err)
2219 goto err_unpin;
2220
2216 rq = i915_request_create(ce);2221 rq = i915_request_create(ce);
2217 if (IS_ERR(rq)) {2222 if (IS_ERR(rq)) {
2218 err = PTR_ERR(rq);2223 err = PTR_ERR(rq);
2219 goto err_unpin;2224 goto err_vma;
2220 }2225 }
2221 2226
2222 err = i915_request_await_object(rq, vma->obj, true);2227 err = i915_request_await_object(rq, vma->obj, true);
@@ -2257,6 +2262,8 @@ retry: · 34 unmodified lines
2257 2262
2258err_rq:2263err_rq:
2259 i915_request_put(rq);2264 i915_request_put(rq);
2265err_vma:
2266 i915_vma_unpin(vma);
2260err_unpin:2267err_unpin:
2261 intel_context_unpin(ce);2268 intel_context_unpin(ce);
2262err_pm:2269err_pm:
@@ -2267,7 +2274,6 @@ err_pm: · 4 unmodified lines
2267 }2274 }
2268 i915_gem_ww_ctx_fini(&ww);2275 i915_gem_ww_ctx_fini(&ww);
2269 intel_engine_pm_put(ce->engine);2276 intel_engine_pm_put(ce->engine);
2270 i915_vma_unpin(vma);
2271 i915_vma_put(vma);2277 i915_vma_put(vma);
2272 return err;2278 return err;
2273}2279}
drivers/gpu/drm/i915/gt/mock_engine.c+20−2
@@ -32,9 +32,20 @@ · 31 unmodified lines
32#include "mock_engine.h"32#include "mock_engine.h"
33#include "selftests/mock_request.h"33#include "selftests/mock_request.h"
34 34
35static void mock_timeline_pin(struct intel_timeline *tl)35static int mock_timeline_pin(struct intel_timeline *tl)
36{36{
37 int err;
38
39 if (WARN_ON(!i915_gem_object_trylock(tl->hwsp_ggtt->obj)))
40 return -EBUSY;
41
42 err = intel_timeline_pin_map(tl);
43 i915_gem_object_unlock(tl->hwsp_ggtt->obj);
44 if (err)
45 return err;
46
37 atomic_inc(&tl->pin_count);47 atomic_inc(&tl->pin_count);
48 return 0;
38}49}
39 50
40static void mock_timeline_unpin(struct intel_timeline *tl)51static void mock_timeline_unpin(struct intel_timeline *tl)
@@ -152,6 +163,8 @@ static void mock_context_destroy(struct kref *ref) · 111 unmodified lines
152 163
153static int mock_context_alloc(struct intel_context *ce)164static int mock_context_alloc(struct intel_context *ce)
154{165{
166 int err;
167
155 ce->ring = mock_ring(ce->engine);168 ce->ring = mock_ring(ce->engine);
156 if (!ce->ring)169 if (!ce->ring)
157 return -ENOMEM;170 return -ENOMEM;
@@ -162,7 +175,12 @@ static int mock_context_alloc(struct intel_context *ce) · 4 unmodified lines
162 return PTR_ERR(ce->timeline);175 return PTR_ERR(ce->timeline);
163 }176 }
164 177
165 mock_timeline_pin(ce->timeline);178 err = mock_timeline_pin(ce->timeline);
179 if (err) {
180 intel_timeline_put(ce->timeline);
181 ce->timeline = NULL;
182 return err;
183 }
166 184
167 return 0;185 return 0;
168}186}
drivers/gpu/drm/i915/gt/selftest_context.c+2−2
@@ -88,8 +88,8 @@ static int __live_context_size(struct intel_engine_cs *engine) · 87 unmodified lines
88 if (err)88 if (err)
89 goto err;89 goto err;
90 90
91 vaddr = i915_gem_object_pin_map(ce->state->obj,91 vaddr = i915_gem_object_pin_map_unlocked(ce->state->obj,
92 i915_coherent_map_type(engine->i915));92 i915_coherent_map_type(engine->i915));
93 if (IS_ERR(vaddr)) {93 if (IS_ERR(vaddr)) {
94 err = PTR_ERR(vaddr);94 err = PTR_ERR(vaddr);
95 intel_context_unpin(ce);95 intel_context_unpin(ce);
drivers/gpu/drm/i915/gt/selftest_engine_cs.c+6−3
@@ -42,6 +42,9 @@ static int perf_end(struct intel_gt *gt) · 41 unmodified lines
42 42
43static int write_timestamp(struct i915_request *rq, int slot)43static int write_timestamp(struct i915_request *rq, int slot)
44{44{
45 struct intel_timeline *tl =
46 rcu_dereference_protected(rq->timeline,
47 !i915_request_signaled(rq));
45 u32 cmd;48 u32 cmd;
46 u32 *cs;49 u32 *cs;
47 50
@@ -54,7 +57,7 @@ static int write_timestamp(struct i915_request *rq, int slot) · 6 unmodified lines
54 cmd++;57 cmd++;
55 *cs++ = cmd;58 *cs++ = cmd;
56 *cs++ = i915_mmio_reg_offset(RING_TIMESTAMP(rq->engine->mmio_base));59 *cs++ = i915_mmio_reg_offset(RING_TIMESTAMP(rq->engine->mmio_base));
57 *cs++ = i915_request_timeline(rq)->hwsp_offset + slot * sizeof(u32);60 *cs++ = tl->hwsp_offset + slot * sizeof(u32);
58 *cs++ = 0;61 *cs++ = 0;
59 62
60 intel_ring_advance(rq, cs);63 intel_ring_advance(rq, cs);
@@ -73,7 +76,7 @@ static struct i915_vma *create_empty_batch(struct intel_context *ce) · 12 unmodified lines
73 if (IS_ERR(obj))76 if (IS_ERR(obj))
74 return ERR_CAST(obj);77 return ERR_CAST(obj);
75 78
76 cs = i915_gem_object_pin_map(obj, I915_MAP_WB);79 cs = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WB);
77 if (IS_ERR(cs)) {80 if (IS_ERR(cs)) {
78 err = PTR_ERR(cs);81 err = PTR_ERR(cs);
79 goto err_put;82 goto err_put;
@@ -209,7 +212,7 @@ static struct i915_vma *create_nop_batch(struct intel_context *ce) · 129 unmodified lines
209 if (IS_ERR(obj))212 if (IS_ERR(obj))
210 return ERR_CAST(obj);213 return ERR_CAST(obj);
211 214
212 cs = i915_gem_object_pin_map(obj, I915_MAP_WB);215 cs = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WB);
213 if (IS_ERR(cs)) {216 if (IS_ERR(cs)) {
214 err = PTR_ERR(cs);217 err = PTR_ERR(cs);
215 goto err_put;218 goto err_put;
drivers/gpu/drm/i915/gt/selftest_execlists.c+12−11
@@ -989,7 +989,7 @@ static int live_timeslice_preempt(void *arg) · 988 unmodified lines
989 goto err_obj;989 goto err_obj;
990 }990 }
991 991
992 vaddr = i915_gem_object_pin_map(obj, I915_MAP_WC);992 vaddr = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WC);
993 if (IS_ERR(vaddr)) {993 if (IS_ERR(vaddr)) {
994 err = PTR_ERR(vaddr);994 err = PTR_ERR(vaddr);
995 goto err_obj;995 goto err_obj;
@@ -1297,7 +1297,7 @@ static int live_timeslice_queue(void *arg) · 301 unmodified lines
1297 goto err_obj;1297 goto err_obj;
1298 }1298 }
1299 1299
1300 vaddr = i915_gem_object_pin_map(obj, I915_MAP_WC);1300 vaddr = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WC);
1301 if (IS_ERR(vaddr)) {1301 if (IS_ERR(vaddr)) {
1302 err = PTR_ERR(vaddr);1302 err = PTR_ERR(vaddr);
1303 goto err_obj;1303 goto err_obj;
@@ -1544,7 +1544,7 @@ static int live_busywait_preempt(void *arg) · 240 unmodified lines
1544 goto err_ctx_lo;1544 goto err_ctx_lo;
1545 }1545 }
1546 1546
1547 map = i915_gem_object_pin_map(obj, I915_MAP_WC);1547 map = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WC);
1548 if (IS_ERR(map)) {1548 if (IS_ERR(map)) {
1549 err = PTR_ERR(map);1549 err = PTR_ERR(map);
1550 goto err_obj;1550 goto err_obj;
@@ -2714,7 +2714,7 @@ static int create_gang(struct intel_engine_cs *engine, · 1163 unmodified lines
2714 if (err)2714 if (err)
2715 goto err_obj;2715 goto err_obj;
2716 2716
2717 cs = i915_gem_object_pin_map(obj, I915_MAP_WC);2717 cs = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WC);
2718 if (IS_ERR(cs)) {2718 if (IS_ERR(cs)) {
2719 err = PTR_ERR(cs);2719 err = PTR_ERR(cs);
2720 goto err_obj;2720 goto err_obj;
@@ -2997,7 +2997,7 @@ static int live_preempt_gang(void *arg) · 276 unmodified lines
2997 * it will terminate the next lowest spinner until there2997 * it will terminate the next lowest spinner until there
2998 * are no more spinners and the gang is complete.2998 * are no more spinners and the gang is complete.
2999 */2999 */
3000 cs = i915_gem_object_pin_map(rq->batch->obj, I915_MAP_WC);3000 cs = i915_gem_object_pin_map_unlocked(rq->batch->obj, I915_MAP_WC);
3001 if (!IS_ERR(cs)) {3001 if (!IS_ERR(cs)) {
3002 *cs = 0;3002 *cs = 0;
3003 i915_gem_object_unpin_map(rq->batch->obj);3003 i915_gem_object_unpin_map(rq->batch->obj);
@@ -3062,7 +3062,7 @@ create_gpr_user(struct intel_engine_cs *engine, · 58 unmodified lines
3062 return ERR_PTR(err);3062 return ERR_PTR(err);
3063 }3063 }
3064 3064
3065 cs = i915_gem_object_pin_map(obj, I915_MAP_WC);3065 cs = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WC);
3066 if (IS_ERR(cs)) {3066 if (IS_ERR(cs)) {
3067 i915_vma_put(vma);3067 i915_vma_put(vma);
3068 return ERR_CAST(cs);3068 return ERR_CAST(cs);
@@ -3269,7 +3269,7 @@ static int live_preempt_user(void *arg) · 200 unmodified lines
3269 if (IS_ERR(global))3269 if (IS_ERR(global))
3270 return PTR_ERR(global);3270 return PTR_ERR(global);
3271 3271
3272 result = i915_gem_object_pin_map(global->obj, I915_MAP_WC);3272 result = i915_gem_object_pin_map_unlocked(global->obj, I915_MAP_WC);
3273 if (IS_ERR(result)) {3273 if (IS_ERR(result)) {
3274 i915_vma_unpin_and_release(&global, 0);3274 i915_vma_unpin_and_release(&global, 0);
3275 return PTR_ERR(result);3275 return PTR_ERR(result);
@@ -3658,7 +3658,7 @@ static int live_preempt_smoke(void *arg) · 382 unmodified lines
3658 goto err_free;3658 goto err_free;
3659 }3659 }
3660 3660
3661 cs = i915_gem_object_pin_map(smoke.batch, I915_MAP_WB);3661 cs = i915_gem_object_pin_map_unlocked(smoke.batch, I915_MAP_WB);
3662 if (IS_ERR(cs)) {3662 if (IS_ERR(cs)) {
3663 err = PTR_ERR(cs);3663 err = PTR_ERR(cs);
3664 goto err_batch;3664 goto err_batch;
@@ -4197,8 +4197,9 @@ static int preserved_virtual_engine(struct intel_gt *gt, · 532 unmodified lines
4197 int err = 0;4197 int err = 0;
4198 u32 *cs;4198 u32 *cs;
4199 4199
4200 scratch = __vm_create_scratch_for_read(&siblings[0]->gt->ggtt->vm,4200 scratch =
4201 PAGE_SIZE);4201 __vm_create_scratch_for_read_pinned(&siblings[0]->gt->ggtt->vm,
4202 PAGE_SIZE);
4202 if (IS_ERR(scratch))4203 if (IS_ERR(scratch))
4203 return PTR_ERR(scratch);4204 return PTR_ERR(scratch);
4204 4205
@@ -4262,7 +4263,7 @@ static int preserved_virtual_engine(struct intel_gt *gt, · 57 unmodified lines
4262 goto out_end;4263 goto out_end;
4263 }4264 }
4264 4265
4265 cs = i915_gem_object_pin_map(scratch->obj, I915_MAP_WB);4266 cs = i915_gem_object_pin_map_unlocked(scratch->obj, I915_MAP_WB);
4266 if (IS_ERR(cs)) {4267 if (IS_ERR(cs)) {
4267 err = PTR_ERR(cs);4268 err = PTR_ERR(cs);
4268 goto out_end;4269 goto out_end;
drivers/gpu/drm/i915/gt/selftest_hangcheck.c+4−4
@@ -80,15 +80,15 @@ static int hang_init(struct hang *h, struct intel_gt *gt) · 79 unmodified lines
80 }80 }
81 81
82 i915_gem_object_set_cache_coherency(h->hws, I915_CACHE_LLC);82 i915_gem_object_set_cache_coherency(h->hws, I915_CACHE_LLC);
83 vaddr = i915_gem_object_pin_map(h->hws, I915_MAP_WB);83 vaddr = i915_gem_object_pin_map_unlocked(h->hws, I915_MAP_WB);
84 if (IS_ERR(vaddr)) {84 if (IS_ERR(vaddr)) {
85 err = PTR_ERR(vaddr);85 err = PTR_ERR(vaddr);
86 goto err_obj;86 goto err_obj;
87 }87 }
88 h->seqno = memset(vaddr, 0xff, PAGE_SIZE);88 h->seqno = memset(vaddr, 0xff, PAGE_SIZE);
89 89
90 vaddr = i915_gem_object_pin_map(h->obj,90 vaddr = i915_gem_object_pin_map_unlocked(h->obj,
91 i915_coherent_map_type(gt->i915));91 i915_coherent_map_type(gt->i915));
92 if (IS_ERR(vaddr)) {92 if (IS_ERR(vaddr)) {
93 err = PTR_ERR(vaddr);93 err = PTR_ERR(vaddr);
94 goto err_unpin_hws;94 goto err_unpin_hws;
@@ -149,7 +149,7 @@ hang_create_request(struct hang *h, struct intel_engine_cs *engine) · 54 unmodified lines
149 return ERR_CAST(obj);149 return ERR_CAST(obj);
150 }150 }
151 151
152 vaddr = i915_gem_object_pin_map(obj, i915_coherent_map_type(gt->i915));152 vaddr = i915_gem_object_pin_map_unlocked(obj, i915_coherent_map_type(gt->i915));
153 if (IS_ERR(vaddr)) {153 if (IS_ERR(vaddr)) {
154 i915_gem_object_put(obj);154 i915_gem_object_put(obj);
155 i915_vm_put(vm);155 i915_vm_put(vm);
drivers/gpu/drm/i915/gt/selftest_lrc.c+9−9
@@ -27,7 +27,7 @@ · 26 unmodified lines
27 27
28static struct i915_vma *create_scratch(struct intel_gt *gt)28static struct i915_vma *create_scratch(struct intel_gt *gt)
29{29{
30 return __vm_create_scratch_for_read(&gt->ggtt->vm, PAGE_SIZE);30 return __vm_create_scratch_for_read_pinned(&gt->ggtt->vm, PAGE_SIZE);
31}31}
32 32
33static bool is_active(struct i915_request *rq)33static bool is_active(struct i915_request *rq)
@@ -627,7 +627,7 @@ static int __live_lrc_gpr(struct intel_engine_cs *engine, · 593 unmodified lines
627 goto err_rq;627 goto err_rq;
628 }628 }
629 629
630 cs = i915_gem_object_pin_map(scratch->obj, I915_MAP_WB);630 cs = i915_gem_object_pin_map_unlocked(scratch->obj, I915_MAP_WB);
631 if (IS_ERR(cs)) {631 if (IS_ERR(cs)) {
632 err = PTR_ERR(cs);632 err = PTR_ERR(cs);
633 goto err_rq;633 goto err_rq;
@@ -921,7 +921,7 @@ store_context(struct intel_context *ce, struct i915_vma *scratch) · 287 unmodified lines
921 if (IS_ERR(batch))921 if (IS_ERR(batch))
922 return batch;922 return batch;
923 923
924 cs = i915_gem_object_pin_map(batch->obj, I915_MAP_WC);924 cs = i915_gem_object_pin_map_unlocked(batch->obj, I915_MAP_WC);
925 if (IS_ERR(cs)) {925 if (IS_ERR(cs)) {
926 i915_vma_put(batch);926 i915_vma_put(batch);
927 return ERR_CAST(cs);927 return ERR_CAST(cs);
@@ -1085,7 +1085,7 @@ static struct i915_vma *load_context(struct intel_context *ce, u32 poison) · 157 unmodified lines
1085 if (IS_ERR(batch))1085 if (IS_ERR(batch))
1086 return batch;1086 return batch;
1087 1087
1088 cs = i915_gem_object_pin_map(batch->obj, I915_MAP_WC);1088 cs = i915_gem_object_pin_map_unlocked(batch->obj, I915_MAP_WC);
1089 if (IS_ERR(cs)) {1089 if (IS_ERR(cs)) {
1090 i915_vma_put(batch);1090 i915_vma_put(batch);
1091 return ERR_CAST(cs);1091 return ERR_CAST(cs);
@@ -1199,29 +1199,29 @@ static int compare_isolation(struct intel_engine_cs *engine, · 107 unmodified lines
1199 u32 *defaults;1199 u32 *defaults;
1200 int err = 0;1200 int err = 0;
1201 1201
1202 A[0] = i915_gem_object_pin_map(ref[0]->obj, I915_MAP_WC);1202 A[0] = i915_gem_object_pin_map_unlocked(ref[0]->obj, I915_MAP_WC);
1203 if (IS_ERR(A[0]))1203 if (IS_ERR(A[0]))
1204 return PTR_ERR(A[0]);1204 return PTR_ERR(A[0]);
1205 1205
1206 A[1] = i915_gem_object_pin_map(ref[1]->obj, I915_MAP_WC);1206 A[1] = i915_gem_object_pin_map_unlocked(ref[1]->obj, I915_MAP_WC);
1207 if (IS_ERR(A[1])) {1207 if (IS_ERR(A[1])) {
1208 err = PTR_ERR(A[1]);1208 err = PTR_ERR(A[1]);
1209 goto err_A0;1209 goto err_A0;
1210 }1210 }
1211 1211
1212 B[0] = i915_gem_object_pin_map(result[0]->obj, I915_MAP_WC);1212 B[0] = i915_gem_object_pin_map_unlocked(result[0]->obj, I915_MAP_WC);
1213 if (IS_ERR(B[0])) {1213 if (IS_ERR(B[0])) {
1214 err = PTR_ERR(B[0]);1214 err = PTR_ERR(B[0]);
1215 goto err_A1;1215 goto err_A1;
1216 }1216 }
1217 1217
1218 B[1] = i915_gem_object_pin_map(result[1]->obj, I915_MAP_WC);1218 B[1] = i915_gem_object_pin_map_unlocked(result[1]->obj, I915_MAP_WC);
1219 if (IS_ERR(B[1])) {1219 if (IS_ERR(B[1])) {
1220 err = PTR_ERR(B[1]);1220 err = PTR_ERR(B[1]);
1221 goto err_B0;1221 goto err_B0;
1222 }1222 }
1223 1223
1224 lrc = i915_gem_object_pin_map(ce->state->obj,1224 lrc = i915_gem_object_pin_map_unlocked(ce->state->obj,
1225 i915_coherent_map_type(engine->i915));1225 i915_coherent_map_type(engine->i915));
1226 if (IS_ERR(lrc)) {1226 if (IS_ERR(lrc)) {
1227 err = PTR_ERR(lrc);1227 err = PTR_ERR(lrc);
drivers/gpu/drm/i915/gt/selftest_mocs.c+3−2
@@ -75,11 +75,12 @@ static int live_mocs_init(struct live_mocs *arg, struct intel_gt *gt) · 74 unmodified lines
75 if (flags & (HAS_GLOBAL_MOCS | HAS_ENGINE_MOCS))75 if (flags & (HAS_GLOBAL_MOCS | HAS_ENGINE_MOCS))
76 arg->mocs = table;76 arg->mocs = table;
77 77
78 arg->scratch = __vm_create_scratch_for_read(&gt->ggtt->vm, PAGE_SIZE);78 arg->scratch =
79 __vm_create_scratch_for_read_pinned(&gt->ggtt->vm, PAGE_SIZE);
79 if (IS_ERR(arg->scratch))80 if (IS_ERR(arg->scratch))
80 return PTR_ERR(arg->scratch);81 return PTR_ERR(arg->scratch);
81 82
82 arg->vaddr = i915_gem_object_pin_map(arg->scratch->obj, I915_MAP_WB);83 arg->vaddr = i915_gem_object_pin_map_unlocked(arg->scratch->obj, I915_MAP_WB);
83 if (IS_ERR(arg->vaddr)) {84 if (IS_ERR(arg->vaddr)) {
84 err = PTR_ERR(arg->vaddr);85 err = PTR_ERR(arg->vaddr);
85 goto err_scratch;86 goto err_scratch;
drivers/gpu/drm/i915/gt/selftest_ring_submission.c+2−2
@@ -35,7 +35,7 @@ static struct i915_vma *create_wally(struct intel_engine_cs *engine) · 34 unmodified lines
35 return ERR_PTR(err);35 return ERR_PTR(err);
36 }36 }
37 37
38 cs = i915_gem_object_pin_map(obj, I915_MAP_WC);38 cs = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WC);
39 if (IS_ERR(cs)) {39 if (IS_ERR(cs)) {
40 i915_gem_object_put(obj);40 i915_gem_object_put(obj);
41 return ERR_CAST(cs);41 return ERR_CAST(cs);
@@ -212,7 +212,7 @@ static int __live_ctx_switch_wa(struct intel_engine_cs *engine) · 170 unmodified lines
212 if (IS_ERR(bb))212 if (IS_ERR(bb))
213 return PTR_ERR(bb);213 return PTR_ERR(bb);
214 214
215 result = i915_gem_object_pin_map(bb->obj, I915_MAP_WC);215 result = i915_gem_object_pin_map_unlocked(bb->obj, I915_MAP_WC);
216 if (IS_ERR(result)) {216 if (IS_ERR(result)) {
217 intel_context_put(bb->private);217 intel_context_put(bb->private);
218 i915_vma_unpin_and_release(&bb, 0);218 i915_vma_unpin_and_release(&bb, 0);
drivers/gpu/drm/i915/gt/selftest_timeline.c+109−68
@@ -35,10 +35,31 @@ static unsigned long hwsp_cacheline(struct intel_timeline *tl) · 34 unmodified lines
35{35{
36 unsigned long address = (unsigned long)page_address(hwsp_page(tl));36 unsigned long address = (unsigned long)page_address(hwsp_page(tl));
37 37
38 return (address + tl->hwsp_offset) / CACHELINE_BYTES;38 return (address + offset_in_page(tl->hwsp_offset)) / TIMELINE_SEQNO_BYTES;
39}39}
40 40
41#define CACHELINES_PER_PAGE (PAGE_SIZE / CACHELINE_BYTES)41static int selftest_tl_pin(struct intel_timeline *tl)
42{
43 struct i915_gem_ww_ctx ww;
44 int err;
45
46 i915_gem_ww_ctx_init(&ww, false);
47retry:
48 err = i915_gem_object_lock(tl->hwsp_ggtt->obj, &ww);
49 if (!err)
50 err = intel_timeline_pin(tl, &ww);
51
52 if (err == -EDEADLK) {
53 err = i915_gem_ww_ctx_backoff(&ww);
54 if (!err)
55 goto retry;
56 }
57 i915_gem_ww_ctx_fini(&ww);
58 return err;
59}
60
61/* Only half of seqno's are usable, see __intel_timeline_get_seqno() */
62#define CACHELINES_PER_PAGE (PAGE_SIZE / TIMELINE_SEQNO_BYTES / 2)
42 63
43struct mock_hwsp_freelist {64struct mock_hwsp_freelist {
44 struct intel_gt *gt;65 struct intel_gt *gt;
@@ -59,6 +80,7 @@ static void __mock_hwsp_record(struct mock_hwsp_freelist *state, · 14 unmodified lines
59 tl = xchg(&state->history[idx], tl);80 tl = xchg(&state->history[idx], tl);
60 if (tl) {81 if (tl) {
61 radix_tree_delete(&state->cachelines, hwsp_cacheline(tl));82 radix_tree_delete(&state->cachelines, hwsp_cacheline(tl));
83 intel_timeline_unpin(tl);
62 intel_timeline_put(tl);84 intel_timeline_put(tl);
63 }85 }
64}86}
@@ -78,6 +100,12 @@ static int __mock_hwsp_timeline(struct mock_hwsp_freelist *state, · 13 unmodified lines
78 if (IS_ERR(tl))100 if (IS_ERR(tl))
79 return PTR_ERR(tl);101 return PTR_ERR(tl);
80 102
103 err = selftest_tl_pin(tl);
104 if (err) {
105 intel_timeline_put(tl);
106 return err;
107 }
108
81 cacheline = hwsp_cacheline(tl);109 cacheline = hwsp_cacheline(tl);
82 err = radix_tree_insert(&state->cachelines, cacheline, tl);110 err = radix_tree_insert(&state->cachelines, cacheline, tl);
83 if (err) {111 if (err) {
@@ -85,6 +113,7 @@ static int __mock_hwsp_timeline(struct mock_hwsp_freelist *state, · 1 unmodified line
85 pr_err("HWSP cacheline %lu already used; duplicate allocation!\n",113 pr_err("HWSP cacheline %lu already used; duplicate allocation!\n",
86 cacheline);114 cacheline);
87 }115 }
116 intel_timeline_unpin(tl);
88 intel_timeline_put(tl);117 intel_timeline_put(tl);
89 return err;118 return err;
90 }119 }
@@ -452,17 +481,24 @@ static int emit_ggtt_store_dw(struct i915_request *rq, u32 addr, u32 value) · 361 unmodified lines
452}481}
453 482
454static struct i915_request *483static struct i915_request *
455tl_write(struct intel_timeline *tl, struct intel_engine_cs *engine, u32 value)484checked_tl_write(struct intel_timeline *tl, struct intel_engine_cs *engine, u32 value)
456{485{
457 struct i915_request *rq;486 struct i915_request *rq;
458 int err;487 int err;
459 488
460 err = intel_timeline_pin(tl, NULL);489 err = selftest_tl_pin(tl);
461 if (err) {490 if (err) {
462 rq = ERR_PTR(err);491 rq = ERR_PTR(err);
463 goto out;492 goto out;
464 }493 }
465 494
495 if (READ_ONCE(*tl->hwsp_seqno) != tl->seqno) {
496 pr_err("Timeline created with incorrect breadcrumb, found %x, expected %x\n",
497 *tl->hwsp_seqno, tl->seqno);
498 intel_timeline_unpin(tl);
499 return ERR_PTR(-EINVAL);
500 }
501
466 rq = intel_engine_create_kernel_request(engine);502 rq = intel_engine_create_kernel_request(engine);
467 if (IS_ERR(rq))503 if (IS_ERR(rq))
468 goto out_unpin;504 goto out_unpin;
@@ -484,25 +520,6 @@ out: · 15 unmodified lines
484 return rq;520 return rq;
485}521}
486 522
487static struct intel_timeline *
488checked_intel_timeline_create(struct intel_gt *gt)
489{
490 struct intel_timeline *tl;
491
492 tl = intel_timeline_create(gt);
493 if (IS_ERR(tl))
494 return tl;
495
496 if (READ_ONCE(*tl->hwsp_seqno) != tl->seqno) {
497 pr_err("Timeline created with incorrect breadcrumb, found %x, expected %x\n",
498 *tl->hwsp_seqno, tl->seqno);
499 intel_timeline_put(tl);
500 return ERR_PTR(-EINVAL);
501 }
502
503 return tl;
504}
505
506static int live_hwsp_engine(void *arg)523static int live_hwsp_engine(void *arg)
507{524{
508#define NUM_TIMELINES 4096525#define NUM_TIMELINES 4096
@@ -535,13 +552,13 @@ static int live_hwsp_engine(void *arg) · 26 unmodified lines
535 struct intel_timeline *tl;552 struct intel_timeline *tl;
536 struct i915_request *rq;553 struct i915_request *rq;
537 554
538 tl = checked_intel_timeline_create(gt);555 tl = intel_timeline_create(gt);
539 if (IS_ERR(tl)) {556 if (IS_ERR(tl)) {
540 err = PTR_ERR(tl);557 err = PTR_ERR(tl);
541 break;558 break;
542 }559 }
543 560
544 rq = tl_write(tl, engine, count);561 rq = checked_tl_write(tl, engine, count);
545 if (IS_ERR(rq)) {562 if (IS_ERR(rq)) {
546 intel_timeline_put(tl);563 intel_timeline_put(tl);
547 err = PTR_ERR(rq);564 err = PTR_ERR(rq);
@@ -608,14 +625,14 @@ static int live_hwsp_alternate(void *arg) · 60 unmodified lines
608 if (!intel_engine_can_store_dword(engine))625 if (!intel_engine_can_store_dword(engine))
609 continue;626 continue;
610 627
611 tl = checked_intel_timeline_create(gt);628 tl = intel_timeline_create(gt);
612 if (IS_ERR(tl)) {629 if (IS_ERR(tl)) {
613 err = PTR_ERR(tl);630 err = PTR_ERR(tl);
614 goto out;631 goto out;
615 }632 }
616 633
617 intel_engine_pm_get(engine);634 intel_engine_pm_get(engine);
618 rq = tl_write(tl, engine, count);635 rq = checked_tl_write(tl, engine, count);
619 intel_engine_pm_put(engine);636 intel_engine_pm_put(engine);
620 if (IS_ERR(rq)) {637 if (IS_ERR(rq)) {
621 intel_timeline_put(tl);638 intel_timeline_put(tl);
@@ -666,10 +683,10 @@ static int live_hwsp_wrap(void *arg) · 44 unmodified lines
666 if (IS_ERR(tl))683 if (IS_ERR(tl))
667 return PTR_ERR(tl);684 return PTR_ERR(tl);
668 685
669 if (!tl->has_initial_breadcrumb || !tl->hwsp_cacheline)686 if (!tl->has_initial_breadcrumb)
670 goto out_free;687 goto out_free;
671 688
672 err = intel_timeline_pin(tl, NULL);689 err = selftest_tl_pin(tl);
673 if (err)690 if (err)
674 goto out_free;691 goto out_free;
675 692
@@ -816,13 +833,13 @@ static int setup_watcher(struct hwsp_watcher *w, struct intel_gt *gt) · 140 unmodified lines
816 if (IS_ERR(obj))833 if (IS_ERR(obj))
817 return PTR_ERR(obj);834 return PTR_ERR(obj);
818 835
819 w->map = i915_gem_object_pin_map(obj, I915_MAP_WB);836 w->map = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WB);
820 if (IS_ERR(w->map)) {837 if (IS_ERR(w->map)) {
821 i915_gem_object_put(obj);838 i915_gem_object_put(obj);
822 return PTR_ERR(w->map);839 return PTR_ERR(w->map);
823 }840 }
824 841
825 vma = i915_gem_object_ggtt_pin_ww(obj, NULL, NULL, 0, 0, 0);842 vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, 0);
826 if (IS_ERR(vma)) {843 if (IS_ERR(vma)) {
827 i915_gem_object_put(obj);844 i915_gem_object_put(obj);
828 return PTR_ERR(vma);845 return PTR_ERR(vma);
@@ -833,12 +850,26 @@ static int setup_watcher(struct hwsp_watcher *w, struct intel_gt *gt) · 4 unmodified lines
833 return 0;850 return 0;
834}851}
835 852
853static void switch_tl_lock(struct i915_request *from, struct i915_request *to)
854{
855 /* some light mutex juggling required; think co-routines */
856
857 if (from) {
858 lockdep_unpin_lock(&from->context->timeline->mutex, from->cookie);
859 mutex_unlock(&from->context->timeline->mutex);
860 }
861
862 if (to) {
863 mutex_lock(&to->context->timeline->mutex);
864 to->cookie = lockdep_pin_lock(&to->context->timeline->mutex);
865 }
866}
867
836static int create_watcher(struct hwsp_watcher *w,868static int create_watcher(struct hwsp_watcher *w,
837 struct intel_engine_cs *engine,869 struct intel_engine_cs *engine,
838 int ringsz)870 int ringsz)
839{871{
840 struct intel_context *ce;872 struct intel_context *ce;
841 struct intel_timeline *tl;
842 873
843 ce = intel_context_create(engine);874 ce = intel_context_create(engine);
844 if (IS_ERR(ce))875 if (IS_ERR(ce))
@@ -851,11 +882,8 @@ static int create_watcher(struct hwsp_watcher *w, · 6 unmodified lines
851 return PTR_ERR(w->rq);882 return PTR_ERR(w->rq);
852 883
853 w->addr = i915_ggtt_offset(w->vma);884 w->addr = i915_ggtt_offset(w->vma);
854 tl = w->rq->context->timeline;
855 885
856 /* some light mutex juggling required; think co-routines */886 switch_tl_lock(w->rq, NULL);
857 lockdep_unpin_lock(&tl->mutex, w->rq->cookie);
858 mutex_unlock(&tl->mutex);
859 887
860 return 0;888 return 0;
861}889}
@@ -864,15 +892,13 @@ static int check_watcher(struct hwsp_watcher *w, const char *name, · 2 unmodified lines
864 bool (*op)(u32 hwsp, u32 seqno))892 bool (*op)(u32 hwsp, u32 seqno))
865{893{
866 struct i915_request *rq = fetch_and_zero(&w->rq);894 struct i915_request *rq = fetch_and_zero(&w->rq);
867 struct intel_timeline *tl = rq->context->timeline;
868 u32 offset, end;895 u32 offset, end;
869 int err;896 int err;
870 897
871 GEM_BUG_ON(w->addr - i915_ggtt_offset(w->vma) > w->vma->size);898 GEM_BUG_ON(w->addr - i915_ggtt_offset(w->vma) > w->vma->size);
872 899
873 i915_request_get(rq);900 i915_request_get(rq);
874 mutex_lock(&tl->mutex);901 switch_tl_lock(NULL, rq);
875 rq->cookie = lockdep_pin_lock(&tl->mutex);
876 i915_request_add(rq);902 i915_request_add(rq);
877 903
878 if (i915_request_wait(rq, 0, HZ) < 0) {904 if (i915_request_wait(rq, 0, HZ) < 0) {
@@ -901,10 +927,7 @@ out: · 22 unmodified lines
901static void cleanup_watcher(struct hwsp_watcher *w)927static void cleanup_watcher(struct hwsp_watcher *w)
902{928{
903 if (w->rq) {929 if (w->rq) {
904 struct intel_timeline *tl = w->rq->context->timeline;930 switch_tl_lock(NULL, w->rq);
905
906 mutex_lock(&tl->mutex);
907 w->rq->cookie = lockdep_pin_lock(&tl->mutex);
908 931
909 i915_request_add(w->rq);932 i915_request_add(w->rq);
910 }933 }
@@ -942,7 +965,7 @@ static struct i915_request *wrap_timeline(struct i915_request *rq) · 31 unmodified lines
942 }965 }
943 966
944 i915_request_put(rq);967 i915_request_put(rq);
945 rq = intel_context_create_request(ce);968 rq = i915_request_create(ce);
946 if (IS_ERR(rq))969 if (IS_ERR(rq))
947 return rq;970 return rq;
948 971
@@ -977,7 +1000,7 @@ static int live_hwsp_read(void *arg) · 28 unmodified lines
977 if (IS_ERR(tl))1000 if (IS_ERR(tl))
978 return PTR_ERR(tl);1001 return PTR_ERR(tl);
979 1002
980 if (!tl->hwsp_cacheline)1003 if (!tl->has_initial_breadcrumb)
981 goto out_free;1004 goto out_free;
982 1005
983 for (i = 0; i < ARRAY_SIZE(watcher); i++) {1006 for (i = 0; i < ARRAY_SIZE(watcher); i++) {
@@ -999,7 +1022,7 @@ static int live_hwsp_read(void *arg) · 15 unmodified lines
999 do {1022 do {
1000 struct i915_sw_fence *submit;1023 struct i915_sw_fence *submit;
1001 struct i915_request *rq;1024 struct i915_request *rq;
1002 u32 hwsp;1025 u32 hwsp, dummy;
1003 1026
1004 submit = heap_fence_create(GFP_KERNEL);1027 submit = heap_fence_create(GFP_KERNEL);
1005 if (!submit) {1028 if (!submit) {
@@ -1017,14 +1040,26 @@ static int live_hwsp_read(void *arg) · 11 unmodified lines
1017 goto out;1040 goto out;
1018 }1041 }
1019 1042
1020 /* Skip to the end, saving 30 minutes of nops */
1021 tl->seqno = -10u + 2 * (count & 3);
1022 WRITE_ONCE(*(u32 *)tl->hwsp_seqno, tl->seqno);
1023 ce->timeline = intel_timeline_get(tl);1043 ce->timeline = intel_timeline_get(tl);
1024 1044
1025 rq = intel_context_create_request(ce);1045 /* Ensure timeline is mapped, done during first pin */
1046 err = intel_context_pin(ce);
1047 if (err) {
1048 intel_context_put(ce);
1049 goto out;
1050 }
1051
1052 /*
1053 * Start at a new wrap, and set seqno right before another wrap,
1054 * saving 30 minutes of nops
1055 */
1056 tl->seqno = -12u + 2 * (count & 3);
1057 __intel_timeline_get_seqno(tl, &dummy);
1058
1059 rq = i915_request_create(ce);
1026 if (IS_ERR(rq)) {1060 if (IS_ERR(rq)) {
1027 err = PTR_ERR(rq);1061 err = PTR_ERR(rq);
1062 intel_context_unpin(ce);
1028 intel_context_put(ce);1063 intel_context_put(ce);
1029 goto out;1064 goto out;
1030 }1065 }
@@ -1034,32 +1069,35 @@ static int live_hwsp_read(void *arg) · 3 unmodified lines
1034 GFP_KERNEL);1069 GFP_KERNEL);
1035 if (err < 0) {1070 if (err < 0) {
1036 i915_request_add(rq);1071 i915_request_add(rq);
1072 intel_context_unpin(ce);
1037 intel_context_put(ce);1073 intel_context_put(ce);
1038 goto out;1074 goto out;
1039 }1075 }
1040 1076
1041 mutex_lock(&watcher[0].rq->context->timeline->mutex);1077 switch_tl_lock(rq, watcher[0].rq);
1042 err = intel_timeline_read_hwsp(rq, watcher[0].rq, &hwsp);1078 err = intel_timeline_read_hwsp(rq, watcher[0].rq, &hwsp);
1043 if (err == 0)1079 if (err == 0)
1044 err = emit_read_hwsp(watcher[0].rq, /* before */1080 err = emit_read_hwsp(watcher[0].rq, /* before */
1045 rq->fence.seqno, hwsp,1081 rq->fence.seqno, hwsp,
1046 &watcher[0].addr);1082 &watcher[0].addr);
1047 mutex_unlock(&watcher[0].rq->context->timeline->mutex);1083 switch_tl_lock(watcher[0].rq, rq);
1048 if (err) {1084 if (err) {
1049 i915_request_add(rq);1085 i915_request_add(rq);
1086 intel_context_unpin(ce);
1050 intel_context_put(ce);1087 intel_context_put(ce);
1051 goto out;1088 goto out;
1052 }1089 }
1053 1090
1054 mutex_lock(&watcher[1].rq->context->timeline->mutex);1091 switch_tl_lock(rq, watcher[1].rq);
1055 err = intel_timeline_read_hwsp(rq, watcher[1].rq, &hwsp);1092 err = intel_timeline_read_hwsp(rq, watcher[1].rq, &hwsp);
1056 if (err == 0)1093 if (err == 0)
1057 err = emit_read_hwsp(watcher[1].rq, /* after */1094 err = emit_read_hwsp(watcher[1].rq, /* after */
1058 rq->fence.seqno, hwsp,1095 rq->fence.seqno, hwsp,
1059 &watcher[1].addr);1096 &watcher[1].addr);
1060 mutex_unlock(&watcher[1].rq->context->timeline->mutex);1097 switch_tl_lock(watcher[1].rq, rq);
1061 if (err) {1098 if (err) {
1062 i915_request_add(rq);1099 i915_request_add(rq);
1100 intel_context_unpin(ce);
1063 intel_context_put(ce);1101 intel_context_put(ce);
1064 goto out;1102 goto out;
1065 }1103 }
@@ -1068,6 +1106,7 @@ static int live_hwsp_read(void *arg) · 2 unmodified lines
1068 i915_request_add(rq);1106 i915_request_add(rq);
1069 1107
1070 rq = wrap_timeline(rq);1108 rq = wrap_timeline(rq);
1109 intel_context_unpin(ce);
1071 intel_context_put(ce);1110 intel_context_put(ce);
1072 if (IS_ERR(rq)) {1111 if (IS_ERR(rq)) {
1073 err = PTR_ERR(rq);1112 err = PTR_ERR(rq);
@@ -1107,8 +1146,8 @@ static int live_hwsp_read(void *arg) · 33 unmodified lines
1107 3 * watcher[1].rq->ring->size)1146 3 * watcher[1].rq->ring->size)
1108 break;1147 break;
1109 1148
1110 } while (!__igt_timeout(end_time, NULL));1149 } while (!__igt_timeout(end_time, NULL) &&
1111 WRITE_ONCE(*(u32 *)tl->hwsp_seqno, 0xdeadbeef);1150 count < (PAGE_SIZE / TIMELINE_SEQNO_BYTES - 1) / 2);
1112 1151
1113 pr_info("%s: simulated %lu wraps\n", engine->name, count);1152 pr_info("%s: simulated %lu wraps\n", engine->name, count);
1114 err = check_watcher(&watcher[1], "after", cmp_gte);1153 err = check_watcher(&watcher[1], "after", cmp_gte);
@@ -1153,9 +1192,7 @@ static int live_hwsp_rollover_kernel(void *arg) · 38 unmodified lines
1153 }1192 }
1154 1193
1155 GEM_BUG_ON(i915_active_fence_isset(&tl->last_request));1194 GEM_BUG_ON(i915_active_fence_isset(&tl->last_request));
1156 tl->seqno = 0;1195 tl->seqno = -2u;
1157 timeline_rollback(tl);
1158 timeline_rollback(tl);
1159 WRITE_ONCE(*(u32 *)tl->hwsp_seqno, tl->seqno);1196 WRITE_ONCE(*(u32 *)tl->hwsp_seqno, tl->seqno);
1160 1197
1161 for (i = 0; i < ARRAY_SIZE(rq); i++) {1198 for (i = 0; i < ARRAY_SIZE(rq); i++) {
@@ -1235,11 +1272,14 @@ static int live_hwsp_rollover_user(void *arg) · 73 unmodified lines
1235 goto out;1272 goto out;
1236 1273
1237 tl = ce->timeline;1274 tl = ce->timeline;
1238 if (!tl->has_initial_breadcrumb || !tl->hwsp_cacheline)1275 if (!tl->has_initial_breadcrumb)
1276 goto out;
1277
1278 err = intel_context_pin(ce);
1279 if (err)
1239 goto out;1280 goto out;
1240 1281
1241 timeline_rollback(tl);1282 tl->seqno = -4u;
1242 timeline_rollback(tl);
1243 WRITE_ONCE(*(u32 *)tl->hwsp_seqno, tl->seqno);1283 WRITE_ONCE(*(u32 *)tl->hwsp_seqno, tl->seqno);
1244 1284
1245 for (i = 0; i < ARRAY_SIZE(rq); i++) {1285 for (i = 0; i < ARRAY_SIZE(rq); i++) {
@@ -1248,7 +1288,7 @@ static int live_hwsp_rollover_user(void *arg) · 2 unmodified lines
1248 this = intel_context_create_request(ce);1288 this = intel_context_create_request(ce);
1249 if (IS_ERR(this)) {1289 if (IS_ERR(this)) {
1250 err = PTR_ERR(this);1290 err = PTR_ERR(this);
1251 goto out;1291 goto out_unpin;
1252 }1292 }
1253 1293
1254 pr_debug("%s: create fence.seqnp:%d\n",1294 pr_debug("%s: create fence.seqnp:%d\n",
@@ -1267,17 +1307,18 @@ static int live_hwsp_rollover_user(void *arg) · 12 unmodified lines
1267 if (i915_request_wait(rq[2], 0, HZ / 5) < 0) {1307 if (i915_request_wait(rq[2], 0, HZ / 5) < 0) {
1268 pr_err("Wait for timeline wrap timed out!\n");1308 pr_err("Wait for timeline wrap timed out!\n");
1269 err = -EIO;1309 err = -EIO;
1270 goto out;1310 goto out_unpin;
1271 }1311 }
1272 1312
1273 for (i = 0; i < ARRAY_SIZE(rq); i++) {1313 for (i = 0; i < ARRAY_SIZE(rq); i++) {
1274 if (!i915_request_completed(rq[i])) {1314 if (!i915_request_completed(rq[i])) {
1275 pr_err("Pre-wrap request not completed!\n");1315 pr_err("Pre-wrap request not completed!\n");
1276 err = -EINVAL;1316 err = -EINVAL;
1277 goto out;1317 goto out_unpin;
1278 }1318 }
1279 }1319 }
1280 1320out_unpin:
1321 intel_context_unpin(ce);
1281out:1322out:
1282 for (i = 0; i < ARRAY_SIZE(rq); i++)1323 for (i = 0; i < ARRAY_SIZE(rq); i++)
1283 i915_request_put(rq[i]);1324 i915_request_put(rq[i]);
@@ -1319,13 +1360,13 @@ static int live_hwsp_recycle(void *arg) · 35 unmodified lines
1319 struct intel_timeline *tl;1360 struct intel_timeline *tl;
1320 struct i915_request *rq;1361 struct i915_request *rq;
1321 1362
1322 tl = checked_intel_timeline_create(gt);1363 tl = intel_timeline_create(gt);
1323 if (IS_ERR(tl)) {1364 if (IS_ERR(tl)) {
1324 err = PTR_ERR(tl);1365 err = PTR_ERR(tl);
1325 break;1366 break;
1326 }1367 }
1327 1368
1328 rq = tl_write(tl, engine, count);1369 rq = checked_tl_write(tl, engine, count);
1329 if (IS_ERR(rq)) {1370 if (IS_ERR(rq)) {
1330 intel_timeline_put(tl);1371 intel_timeline_put(tl);
1331 err = PTR_ERR(rq);1372 err = PTR_ERR(rq);
drivers/gpu/drm/i915/gt/selftest_workarounds.c+52−30
@@ -112,7 +112,7 @@ read_nonprivs(struct intel_context *ce) · 111 unmodified lines
112 112
113 i915_gem_object_set_cache_coherency(result, I915_CACHE_LLC);113 i915_gem_object_set_cache_coherency(result, I915_CACHE_LLC);
114 114
115 cs = i915_gem_object_pin_map(result, I915_MAP_WB);115 cs = i915_gem_object_pin_map_unlocked(result, I915_MAP_WB);
116 if (IS_ERR(cs)) {116 if (IS_ERR(cs)) {
117 err = PTR_ERR(cs);117 err = PTR_ERR(cs);
118 goto err_obj;118 goto err_obj;
@@ -218,7 +218,7 @@ static int check_whitelist(struct intel_context *ce) · 99 unmodified lines
218 i915_gem_object_lock(results, NULL);218 i915_gem_object_lock(results, NULL);
219 intel_wedge_on_timeout(&wedge, engine->gt, HZ / 5) /* safety net! */219 intel_wedge_on_timeout(&wedge, engine->gt, HZ / 5) /* safety net! */
220 err = i915_gem_object_set_to_cpu_domain(results, false);220 err = i915_gem_object_set_to_cpu_domain(results, false);
221 i915_gem_object_unlock(results);221
222 if (intel_gt_is_wedged(engine->gt))222 if (intel_gt_is_wedged(engine->gt))
223 err = -EIO;223 err = -EIO;
224 if (err)224 if (err)
@@ -246,6 +246,7 @@ static int check_whitelist(struct intel_context *ce) · 21 unmodified lines
246 246
247 i915_gem_object_unpin_map(results);247 i915_gem_object_unpin_map(results);
248out_put:248out_put:
249 i915_gem_object_unlock(results);
249 i915_gem_object_put(results);250 i915_gem_object_put(results);
250 return err;251 return err;
251}252}
@@ -490,7 +491,7 @@ static int check_dirty_whitelist(struct intel_context *ce) · 238 unmodified lines
490 u32 *cs, *results;491 u32 *cs, *results;
491 492
492 sz = (2 * ARRAY_SIZE(values) + 1) * sizeof(u32);493 sz = (2 * ARRAY_SIZE(values) + 1) * sizeof(u32);
493 scratch = __vm_create_scratch_for_read(ce->vm, sz);494 scratch = __vm_create_scratch_for_read_pinned(ce->vm, sz);
494 if (IS_ERR(scratch))495 if (IS_ERR(scratch))
495 return PTR_ERR(scratch);496 return PTR_ERR(scratch);
496 497
@@ -502,6 +503,7 @@ static int check_dirty_whitelist(struct intel_context *ce) · 5 unmodified lines
502 503
503 for (i = 0; i < engine->whitelist.count; i++) {504 for (i = 0; i < engine->whitelist.count; i++) {
504 u32 reg = i915_mmio_reg_offset(engine->whitelist.list[i].reg);505 u32 reg = i915_mmio_reg_offset(engine->whitelist.list[i].reg);
506 struct i915_gem_ww_ctx ww;
505 u64 addr = scratch->node.start;507 u64 addr = scratch->node.start;
506 struct i915_request *rq;508 struct i915_request *rq;
507 u32 srm, lrm, rsvd;509 u32 srm, lrm, rsvd;
@@ -517,6 +519,29 @@ static int check_dirty_whitelist(struct intel_context *ce) · 9 unmodified lines
517 519
518 ro_reg = ro_register(reg);520 ro_reg = ro_register(reg);
519 521
522 i915_gem_ww_ctx_init(&ww, false);
523retry:
524 cs = NULL;
525 err = i915_gem_object_lock(scratch->obj, &ww);
526 if (!err)
527 err = i915_gem_object_lock(batch->obj, &ww);
528 if (!err)
529 err = intel_context_pin_ww(ce, &ww);
530 if (err)
531 goto out;
532
533 cs = i915_gem_object_pin_map(batch->obj, I915_MAP_WC);
534 if (IS_ERR(cs)) {
535 err = PTR_ERR(cs);
536 goto out_ctx;
537 }
538
539 results = i915_gem_object_pin_map(scratch->obj, I915_MAP_WB);
540 if (IS_ERR(results)) {
541 err = PTR_ERR(results);
542 goto out_unmap_batch;
543 }
544
520 /* Clear non priv flags */545 /* Clear non priv flags */
521 reg &= RING_FORCE_TO_NONPRIV_ADDRESS_MASK;546 reg &= RING_FORCE_TO_NONPRIV_ADDRESS_MASK;
522 547
@@ -528,12 +553,6 @@ static int check_dirty_whitelist(struct intel_context *ce) · 5 unmodified lines
528 pr_debug("%s: Writing garbage to %x\n",553 pr_debug("%s: Writing garbage to %x\n",
529 engine->name, reg);554 engine->name, reg);
530 555
531 cs = i915_gem_object_pin_map(batch->obj, I915_MAP_WC);
532 if (IS_ERR(cs)) {
533 err = PTR_ERR(cs);
534 goto out_batch;
535 }
536
537 /* SRM original */556 /* SRM original */
538 *cs++ = srm;557 *cs++ = srm;
539 *cs++ = reg;558 *cs++ = reg;
@@ -580,11 +599,12 @@ static int check_dirty_whitelist(struct intel_context *ce) · 40 unmodified lines
580 i915_gem_object_flush_map(batch->obj);599 i915_gem_object_flush_map(batch->obj);
581 i915_gem_object_unpin_map(batch->obj);600 i915_gem_object_unpin_map(batch->obj);
582 intel_gt_chipset_flush(engine->gt);601 intel_gt_chipset_flush(engine->gt);
602 cs = NULL;
583 603
584 rq = intel_context_create_request(ce);604 rq = i915_request_create(ce);
585 if (IS_ERR(rq)) {605 if (IS_ERR(rq)) {
586 err = PTR_ERR(rq);606 err = PTR_ERR(rq);
587 goto out_batch;607 goto out_unmap_scratch;
588 }608 }
589 609
590 if (engine->emit_init_breadcrumb) { /* Be nice if we hang */610 if (engine->emit_init_breadcrumb) { /* Be nice if we hang */
@@ -593,20 +613,16 @@ static int check_dirty_whitelist(struct intel_context *ce) · 2 unmodified lines
593 goto err_request;613 goto err_request;
594 }614 }
595 615
596 i915_vma_lock(batch);
597 err = i915_request_await_object(rq, batch->obj, false);616 err = i915_request_await_object(rq, batch->obj, false);
598 if (err == 0)617 if (err == 0)
599 err = i915_vma_move_to_active(batch, rq, 0);618 err = i915_vma_move_to_active(batch, rq, 0);
600 i915_vma_unlock(batch);
601 if (err)619 if (err)
602 goto err_request;620 goto err_request;
603 621
604 i915_vma_lock(scratch);
605 err = i915_request_await_object(rq, scratch->obj, true);622 err = i915_request_await_object(rq, scratch->obj, true);
606 if (err == 0)623 if (err == 0)
607 err = i915_vma_move_to_active(scratch, rq,624 err = i915_vma_move_to_active(scratch, rq,
608 EXEC_OBJECT_WRITE);625 EXEC_OBJECT_WRITE);
609 i915_vma_unlock(scratch);
610 if (err)626 if (err)
611 goto err_request;627 goto err_request;
612 628
@@ -622,13 +638,7 @@ err_request: · 9 unmodified lines
622 pr_err("%s: Futzing %x timedout; cancelling test\n",638 pr_err("%s: Futzing %x timedout; cancelling test\n",
623 engine->name, reg);639 engine->name, reg);
624 intel_gt_set_wedged(engine->gt);640 intel_gt_set_wedged(engine->gt);
625 goto out_batch;641 goto out_unmap_scratch;
626 }
627
628 results = i915_gem_object_pin_map(scratch->obj, I915_MAP_WB);
629 if (IS_ERR(results)) {
630 err = PTR_ERR(results);
631 goto out_batch;
632 }642 }
633 643
634 GEM_BUG_ON(values[ARRAY_SIZE(values) - 1] != 0xffffffff);644 GEM_BUG_ON(values[ARRAY_SIZE(values) - 1] != 0xffffffff);
@@ -639,7 +649,7 @@ err_request: · 4 unmodified lines
639 pr_err("%s: Unable to write to whitelisted register %x\n",649 pr_err("%s: Unable to write to whitelisted register %x\n",
640 engine->name, reg);650 engine->name, reg);
641 err = -EINVAL;651 err = -EINVAL;
642 goto out_unpin;652 goto out_unmap_scratch;
643 }653 }
644 } else {654 } else {
645 rsvd = 0;655 rsvd = 0;
@@ -705,15 +715,27 @@ err_request: · 59 unmodified lines
705 715
706 err = -EINVAL;716 err = -EINVAL;
707 }717 }
708out_unpin:718out_unmap_scratch:
709 i915_gem_object_unpin_map(scratch->obj);719 i915_gem_object_unpin_map(scratch->obj);
720out_unmap_batch:
721 if (cs)
722 i915_gem_object_unpin_map(batch->obj);
723out_ctx:
724 intel_context_unpin(ce);
725out:
726 if (err == -EDEADLK) {
727 err = i915_gem_ww_ctx_backoff(&ww);
728 if (!err)
729 goto retry;
730 }
731 i915_gem_ww_ctx_fini(&ww);
710 if (err)732 if (err)
711 break;733 break;
712 }734 }
713 735
714 if (igt_flush_test(engine->i915))736 if (igt_flush_test(engine->i915))
715 err = -EIO;737 err = -EIO;
716out_batch:738
717 i915_vma_unpin_and_release(&batch, 0);739 i915_vma_unpin_and_release(&batch, 0);
718out_scratch:740out_scratch:
719 i915_vma_unpin_and_release(&scratch, 0);741 i915_vma_unpin_and_release(&scratch, 0);
@@ -847,7 +869,7 @@ static int scrub_whitelisted_registers(struct intel_context *ce) · 127 unmodified lines
847 if (IS_ERR(batch))869 if (IS_ERR(batch))
848 return PTR_ERR(batch);870 return PTR_ERR(batch);
849 871
850 cs = i915_gem_object_pin_map(batch->obj, I915_MAP_WC);872 cs = i915_gem_object_pin_map_unlocked(batch->obj, I915_MAP_WC);
851 if (IS_ERR(cs)) {873 if (IS_ERR(cs)) {
852 err = PTR_ERR(cs);874 err = PTR_ERR(cs);
853 goto err_batch;875 goto err_batch;
@@ -982,11 +1004,11 @@ check_whitelisted_registers(struct intel_engine_cs *engine, · 128 unmodified lines
982 u32 *a, *b;1004 u32 *a, *b;
983 int i, err;1005 int i, err;
984 1006
985 a = i915_gem_object_pin_map(A->obj, I915_MAP_WB);1007 a = i915_gem_object_pin_map_unlocked(A->obj, I915_MAP_WB);
986 if (IS_ERR(a))1008 if (IS_ERR(a))
987 return PTR_ERR(a);1009 return PTR_ERR(a);
988 1010
989 b = i915_gem_object_pin_map(B->obj, I915_MAP_WB);1011 b = i915_gem_object_pin_map_unlocked(B->obj, I915_MAP_WB);
990 if (IS_ERR(b)) {1012 if (IS_ERR(b)) {
991 err = PTR_ERR(b);1013 err = PTR_ERR(b);
992 goto err_a;1014 goto err_a;
@@ -1030,14 +1052,14 @@ static int live_isolated_whitelist(void *arg) · 37 unmodified lines
1030 1052
1031 for (i = 0; i < ARRAY_SIZE(client); i++) {1053 for (i = 0; i < ARRAY_SIZE(client); i++) {
1032 client[i].scratch[0] =1054 client[i].scratch[0] =
1033 __vm_create_scratch_for_read(gt->vm, 4096);1055 __vm_create_scratch_for_read_pinned(gt->vm, 4096);
1034 if (IS_ERR(client[i].scratch[0])) {1056 if (IS_ERR(client[i].scratch[0])) {
1035 err = PTR_ERR(client[i].scratch[0]);1057 err = PTR_ERR(client[i].scratch[0]);
1036 goto err;1058 goto err;
1037 }1059 }
1038 1060
1039 client[i].scratch[1] =1061 client[i].scratch[1] =
1040 __vm_create_scratch_for_read(gt->vm, 4096);1062 __vm_create_scratch_for_read_pinned(gt->vm, 4096);
1041 if (IS_ERR(client[i].scratch[1])) {1063 if (IS_ERR(client[i].scratch[1])) {
1042 err = PTR_ERR(client[i].scratch[1]);1064 err = PTR_ERR(client[i].scratch[1]);
1043 i915_vma_unpin_and_release(&client[i].scratch[0], 0);1065 i915_vma_unpin_and_release(&client[i].scratch[0], 0);
drivers/gpu/drm/i915/gt/shmem_utils.c+1−1
@@ -39,7 +39,7 @@ struct file *shmem_create_from_object(struct drm_i915_gem_object *obj) · 38 unmodified lines
39 return file;39 return file;
40 }40 }
41 41
42 ptr = i915_gem_object_pin_map(obj, I915_MAP_WB);42 ptr = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WB);
43 if (IS_ERR(ptr))43 if (IS_ERR(ptr))
44 return ERR_CAST(ptr);44 return ERR_CAST(ptr);
45 45
drivers/gpu/drm/i915/gt/uc/intel_guc.c+1−1
@@ -682,7 +682,7 @@ int intel_guc_allocate_and_map_vma(struct intel_guc *guc, u32 size, · 681 unmodified lines
682 if (IS_ERR(vma))682 if (IS_ERR(vma))
683 return PTR_ERR(vma);683 return PTR_ERR(vma);
684 684
685 vaddr = i915_gem_object_pin_map(vma->obj, I915_MAP_WB);685 vaddr = i915_gem_object_pin_map_unlocked(vma->obj, I915_MAP_WB);
686 if (IS_ERR(vaddr)) {686 if (IS_ERR(vaddr)) {
687 i915_vma_unpin_and_release(&vma, 0);687 i915_vma_unpin_and_release(&vma, 0);
688 return PTR_ERR(vaddr);688 return PTR_ERR(vaddr);
drivers/gpu/drm/i915/gt/uc/intel_guc_log.c+2−2
@@ -335,7 +335,7 @@ static int guc_log_map(struct intel_guc_log *log) · 334 unmodified lines
335 * buffer pages, so that we can directly get the data335 * buffer pages, so that we can directly get the data
336 * (up-to-date) from memory.336 * (up-to-date) from memory.
337 */337 */
338 vaddr = i915_gem_object_pin_map(log->vma->obj, I915_MAP_WC);338 vaddr = i915_gem_object_pin_map_unlocked(log->vma->obj, I915_MAP_WC);
339 if (IS_ERR(vaddr))339 if (IS_ERR(vaddr))
340 return PTR_ERR(vaddr);340 return PTR_ERR(vaddr);
341 341
@@ -744,7 +744,7 @@ int intel_guc_log_dump(struct intel_guc_log *log, struct drm_printer *p, · 402 unmodified lines
744 if (!obj)744 if (!obj)
745 return 0;745 return 0;
746 746
747 map = i915_gem_object_pin_map(obj, I915_MAP_WC);747 map = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WC);
748 if (IS_ERR(map)) {748 if (IS_ERR(map)) {
749 DRM_DEBUG("Failed to pin object\n");749 DRM_DEBUG("Failed to pin object\n");
750 drm_puts(p, "(log data unaccessible)\n");750 drm_puts(p, "(log data unaccessible)\n");
drivers/gpu/drm/i915/gt/uc/intel_huc.c+1−1
@@ -82,7 +82,7 @@ static int intel_huc_rsa_data_create(struct intel_huc *huc) · 81 unmodified lines
82 if (IS_ERR(vma))82 if (IS_ERR(vma))
83 return PTR_ERR(vma);83 return PTR_ERR(vma);
84 84
85 vaddr = i915_gem_object_pin_map(vma->obj, I915_MAP_WB);85 vaddr = i915_gem_object_pin_map_unlocked(vma->obj, I915_MAP_WB);
86 if (IS_ERR(vaddr)) {86 if (IS_ERR(vaddr)) {
87 i915_vma_unpin_and_release(&vma, 0);87 i915_vma_unpin_and_release(&vma, 0);
88 return PTR_ERR(vaddr);88 return PTR_ERR(vaddr);
drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c+1−1
@@ -539,7 +539,7 @@ int intel_uc_fw_init(struct intel_uc_fw *uc_fw) · 538 unmodified lines
539 if (!intel_uc_fw_is_available(uc_fw))539 if (!intel_uc_fw_is_available(uc_fw))
540 return -ENOEXEC;540 return -ENOEXEC;
541 541
542 err = i915_gem_object_pin_pages(uc_fw->obj);542 err = i915_gem_object_pin_pages_unlocked(uc_fw->obj);
543 if (err) {543 if (err) {
544 DRM_DEBUG_DRIVER("%s fw pin-pages err=%d\n",544 DRM_DEBUG_DRIVER("%s fw pin-pages err=%d\n",
545 intel_uc_fw_type_repr(uc_fw->type), err);545 intel_uc_fw_type_repr(uc_fw->type), err);
drivers/gpu/drm/i915/gvt/dmabuf.c+1−1
@@ -218,7 +218,7 @@ static struct drm_i915_gem_object *vgpu_create_gem(struct drm_device *dev, · 217 unmodified lines
218 218
219 drm_gem_private_object_init(dev, &obj->base,219 drm_gem_private_object_init(dev, &obj->base,
220 roundup(info->size, PAGE_SIZE));220 roundup(info->size, PAGE_SIZE));
221 i915_gem_object_init(obj, &intel_vgpu_gem_ops, &lock_class);221 i915_gem_object_init(obj, &intel_vgpu_gem_ops, &lock_class, 0);
222 i915_gem_object_set_readonly(obj);222 i915_gem_object_set_readonly(obj);
223 223
224 obj->read_domains = I915_GEM_DOMAIN_GTT;224 obj->read_domains = I915_GEM_DOMAIN_GTT;
drivers/gpu/drm/i915/i915_active.c+10−10
@@ -293,18 +293,13 @@ static struct active_node *__active_lookup(struct i915_active *ref, u64 idx) · 292 unmodified lines
293static struct i915_active_fence *293static struct i915_active_fence *
294active_instance(struct i915_active *ref, u64 idx)294active_instance(struct i915_active *ref, u64 idx)
295{295{
296 struct active_node *node, *prealloc;296 struct active_node *node;
297 struct rb_node **p, *parent;297 struct rb_node **p, *parent;
298 298
299 node = __active_lookup(ref, idx);299 node = __active_lookup(ref, idx);
300 if (likely(node))300 if (likely(node))
301 return &node->base;301 return &node->base;
302 302
303 /* Preallocate a replacement, just in case */
304 prealloc = kmem_cache_alloc(global.slab_cache, GFP_KERNEL);
305 if (!prealloc)
306 return NULL;
307
308 spin_lock_irq(&ref->tree_lock);303 spin_lock_irq(&ref->tree_lock);
309 GEM_BUG_ON(i915_active_is_idle(ref));304 GEM_BUG_ON(i915_active_is_idle(ref));
310 305
@@ -314,10 +309,8 @@ active_instance(struct i915_active *ref, u64 idx) · 3 unmodified lines
314 parent = *p;309 parent = *p;
315 310
316 node = rb_entry(parent, struct active_node, node);311 node = rb_entry(parent, struct active_node, node);
317 if (node->timeline == idx) {312 if (node->timeline == idx)
318 kmem_cache_free(global.slab_cache, prealloc);
319 goto out;313 goto out;
320 }
321 314
322 if (node->timeline < idx)315 if (node->timeline < idx)
323 p = &parent->rb_right;316 p = &parent->rb_right;
@@ -325,7 +318,14 @@ active_instance(struct i915_active *ref, u64 idx) · 1 unmodified line
325 p = &parent->rb_left;318 p = &parent->rb_left;
326 }319 }
327 320
328 node = prealloc;321 /*
322 * XXX: We should preallocate this before i915_active_ref() is ever
323 * called, but we cannot call into fs_reclaim() anyway, so use GFP_ATOMIC.
324 */
325 node = kmem_cache_alloc(global.slab_cache, GFP_ATOMIC);
326 if (!node)
327 goto out;
328
329 __i915_active_fence_init(&node->base, NULL, node_retire);329 __i915_active_fence_init(&node->base, NULL, node_retire);
330 node->ref = ref;330 node->ref = ref;
331 node->timeline = idx;331 node->timeline = idx;
drivers/gpu/drm/i915/i915_cmd_parser.c+43−61
@@ -1144,38 +1144,20 @@ find_reg(const struct intel_engine_cs *engine, u32 addr) · 1143 unmodified lines
1144/* Returns a vmap'd pointer to dst_obj, which the caller must unmap */1144/* Returns a vmap'd pointer to dst_obj, which the caller must unmap */
1145static u32 *copy_batch(struct drm_i915_gem_object *dst_obj,1145static u32 *copy_batch(struct drm_i915_gem_object *dst_obj,
1146 struct drm_i915_gem_object *src_obj,1146 struct drm_i915_gem_object *src_obj,
1147 unsigned long offset, unsigned long length)1147 unsigned long offset, unsigned long length,
1148 void *dst, const void *src)
1148{1149{
1149 bool needs_clflush;1150 bool needs_clflush =
1150 void *dst, *src;
1151 int ret;
1152
1153 dst = i915_gem_object_pin_map(dst_obj, I915_MAP_WB);
1154 if (IS_ERR(dst))
1155 return dst;
1156
1157 ret = i915_gem_object_pin_pages(src_obj);
1158 if (ret) {
1159 i915_gem_object_unpin_map(dst_obj);
1160 return ERR_PTR(ret);
1161 }
1162
1163 needs_clflush =
1164 !(src_obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_READ);1151 !(src_obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_READ);
1165 1152
1166 src = ERR_PTR(-ENODEV);1153 if (src) {
1167 if (needs_clflush && i915_has_memcpy_from_wc()) {1154 GEM_BUG_ON(!needs_clflush);
1168 src = i915_gem_object_pin_map(src_obj, I915_MAP_WC);1155 i915_unaligned_memcpy_from_wc(dst, src + offset, length);
1169 if (!IS_ERR(src)) {1156 } else {
1170 i915_unaligned_memcpy_from_wc(dst,1157 struct scatterlist *sg;
1171 src + offset,
1172 length);
1173 i915_gem_object_unpin_map(src_obj);
1174 }
1175 }
1176 if (IS_ERR(src)) {
1177 unsigned long x, n, remain;
1178 void *ptr;1158 void *ptr;
1159 unsigned int x, sg_ofs;
1160 unsigned long remain;
1179 1161
1180 /*1162 /*
1181 * We can avoid clflushing partial cachelines before the write1163 * We can avoid clflushing partial cachelines before the write
@@ -1192,23 +1174,31 @@ static u32 *copy_batch(struct drm_i915_gem_object *dst_obj, · 10 unmodified lines
1192 1174
1193 ptr = dst;1175 ptr = dst;
1194 x = offset_in_page(offset);1176 x = offset_in_page(offset);
1195 for (n = offset >> PAGE_SHIFT; remain; n++) {1177 sg = i915_gem_object_get_sg(src_obj, offset >> PAGE_SHIFT, &sg_ofs, false);
1196 int len = min(remain, PAGE_SIZE - x);1178
1197 1179 while (remain) {
1198 src = kmap_atomic(i915_gem_object_get_page(src_obj, n));1180 unsigned long sg_max = sg->length >> PAGE_SHIFT;
1199 if (needs_clflush)1181
1200 drm_clflush_virt_range(src + x, len);1182 for (; remain && sg_ofs < sg_max; sg_ofs++) {
1201 memcpy(ptr, src + x, len);1183 unsigned long len = min(remain, PAGE_SIZE - x);
1202 kunmap_atomic(src);1184 void *map;
1203 1185
1204 ptr += len;1186 map = kmap_atomic(nth_page(sg_page(sg), sg_ofs));
1205 remain -= len;1187 if (needs_clflush)
1206 x = 0;1188 drm_clflush_virt_range(map + x, len);
1189 memcpy(ptr, map + x, len);
1190 kunmap_atomic(map);
1191
1192 ptr += len;
1193 remain -= len;
1194 x = 0;
1195 }
1196
1197 sg_ofs = 0;
1198 sg = sg_next(sg);
1207 }1199 }
1208 }1200 }
1209 1201
1210 i915_gem_object_unpin_pages(src_obj);
1211
1212 memset32(dst + length, 0, (dst_obj->base.size - length) / sizeof(u32));1202 memset32(dst + length, 0, (dst_obj->base.size - length) / sizeof(u32));
1213 1203
1214 /* dst_obj is returned with vmap pinned */1204 /* dst_obj is returned with vmap pinned */
@@ -1370,9 +1360,6 @@ static int check_bbstart(u32 *cmd, u32 offset, u32 length, · 155 unmodified lines
1370 if (target_cmd_index == offset)1360 if (target_cmd_index == offset)
1371 return 0;1361 return 0;
1372 1362
1373 if (IS_ERR(jump_whitelist))
1374 return PTR_ERR(jump_whitelist);
1375
1376 if (!test_bit(target_cmd_index, jump_whitelist)) {1363 if (!test_bit(target_cmd_index, jump_whitelist)) {
1377 DRM_DEBUG("CMD: BB_START to 0x%llx not a previously executed cmd\n",1364 DRM_DEBUG("CMD: BB_START to 0x%llx not a previously executed cmd\n",
1378 jump_target);1365 jump_target);
@@ -1382,10 +1369,14 @@ static int check_bbstart(u32 *cmd, u32 offset, u32 length, · 3 unmodified lines
1382 return 0;1369 return 0;
1383}1370}
1384 1371
1385static unsigned long *alloc_whitelist(u32 batch_length)1372unsigned long *intel_engine_cmd_parser_alloc_jump_whitelist(u32 batch_length,
1373 bool trampoline)
1386{1374{
1387 unsigned long *jmp;1375 unsigned long *jmp;
1388 1376
1377 if (trampoline)
1378 return NULL;
1379
1389 /*1380 /*
1390 * We expect batch_length to be less than 256KiB for known users,1381 * We expect batch_length to be less than 256KiB for known users,
1391 * i.e. we need at most an 8KiB bitmap allocation which should be1382 * i.e. we need at most an 8KiB bitmap allocation which should be
@@ -1423,14 +1414,16 @@ int intel_engine_cmd_parser(struct intel_engine_cs *engine, · 31 unmodified lines
1423 unsigned long batch_offset,1414 unsigned long batch_offset,
1424 unsigned long batch_length,1415 unsigned long batch_length,
1425 struct i915_vma *shadow,1416 struct i915_vma *shadow,
1426 bool trampoline)1417 unsigned long *jump_whitelist,
1418 void *shadow_map,
1419 const void *batch_map)
1427{1420{
1428 u32 *cmd, *batch_end, offset = 0;1421 u32 *cmd, *batch_end, offset = 0;
1429 struct drm_i915_cmd_descriptor default_desc = noop_desc;1422 struct drm_i915_cmd_descriptor default_desc = noop_desc;
1430 const struct drm_i915_cmd_descriptor *desc = &default_desc;1423 const struct drm_i915_cmd_descriptor *desc = &default_desc;
1431 unsigned long *jump_whitelist;
1432 u64 batch_addr, shadow_addr;1424 u64 batch_addr, shadow_addr;
1433 int ret = 0;1425 int ret = 0;
1426 bool trampoline = !jump_whitelist;
1434 1427
1435 GEM_BUG_ON(!IS_ALIGNED(batch_offset, sizeof(*cmd)));1428 GEM_BUG_ON(!IS_ALIGNED(batch_offset, sizeof(*cmd)));
1436 GEM_BUG_ON(!IS_ALIGNED(batch_length, sizeof(*cmd)));1429 GEM_BUG_ON(!IS_ALIGNED(batch_length, sizeof(*cmd)));
@@ -1438,16 +1431,8 @@ int intel_engine_cmd_parser(struct intel_engine_cs *engine, · 1 unmodified line
1438 batch->size));1431 batch->size));
1439 GEM_BUG_ON(!batch_length);1432 GEM_BUG_ON(!batch_length);
1440 1433
1441 cmd = copy_batch(shadow->obj, batch->obj, batch_offset, batch_length);1434 cmd = copy_batch(shadow->obj, batch->obj, batch_offset, batch_length,
1442 if (IS_ERR(cmd)) {1435 shadow_map, batch_map);
1443 DRM_DEBUG("CMD: Failed to copy batch\n");
1444 return PTR_ERR(cmd);
1445 }
1446
1447 jump_whitelist = NULL;
1448 if (!trampoline)
1449 /* Defer failure until attempted use */
1450 jump_whitelist = alloc_whitelist(batch_length);
1451 1436
1452 shadow_addr = gen8_canonical_addr(shadow->node.start);1437 shadow_addr = gen8_canonical_addr(shadow->node.start);
1453 batch_addr = gen8_canonical_addr(batch->node.start + batch_offset);1438 batch_addr = gen8_canonical_addr(batch->node.start + batch_offset);
@@ -1548,9 +1533,6 @@ int intel_engine_cmd_parser(struct intel_engine_cs *engine, · 94 unmodified lines
1548 1533
1549 i915_gem_object_flush_map(shadow->obj);1534 i915_gem_object_flush_map(shadow->obj);
1550 1535
1551 if (!IS_ERR_OR_NULL(jump_whitelist))
1552 kfree(jump_whitelist);
1553 i915_gem_object_unpin_map(shadow->obj);
1554 return ret;1536 return ret;
1555}1537}
1556 1538
drivers/gpu/drm/i915/i915_debugfs.c+2−2
@@ -904,10 +904,10 @@ i915_drop_caches_set(void *data, u64 val) · 903 unmodified lines
904 904
905 fs_reclaim_acquire(GFP_KERNEL);905 fs_reclaim_acquire(GFP_KERNEL);
906 if (val & DROP_BOUND)906 if (val & DROP_BOUND)
907 i915_gem_shrink(i915, LONG_MAX, NULL, I915_SHRINK_BOUND);907 i915_gem_shrink(NULL, i915, LONG_MAX, NULL, I915_SHRINK_BOUND);
908 908
909 if (val & DROP_UNBOUND)909 if (val & DROP_UNBOUND)
910 i915_gem_shrink(i915, LONG_MAX, NULL, I915_SHRINK_UNBOUND);910 i915_gem_shrink(NULL, i915, LONG_MAX, NULL, I915_SHRINK_UNBOUND);
911 911
912 if (val & DROP_SHRINK_ALL)912 if (val & DROP_SHRINK_ALL)
913 i915_gem_shrink_all(i915);913 i915_gem_shrink_all(i915);
drivers/gpu/drm/i915/i915_drv.c+1−1
@@ -1691,7 +1691,7 @@ static const struct drm_ioctl_desc i915_ioctls[] = { · 1690 unmodified lines
1691 DRM_IOCTL_DEF_DRV(I915_VBLANK_SWAP, drm_noop, DRM_AUTH),1691 DRM_IOCTL_DEF_DRV(I915_VBLANK_SWAP, drm_noop, DRM_AUTH),
1692 DRM_IOCTL_DEF_DRV(I915_HWS_ADDR, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),1692 DRM_IOCTL_DEF_DRV(I915_HWS_ADDR, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
1693 DRM_IOCTL_DEF_DRV(I915_GEM_INIT, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),1693 DRM_IOCTL_DEF_DRV(I915_GEM_INIT, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
1694 DRM_IOCTL_DEF_DRV(I915_GEM_EXECBUFFER, i915_gem_execbuffer_ioctl, DRM_AUTH),1694 DRM_IOCTL_DEF_DRV(I915_GEM_EXECBUFFER, drm_invalid_op, DRM_AUTH),
1695 DRM_IOCTL_DEF_DRV(I915_GEM_EXECBUFFER2_WR, i915_gem_execbuffer2_ioctl, DRM_RENDER_ALLOW),1695 DRM_IOCTL_DEF_DRV(I915_GEM_EXECBUFFER2_WR, i915_gem_execbuffer2_ioctl, DRM_RENDER_ALLOW),
1696 DRM_IOCTL_DEF_DRV(I915_GEM_PIN, i915_gem_reject_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY),1696 DRM_IOCTL_DEF_DRV(I915_GEM_PIN, i915_gem_reject_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY),
1697 DRM_IOCTL_DEF_DRV(I915_GEM_UNPIN, i915_gem_reject_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY),1697 DRM_IOCTL_DEF_DRV(I915_GEM_UNPIN, i915_gem_reject_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY),
drivers/gpu/drm/i915/i915_drv.h+11−7
@@ -554,12 +554,13 @@ struct i915_gem_mm { · 553 unmodified lines
554 struct notifier_block vmap_notifier;554 struct notifier_block vmap_notifier;
555 struct shrinker shrinker;555 struct shrinker shrinker;
556 556
557#ifdef CONFIG_MMU_NOTIFIER
557 /**558 /**
558 * Workqueue to fault in userptr pages, flushed by the execbuf559 * notifier_lock for mmu notifiers, memory may not be allocated
559 * when required but otherwise left to userspace to try again560 * while holding this lock.
560 * on EAGAIN.
561 */561 */
562 struct workqueue_struct *userptr_wq;562 spinlock_t notifier_lock;
563#endif
563 564
564 /* shrinker accounting, also useful for userland debugging */565 /* shrinker accounting, also useful for userland debugging */
565 u64 shrink_memory;566 u64 shrink_memory;
@@ -938,8 +939,6 @@ struct drm_i915_private { · 372 unmodified lines
938 struct i915_ggtt ggtt; /* VM representing the global address space */939 struct i915_ggtt ggtt; /* VM representing the global address space */
939 940
940 struct i915_gem_mm mm;941 struct i915_gem_mm mm;
941 DECLARE_HASHTABLE(mm_structs, 7);
942 spinlock_t mm_lock;
943 942
944 /* Kernel Modesetting */943 /* Kernel Modesetting */
945 944
@@ -1946,12 +1945,17 @@ const char *i915_cache_level_str(struct drm_i915_private *i915, int type); · 1000 unmodified lines
1946int i915_cmd_parser_get_version(struct drm_i915_private *dev_priv);1945int i915_cmd_parser_get_version(struct drm_i915_private *dev_priv);
1947int intel_engine_init_cmd_parser(struct intel_engine_cs *engine);1946int intel_engine_init_cmd_parser(struct intel_engine_cs *engine);
1948void intel_engine_cleanup_cmd_parser(struct intel_engine_cs *engine);1947void intel_engine_cleanup_cmd_parser(struct intel_engine_cs *engine);
1948unsigned long *intel_engine_cmd_parser_alloc_jump_whitelist(u32 batch_length,
1949 bool trampoline);
1950
1949int intel_engine_cmd_parser(struct intel_engine_cs *engine,1951int intel_engine_cmd_parser(struct intel_engine_cs *engine,
1950 struct i915_vma *batch,1952 struct i915_vma *batch,
1951 unsigned long batch_offset,1953 unsigned long batch_offset,
1952 unsigned long batch_length,1954 unsigned long batch_length,
1953 struct i915_vma *shadow,1955 struct i915_vma *shadow,
1954 bool trampoline);1956 unsigned long *jump_whitelist,
1957 void *shadow_map,
1958 const void *batch_map);
1955#define I915_CMD_PARSER_TRAMPOLINE_SIZE 81959#define I915_CMD_PARSER_TRAMPOLINE_SIZE 8
1956 1960
1957/* intel_device_info.c */1961/* intel_device_info.c */
drivers/gpu/drm/i915/i915_gem.c+141−117
@@ -204,7 +204,6 @@ i915_gem_shmem_pread(struct drm_i915_gem_object *obj, · 203 unmodified lines
204{204{
205 unsigned int needs_clflush;205 unsigned int needs_clflush;
206 unsigned int idx, offset;206 unsigned int idx, offset;
207 struct dma_fence *fence;
208 char __user *user_data;207 char __user *user_data;
209 u64 remain;208 u64 remain;
210 int ret;209 int ret;
@@ -213,19 +212,17 @@ i915_gem_shmem_pread(struct drm_i915_gem_object *obj, · 2 unmodified lines
213 if (ret)212 if (ret)
214 return ret;213 return ret;
215 214
215 ret = i915_gem_object_pin_pages(obj);
216 if (ret)
217 goto err_unlock;
218
216 ret = i915_gem_object_prepare_read(obj, &needs_clflush);219 ret = i915_gem_object_prepare_read(obj, &needs_clflush);
217 if (ret) {220 if (ret)
218 i915_gem_object_unlock(obj);221 goto err_unpin;
219 return ret;
220 }
221 222
222 fence = i915_gem_object_lock_fence(obj);
223 i915_gem_object_finish_access(obj);223 i915_gem_object_finish_access(obj);
224 i915_gem_object_unlock(obj);224 i915_gem_object_unlock(obj);
225 225
226 if (!fence)
227 return -ENOMEM;
228
229 remain = args->size;226 remain = args->size;
230 user_data = u64_to_user_ptr(args->data_ptr);227 user_data = u64_to_user_ptr(args->data_ptr);
231 offset = offset_in_page(args->offset);228 offset = offset_in_page(args->offset);
@@ -243,7 +240,13 @@ i915_gem_shmem_pread(struct drm_i915_gem_object *obj, · 11 unmodified lines
243 offset = 0;240 offset = 0;
244 }241 }
245 242
246 i915_gem_object_unlock_fence(obj, fence);243 i915_gem_object_unpin_pages(obj);
244 return ret;
245
246err_unpin:
247 i915_gem_object_unpin_pages(obj);
248err_unlock:
249 i915_gem_object_unlock(obj);
247 return ret;250 return ret;
248}251}
249 252
@@ -271,52 +274,102 @@ gtt_user_read(struct io_mapping *mapping, · 21 unmodified lines
271 return unwritten;274 return unwritten;
272}275}
273 276
274static int277static struct i915_vma *i915_gem_gtt_prepare(struct drm_i915_gem_object *obj,
275i915_gem_gtt_pread(struct drm_i915_gem_object *obj,278 struct drm_mm_node *node,
276 const struct drm_i915_gem_pread *args)279 bool write)
277{280{
278 struct drm_i915_private *i915 = to_i915(obj->base.dev);281 struct drm_i915_private *i915 = to_i915(obj->base.dev);
279 struct i915_ggtt *ggtt = &i915->ggtt;282 struct i915_ggtt *ggtt = &i915->ggtt;
280 intel_wakeref_t wakeref;
281 struct drm_mm_node node;
282 struct dma_fence *fence;
283 void __user *user_data;
284 struct i915_vma *vma;283 struct i915_vma *vma;
285 u64 remain, offset;284 struct i915_gem_ww_ctx ww;
286 int ret;285 int ret;
287 286
288 wakeref = intel_runtime_pm_get(&i915->runtime_pm);287 i915_gem_ww_ctx_init(&ww, true);
288retry:
289 vma = ERR_PTR(-ENODEV);289 vma = ERR_PTR(-ENODEV);
290 ret = i915_gem_object_lock(obj, &ww);
291 if (ret)
292 goto err_ww;
293
294 ret = i915_gem_object_set_to_gtt_domain(obj, write);
295 if (ret)
296 goto err_ww;
297
290 if (!i915_gem_object_is_tiled(obj))298 if (!i915_gem_object_is_tiled(obj))
291 vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0,299 vma = i915_gem_object_ggtt_pin_ww(obj, &ww, NULL, 0, 0,
292 PIN_MAPPABLE |300 PIN_MAPPABLE |
293 PIN_NONBLOCK /* NOWARN */ |301 PIN_NONBLOCK /* NOWARN */ |
294 PIN_NOEVICT);302 PIN_NOEVICT);
295 if (!IS_ERR(vma)) {303 if (vma == ERR_PTR(-EDEADLK)) {
296 node.start = i915_ggtt_offset(vma);304 ret = -EDEADLK;
297 node.flags = 0;305 goto err_ww;
306 } else if (!IS_ERR(vma)) {
307 node->start = i915_ggtt_offset(vma);
308 node->flags = 0;
298 } else {309 } else {
299 ret = insert_mappable_node(ggtt, &node, PAGE_SIZE);310 ret = insert_mappable_node(ggtt, node, PAGE_SIZE);
300 if (ret)311 if (ret)
301 goto out_rpm;312 goto err_ww;
302 GEM_BUG_ON(!drm_mm_node_allocated(&node));313 GEM_BUG_ON(!drm_mm_node_allocated(node));
314 vma = NULL;
303 }315 }
304 316
305 ret = i915_gem_object_lock_interruptible(obj, NULL);317 ret = i915_gem_object_pin_pages(obj);
306 if (ret)
307 goto out_unpin;
308
309 ret = i915_gem_object_set_to_gtt_domain(obj, false);
310 if (ret) {318 if (ret) {
311 i915_gem_object_unlock(obj);319 if (drm_mm_node_allocated(node)) {
312 goto out_unpin;320 ggtt->vm.clear_range(&ggtt->vm, node->start, node->size);
321 remove_mappable_node(ggtt, node);
322 } else {
323 i915_vma_unpin(vma);
324 }
313 }325 }
314 326
315 fence = i915_gem_object_lock_fence(obj);327err_ww:
316 i915_gem_object_unlock(obj);328 if (ret == -EDEADLK) {
317 if (!fence) {329 ret = i915_gem_ww_ctx_backoff(&ww);
318 ret = -ENOMEM;330 if (!ret)
319 goto out_unpin;331 goto retry;
332 }
333 i915_gem_ww_ctx_fini(&ww);
334
335 return ret ? ERR_PTR(ret) : vma;
336}
337
338static void i915_gem_gtt_cleanup(struct drm_i915_gem_object *obj,
339 struct drm_mm_node *node,
340 struct i915_vma *vma)
341{
342 struct drm_i915_private *i915 = to_i915(obj->base.dev);
343 struct i915_ggtt *ggtt = &i915->ggtt;
344
345 i915_gem_object_unpin_pages(obj);
346 if (drm_mm_node_allocated(node)) {
347 ggtt->vm.clear_range(&ggtt->vm, node->start, node->size);
348 remove_mappable_node(ggtt, node);
349 } else {
350 i915_vma_unpin(vma);
351 }
352}
353
354static int
355i915_gem_gtt_pread(struct drm_i915_gem_object *obj,
356 const struct drm_i915_gem_pread *args)
357{
358 struct drm_i915_private *i915 = to_i915(obj->base.dev);
359 struct i915_ggtt *ggtt = &i915->ggtt;
360 intel_wakeref_t wakeref;
361 struct drm_mm_node node;
362 void __user *user_data;
363 struct i915_vma *vma;
364 u64 remain, offset;
365 int ret = 0;
366
367 wakeref = intel_runtime_pm_get(&i915->runtime_pm);
368
369 vma = i915_gem_gtt_prepare(obj, &node, false);
370 if (IS_ERR(vma)) {
371 ret = PTR_ERR(vma);
372 goto out_rpm;
320 }373 }
321 374
322 user_data = u64_to_user_ptr(args->data_ptr);375 user_data = u64_to_user_ptr(args->data_ptr);
@@ -353,14 +406,7 @@ i915_gem_gtt_pread(struct drm_i915_gem_object *obj, · 30 unmodified lines
353 offset += page_length;406 offset += page_length;
354 }407 }
355 408
356 i915_gem_object_unlock_fence(obj, fence);409 i915_gem_gtt_cleanup(obj, &node, vma);
357out_unpin:
358 if (drm_mm_node_allocated(&node)) {
359 ggtt->vm.clear_range(&ggtt->vm, node.start, node.size);
360 remove_mappable_node(ggtt, &node);
361 } else {
362 i915_vma_unpin(vma);
363 }
364out_rpm:410out_rpm:
365 intel_runtime_pm_put(&i915->runtime_pm, wakeref);411 intel_runtime_pm_put(&i915->runtime_pm, wakeref);
366 return ret;412 return ret;
@@ -378,10 +424,17 @@ int · 11 unmodified lines
378i915_gem_pread_ioctl(struct drm_device *dev, void *data,424i915_gem_pread_ioctl(struct drm_device *dev, void *data,
379 struct drm_file *file)425 struct drm_file *file)
380{426{
427 struct drm_i915_private *i915 = to_i915(dev);
381 struct drm_i915_gem_pread *args = data;428 struct drm_i915_gem_pread *args = data;
382 struct drm_i915_gem_object *obj;429 struct drm_i915_gem_object *obj;
383 int ret;430 int ret;
384 431
432 /* PREAD is disallowed for all platforms after TGL-LP. This also
433 * covers all platforms with local memory.
434 */
435 if (INTEL_GEN(i915) >= 12 && !IS_TIGERLAKE(i915))
436 return -EOPNOTSUPP;
437
385 if (args->size == 0)438 if (args->size == 0)
386 return 0;439 return 0;
387 440
@@ -400,6 +453,11 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data, · 12 unmodified lines
400 }453 }
401 454
402 trace_i915_gem_object_pread(obj, args->offset, args->size);455 trace_i915_gem_object_pread(obj, args->offset, args->size);
456 ret = -ENODEV;
457 if (obj->ops->pread)
458 ret = obj->ops->pread(obj, args);
459 if (ret != -ENODEV)
460 goto out;
403 461
404 ret = -ENODEV;462 ret = -ENODEV;
405 if (obj->ops->pread)463 if (obj->ops->pread)
@@ -413,15 +471,10 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data, · 7 unmodified lines
413 if (ret)471 if (ret)
414 goto out;472 goto out;
415 473
416 ret = i915_gem_object_pin_pages(obj);
417 if (ret)
418 goto out;
419
420 ret = i915_gem_shmem_pread(obj, args);474 ret = i915_gem_shmem_pread(obj, args);
421 if (ret == -EFAULT || ret == -ENODEV)475 if (ret == -EFAULT || ret == -ENODEV)
422 ret = i915_gem_gtt_pread(obj, args);476 ret = i915_gem_gtt_pread(obj, args);
423 477
424 i915_gem_object_unpin_pages(obj);
425out:478out:
426 i915_gem_object_put(obj);479 i915_gem_object_put(obj);
427 return ret;480 return ret;
@@ -469,11 +522,10 @@ i915_gem_gtt_pwrite_fast(struct drm_i915_gem_object *obj, · 41 unmodified lines
469 struct intel_runtime_pm *rpm = &i915->runtime_pm;522 struct intel_runtime_pm *rpm = &i915->runtime_pm;
470 intel_wakeref_t wakeref;523 intel_wakeref_t wakeref;
471 struct drm_mm_node node;524 struct drm_mm_node node;
472 struct dma_fence *fence;
473 struct i915_vma *vma;525 struct i915_vma *vma;
474 u64 remain, offset;526 u64 remain, offset;
475 void __user *user_data;527 void __user *user_data;
476 int ret;528 int ret = 0;
477 529
478 if (i915_gem_object_has_struct_page(obj)) {530 if (i915_gem_object_has_struct_page(obj)) {
479 /*531 /*
@@ -491,37 +543,10 @@ i915_gem_gtt_pwrite_fast(struct drm_i915_gem_object *obj, · 11 unmodified lines
491 wakeref = intel_runtime_pm_get(rpm);543 wakeref = intel_runtime_pm_get(rpm);
492 }544 }
493 545
494 vma = ERR_PTR(-ENODEV);546 vma = i915_gem_gtt_prepare(obj, &node, true);
495 if (!i915_gem_object_is_tiled(obj))547 if (IS_ERR(vma)) {
496 vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0,548 ret = PTR_ERR(vma);
497 PIN_MAPPABLE |549 goto out_rpm;
498 PIN_NONBLOCK /* NOWARN */ |
499 PIN_NOEVICT);
500 if (!IS_ERR(vma)) {
501 node.start = i915_ggtt_offset(vma);
502 node.flags = 0;
503 } else {
504 ret = insert_mappable_node(ggtt, &node, PAGE_SIZE);
505 if (ret)
506 goto out_rpm;
507 GEM_BUG_ON(!drm_mm_node_allocated(&node));
508 }
509
510 ret = i915_gem_object_lock_interruptible(obj, NULL);
511 if (ret)
512 goto out_unpin;
513
514 ret = i915_gem_object_set_to_gtt_domain(obj, true);
515 if (ret) {
516 i915_gem_object_unlock(obj);
517 goto out_unpin;
518 }
519
520 fence = i915_gem_object_lock_fence(obj);
521 i915_gem_object_unlock(obj);
522 if (!fence) {
523 ret = -ENOMEM;
524 goto out_unpin;
525 }550 }
526 551
527 i915_gem_object_invalidate_frontbuffer(obj, ORIGIN_CPU);552 i915_gem_object_invalidate_frontbuffer(obj, ORIGIN_CPU);
@@ -570,14 +595,7 @@ i915_gem_gtt_pwrite_fast(struct drm_i915_gem_object *obj, · 42 unmodified lines
570 intel_gt_flush_ggtt_writes(ggtt->vm.gt);595 intel_gt_flush_ggtt_writes(ggtt->vm.gt);
571 i915_gem_object_flush_frontbuffer(obj, ORIGIN_CPU);596 i915_gem_object_flush_frontbuffer(obj, ORIGIN_CPU);
572 597
573 i915_gem_object_unlock_fence(obj, fence);598 i915_gem_gtt_cleanup(obj, &node, vma);
574out_unpin:
575 if (drm_mm_node_allocated(&node)) {
576 ggtt->vm.clear_range(&ggtt->vm, node.start, node.size);
577 remove_mappable_node(ggtt, &node);
578 } else {
579 i915_vma_unpin(vma);
580 }
581out_rpm:599out_rpm:
582 intel_runtime_pm_put(rpm, wakeref);600 intel_runtime_pm_put(rpm, wakeref);
583 return ret;601 return ret;
@@ -617,7 +635,6 @@ i915_gem_shmem_pwrite(struct drm_i915_gem_object *obj, · 33 unmodified lines
617 unsigned int partial_cacheline_write;635 unsigned int partial_cacheline_write;
618 unsigned int needs_clflush;636 unsigned int needs_clflush;
619 unsigned int offset, idx;637 unsigned int offset, idx;
620 struct dma_fence *fence;
621 void __user *user_data;638 void __user *user_data;
622 u64 remain;639 u64 remain;
623 int ret;640 int ret;
@@ -626,19 +643,17 @@ i915_gem_shmem_pwrite(struct drm_i915_gem_object *obj, · 2 unmodified lines
626 if (ret)643 if (ret)
627 return ret;644 return ret;
628 645
646 ret = i915_gem_object_pin_pages(obj);
647 if (ret)
648 goto err_unlock;
649
629 ret = i915_gem_object_prepare_write(obj, &needs_clflush);650 ret = i915_gem_object_prepare_write(obj, &needs_clflush);
630 if (ret) {651 if (ret)
631 i915_gem_object_unlock(obj);652 goto err_unpin;
632 return ret;
633 }
634 653
635 fence = i915_gem_object_lock_fence(obj);
636 i915_gem_object_finish_access(obj);654 i915_gem_object_finish_access(obj);
637 i915_gem_object_unlock(obj);655 i915_gem_object_unlock(obj);
638 656
639 if (!fence)
640 return -ENOMEM;
641
642 /* If we don't overwrite a cacheline completely we need to be657 /* If we don't overwrite a cacheline completely we need to be
643 * careful to have up-to-date data by first clflushing. Don't658 * careful to have up-to-date data by first clflushing. Don't
644 * overcomplicate things and flush the entire patch.659 * overcomplicate things and flush the entire patch.
@@ -666,8 +681,14 @@ i915_gem_shmem_pwrite(struct drm_i915_gem_object *obj, · 21 unmodified lines
666 }681 }
667 682
668 i915_gem_object_flush_frontbuffer(obj, ORIGIN_CPU);683 i915_gem_object_flush_frontbuffer(obj, ORIGIN_CPU);
669 i915_gem_object_unlock_fence(obj, fence);
670 684
685 i915_gem_object_unpin_pages(obj);
686 return ret;
687
688err_unpin:
689 i915_gem_object_unpin_pages(obj);
690err_unlock:
691 i915_gem_object_unlock(obj);
671 return ret;692 return ret;
672}693}
673 694
@@ -683,10 +704,17 @@ int · 9 unmodified lines
683i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,704i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
684 struct drm_file *file)705 struct drm_file *file)
685{706{
707 struct drm_i915_private *i915 = to_i915(dev);
686 struct drm_i915_gem_pwrite *args = data;708 struct drm_i915_gem_pwrite *args = data;
687 struct drm_i915_gem_object *obj;709 struct drm_i915_gem_object *obj;
688 int ret;710 int ret;
689 711
712 /* PWRITE is disallowed for all platforms after TGL-LP. This also
713 * covers all platforms with local memory.
714 */
715 if (INTEL_GEN(i915) >= 12 && !IS_TIGERLAKE(i915))
716 return -EOPNOTSUPP;
717
690 if (args->size == 0)718 if (args->size == 0)
691 return 0;719 return 0;
692 720
@@ -724,10 +752,6 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, · 31 unmodified lines
724 if (ret)752 if (ret)
725 goto err;753 goto err;
726 754
727 ret = i915_gem_object_pin_pages(obj);
728 if (ret)
729 goto err;
730
731 ret = -EFAULT;755 ret = -EFAULT;
732 /* We can only do the GTT pwrite on untiled buffers, as otherwise756 /* We can only do the GTT pwrite on untiled buffers, as otherwise
733 * it would end up going through the fenced access, and we'll get757 * it would end up going through the fenced access, and we'll get
@@ -748,7 +772,6 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, · 14 unmodified lines
748 ret = i915_gem_shmem_pwrite(obj, args);772 ret = i915_gem_shmem_pwrite(obj, args);
749 }773 }
750 774
751 i915_gem_object_unpin_pages(obj);
752err:775err:
753 i915_gem_object_put(obj);776 i915_gem_object_put(obj);
754 return ret;777 return ret;
@@ -909,7 +932,11 @@ new_vma: · 154 unmodified lines
909 return ERR_PTR(ret);932 return ERR_PTR(ret);
910 }933 }
911 934
912 ret = i915_vma_pin_ww(vma, ww, size, alignment, flags | PIN_GLOBAL);935 if (ww)
936 ret = i915_vma_pin_ww(vma, ww, size, alignment, flags | PIN_GLOBAL);
937 else
938 ret = i915_vma_pin(vma, size, alignment, flags | PIN_GLOBAL);
939
913 if (ret)940 if (ret)
914 return ERR_PTR(ret);941 return ERR_PTR(ret);
915 942
@@ -949,7 +976,7 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void *data, · 33 unmodified lines
949 if (!obj)976 if (!obj)
950 return -ENOENT;977 return -ENOENT;
951 978
952 err = mutex_lock_interruptible(&obj->mm.lock);979 err = i915_gem_object_lock_interruptible(obj, NULL);
953 if (err)980 if (err)
954 goto out;981 goto out;
955 982
@@ -995,8 +1022,8 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void *data, · 39 unmodified lines
995 i915_gem_object_truncate(obj);1022 i915_gem_object_truncate(obj);
996 1023
997 args->retained = obj->mm.madv != __I915_MADV_PURGED;1024 args->retained = obj->mm.madv != __I915_MADV_PURGED;
998 mutex_unlock(&obj->mm.lock);
999 1025
1026 i915_gem_object_unlock(obj);
1000out:1027out:
1001 i915_gem_object_put(obj);1028 i915_gem_object_put(obj);
1002 return err;1029 return err;
@@ -1050,10 +1077,8 @@ int i915_gem_init(struct drm_i915_private *dev_priv) · 47 unmodified lines
1050err_unlock:1077err_unlock:
1051 i915_gem_drain_workqueue(dev_priv);1078 i915_gem_drain_workqueue(dev_priv);
1052 1079
1053 if (ret != -EIO) {1080 if (ret != -EIO)
1054 intel_uc_cleanup_firmwares(&dev_priv->gt.uc);1081 intel_uc_cleanup_firmwares(&dev_priv->gt.uc);
1055 i915_gem_cleanup_userptr(dev_priv);
1056 }
1057 1082
1058 if (ret == -EIO) {1083 if (ret == -EIO) {
1059 /*1084 /*
@@ -1110,7 +1135,6 @@ void i915_gem_driver_release(struct drm_i915_private *dev_priv) · 50 unmodified lines
1110 intel_wa_list_free(&dev_priv->gt_wa_list);1135 intel_wa_list_free(&dev_priv->gt_wa_list);
1111 1136
1112 intel_uc_cleanup_firmwares(&dev_priv->gt.uc);1137 intel_uc_cleanup_firmwares(&dev_priv->gt.uc);
1113 i915_gem_cleanup_userptr(dev_priv);
1114 1138
1115 i915_gem_drain_freed_objects(dev_priv);1139 i915_gem_drain_freed_objects(dev_priv);
1116 1140
drivers/gpu/drm/i915/i915_gem_gtt.c+1−1
@@ -44,7 +44,7 @@ int i915_gem_gtt_prepare_pages(struct drm_i915_gem_object *obj, · 43 unmodified lines
44 * the DMA remapper, i915_gem_shrink will return 0.44 * the DMA remapper, i915_gem_shrink will return 0.
45 */45 */
46 GEM_BUG_ON(obj->mm.pages == pages);46 GEM_BUG_ON(obj->mm.pages == pages);
47 } while (i915_gem_shrink(to_i915(obj->base.dev),47 } while (i915_gem_shrink(NULL, to_i915(obj->base.dev),
48 obj->base.size >> PAGE_SHIFT, NULL,48 obj->base.size >> PAGE_SHIFT, NULL,
49 I915_SHRINK_BOUND |49 I915_SHRINK_BOUND |
50 I915_SHRINK_UNBOUND));50 I915_SHRINK_UNBOUND));
drivers/gpu/drm/i915/i915_memcpy.c+1−1
@@ -135,7 +135,7 @@ bool i915_memcpy_from_wc(void *dst, const void *src, unsigned long len) · 134 unmodified lines
135 * accepts that its arguments may not be aligned, but are valid for the135 * accepts that its arguments may not be aligned, but are valid for the
136 * potential 16-byte read past the end.136 * potential 16-byte read past the end.
137 */137 */
138void i915_unaligned_memcpy_from_wc(void *dst, void *src, unsigned long len)138void i915_unaligned_memcpy_from_wc(void *dst, const void *src, unsigned long len)
139{139{
140 unsigned long addr;140 unsigned long addr;
141 141
drivers/gpu/drm/i915/i915_memcpy.h+1−1
@@ -13,7 +13,7 @@ struct drm_i915_private; · 12 unmodified lines
13void i915_memcpy_init_early(struct drm_i915_private *i915);13void i915_memcpy_init_early(struct drm_i915_private *i915);
14 14
15bool i915_memcpy_from_wc(void *dst, const void *src, unsigned long len);15bool i915_memcpy_from_wc(void *dst, const void *src, unsigned long len);
16void i915_unaligned_memcpy_from_wc(void *dst, void *src, unsigned long len);16void i915_unaligned_memcpy_from_wc(void *dst, const void *src, unsigned long len);
17 17
18/* The movntdqa instructions used for memcpy-from-wc require 16-byte alignment,18/* The movntdqa instructions used for memcpy-from-wc require 16-byte alignment,
19 * as well as SSE4.1 support. i915_memcpy_from_wc() will report if it cannot19 * as well as SSE4.1 support. i915_memcpy_from_wc() will report if it cannot
drivers/gpu/drm/i915/i915_params.c+5−0
@@ -197,6 +197,11 @@ i915_param_named_unsafe(fake_lmem_start, ulong, 0400, · 196 unmodified lines
197 "Fake LMEM start offset (default: 0)");197 "Fake LMEM start offset (default: 0)");
198#endif198#endif
199 199
200#if CONFIG_DRM_I915_REQUEST_TIMEOUT
201i915_param_named_unsafe(request_timeout_ms, uint, 0600,
202 "Default request/fence/batch buffer expiration timeout.");
203#endif
204
200static __always_inline void _print_param(struct drm_printer *p,205static __always_inline void _print_param(struct drm_printer *p,
201 const char *name,206 const char *name,
202 const char *type,207 const char *type,
drivers/gpu/drm/i915/i915_params.h+1−0
@@ -72,6 +72,7 @@ struct drm_printer; · 71 unmodified lines
72 param(int, enable_dpcd_backlight, -1, 0600) \72 param(int, enable_dpcd_backlight, -1, 0600) \
73 param(char *, force_probe, CONFIG_DRM_I915_FORCE_PROBE, 0400) \73 param(char *, force_probe, CONFIG_DRM_I915_FORCE_PROBE, 0400) \
74 param(unsigned long, fake_lmem_start, 0, 0400) \74 param(unsigned long, fake_lmem_start, 0, 0400) \
75 param(unsigned int, request_timeout_ms, CONFIG_DRM_I915_REQUEST_TIMEOUT, 0600) \
75 /* leave bools at the end to not create holes */ \76 /* leave bools at the end to not create holes */ \
76 param(bool, enable_hangcheck, true, 0600) \77 param(bool, enable_hangcheck, true, 0600) \
77 param(bool, load_detect_test, false, 0600) \78 param(bool, load_detect_test, false, 0600) \
drivers/gpu/drm/i915/i915_perf.c+43−13
@@ -1573,7 +1573,7 @@ static int alloc_oa_buffer(struct i915_perf_stream *stream) · 1572 unmodified lines
1573 stream->oa_buffer.vma = vma;1573 stream->oa_buffer.vma = vma;
1574 1574
1575 stream->oa_buffer.vaddr =1575 stream->oa_buffer.vaddr =
1576 i915_gem_object_pin_map(bo, I915_MAP_WB);1576 i915_gem_object_pin_map_unlocked(bo, I915_MAP_WB);
1577 if (IS_ERR(stream->oa_buffer.vaddr)) {1577 if (IS_ERR(stream->oa_buffer.vaddr)) {
1578 ret = PTR_ERR(stream->oa_buffer.vaddr);1578 ret = PTR_ERR(stream->oa_buffer.vaddr);
1579 goto err_unpin;1579 goto err_unpin;
@@ -1627,6 +1627,7 @@ static int alloc_noa_wait(struct i915_perf_stream *stream) · 47 unmodified lines
1627 const u32 base = stream->engine->mmio_base;1627 const u32 base = stream->engine->mmio_base;
1628#define CS_GPR(x) GEN8_RING_CS_GPR(base, x)1628#define CS_GPR(x) GEN8_RING_CS_GPR(base, x)
1629 u32 *batch, *ts0, *cs, *jump;1629 u32 *batch, *ts0, *cs, *jump;
1630 struct i915_gem_ww_ctx ww;
1630 int ret, i;1631 int ret, i;
1631 enum {1632 enum {
1632 START_TS,1633 START_TS,
@@ -1644,15 +1645,21 @@ static int alloc_noa_wait(struct i915_perf_stream *stream) · 11 unmodified lines
1644 return PTR_ERR(bo);1645 return PTR_ERR(bo);
1645 }1646 }
1646 1647
1648 i915_gem_ww_ctx_init(&ww, true);
1649retry:
1650 ret = i915_gem_object_lock(bo, &ww);
1651 if (ret)
1652 goto out_ww;
1653
1647 /*1654 /*
1648 * We pin in GGTT because we jump into this buffer now because1655 * We pin in GGTT because we jump into this buffer now because
1649 * multiple OA config BOs will have a jump to this address and it1656 * multiple OA config BOs will have a jump to this address and it
1650 * needs to be fixed during the lifetime of the i915/perf stream.1657 * needs to be fixed during the lifetime of the i915/perf stream.
1651 */1658 */
1652 vma = i915_gem_object_ggtt_pin(bo, NULL, 0, 0, PIN_HIGH);1659 vma = i915_gem_object_ggtt_pin_ww(bo, &ww, NULL, 0, 0, PIN_HIGH);
1653 if (IS_ERR(vma)) {1660 if (IS_ERR(vma)) {
1654 ret = PTR_ERR(vma);1661 ret = PTR_ERR(vma);
1655 goto err_unref;1662 goto out_ww;
1656 }1663 }
1657 1664
1658 batch = cs = i915_gem_object_pin_map(bo, I915_MAP_WB);1665 batch = cs = i915_gem_object_pin_map(bo, I915_MAP_WB);
@@ -1786,12 +1793,19 @@ static int alloc_noa_wait(struct i915_perf_stream *stream) · 127 unmodified lines
1786 __i915_gem_object_release_map(bo);1793 __i915_gem_object_release_map(bo);
1787 1794
1788 stream->noa_wait = vma;1795 stream->noa_wait = vma;
1789 return 0;1796 goto out_ww;
1790 1797
1791err_unpin:1798err_unpin:
1792 i915_vma_unpin_and_release(&vma, 0);1799 i915_vma_unpin_and_release(&vma, 0);
1793err_unref:1800out_ww:
1794 i915_gem_object_put(bo);1801 if (ret == -EDEADLK) {
1802 ret = i915_gem_ww_ctx_backoff(&ww);
1803 if (!ret)
1804 goto retry;
1805 }
1806 i915_gem_ww_ctx_fini(&ww);
1807 if (ret)
1808 i915_gem_object_put(bo);
1795 return ret;1809 return ret;
1796}1810}
1797 1811
@@ -1834,6 +1848,7 @@ alloc_oa_config_buffer(struct i915_perf_stream *stream, · 36 unmodified lines
1834{1848{
1835 struct drm_i915_gem_object *obj;1849 struct drm_i915_gem_object *obj;
1836 struct i915_oa_config_bo *oa_bo;1850 struct i915_oa_config_bo *oa_bo;
1851 struct i915_gem_ww_ctx ww;
1837 size_t config_length = 0;1852 size_t config_length = 0;
1838 u32 *cs;1853 u32 *cs;
1839 int err;1854 int err;
@@ -1854,10 +1869,16 @@ alloc_oa_config_buffer(struct i915_perf_stream *stream, · 14 unmodified lines
1854 goto err_free;1869 goto err_free;
1855 }1870 }
1856 1871
1872 i915_gem_ww_ctx_init(&ww, true);
1873retry:
1874 err = i915_gem_object_lock(obj, &ww);
1875 if (err)
1876 goto out_ww;
1877
1857 cs = i915_gem_object_pin_map(obj, I915_MAP_WB);1878 cs = i915_gem_object_pin_map(obj, I915_MAP_WB);
1858 if (IS_ERR(cs)) {1879 if (IS_ERR(cs)) {
1859 err = PTR_ERR(cs);1880 err = PTR_ERR(cs);
1860 goto err_oa_bo;1881 goto out_ww;
1861 }1882 }
1862 1883
1863 cs = write_cs_mi_lri(cs,1884 cs = write_cs_mi_lri(cs,
@@ -1885,19 +1906,28 @@ alloc_oa_config_buffer(struct i915_perf_stream *stream, · 21 unmodified lines
1885 NULL);1906 NULL);
1886 if (IS_ERR(oa_bo->vma)) {1907 if (IS_ERR(oa_bo->vma)) {
1887 err = PTR_ERR(oa_bo->vma);1908 err = PTR_ERR(oa_bo->vma);
1888 goto err_oa_bo;1909 goto out_ww;
1889 }1910 }
1890 1911
1891 oa_bo->oa_config = i915_oa_config_get(oa_config);1912 oa_bo->oa_config = i915_oa_config_get(oa_config);
1892 llist_add(&oa_bo->node, &stream->oa_config_bos);1913 llist_add(&oa_bo->node, &stream->oa_config_bos);
1893 1914
1894 return oa_bo;1915out_ww:
1916 if (err == -EDEADLK) {
1917 err = i915_gem_ww_ctx_backoff(&ww);
1918 if (!err)
1919 goto retry;
1920 }
1921 i915_gem_ww_ctx_fini(&ww);
1895 1922
1896err_oa_bo:1923 if (err)
1897 i915_gem_object_put(obj);1924 i915_gem_object_put(obj);
1898err_free:1925err_free:
1899 kfree(oa_bo);1926 if (err) {
1900 return ERR_PTR(err);1927 kfree(oa_bo);
1928 return ERR_PTR(err);
1929 }
1930 return oa_bo;
1901}1931}
1902 1932
1903static struct i915_vma *1933static struct i915_vma *
drivers/gpu/drm/i915/i915_request.c+126−7
@@ -33,7 +33,10 @@ · 32 unmodified lines
33#include "gem/i915_gem_context.h"33#include "gem/i915_gem_context.h"
34#include "gt/intel_breadcrumbs.h"34#include "gt/intel_breadcrumbs.h"
35#include "gt/intel_context.h"35#include "gt/intel_context.h"
36#include "gt/intel_engine.h"
37#include "gt/intel_engine_heartbeat.h"
36#include "gt/intel_gpu_commands.h"38#include "gt/intel_gpu_commands.h"
39#include "gt/intel_reset.h"
37#include "gt/intel_ring.h"40#include "gt/intel_ring.h"
38#include "gt/intel_rps.h"41#include "gt/intel_rps.h"
39 42
@@ -244,6 +247,50 @@ static void __i915_request_fill(struct i915_request *rq, u8 val) · 204 unmodified lines
244 memset(vaddr + head, val, rq->postfix - head);247 memset(vaddr + head, val, rq->postfix - head);
245}248}
246 249
250/**
251 * i915_request_active_engine
252 * @rq: request to inspect
253 * @active: pointer in which to return the active engine
254 *
255 * Fills the currently active engine to the @active pointer if the request
256 * is active and still not completed.
257 *
258 * Returns true if request was active or false otherwise.
259 */
260bool
261i915_request_active_engine(struct i915_request *rq,
262 struct intel_engine_cs **active)
263{
264 struct intel_engine_cs *engine, *locked;
265 bool ret = false;
266
267 /*
268 * Serialise with __i915_request_submit() so that it sees
269 * is-banned?, or we know the request is already inflight.
270 *
271 * Note that rq->engine is unstable, and so we double
272 * check that we have acquired the lock on the final engine.
273 */
274 locked = READ_ONCE(rq->engine);
275 spin_lock_irq(&locked->active.lock);
276 while (unlikely(locked != (engine = READ_ONCE(rq->engine)))) {
277 spin_unlock(&locked->active.lock);
278 locked = engine;
279 spin_lock(&locked->active.lock);
280 }
281
282 if (i915_request_is_active(rq)) {
283 if (!__i915_request_is_complete(rq))
284 *active = locked;
285 ret = true;
286 }
287
288 spin_unlock_irq(&locked->active.lock);
289
290 return ret;
291}
292
293
247static void remove_from_engine(struct i915_request *rq)294static void remove_from_engine(struct i915_request *rq)
248{295{
249 struct intel_engine_cs *engine, *locked;296 struct intel_engine_cs *engine, *locked;
@@ -274,6 +321,53 @@ static void remove_from_engine(struct i915_request *rq) · 24 unmodified lines
274 __notify_execute_cb_imm(rq);321 __notify_execute_cb_imm(rq);
275}322}
276 323
324static void __rq_init_watchdog(struct i915_request *rq)
325{
326 rq->watchdog.timer.function = NULL;
327}
328
329static enum hrtimer_restart __rq_watchdog_expired(struct hrtimer *hrtimer)
330{
331 struct i915_request *rq =
332 container_of(hrtimer, struct i915_request, watchdog.timer);
333 struct intel_gt *gt = rq->engine->gt;
334
335 if (!i915_request_completed(rq)) {
336 if (llist_add(&rq->watchdog.link, &gt->watchdog.list))
337 schedule_work(&gt->watchdog.work);
338 } else {
339 i915_request_put(rq);
340 }
341
342 return HRTIMER_NORESTART;
343}
344
345static void __rq_arm_watchdog(struct i915_request *rq)
346{
347 struct i915_request_watchdog *wdg = &rq->watchdog;
348 struct intel_context *ce = rq->context;
349
350 if (!ce->watchdog.timeout_us)
351 return;
352
353 hrtimer_init(&wdg->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
354 wdg->timer.function = __rq_watchdog_expired;
355 hrtimer_start_range_ns(&wdg->timer,
356 ns_to_ktime(ce->watchdog.timeout_us *
357 NSEC_PER_USEC),
358 NSEC_PER_MSEC,
359 HRTIMER_MODE_REL);
360 i915_request_get(rq);
361}
362
363static void __rq_cancel_watchdog(struct i915_request *rq)
364{
365 struct i915_request_watchdog *wdg = &rq->watchdog;
366
367 if (wdg->timer.function && hrtimer_try_to_cancel(&wdg->timer) > 0)
368 i915_request_put(rq);
369}
370
277bool i915_request_retire(struct i915_request *rq)371bool i915_request_retire(struct i915_request *rq)
278{372{
279 if (!__i915_request_is_complete(rq))373 if (!__i915_request_is_complete(rq))
@@ -285,6 +379,8 @@ bool i915_request_retire(struct i915_request *rq) · 5 unmodified lines
285 trace_i915_request_retire(rq);379 trace_i915_request_retire(rq);
286 i915_request_mark_complete(rq);380 i915_request_mark_complete(rq);
287 381
382 __rq_cancel_watchdog(rq);
383
288 /*384 /*
289 * We know the GPU must have read the request to have385 * We know the GPU must have read the request to have
290 * sent us the seqno + interrupt, so use the position386 * sent us the seqno + interrupt, so use the position
@@ -498,20 +594,22 @@ void __i915_request_skip(struct i915_request *rq) · 207 unmodified lines
498 rq->infix = rq->postfix;594 rq->infix = rq->postfix;
499}595}
500 596
501void i915_request_set_error_once(struct i915_request *rq, int error)597bool i915_request_set_error_once(struct i915_request *rq, int error)
502{598{
503 int old;599 int old;
504 600
505 GEM_BUG_ON(!IS_ERR_VALUE((long)error));601 GEM_BUG_ON(!IS_ERR_VALUE((long)error));
506 602
507 if (i915_request_signaled(rq))603 if (i915_request_signaled(rq))
508 return;604 return false;
509 605
510 old = READ_ONCE(rq->fence.error);606 old = READ_ONCE(rq->fence.error);
511 do {607 do {
512 if (fatal_error(old))608 if (fatal_error(old))
513 return;609 return false;
514 } while (!try_cmpxchg(&rq->fence.error, &old, error));610 } while (!try_cmpxchg(&rq->fence.error, &old, error));
611
612 return true;
515}613}
516 614
517void i915_request_mark_eio(struct i915_request *rq)615void i915_request_mark_eio(struct i915_request *rq)
@@ -678,6 +776,28 @@ void i915_request_unsubmit(struct i915_request *request) · 160 unmodified lines
678 spin_unlock_irqrestore(&engine->active.lock, flags);776 spin_unlock_irqrestore(&engine->active.lock, flags);
679}777}
680 778
779static void __cancel_request(struct i915_request *rq)
780{
781 struct intel_engine_cs *engine = NULL;
782
783 i915_request_active_engine(rq, &engine);
784
785 if (engine && intel_engine_pulse(engine))
786 intel_gt_handle_error(engine->gt, engine->mask, 0,
787 "request cancellation by %s",
788 current->comm);
789}
790
791void i915_request_cancel(struct i915_request *rq, int error)
792{
793 if (!i915_request_set_error_once(rq, error))
794 return;
795
796 set_bit(I915_FENCE_FLAG_SENTINEL, &rq->fence.flags);
797
798 __cancel_request(rq);
799}
800
681static int __i915_sw_fence_call801static int __i915_sw_fence_call
682submit_notify(struct i915_sw_fence *fence, enum i915_sw_fence_notify state)802submit_notify(struct i915_sw_fence *fence, enum i915_sw_fence_notify state)
683{803{
@@ -690,6 +810,8 @@ submit_notify(struct i915_sw_fence *fence, enum i915_sw_fence_notify state) · 6 unmodified lines
690 810
691 if (unlikely(fence->error))811 if (unlikely(fence->error))
692 i915_request_set_error_once(request, fence->error);812 i915_request_set_error_once(request, fence->error);
813 else
814 __rq_arm_watchdog(request);
693 815
694 /*816 /*
695 * We need to serialize use of the submit_request() callback817 * We need to serialize use of the submit_request() callback
@@ -863,7 +985,6 @@ __i915_request_create(struct intel_context *ce, gfp_t gfp) · 167 unmodified lines
863 rq->fence.seqno = seqno;985 rq->fence.seqno = seqno;
864 986
865 RCU_INIT_POINTER(rq->timeline, tl);987 RCU_INIT_POINTER(rq->timeline, tl);
866 RCU_INIT_POINTER(rq->hwsp_cacheline, tl->hwsp_cacheline);
867 rq->hwsp_seqno = tl->hwsp_seqno;988 rq->hwsp_seqno = tl->hwsp_seqno;
868 GEM_BUG_ON(__i915_request_is_complete(rq));989 GEM_BUG_ON(__i915_request_is_complete(rq));
869 990
@@ -877,6 +998,7 @@ __i915_request_create(struct intel_context *ce, gfp_t gfp) · 7 unmodified lines
877 998
878 /* No zalloc, everything must be cleared after use */999 /* No zalloc, everything must be cleared after use */
879 rq->batch = NULL;1000 rq->batch = NULL;
1001 __rq_init_watchdog(rq);
880 GEM_BUG_ON(rq->capture_list);1002 GEM_BUG_ON(rq->capture_list);
881 GEM_BUG_ON(!llist_empty(&rq->execute_cb));1003 GEM_BUG_ON(!llist_empty(&rq->execute_cb));
882 1004
@@ -1108,9 +1230,6 @@ emit_semaphore_wait(struct i915_request *to, · 225 unmodified lines
1108 if (i915_request_has_initial_breadcrumb(to))1230 if (i915_request_has_initial_breadcrumb(to))
1109 goto await_fence;1231 goto await_fence;
1110 1232
1111 if (!rcu_access_pointer(from->hwsp_cacheline))
1112 goto await_fence;
1113
1114 /*1233 /*
1115 * If this or its dependents are waiting on an external fence1234 * If this or its dependents are waiting on an external fence
1116 * that may fail catastrophically, then we want to avoid using1235 * that may fail catastrophically, then we want to avoid using
drivers/gpu/drm/i915/i915_request.h+36−11
@@ -26,7 +26,9 @@ · 25 unmodified lines
26#define I915_REQUEST_H26#define I915_REQUEST_H
27 27
28#include <linux/dma-fence.h>28#include <linux/dma-fence.h>
29#include <linux/hrtimer.h>
29#include <linux/irq_work.h>30#include <linux/irq_work.h>
31#include <linux/llist.h>
30#include <linux/lockdep.h>32#include <linux/lockdep.h>
31 33
32#include "gem/i915_gem_context_types.h"34#include "gem/i915_gem_context_types.h"
@@ -237,16 +239,6 @@ struct i915_request { · 204 unmodified lines
237 */239 */
238 const u32 *hwsp_seqno;240 const u32 *hwsp_seqno;
239 241
240 /*
241 * If we need to access the timeline's seqno for this request in
242 * another request, we need to keep a read reference to this associated
243 * cacheline, so that we do not free and recycle it before the foreign
244 * observers have completed. Hence, we keep a pointer to the cacheline
245 * inside the timeline's HWSP vma, but it is only valid while this
246 * request has not completed and guarded by the timeline mutex.
247 */
248 struct intel_timeline_cacheline __rcu *hwsp_cacheline;
249
250 /** Position in the ring of the start of the request */242 /** Position in the ring of the start of the request */
251 u32 head;243 u32 head;
252 244
@@ -287,6 +279,12 @@ struct i915_request { · 34 unmodified lines
287 /** timeline->request entry for this request */279 /** timeline->request entry for this request */
288 struct list_head link;280 struct list_head link;
289 281
282 /** Watchdog support fields. */
283 struct i915_request_watchdog {
284 struct llist_node link;
285 struct hrtimer timer;
286 } watchdog;
287
290 I915_SELFTEST_DECLARE(struct {288 I915_SELFTEST_DECLARE(struct {
291 struct list_head link;289 struct list_head link;
292 unsigned long delay;290 unsigned long delay;
@@ -310,7 +308,7 @@ struct i915_request * __must_check · 17 unmodified lines
310i915_request_create(struct intel_context *ce);308i915_request_create(struct intel_context *ce);
311 309
312void __i915_request_skip(struct i915_request *rq);310void __i915_request_skip(struct i915_request *rq);
313void i915_request_set_error_once(struct i915_request *rq, int error);311bool i915_request_set_error_once(struct i915_request *rq, int error);
314void i915_request_mark_eio(struct i915_request *rq);312void i915_request_mark_eio(struct i915_request *rq);
315 313
316struct i915_request *__i915_request_commit(struct i915_request *request);314struct i915_request *__i915_request_commit(struct i915_request *request);
@@ -366,6 +364,8 @@ void i915_request_submit(struct i915_request *request); · 49 unmodified lines
366void __i915_request_unsubmit(struct i915_request *request);364void __i915_request_unsubmit(struct i915_request *request);
367void i915_request_unsubmit(struct i915_request *request);365void i915_request_unsubmit(struct i915_request *request);
368 366
367void i915_request_cancel(struct i915_request *rq, int error);
368
369long i915_request_wait(struct i915_request *rq,369long i915_request_wait(struct i915_request *rq,
370 unsigned int flags,370 unsigned int flags,
371 long timeout)371 long timeout)
@@ -616,4 +616,29 @@ i915_request_active_timeline(const struct i915_request *rq) · 244 unmodified lines
616 lockdep_is_held(&rq->engine->active.lock));616 lockdep_is_held(&rq->engine->active.lock));
617}617}
618 618
619static inline u32
620i915_request_active_seqno(const struct i915_request *rq)
621{
622 u32 hwsp_phys_base =
623 page_mask_bits(i915_request_active_timeline(rq)->hwsp_offset);
624 u32 hwsp_relative_offset = offset_in_page(rq->hwsp_seqno);
625
626 /*
627 * Because of wraparound, we cannot simply take tl->hwsp_offset,
628 * but instead use the fact that the relative for vaddr is the
629 * offset as for hwsp_offset. Take the top bits from tl->hwsp_offset
630 * and combine them with the relative offset in rq->hwsp_seqno.
631 *
632 * As rw->hwsp_seqno is rewritten when signaled, this only works
633 * when the request isn't signaled yet, but at that point you
634 * no longer need the offset.
635 */
636
637 return hwsp_phys_base + hwsp_relative_offset;
638}
639
640bool
641i915_request_active_engine(struct i915_request *rq,
642 struct intel_engine_cs **active);
643
619#endif /* I915_REQUEST_H */644#endif /* I915_REQUEST_H */
drivers/gpu/drm/i915/i915_selftest.h+2−0
@@ -107,6 +107,7 @@ int __i915_subtests(const char *caller, · 106 unmodified lines
107 107
108#define I915_SELFTEST_DECLARE(x) x108#define I915_SELFTEST_DECLARE(x) x
109#define I915_SELFTEST_ONLY(x) unlikely(x)109#define I915_SELFTEST_ONLY(x) unlikely(x)
110#define I915_SELFTEST_EXPORT
110 111
111#else /* !IS_ENABLED(CONFIG_DRM_I915_SELFTEST) */112#else /* !IS_ENABLED(CONFIG_DRM_I915_SELFTEST) */
112 113
@@ -116,6 +117,7 @@ static inline int i915_perf_selftests(struct pci_dev *pdev) { return 0; } · 3 unmodified lines
116 117
117#define I915_SELFTEST_DECLARE(x)118#define I915_SELFTEST_DECLARE(x)
118#define I915_SELFTEST_ONLY(x) 0119#define I915_SELFTEST_ONLY(x) 0
120#define I915_SELFTEST_EXPORT static
119 121
120#endif122#endif
121 123
drivers/gpu/drm/i915/i915_vma.c+22−8
@@ -230,7 +230,7 @@ err_vma: · 229 unmodified lines
230}230}
231 231
232static struct i915_vma *232static struct i915_vma *
233vma_lookup(struct drm_i915_gem_object *obj,233i915_vma_lookup(struct drm_i915_gem_object *obj,
234 struct i915_address_space *vm,234 struct i915_address_space *vm,
235 const struct i915_ggtt_view *view)235 const struct i915_ggtt_view *view)
236{236{
@@ -278,7 +278,7 @@ i915_vma_instance(struct drm_i915_gem_object *obj, · 41 unmodified lines
278 GEM_BUG_ON(!atomic_read(&vm->open));278 GEM_BUG_ON(!atomic_read(&vm->open));
279 279
280 spin_lock(&obj->vma.lock);280 spin_lock(&obj->vma.lock);
281 vma = vma_lookup(obj, vm, view);281 vma = i915_vma_lookup(obj, vm, view);
282 spin_unlock(&obj->vma.lock);282 spin_unlock(&obj->vma.lock);
283 283
284 /* vma_create() will resolve the race if another creates the vma */284 /* vma_create() will resolve the race if another creates the vma */
@@ -863,8 +863,8 @@ int i915_vma_pin_ww(struct i915_vma *vma, struct i915_gem_ww_ctx *ww, · 578 unmodified lines
863 int err;863 int err;
864 864
865#ifdef CONFIG_PROVE_LOCKING865#ifdef CONFIG_PROVE_LOCKING
866 if (debug_locks && lockdep_is_held(&vma->vm->i915->drm.struct_mutex))866 if (debug_locks && !WARN_ON(!ww) && vma->resv)
867 WARN_ON(!ww);867 assert_vma_held(vma);
868#endif868#endif
869 869
870 BUILD_BUG_ON(PIN_GLOBAL != I915_VMA_GLOBAL_BIND);870 BUILD_BUG_ON(PIN_GLOBAL != I915_VMA_GLOBAL_BIND);
@@ -884,6 +884,11 @@ int i915_vma_pin_ww(struct i915_vma *vma, struct i915_gem_ww_ctx *ww, · 13 unmodified lines
884 wakeref = intel_runtime_pm_get(&vma->vm->i915->runtime_pm);884 wakeref = intel_runtime_pm_get(&vma->vm->i915->runtime_pm);
885 885
886 if (flags & vma->vm->bind_async_flags) {886 if (flags & vma->vm->bind_async_flags) {
887 /* lock VM */
888 err = i915_vm_lock_objects(vma->vm, ww);
889 if (err)
890 goto err_rpm;
891
887 work = i915_vma_work();892 work = i915_vma_work();
888 if (!work) {893 if (!work) {
889 err = -ENOMEM;894 err = -ENOMEM;
@@ -1020,8 +1025,15 @@ int i915_ggtt_pin(struct i915_vma *vma, struct i915_gem_ww_ctx *ww, · 130 unmodified lines
1020 1025
1021 GEM_BUG_ON(!i915_vma_is_ggtt(vma));1026 GEM_BUG_ON(!i915_vma_is_ggtt(vma));
1022 1027
1028#ifdef CONFIG_LOCKDEP
1029 WARN_ON(!ww && vma->resv && dma_resv_held(vma->resv));
1030#endif
1031
1023 do {1032 do {
1024 err = i915_vma_pin_ww(vma, ww, 0, align, flags | PIN_GLOBAL);1033 if (ww)
1034 err = i915_vma_pin_ww(vma, ww, 0, align, flags | PIN_GLOBAL);
1035 else
1036 err = i915_vma_pin(vma, 0, align, flags | PIN_GLOBAL);
1025 if (err != -ENOSPC) {1037 if (err != -ENOSPC) {
1026 if (!err) {1038 if (!err) {
1027 err = i915_vma_wait_for_bind(vma);1039 err = i915_vma_wait_for_bind(vma);
@@ -1238,9 +1250,11 @@ int i915_vma_move_to_active(struct i915_vma *vma, · 210 unmodified lines
1238 obj->write_domain = I915_GEM_DOMAIN_RENDER;1250 obj->write_domain = I915_GEM_DOMAIN_RENDER;
1239 obj->read_domains = 0;1251 obj->read_domains = 0;
1240 } else {1252 } else {
1241 err = dma_resv_reserve_shared(vma->resv, 1);1253 if (!(flags & __EXEC_OBJECT_NO_RESERVE)) {
1242 if (unlikely(err))1254 err = dma_resv_reserve_shared(vma->resv, 1);
1243 return err;1255 if (unlikely(err))
1256 return err;
1257 }
1244 1258
1245 dma_resv_add_shared_fence(vma->resv, &rq->fence);1259 dma_resv_add_shared_fence(vma->resv, &rq->fence);
1246 obj->write_domain = 0;1260 obj->write_domain = 0;
drivers/gpu/drm/i915/i915_vma.h+19−1
@@ -52,6 +52,9 @@ static inline bool i915_vma_is_active(const struct i915_vma *vma) · 51 unmodified lines
52 return !i915_active_is_idle(&vma->active);52 return !i915_active_is_idle(&vma->active);
53}53}
54 54
55/* do not reserve memory to prevent deadlocks */
56#define __EXEC_OBJECT_NO_RESERVE BIT(31)
57
55int __must_check __i915_vma_move_to_active(struct i915_vma *vma,58int __must_check __i915_vma_move_to_active(struct i915_vma *vma,
56 struct i915_request *rq);59 struct i915_request *rq);
57int __must_check i915_vma_move_to_active(struct i915_vma *vma,60int __must_check i915_vma_move_to_active(struct i915_vma *vma,
@@ -243,7 +246,22 @@ i915_vma_pin_ww(struct i915_vma *vma, struct i915_gem_ww_ctx *ww, · 185 unmodified lines
243static inline int __must_check246static inline int __must_check
244i915_vma_pin(struct i915_vma *vma, u64 size, u64 alignment, u64 flags)247i915_vma_pin(struct i915_vma *vma, u64 size, u64 alignment, u64 flags)
245{248{
246 return i915_vma_pin_ww(vma, NULL, size, alignment, flags);249 struct i915_gem_ww_ctx ww;
250 int err;
251
252 i915_gem_ww_ctx_init(&ww, true);
253retry:
254 err = i915_gem_object_lock(vma->obj, &ww);
255 if (!err)
256 err = i915_vma_pin_ww(vma, &ww, size, alignment, flags);
257 if (err == -EDEADLK) {
258 err = i915_gem_ww_ctx_backoff(&ww);
259 if (!err)
260 goto retry;
261 }
262 i915_gem_ww_ctx_fini(&ww);
263
264 return err;
247}265}
248 266
249int i915_ggtt_pin(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,267int i915_ggtt_pin(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
drivers/gpu/drm/i915/selftests/i915_gem_gtt.c+68−26
@@ -121,7 +121,7 @@ fake_dma_object(struct drm_i915_private *i915, u64 size) · 120 unmodified lines
121 goto err;121 goto err;
122 122
123 drm_gem_private_object_init(&i915->drm, &obj->base, size);123 drm_gem_private_object_init(&i915->drm, &obj->base, size);
124 i915_gem_object_init(obj, &fake_ops, &lock_class);124 i915_gem_object_init(obj, &fake_ops, &lock_class, 0);
125 125
126 i915_gem_object_set_volatile(obj);126 i915_gem_object_set_volatile(obj);
127 127
@@ -130,7 +130,7 @@ fake_dma_object(struct drm_i915_private *i915, u64 size) · 2 unmodified lines
130 obj->cache_level = I915_CACHE_NONE;130 obj->cache_level = I915_CACHE_NONE;
131 131
132 /* Preallocate the "backing storage" */132 /* Preallocate the "backing storage" */
133 if (i915_gem_object_pin_pages(obj))133 if (i915_gem_object_pin_pages_unlocked(obj))
134 goto err_obj;134 goto err_obj;
135 135
136 i915_gem_object_unpin_pages(obj);136 i915_gem_object_unpin_pages(obj);
@@ -146,6 +146,7 @@ static int igt_ppgtt_alloc(void *arg) · 9 unmodified lines
146{146{
147 struct drm_i915_private *dev_priv = arg;147 struct drm_i915_private *dev_priv = arg;
148 struct i915_ppgtt *ppgtt;148 struct i915_ppgtt *ppgtt;
149 struct i915_gem_ww_ctx ww;
149 u64 size, last, limit;150 u64 size, last, limit;
150 int err = 0;151 int err = 0;
151 152
@@ -171,6 +172,12 @@ static int igt_ppgtt_alloc(void *arg) · 19 unmodified lines
171 limit = totalram_pages() << PAGE_SHIFT;172 limit = totalram_pages() << PAGE_SHIFT;
172 limit = min(ppgtt->vm.total, limit);173 limit = min(ppgtt->vm.total, limit);
173 174
175 i915_gem_ww_ctx_init(&ww, false);
176retry:
177 err = i915_vm_lock_objects(&ppgtt->vm, &ww);
178 if (err)
179 goto err_ppgtt_cleanup;
180
174 /* Check we can allocate the entire range */181 /* Check we can allocate the entire range */
175 for (size = 4096; size <= limit; size <<= 2) {182 for (size = 4096; size <= limit; size <<= 2) {
176 struct i915_vm_pt_stash stash = {};183 struct i915_vm_pt_stash stash = {};
@@ -215,6 +222,13 @@ static int igt_ppgtt_alloc(void *arg) · 38 unmodified lines
215 }222 }
216 223
217err_ppgtt_cleanup:224err_ppgtt_cleanup:
225 if (err == -EDEADLK) {
226 err = i915_gem_ww_ctx_backoff(&ww);
227 if (!err)
228 goto retry;
229 }
230 i915_gem_ww_ctx_fini(&ww);
231
218 i915_vm_put(&ppgtt->vm);232 i915_vm_put(&ppgtt->vm);
219 return err;233 return err;
220}234}
@@ -276,7 +290,7 @@ static int lowlevel_hole(struct i915_address_space *vm, · 55 unmodified lines
276 290
277 GEM_BUG_ON(obj->base.size != BIT_ULL(size));291 GEM_BUG_ON(obj->base.size != BIT_ULL(size));
278 292
279 if (i915_gem_object_pin_pages(obj)) {293 if (i915_gem_object_pin_pages_unlocked(obj)) {
280 i915_gem_object_put(obj);294 i915_gem_object_put(obj);
281 kfree(order);295 kfree(order);
282 break;296 break;
@@ -297,20 +311,36 @@ static int lowlevel_hole(struct i915_address_space *vm, · 14 unmodified lines
297 311
298 if (vm->allocate_va_range) {312 if (vm->allocate_va_range) {
299 struct i915_vm_pt_stash stash = {};313 struct i915_vm_pt_stash stash = {};
314 struct i915_gem_ww_ctx ww;
315 int err;
316
317 i915_gem_ww_ctx_init(&ww, false);
318retry:
319 err = i915_vm_lock_objects(vm, &ww);
320 if (err)
321 goto alloc_vm_end;
300 322
323 err = -ENOMEM;
301 if (i915_vm_alloc_pt_stash(vm, &stash,324 if (i915_vm_alloc_pt_stash(vm, &stash,
302 BIT_ULL(size)))325 BIT_ULL(size)))
303 break;326 goto alloc_vm_end;
304
305 if (i915_vm_pin_pt_stash(vm, &stash)) {
306 i915_vm_free_pt_stash(vm, &stash);
307 break;
308 }
309 327
310 vm->allocate_va_range(vm, &stash,328 err = i915_vm_pin_pt_stash(vm, &stash);
311 addr, BIT_ULL(size));329 if (!err)
330 vm->allocate_va_range(vm, &stash,
331 addr, BIT_ULL(size));
312 332
313 i915_vm_free_pt_stash(vm, &stash);333 i915_vm_free_pt_stash(vm, &stash);
334alloc_vm_end:
335 if (err == -EDEADLK) {
336 err = i915_gem_ww_ctx_backoff(&ww);
337 if (!err)
338 goto retry;
339 }
340 i915_gem_ww_ctx_fini(&ww);
341
342 if (err)
343 break;
314 }344 }
315 345
316 mock_vma->pages = obj->mm.pages;346 mock_vma->pages = obj->mm.pages;
@@ -1166,7 +1196,7 @@ static int igt_ggtt_page(void *arg) · 849 unmodified lines
1166 if (IS_ERR(obj))1196 if (IS_ERR(obj))
1167 return PTR_ERR(obj);1197 return PTR_ERR(obj);
1168 1198
1169 err = i915_gem_object_pin_pages(obj);1199 err = i915_gem_object_pin_pages_unlocked(obj);
1170 if (err)1200 if (err)
1171 goto out_free;1201 goto out_free;
1172 1202
@@ -1333,7 +1363,7 @@ static int igt_gtt_reserve(void *arg) · 160 unmodified lines
1333 goto out;1363 goto out;
1334 }1364 }
1335 1365
1336 err = i915_gem_object_pin_pages(obj);1366 err = i915_gem_object_pin_pages_unlocked(obj);
1337 if (err) {1367 if (err) {
1338 i915_gem_object_put(obj);1368 i915_gem_object_put(obj);
1339 goto out;1369 goto out;
@@ -1385,7 +1415,7 @@ static int igt_gtt_reserve(void *arg) · 45 unmodified lines
1385 goto out;1415 goto out;
1386 }1416 }
1387 1417
1388 err = i915_gem_object_pin_pages(obj);1418 err = i915_gem_object_pin_pages_unlocked(obj);
1389 if (err) {1419 if (err) {
1390 i915_gem_object_put(obj);1420 i915_gem_object_put(obj);
1391 goto out;1421 goto out;
@@ -1549,7 +1579,7 @@ static int igt_gtt_insert(void *arg) · 157 unmodified lines
1549 goto out;1579 goto out;
1550 }1580 }
1551 1581
1552 err = i915_gem_object_pin_pages(obj);1582 err = i915_gem_object_pin_pages_unlocked(obj);
1553 if (err) {1583 if (err) {
1554 i915_gem_object_put(obj);1584 i915_gem_object_put(obj);
1555 goto out;1585 goto out;
@@ -1658,7 +1688,7 @@ static int igt_gtt_insert(void *arg) · 102 unmodified lines
1658 goto out;1688 goto out;
1659 }1689 }
1660 1690
1661 err = i915_gem_object_pin_pages(obj);1691 err = i915_gem_object_pin_pages_unlocked(obj);
1662 if (err) {1692 if (err) {
1663 i915_gem_object_put(obj);1693 i915_gem_object_put(obj);
1664 goto out;1694 goto out;
@@ -1829,7 +1859,7 @@ static int igt_cs_tlb(void *arg) · 164 unmodified lines
1829 goto out_vm;1859 goto out_vm;
1830 }1860 }
1831 1861
1832 batch = i915_gem_object_pin_map(bbe, I915_MAP_WC);1862 batch = i915_gem_object_pin_map_unlocked(bbe, I915_MAP_WC);
1833 if (IS_ERR(batch)) {1863 if (IS_ERR(batch)) {
1834 err = PTR_ERR(batch);1864 err = PTR_ERR(batch);
1835 goto out_put_bbe;1865 goto out_put_bbe;
@@ -1845,7 +1875,7 @@ static int igt_cs_tlb(void *arg) · 9 unmodified lines
1845 }1875 }
1846 1876
1847 /* Track the execution of each request by writing into different slot */1877 /* Track the execution of each request by writing into different slot */
1848 batch = i915_gem_object_pin_map(act, I915_MAP_WC);1878 batch = i915_gem_object_pin_map_unlocked(act, I915_MAP_WC);
1849 if (IS_ERR(batch)) {1879 if (IS_ERR(batch)) {
1850 err = PTR_ERR(batch);1880 err = PTR_ERR(batch);
1851 goto out_put_act;1881 goto out_put_act;
@@ -1892,7 +1922,7 @@ static int igt_cs_tlb(void *arg) · 40 unmodified lines
1892 goto out_put_out;1922 goto out_put_out;
1893 GEM_BUG_ON(vma->node.start != vm->total - PAGE_SIZE);1923 GEM_BUG_ON(vma->node.start != vm->total - PAGE_SIZE);
1894 1924
1895 result = i915_gem_object_pin_map(out, I915_MAP_WB);1925 result = i915_gem_object_pin_map_unlocked(out, I915_MAP_WB);
1896 if (IS_ERR(result)) {1926 if (IS_ERR(result)) {
1897 err = PTR_ERR(result);1927 err = PTR_ERR(result);
1898 goto out_put_out;1928 goto out_put_out;
@@ -1908,6 +1938,7 @@ static int igt_cs_tlb(void *arg) · 9 unmodified lines
1908 while (!__igt_timeout(end_time, NULL)) {1938 while (!__igt_timeout(end_time, NULL)) {
1909 struct i915_vm_pt_stash stash = {};1939 struct i915_vm_pt_stash stash = {};
1910 struct i915_request *rq;1940 struct i915_request *rq;
1941 struct i915_gem_ww_ctx ww;
1911 u64 offset;1942 u64 offset;
1912 1943
1913 offset = igt_random_offset(&prng,1944 offset = igt_random_offset(&prng,
@@ -1926,19 +1957,30 @@ static int igt_cs_tlb(void *arg) · 12 unmodified lines
1926 if (err)1957 if (err)
1927 goto end;1958 goto end;
1928 1959
1960 i915_gem_ww_ctx_init(&ww, false);
1961retry:
1962 err = i915_vm_lock_objects(vm, &ww);
1963 if (err)
1964 goto end_ww;
1965
1929 err = i915_vm_alloc_pt_stash(vm, &stash, chunk_size);1966 err = i915_vm_alloc_pt_stash(vm, &stash, chunk_size);
1930 if (err)1967 if (err)
1931 goto end;1968 goto end_ww;
1932 1969
1933 err = i915_vm_pin_pt_stash(vm, &stash);1970 err = i915_vm_pin_pt_stash(vm, &stash);
1934 if (err) {1971 if (!err)
1935 i915_vm_free_pt_stash(vm, &stash);1972 vm->allocate_va_range(vm, &stash, offset, chunk_size);
1936 goto end;
1937 }
1938
1939 vm->allocate_va_range(vm, &stash, offset, chunk_size);
1940 1973
1941 i915_vm_free_pt_stash(vm, &stash);1974 i915_vm_free_pt_stash(vm, &stash);
1975end_ww:
1976 if (err == -EDEADLK) {
1977 err = i915_gem_ww_ctx_backoff(&ww);
1978 if (!err)
1979 goto retry;
1980 }
1981 i915_gem_ww_ctx_fini(&ww);
1982 if (err)
1983 goto end;
1942 1984
1943 /* Prime the TLB with the dummy pages */1985 /* Prime the TLB with the dummy pages */
1944 for (i = 0; i < count; i++) {1986 for (i = 0; i < count; i++) {
drivers/gpu/drm/i915/selftests/i915_request.c+206−5
@@ -609,6 +609,206 @@ static int live_nop_request(void *arg) · 608 unmodified lines
609 return err;609 return err;
610}610}
611 611
612static int __cancel_inactive(struct intel_engine_cs *engine)
613{
614 struct intel_context *ce;
615 struct igt_spinner spin;
616 struct i915_request *rq;
617 int err = 0;
618
619 if (igt_spinner_init(&spin, engine->gt))
620 return -ENOMEM;
621
622 ce = intel_context_create(engine);
623 if (IS_ERR(ce)) {
624 err = PTR_ERR(ce);
625 goto out_spin;
626 }
627
628 rq = igt_spinner_create_request(&spin, ce, MI_ARB_CHECK);
629 if (IS_ERR(rq)) {
630 err = PTR_ERR(rq);
631 goto out_ce;
632 }
633
634 pr_debug("%s: Cancelling inactive request\n", engine->name);
635 i915_request_cancel(rq, -EINTR);
636 i915_request_get(rq);
637 i915_request_add(rq);
638
639 if (i915_request_wait(rq, 0, HZ / 5) < 0) {
640 struct drm_printer p = drm_info_printer(engine->i915->drm.dev);
641
642 pr_err("%s: Failed to cancel inactive request\n", engine->name);
643 intel_engine_dump(engine, &p, "%s\n", engine->name);
644 err = -ETIME;
645 goto out_rq;
646 }
647
648 if (rq->fence.error != -EINTR) {
649 pr_err("%s: fence not cancelled (%u)\n",
650 engine->name, rq->fence.error);
651 err = -EINVAL;
652 }
653
654out_rq:
655 i915_request_put(rq);
656out_ce:
657 intel_context_put(ce);
658out_spin:
659 igt_spinner_fini(&spin);
660 if (err)
661 pr_err("%s: %s error %d\n", __func__, engine->name, err);
662 return err;
663}
664
665static int __cancel_active(struct intel_engine_cs *engine)
666{
667 struct intel_context *ce;
668 struct igt_spinner spin;
669 struct i915_request *rq;
670 int err = 0;
671
672 if (igt_spinner_init(&spin, engine->gt))
673 return -ENOMEM;
674
675 ce = intel_context_create(engine);
676 if (IS_ERR(ce)) {
677 err = PTR_ERR(ce);
678 goto out_spin;
679 }
680
681 rq = igt_spinner_create_request(&spin, ce, MI_ARB_CHECK);
682 if (IS_ERR(rq)) {
683 err = PTR_ERR(rq);
684 goto out_ce;
685 }
686
687 pr_debug("%s: Cancelling active request\n", engine->name);
688 i915_request_get(rq);
689 i915_request_add(rq);
690 if (!igt_wait_for_spinner(&spin, rq)) {
691 struct drm_printer p = drm_info_printer(engine->i915->drm.dev);
692
693 pr_err("Failed to start spinner on %s\n", engine->name);
694 intel_engine_dump(engine, &p, "%s\n", engine->name);
695 err = -ETIME;
696 goto out_rq;
697 }
698 i915_request_cancel(rq, -EINTR);
699
700 if (i915_request_wait(rq, 0, HZ / 5) < 0) {
701 struct drm_printer p = drm_info_printer(engine->i915->drm.dev);
702
703 pr_err("%s: Failed to cancel active request\n", engine->name);
704 intel_engine_dump(engine, &p, "%s\n", engine->name);
705 err = -ETIME;
706 goto out_rq;
707 }
708
709 if (rq->fence.error != -EINTR) {
710 pr_err("%s: fence not cancelled (%u)\n",
711 engine->name, rq->fence.error);
712 err = -EINVAL;
713 }
714
715out_rq:
716 i915_request_put(rq);
717out_ce:
718 intel_context_put(ce);
719out_spin:
720 igt_spinner_fini(&spin);
721 if (err)
722 pr_err("%s: %s error %d\n", __func__, engine->name, err);
723 return err;
724}
725
726static int __cancel_completed(struct intel_engine_cs *engine)
727{
728 struct intel_context *ce;
729 struct igt_spinner spin;
730 struct i915_request *rq;
731 int err = 0;
732
733 if (igt_spinner_init(&spin, engine->gt))
734 return -ENOMEM;
735
736 ce = intel_context_create(engine);
737 if (IS_ERR(ce)) {
738 err = PTR_ERR(ce);
739 goto out_spin;
740 }
741
742 rq = igt_spinner_create_request(&spin, ce, MI_ARB_CHECK);
743 if (IS_ERR(rq)) {
744 err = PTR_ERR(rq);
745 goto out_ce;
746 }
747 igt_spinner_end(&spin);
748 i915_request_get(rq);
749 i915_request_add(rq);
750
751 if (i915_request_wait(rq, 0, HZ / 5) < 0) {
752 err = -ETIME;
753 goto out_rq;
754 }
755
756 pr_debug("%s: Cancelling completed request\n", engine->name);
757 i915_request_cancel(rq, -EINTR);
758 if (rq->fence.error) {
759 pr_err("%s: fence not cancelled (%u)\n",
760 engine->name, rq->fence.error);
761 err = -EINVAL;
762 }
763
764out_rq:
765 i915_request_put(rq);
766out_ce:
767 intel_context_put(ce);
768out_spin:
769 igt_spinner_fini(&spin);
770 if (err)
771 pr_err("%s: %s error %d\n", __func__, engine->name, err);
772 return err;
773}
774
775static int live_cancel_request(void *arg)
776{
777 struct drm_i915_private *i915 = arg;
778 struct intel_engine_cs *engine;
779
780 /*
781 * Check cancellation of requests. We expect to be able to immediately
782 * cancel active requests, even if they are currently on the GPU.
783 */
784
785 for_each_uabi_engine(engine, i915) {
786 struct igt_live_test t;
787 int err, err2;
788
789 if (!intel_engine_has_preemption(engine))
790 continue;
791
792 err = igt_live_test_begin(&t, i915, __func__, engine->name);
793 if (err)
794 return err;
795
796 err = __cancel_inactive(engine);
797 if (err == 0)
798 err = __cancel_active(engine);
799 if (err == 0)
800 err = __cancel_completed(engine);
801
802 err2 = igt_live_test_end(&t);
803 if (err)
804 return err;
805 if (err2)
806 return err2;
807 }
808
809 return 0;
810}
811
612static struct i915_vma *empty_batch(struct drm_i915_private *i915)812static struct i915_vma *empty_batch(struct drm_i915_private *i915)
613{813{
614 struct drm_i915_gem_object *obj;814 struct drm_i915_gem_object *obj;
@@ -620,7 +820,7 @@ static struct i915_vma *empty_batch(struct drm_i915_private *i915) · 5 unmodified lines
620 if (IS_ERR(obj))820 if (IS_ERR(obj))
621 return ERR_CAST(obj);821 return ERR_CAST(obj);
622 822
623 cmd = i915_gem_object_pin_map(obj, I915_MAP_WB);823 cmd = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WB);
624 if (IS_ERR(cmd)) {824 if (IS_ERR(cmd)) {
625 err = PTR_ERR(cmd);825 err = PTR_ERR(cmd);
626 goto err;826 goto err;
@@ -782,7 +982,7 @@ static struct i915_vma *recursive_batch(struct drm_i915_private *i915) · 155 unmodified lines
782 if (err)982 if (err)
783 goto err;983 goto err;
784 984
785 cmd = i915_gem_object_pin_map(obj, I915_MAP_WC);985 cmd = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WC);
786 if (IS_ERR(cmd)) {986 if (IS_ERR(cmd)) {
787 err = PTR_ERR(cmd);987 err = PTR_ERR(cmd);
788 goto err;988 goto err;
@@ -817,7 +1017,7 @@ static int recursive_batch_resolve(struct i915_vma *batch) · 28 unmodified lines
817{1017{
818 u32 *cmd;1018 u32 *cmd;
819 1019
820 cmd = i915_gem_object_pin_map(batch->obj, I915_MAP_WC);1020 cmd = i915_gem_object_pin_map_unlocked(batch->obj, I915_MAP_WC);
821 if (IS_ERR(cmd))1021 if (IS_ERR(cmd))
822 return PTR_ERR(cmd);1022 return PTR_ERR(cmd);
823 1023
@@ -1070,8 +1270,8 @@ out_request: · 246 unmodified lines
1070 if (!request[idx])1270 if (!request[idx])
1071 break;1271 break;
1072 1272
1073 cmd = i915_gem_object_pin_map(request[idx]->batch->obj,1273 cmd = i915_gem_object_pin_map_unlocked(request[idx]->batch->obj,
1074 I915_MAP_WC);1274 I915_MAP_WC);
1075 if (!IS_ERR(cmd)) {1275 if (!IS_ERR(cmd)) {
1076 *cmd = MI_BATCH_BUFFER_END;1276 *cmd = MI_BATCH_BUFFER_END;
1077 1277
@@ -1486,6 +1686,7 @@ int i915_request_live_selftests(struct drm_i915_private *i915) · 408 unmodified lines
1486 SUBTEST(live_sequential_engines),1686 SUBTEST(live_sequential_engines),
1487 SUBTEST(live_parallel_engines),1687 SUBTEST(live_parallel_engines),
1488 SUBTEST(live_empty_request),1688 SUBTEST(live_empty_request),
1689 SUBTEST(live_cancel_request),
1489 SUBTEST(live_breadcrumbs_smoketest),1690 SUBTEST(live_breadcrumbs_smoketest),
1490 };1691 };
1491 1692
drivers/gpu/drm/i915/selftests/igt_spinner.c+90−46
@@ -12,8 +12,6 @@ · 11 unmodified lines
12 12
13int igt_spinner_init(struct igt_spinner *spin, struct intel_gt *gt)13int igt_spinner_init(struct igt_spinner *spin, struct intel_gt *gt)
14{14{
15 unsigned int mode;
16 void *vaddr;
17 int err;15 int err;
18 16
19 memset(spin, 0, sizeof(*spin));17 memset(spin, 0, sizeof(*spin));
@@ -24,6 +22,7 @@ int igt_spinner_init(struct igt_spinner *spin, struct intel_gt *gt) · 4 unmodified lines
24 err = PTR_ERR(spin->hws);22 err = PTR_ERR(spin->hws);
25 goto err;23 goto err;
26 }24 }
25 i915_gem_object_set_cache_coherency(spin->hws, I915_CACHE_LLC);
27 26
28 spin->obj = i915_gem_object_create_internal(gt->i915, PAGE_SIZE);27 spin->obj = i915_gem_object_create_internal(gt->i915, PAGE_SIZE);
29 if (IS_ERR(spin->obj)) {28 if (IS_ERR(spin->obj)) {
@@ -31,34 +30,83 @@ int igt_spinner_init(struct igt_spinner *spin, struct intel_gt *gt) · 1 unmodified line
31 goto err_hws;30 goto err_hws;
32 }31 }
33 32
34 i915_gem_object_set_cache_coherency(spin->hws, I915_CACHE_LLC);
35 vaddr = i915_gem_object_pin_map(spin->hws, I915_MAP_WB);
36 if (IS_ERR(vaddr)) {
37 err = PTR_ERR(vaddr);
38 goto err_obj;
39 }
40 spin->seqno = memset(vaddr, 0xff, PAGE_SIZE);
41
42 mode = i915_coherent_map_type(gt->i915);
43 vaddr = i915_gem_object_pin_map(spin->obj, mode);
44 if (IS_ERR(vaddr)) {
45 err = PTR_ERR(vaddr);
46 goto err_unpin_hws;
47 }
48 spin->batch = vaddr;
49
50 return 0;33 return 0;
51 34
52err_unpin_hws:
53 i915_gem_object_unpin_map(spin->hws);
54err_obj:
55 i915_gem_object_put(spin->obj);
56err_hws:35err_hws:
57 i915_gem_object_put(spin->hws);36 i915_gem_object_put(spin->hws);
58err:37err:
59 return err;38 return err;
60}39}
61 40
41static void *igt_spinner_pin_obj(struct intel_context *ce,
42 struct i915_gem_ww_ctx *ww,
43 struct drm_i915_gem_object *obj,
44 unsigned int mode, struct i915_vma **vma)
45{
46 void *vaddr;
47 int ret;
48
49 *vma = i915_vma_instance(obj, ce->vm, NULL);
50 if (IS_ERR(*vma))
51 return ERR_CAST(*vma);
52
53 ret = i915_gem_object_lock(obj, ww);
54 if (ret)
55 return ERR_PTR(ret);
56
57 vaddr = i915_gem_object_pin_map(obj, mode);
58
59 if (!ww)
60 i915_gem_object_unlock(obj);
61
62 if (IS_ERR(vaddr))
63 return vaddr;
64
65 if (ww)
66 ret = i915_vma_pin_ww(*vma, ww, 0, 0, PIN_USER);
67 else
68 ret = i915_vma_pin(*vma, 0, 0, PIN_USER);
69
70 if (ret) {
71 i915_gem_object_unpin_map(obj);
72 return ERR_PTR(ret);
73 }
74
75 return vaddr;
76}
77
78int igt_spinner_pin(struct igt_spinner *spin,
79 struct intel_context *ce,
80 struct i915_gem_ww_ctx *ww)
81{
82 void *vaddr;
83
84 if (spin->ce && WARN_ON(spin->ce != ce))
85 return -ENODEV;
86 spin->ce = ce;
87
88 if (!spin->seqno) {
89 vaddr = igt_spinner_pin_obj(ce, ww, spin->hws, I915_MAP_WB, &spin->hws_vma);
90 if (IS_ERR(vaddr))
91 return PTR_ERR(vaddr);
92
93 spin->seqno = memset(vaddr, 0xff, PAGE_SIZE);
94 }
95
96 if (!spin->batch) {
97 unsigned int mode =
98 i915_coherent_map_type(spin->gt->i915);
99
100 vaddr = igt_spinner_pin_obj(ce, ww, spin->obj, mode, &spin->batch_vma);
101 if (IS_ERR(vaddr))
102 return PTR_ERR(vaddr);
103
104 spin->batch = vaddr;
105 }
106
107 return 0;
108}
109
62static unsigned int seqno_offset(u64 fence)110static unsigned int seqno_offset(u64 fence)
63{111{
64 return offset_in_page(sizeof(u32) * fence);112 return offset_in_page(sizeof(u32) * fence);
@@ -103,27 +151,18 @@ igt_spinner_create_request(struct igt_spinner *spin, · 38 unmodified lines
103 if (!intel_engine_can_store_dword(ce->engine))151 if (!intel_engine_can_store_dword(ce->engine))
104 return ERR_PTR(-ENODEV);152 return ERR_PTR(-ENODEV);
105 153
106 vma = i915_vma_instance(spin->obj, ce->vm, NULL);154 if (!spin->batch) {
107 if (IS_ERR(vma))155 err = igt_spinner_pin(spin, ce, NULL);
108 return ERR_CAST(vma);156 if (err)
109 157 return ERR_PTR(err);
110 hws = i915_vma_instance(spin->hws, ce->vm, NULL);158 }
111 if (IS_ERR(hws))
112 return ERR_CAST(hws);
113 159
114 err = i915_vma_pin(vma, 0, 0, PIN_USER);160 hws = spin->hws_vma;
115 if (err)161 vma = spin->batch_vma;
116 return ERR_PTR(err);
117
118 err = i915_vma_pin(hws, 0, 0, PIN_USER);
119 if (err)
120 goto unpin_vma;
121 162
122 rq = intel_context_create_request(ce);163 rq = intel_context_create_request(ce);
123 if (IS_ERR(rq)) {164 if (IS_ERR(rq))
124 err = PTR_ERR(rq);165 return ERR_CAST(rq);
125 goto unpin_hws;
126 }
127 166
128 err = move_to_active(vma, rq, 0);167 err = move_to_active(vma, rq, 0);
129 if (err)168 if (err)
@@ -186,10 +225,6 @@ cancel_rq: · 56 unmodified lines
186 i915_request_set_error_once(rq, err);225 i915_request_set_error_once(rq, err);
187 i915_request_add(rq);226 i915_request_add(rq);
188 }227 }
189unpin_hws:
190 i915_vma_unpin(hws);
191unpin_vma:
192 i915_vma_unpin(vma);
193 return err ? ERR_PTR(err) : rq;228 return err ? ERR_PTR(err) : rq;
194}229}
195 230
@@ -203,6 +238,9 @@ hws_seqno(const struct igt_spinner *spin, const struct i915_request *rq) · 7 unmodified lines
203 238
204void igt_spinner_end(struct igt_spinner *spin)239void igt_spinner_end(struct igt_spinner *spin)
205{240{
241 if (!spin->batch)
242 return;
243
206 *spin->batch = MI_BATCH_BUFFER_END;244 *spin->batch = MI_BATCH_BUFFER_END;
207 intel_gt_chipset_flush(spin->gt);245 intel_gt_chipset_flush(spin->gt);
208}246}
@@ -211,10 +249,16 @@ void igt_spinner_fini(struct igt_spinner *spin) · 2 unmodified lines
211{249{
212 igt_spinner_end(spin);250 igt_spinner_end(spin);
213 251
214 i915_gem_object_unpin_map(spin->obj);252 if (spin->batch) {
253 i915_vma_unpin(spin->batch_vma);
254 i915_gem_object_unpin_map(spin->obj);
255 }
215 i915_gem_object_put(spin->obj);256 i915_gem_object_put(spin->obj);
216 257
217 i915_gem_object_unpin_map(spin->hws);258 if (spin->seqno) {
259 i915_vma_unpin(spin->hws_vma);
260 i915_gem_object_unpin_map(spin->hws);
261 }
218 i915_gem_object_put(spin->hws);262 i915_gem_object_put(spin->hws);
219}263}
220 264
drivers/gpu/drm/i915/selftests/igt_spinner.h+5−0
@@ -20,11 +20,16 @@ struct igt_spinner { · 19 unmodified lines
20 struct intel_gt *gt;20 struct intel_gt *gt;
21 struct drm_i915_gem_object *hws;21 struct drm_i915_gem_object *hws;
22 struct drm_i915_gem_object *obj;22 struct drm_i915_gem_object *obj;
23 struct intel_context *ce;
24 struct i915_vma *hws_vma, *batch_vma;
23 u32 *batch;25 u32 *batch;
24 void *seqno;26 void *seqno;
25};27};
26 28
27int igt_spinner_init(struct igt_spinner *spin, struct intel_gt *gt);29int igt_spinner_init(struct igt_spinner *spin, struct intel_gt *gt);
30int igt_spinner_pin(struct igt_spinner *spin,
31 struct intel_context *ce,
32 struct i915_gem_ww_ctx *ww);
28void igt_spinner_fini(struct igt_spinner *spin);33void igt_spinner_fini(struct igt_spinner *spin);
29 34
30struct i915_request *35struct i915_request *
drivers/gpu/drm/i915/selftests/intel_memory_region.c+11−7
@@ -31,10 +31,12 @@ static void close_objects(struct intel_memory_region *mem, · 30 unmodified lines
31 struct drm_i915_gem_object *obj, *on;31 struct drm_i915_gem_object *obj, *on;
32 32
33 list_for_each_entry_safe(obj, on, objects, st_link) {33 list_for_each_entry_safe(obj, on, objects, st_link) {
34 i915_gem_object_lock(obj, NULL);
34 if (i915_gem_object_has_pinned_pages(obj))35 if (i915_gem_object_has_pinned_pages(obj))
35 i915_gem_object_unpin_pages(obj);36 i915_gem_object_unpin_pages(obj);
36 /* No polluting the memory region between tests */37 /* No polluting the memory region between tests */
37 __i915_gem_object_put_pages(obj);38 __i915_gem_object_put_pages(obj);
39 i915_gem_object_unlock(obj);
38 list_del(&obj->st_link);40 list_del(&obj->st_link);
39 i915_gem_object_put(obj);41 i915_gem_object_put(obj);
40 }42 }
@@ -69,7 +71,7 @@ static int igt_mock_fill(void *arg) · 28 unmodified lines
69 break;71 break;
70 }72 }
71 73
72 err = i915_gem_object_pin_pages(obj);74 err = i915_gem_object_pin_pages_unlocked(obj);
73 if (err) {75 if (err) {
74 i915_gem_object_put(obj);76 i915_gem_object_put(obj);
75 break;77 break;
@@ -109,7 +111,7 @@ igt_object_create(struct intel_memory_region *mem, · 33 unmodified lines
109 if (IS_ERR(obj))111 if (IS_ERR(obj))
110 return obj;112 return obj;
111 113
112 err = i915_gem_object_pin_pages(obj);114 err = i915_gem_object_pin_pages_unlocked(obj);
113 if (err)115 if (err)
114 goto put;116 goto put;
115 117
@@ -123,8 +125,10 @@ put: · 7 unmodified lines
123 125
124static void igt_object_release(struct drm_i915_gem_object *obj)126static void igt_object_release(struct drm_i915_gem_object *obj)
125{127{
128 i915_gem_object_lock(obj, NULL);
126 i915_gem_object_unpin_pages(obj);129 i915_gem_object_unpin_pages(obj);
127 __i915_gem_object_put_pages(obj);130 __i915_gem_object_put_pages(obj);
131 i915_gem_object_unlock(obj);
128 list_del(&obj->st_link);132 list_del(&obj->st_link);
129 i915_gem_object_put(obj);133 i915_gem_object_put(obj);
130}134}
@@ -433,7 +437,7 @@ static int igt_cpu_check(struct drm_i915_gem_object *obj, u32 dword, u32 val) · 302 unmodified lines
433 if (err)437 if (err)
434 return err;438 return err;
435 439
436 ptr = i915_gem_object_pin_map(obj, I915_MAP_WC);440 ptr = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WC);
437 if (IS_ERR(ptr))441 if (IS_ERR(ptr))
438 return PTR_ERR(ptr);442 return PTR_ERR(ptr);
439 443
@@ -538,7 +542,7 @@ static int igt_lmem_create(void *arg) · 98 unmodified lines
538 if (IS_ERR(obj))542 if (IS_ERR(obj))
539 return PTR_ERR(obj);543 return PTR_ERR(obj);
540 544
541 err = i915_gem_object_pin_pages(obj);545 err = i915_gem_object_pin_pages_unlocked(obj);
542 if (err)546 if (err)
543 goto out_put;547 goto out_put;
544 548
@@ -577,7 +581,7 @@ static int igt_lmem_write_gpu(void *arg) · 32 unmodified lines
577 goto out_file;581 goto out_file;
578 }582 }
579 583
580 err = i915_gem_object_pin_pages(obj);584 err = i915_gem_object_pin_pages_unlocked(obj);
581 if (err)585 if (err)
582 goto out_put;586 goto out_put;
583 587
@@ -649,7 +653,7 @@ static int igt_lmem_write_cpu(void *arg) · 65 unmodified lines
649 if (IS_ERR(obj))653 if (IS_ERR(obj))
650 return PTR_ERR(obj);654 return PTR_ERR(obj);
651 655
652 vaddr = i915_gem_object_pin_map(obj, I915_MAP_WC);656 vaddr = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WC);
653 if (IS_ERR(vaddr)) {657 if (IS_ERR(vaddr)) {
654 err = PTR_ERR(vaddr);658 err = PTR_ERR(vaddr);
655 goto out_put;659 goto out_put;
@@ -753,7 +757,7 @@ create_region_for_mapping(struct intel_memory_region *mr, u64 size, u32 type, · 97 unmodified lines
753 return obj;757 return obj;
754 }758 }
755 759
756 addr = i915_gem_object_pin_map(obj, type);760 addr = i915_gem_object_pin_map_unlocked(obj, type);
757 if (IS_ERR(addr)) {761 if (IS_ERR(addr)) {
758 i915_gem_object_put(obj);762 i915_gem_object_put(obj);
759 if (PTR_ERR(addr) == -ENXIO)763 if (PTR_ERR(addr) == -ENXIO)
drivers/gpu/drm/i915/selftests/mock_region.c+2−2
@@ -27,13 +27,13 @@ static int mock_object_init(struct intel_memory_region *mem, · 26 unmodified lines
27 return -E2BIG;27 return -E2BIG;
28 28
29 drm_gem_private_object_init(&i915->drm, &obj->base, size);29 drm_gem_private_object_init(&i915->drm, &obj->base, size);
30 i915_gem_object_init(obj, &mock_region_obj_ops, &lock_class);30 i915_gem_object_init(obj, &mock_region_obj_ops, &lock_class, flags);
31 31
32 obj->read_domains = I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT;32 obj->read_domains = I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT;
33 33
34 i915_gem_object_set_cache_coherency(obj, I915_CACHE_NONE);34 i915_gem_object_set_cache_coherency(obj, I915_CACHE_NONE);
35 35
36 i915_gem_object_init_memory_region(obj, mem, flags);36 i915_gem_object_init_memory_region(obj, mem);
37 37
38 return 0;38 return 0;
39}39}
include/uapi/drm/i915_drm.h+1−0
@@ -943,6 +943,7 @@ struct drm_i915_gem_exec_object { · 942 unmodified lines
943 __u64 offset;943 __u64 offset;
944};944};
945 945
946/* DRM_IOCTL_I915_GEM_EXECBUFFER was removed in Linux 5.13 */
946struct drm_i915_gem_execbuffer {947struct drm_i915_gem_execbuffer {
947 /**948 /**
948 * List of buffers to be validated with their relocations to be949 * List of buffers to be validated with their relocations to be