Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'drm-intel-next-fixes-2020-06-04' of git://anongit.freedesktop.org/drm/drm-intel into drm-next

- Includes gvt-next-fixes-2020-05-28
- Use after free fix for display global state.
- Whitelisting context-local timestamp on Gen9
and two scheduler fixes with deps (Cc: stable)
- Removal of write flag from sysfs files where
ineffective

Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200604150454.GA59322@jlahtine-desk.ger.corp.intel.com

+308 -172
+39 -6
drivers/gpu/drm/i915/display/intel_global_state.c
··· 10 10 #include "intel_display_types.h" 11 11 #include "intel_global_state.h" 12 12 13 + static void __intel_atomic_global_state_free(struct kref *kref) 14 + { 15 + struct intel_global_state *obj_state = 16 + container_of(kref, struct intel_global_state, ref); 17 + struct intel_global_obj *obj = obj_state->obj; 18 + 19 + obj->funcs->atomic_destroy_state(obj, obj_state); 20 + } 21 + 22 + static void intel_atomic_global_state_put(struct intel_global_state *obj_state) 23 + { 24 + kref_put(&obj_state->ref, __intel_atomic_global_state_free); 25 + } 26 + 27 + static struct intel_global_state * 28 + intel_atomic_global_state_get(struct intel_global_state *obj_state) 29 + { 30 + kref_get(&obj_state->ref); 31 + 32 + return obj_state; 33 + } 34 + 13 35 void intel_atomic_global_obj_init(struct drm_i915_private *dev_priv, 14 36 struct intel_global_obj *obj, 15 37 struct intel_global_state *state, 16 38 const struct intel_global_state_funcs *funcs) 17 39 { 18 40 memset(obj, 0, sizeof(*obj)); 41 + 42 + state->obj = obj; 43 + 44 + kref_init(&state->ref); 19 45 20 46 obj->state = state; 21 47 obj->funcs = funcs; ··· 54 28 55 29 list_for_each_entry_safe(obj, next, &dev_priv->global_obj_list, head) { 56 30 list_del(&obj->head); 57 - obj->funcs->atomic_destroy_state(obj, obj->state); 31 + 32 + drm_WARN_ON(&dev_priv->drm, kref_read(&obj->state->ref) != 1); 33 + intel_atomic_global_state_put(obj->state); 58 34 } 59 35 } 60 36 ··· 125 97 if (!obj_state) 126 98 return ERR_PTR(-ENOMEM); 127 99 100 + obj_state->obj = obj; 128 101 obj_state->changed = false; 129 102 103 + kref_init(&obj_state->ref); 104 + 130 105 state->global_objs[index].state = obj_state; 131 - state->global_objs[index].old_state = obj->state; 106 + state->global_objs[index].old_state = 107 + intel_atomic_global_state_get(obj->state); 132 108 state->global_objs[index].new_state = obj_state; 133 109 state->global_objs[index].ptr = obj; 134 110 obj_state->state = state; ··· 195 163 new_obj_state->state = NULL; 196 164 197 165 state->global_objs[i].state = old_obj_state; 198 - obj->state = new_obj_state; 166 + 167 + intel_atomic_global_state_put(obj->state); 168 + obj->state = intel_atomic_global_state_get(new_obj_state); 199 169 } 200 170 } 201 171 ··· 206 172 int i; 207 173 208 174 for (i = 0; i < state->num_global_objs; i++) { 209 - struct intel_global_obj *obj = state->global_objs[i].ptr; 175 + intel_atomic_global_state_put(state->global_objs[i].old_state); 176 + intel_atomic_global_state_put(state->global_objs[i].new_state); 210 177 211 - obj->funcs->atomic_destroy_state(obj, 212 - state->global_objs[i].state); 213 178 state->global_objs[i].ptr = NULL; 214 179 state->global_objs[i].state = NULL; 215 180 state->global_objs[i].old_state = NULL;
+3
drivers/gpu/drm/i915/display/intel_global_state.h
··· 6 6 #ifndef __INTEL_GLOBAL_STATE_H__ 7 7 #define __INTEL_GLOBAL_STATE_H__ 8 8 9 + #include <linux/kref.h> 9 10 #include <linux/list.h> 10 11 11 12 struct drm_i915_private; ··· 55 54 for_each_if(obj) 56 55 57 56 struct intel_global_state { 57 + struct intel_global_obj *obj; 58 58 struct intel_atomic_state *state; 59 + struct kref ref; 59 60 bool changed; 60 61 }; 61 62
+2 -2
drivers/gpu/drm/i915/gem/i915_gem_context.c
··· 230 230 ce->timeline = intel_timeline_get(ctx->timeline); 231 231 232 232 if (ctx->sched.priority >= I915_PRIORITY_NORMAL && 233 - intel_engine_has_semaphores(ce->engine)) 233 + intel_engine_has_timeslices(ce->engine)) 234 234 __set_bit(CONTEXT_USE_SEMAPHORES, &ce->flags); 235 235 } 236 236 ··· 1969 1969 { 1970 1970 struct i915_gem_context *ctx = arg; 1971 1971 1972 - if (!intel_engine_has_semaphores(ce->engine)) 1972 + if (!intel_engine_has_timeslices(ce->engine)) 1973 1973 return 0; 1974 1974 1975 1975 if (ctx->sched.priority >= I915_PRIORITY_NORMAL)
+9 -6
drivers/gpu/drm/i915/gem/i915_gem_shmem.c
··· 39 39 unsigned long last_pfn = 0; /* suppress gcc warning */ 40 40 unsigned int max_segment = i915_sg_segment_size(); 41 41 unsigned int sg_page_sizes; 42 - struct pagevec pvec; 43 42 gfp_t noreclaim; 44 43 int ret; 45 44 ··· 191 192 sg_mark_end(sg); 192 193 err_pages: 193 194 mapping_clear_unevictable(mapping); 194 - pagevec_init(&pvec); 195 - for_each_sgt_page(page, sgt_iter, st) { 196 - if (!pagevec_add(&pvec, page)) 195 + if (sg != st->sgl) { 196 + struct pagevec pvec; 197 + 198 + pagevec_init(&pvec); 199 + for_each_sgt_page(page, sgt_iter, st) { 200 + if (!pagevec_add(&pvec, page)) 201 + check_release_pagevec(&pvec); 202 + } 203 + if (pagevec_count(&pvec)) 197 204 check_release_pagevec(&pvec); 198 205 } 199 - if (pagevec_count(&pvec)) 200 - check_release_pagevec(&pvec); 201 206 sg_free_table(st); 202 207 kfree(st); 203 208
-2
drivers/gpu/drm/i915/gt/intel_context.c
··· 97 97 { 98 98 int err; 99 99 100 - GEM_BUG_ON(intel_context_is_closed(ce)); 101 - 102 100 if (unlikely(!test_bit(CONTEXT_ALLOC_BIT, &ce->flags))) { 103 101 err = intel_context_alloc_state(ce); 104 102 if (err)
+1 -1
drivers/gpu/drm/i915/gvt/vgpu.c
··· 124 124 */ 125 125 low_avail = gvt_aperture_sz(gvt) - HOST_LOW_GM_SIZE; 126 126 high_avail = gvt_hidden_sz(gvt) - HOST_HIGH_GM_SIZE; 127 - num_types = sizeof(vgpu_types) / sizeof(vgpu_types[0]); 127 + num_types = ARRAY_SIZE(vgpu_types); 128 128 129 129 gvt->types = kcalloc(num_types, sizeof(struct intel_vgpu_type), 130 130 GFP_KERNEL);
+4
drivers/gpu/drm/i915/i915_cmd_parser.c
··· 572 572 #define REG32(_reg, ...) \ 573 573 { .addr = (_reg), __VA_ARGS__ } 574 574 575 + #define REG32_IDX(_reg, idx) \ 576 + { .addr = _reg(idx) } 577 + 575 578 /* 576 579 * Convenience macro for adding 64-bit registers. 577 580 * ··· 672 669 REG64_IDX(RING_TIMESTAMP, BSD_RING_BASE), 673 670 REG32(BCS_SWCTRL), 674 671 REG64_IDX(RING_TIMESTAMP, BLT_RING_BASE), 672 + REG32_IDX(RING_CTX_TIMESTAMP, BLT_RING_BASE), 675 673 REG64_IDX(BCS_GPR, 0), 676 674 REG64_IDX(BCS_GPR, 1), 677 675 REG64_IDX(BCS_GPR, 2),
+1 -1
drivers/gpu/drm/i915/i915_params.c
··· 173 173 #endif 174 174 175 175 #if IS_ENABLED(CONFIG_DRM_I915_UNSTABLE_FAKE_LMEM) 176 - i915_param_named_unsafe(fake_lmem_start, ulong, 0600, 176 + i915_param_named_unsafe(fake_lmem_start, ulong, 0400, 177 177 "Fake LMEM start offset (default: 0)"); 178 178 #endif 179 179
+1 -1
drivers/gpu/drm/i915/i915_params.h
··· 64 64 param(int, mmio_debug, -IS_ENABLED(CONFIG_DRM_I915_DEBUG_MMIO), 0600) \ 65 65 param(int, edp_vswing, 0, 0400) \ 66 66 param(unsigned int, reset, 3, 0600) \ 67 - param(unsigned int, inject_probe_failure, 0, 0600) \ 67 + param(unsigned int, inject_probe_failure, 0, 0) \ 68 68 param(int, fastboot, -1, 0600) \ 69 69 param(int, enable_dpcd_backlight, -1, 0600) \ 70 70 param(char *, force_probe, CONFIG_DRM_I915_FORCE_PROBE, 0400) \
+240 -145
drivers/gpu/drm/i915/i915_request.c
··· 121 121 i915_sw_fence_fini(&rq->submit); 122 122 i915_sw_fence_fini(&rq->semaphore); 123 123 124 - /* Keep one request on each engine for reserved use under mempressure */ 125 - if (!cmpxchg(&rq->engine->request_pool, NULL, rq)) 124 + /* 125 + * Keep one request on each engine for reserved use under mempressure 126 + * 127 + * We do not hold a reference to the engine here and so have to be 128 + * very careful in what rq->engine we poke. The virtual engine is 129 + * referenced via the rq->context and we released that ref during 130 + * i915_request_retire(), ergo we must not dereference a virtual 131 + * engine here. Not that we would want to, as the only consumer of 132 + * the reserved engine->request_pool is the power management parking, 133 + * which must-not-fail, and that is only run on the physical engines. 134 + * 135 + * Since the request must have been executed to be have completed, 136 + * we know that it will have been processed by the HW and will 137 + * not be unsubmitted again, so rq->engine and rq->execution_mask 138 + * at this point is stable. rq->execution_mask will be a single 139 + * bit if the last and _only_ engine it could execution on was a 140 + * physical engine, if it's multiple bits then it started on and 141 + * could still be on a virtual engine. Thus if the mask is not a 142 + * power-of-two we assume that rq->engine may still be a virtual 143 + * engine and so a dangling invalid pointer that we cannot dereference 144 + * 145 + * For example, consider the flow of a bonded request through a virtual 146 + * engine. The request is created with a wide engine mask (all engines 147 + * that we might execute on). On processing the bond, the request mask 148 + * is reduced to one or more engines. If the request is subsequently 149 + * bound to a single engine, it will then be constrained to only 150 + * execute on that engine and never returned to the virtual engine 151 + * after timeslicing away, see __unwind_incomplete_requests(). Thus we 152 + * know that if the rq->execution_mask is a single bit, rq->engine 153 + * can be a physical engine with the exact corresponding mask. 154 + */ 155 + if (is_power_of_2(rq->execution_mask) && 156 + !cmpxchg(&rq->engine->request_pool, NULL, rq)) 126 157 return; 127 158 128 159 kmem_cache_free(global.slab_requests, rq); ··· 357 326 } while (i915_request_retire(tmp) && tmp != rq); 358 327 } 359 328 329 + static struct i915_request * const * 330 + __engine_active(struct intel_engine_cs *engine) 331 + { 332 + return READ_ONCE(engine->execlists.active); 333 + } 334 + 335 + static bool __request_in_flight(const struct i915_request *signal) 336 + { 337 + struct i915_request * const *port, *rq; 338 + bool inflight = false; 339 + 340 + if (!i915_request_is_ready(signal)) 341 + return false; 342 + 343 + /* 344 + * Even if we have unwound the request, it may still be on 345 + * the GPU (preempt-to-busy). If that request is inside an 346 + * unpreemptible critical section, it will not be removed. Some 347 + * GPU functions may even be stuck waiting for the paired request 348 + * (__await_execution) to be submitted and cannot be preempted 349 + * until the bond is executing. 350 + * 351 + * As we know that there are always preemption points between 352 + * requests, we know that only the currently executing request 353 + * may be still active even though we have cleared the flag. 354 + * However, we can't rely on our tracking of ELSP[0] to known 355 + * which request is currently active and so maybe stuck, as 356 + * the tracking maybe an event behind. Instead assume that 357 + * if the context is still inflight, then it is still active 358 + * even if the active flag has been cleared. 359 + */ 360 + if (!intel_context_inflight(signal->context)) 361 + return false; 362 + 363 + rcu_read_lock(); 364 + for (port = __engine_active(signal->engine); (rq = *port); port++) { 365 + if (rq->context == signal->context) { 366 + inflight = i915_seqno_passed(rq->fence.seqno, 367 + signal->fence.seqno); 368 + break; 369 + } 370 + } 371 + rcu_read_unlock(); 372 + 373 + return inflight; 374 + } 375 + 360 376 static int 361 377 __await_execution(struct i915_request *rq, 362 378 struct i915_request *signal, ··· 434 356 } 435 357 436 358 spin_lock_irq(&signal->lock); 437 - if (i915_request_is_active(signal)) { 359 + if (i915_request_is_active(signal) || __request_in_flight(signal)) { 438 360 if (hook) { 439 361 hook(rq, &signal->fence); 440 362 i915_request_put(signal); ··· 1100 1022 I915_FENCE_GFP); 1101 1023 } 1102 1024 1103 - static int 1104 - i915_request_await_request(struct i915_request *to, struct i915_request *from) 1105 - { 1106 - int ret; 1107 - 1108 - GEM_BUG_ON(to == from); 1109 - GEM_BUG_ON(to->timeline == from->timeline); 1110 - 1111 - if (i915_request_completed(from)) { 1112 - i915_sw_fence_set_error_once(&to->submit, from->fence.error); 1113 - return 0; 1114 - } 1115 - 1116 - if (to->engine->schedule) { 1117 - ret = i915_sched_node_add_dependency(&to->sched, 1118 - &from->sched, 1119 - I915_DEPENDENCY_EXTERNAL); 1120 - if (ret < 0) 1121 - return ret; 1122 - } 1123 - 1124 - if (to->engine == from->engine) 1125 - ret = i915_sw_fence_await_sw_fence_gfp(&to->submit, 1126 - &from->submit, 1127 - I915_FENCE_GFP); 1128 - else 1129 - ret = emit_semaphore_wait(to, from, I915_FENCE_GFP); 1130 - if (ret < 0) 1131 - return ret; 1132 - 1133 - return 0; 1134 - } 1135 - 1136 - static void mark_external(struct i915_request *rq) 1137 - { 1138 - /* 1139 - * The downside of using semaphores is that we lose metadata passing 1140 - * along the signaling chain. This is particularly nasty when we 1141 - * need to pass along a fatal error such as EFAULT or EDEADLK. For 1142 - * fatal errors we want to scrub the request before it is executed, 1143 - * which means that we cannot preload the request onto HW and have 1144 - * it wait upon a semaphore. 1145 - */ 1146 - rq->sched.flags |= I915_SCHED_HAS_EXTERNAL_CHAIN; 1147 - } 1148 - 1149 - static int 1150 - __i915_request_await_external(struct i915_request *rq, struct dma_fence *fence) 1151 - { 1152 - mark_external(rq); 1153 - return i915_sw_fence_await_dma_fence(&rq->submit, fence, 1154 - i915_fence_context_timeout(rq->i915, 1155 - fence->context), 1156 - I915_FENCE_GFP); 1157 - } 1158 - 1159 - static int 1160 - i915_request_await_external(struct i915_request *rq, struct dma_fence *fence) 1161 - { 1162 - struct dma_fence *iter; 1163 - int err = 0; 1164 - 1165 - if (!to_dma_fence_chain(fence)) 1166 - return __i915_request_await_external(rq, fence); 1167 - 1168 - dma_fence_chain_for_each(iter, fence) { 1169 - struct dma_fence_chain *chain = to_dma_fence_chain(iter); 1170 - 1171 - if (!dma_fence_is_i915(chain->fence)) { 1172 - err = __i915_request_await_external(rq, iter); 1173 - break; 1174 - } 1175 - 1176 - err = i915_request_await_dma_fence(rq, chain->fence); 1177 - if (err < 0) 1178 - break; 1179 - } 1180 - 1181 - dma_fence_put(iter); 1182 - return err; 1183 - } 1184 - 1185 - int 1186 - i915_request_await_dma_fence(struct i915_request *rq, struct dma_fence *fence) 1187 - { 1188 - struct dma_fence **child = &fence; 1189 - unsigned int nchild = 1; 1190 - int ret; 1191 - 1192 - /* 1193 - * Note that if the fence-array was created in signal-on-any mode, 1194 - * we should *not* decompose it into its individual fences. However, 1195 - * we don't currently store which mode the fence-array is operating 1196 - * in. Fortunately, the only user of signal-on-any is private to 1197 - * amdgpu and we should not see any incoming fence-array from 1198 - * sync-file being in signal-on-any mode. 1199 - */ 1200 - if (dma_fence_is_array(fence)) { 1201 - struct dma_fence_array *array = to_dma_fence_array(fence); 1202 - 1203 - child = array->fences; 1204 - nchild = array->num_fences; 1205 - GEM_BUG_ON(!nchild); 1206 - } 1207 - 1208 - do { 1209 - fence = *child++; 1210 - if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) { 1211 - i915_sw_fence_set_error_once(&rq->submit, fence->error); 1212 - continue; 1213 - } 1214 - 1215 - /* 1216 - * Requests on the same timeline are explicitly ordered, along 1217 - * with their dependencies, by i915_request_add() which ensures 1218 - * that requests are submitted in-order through each ring. 1219 - */ 1220 - if (fence->context == rq->fence.context) 1221 - continue; 1222 - 1223 - /* Squash repeated waits to the same timelines */ 1224 - if (fence->context && 1225 - intel_timeline_sync_is_later(i915_request_timeline(rq), 1226 - fence)) 1227 - continue; 1228 - 1229 - if (dma_fence_is_i915(fence)) 1230 - ret = i915_request_await_request(rq, to_request(fence)); 1231 - else 1232 - ret = i915_request_await_external(rq, fence); 1233 - if (ret < 0) 1234 - return ret; 1235 - 1236 - /* Record the latest fence used against each timeline */ 1237 - if (fence->context) 1238 - intel_timeline_sync_set(i915_request_timeline(rq), 1239 - fence); 1240 - } while (--nchild); 1241 - 1242 - return 0; 1243 - } 1244 - 1245 1025 static bool intel_timeline_sync_has_start(struct intel_timeline *tl, 1246 1026 struct dma_fence *fence) 1247 1027 { ··· 1187 1251 &from->fence); 1188 1252 } 1189 1253 1254 + static void mark_external(struct i915_request *rq) 1255 + { 1256 + /* 1257 + * The downside of using semaphores is that we lose metadata passing 1258 + * along the signaling chain. This is particularly nasty when we 1259 + * need to pass along a fatal error such as EFAULT or EDEADLK. For 1260 + * fatal errors we want to scrub the request before it is executed, 1261 + * which means that we cannot preload the request onto HW and have 1262 + * it wait upon a semaphore. 1263 + */ 1264 + rq->sched.flags |= I915_SCHED_HAS_EXTERNAL_CHAIN; 1265 + } 1266 + 1267 + static int 1268 + __i915_request_await_external(struct i915_request *rq, struct dma_fence *fence) 1269 + { 1270 + mark_external(rq); 1271 + return i915_sw_fence_await_dma_fence(&rq->submit, fence, 1272 + i915_fence_context_timeout(rq->i915, 1273 + fence->context), 1274 + I915_FENCE_GFP); 1275 + } 1276 + 1277 + static int 1278 + i915_request_await_external(struct i915_request *rq, struct dma_fence *fence) 1279 + { 1280 + struct dma_fence *iter; 1281 + int err = 0; 1282 + 1283 + if (!to_dma_fence_chain(fence)) 1284 + return __i915_request_await_external(rq, fence); 1285 + 1286 + dma_fence_chain_for_each(iter, fence) { 1287 + struct dma_fence_chain *chain = to_dma_fence_chain(iter); 1288 + 1289 + if (!dma_fence_is_i915(chain->fence)) { 1290 + err = __i915_request_await_external(rq, iter); 1291 + break; 1292 + } 1293 + 1294 + err = i915_request_await_dma_fence(rq, chain->fence); 1295 + if (err < 0) 1296 + break; 1297 + } 1298 + 1299 + dma_fence_put(iter); 1300 + return err; 1301 + } 1302 + 1190 1303 int 1191 1304 i915_request_await_execution(struct i915_request *rq, 1192 1305 struct dma_fence *fence, ··· 1279 1294 ret = i915_request_await_external(rq, fence); 1280 1295 if (ret < 0) 1281 1296 return ret; 1297 + } while (--nchild); 1298 + 1299 + return 0; 1300 + } 1301 + 1302 + static int 1303 + await_request_submit(struct i915_request *to, struct i915_request *from) 1304 + { 1305 + /* 1306 + * If we are waiting on a virtual engine, then it may be 1307 + * constrained to execute on a single engine *prior* to submission. 1308 + * When it is submitted, it will be first submitted to the virtual 1309 + * engine and then passed to the physical engine. We cannot allow 1310 + * the waiter to be submitted immediately to the physical engine 1311 + * as it may then bypass the virtual request. 1312 + */ 1313 + if (to->engine == READ_ONCE(from->engine)) 1314 + return i915_sw_fence_await_sw_fence_gfp(&to->submit, 1315 + &from->submit, 1316 + I915_FENCE_GFP); 1317 + else 1318 + return __i915_request_await_execution(to, from, NULL); 1319 + } 1320 + 1321 + static int 1322 + i915_request_await_request(struct i915_request *to, struct i915_request *from) 1323 + { 1324 + int ret; 1325 + 1326 + GEM_BUG_ON(to == from); 1327 + GEM_BUG_ON(to->timeline == from->timeline); 1328 + 1329 + if (i915_request_completed(from)) { 1330 + i915_sw_fence_set_error_once(&to->submit, from->fence.error); 1331 + return 0; 1332 + } 1333 + 1334 + if (to->engine->schedule) { 1335 + ret = i915_sched_node_add_dependency(&to->sched, 1336 + &from->sched, 1337 + I915_DEPENDENCY_EXTERNAL); 1338 + if (ret < 0) 1339 + return ret; 1340 + } 1341 + 1342 + if (is_power_of_2(to->execution_mask | READ_ONCE(from->execution_mask))) 1343 + ret = await_request_submit(to, from); 1344 + else 1345 + ret = emit_semaphore_wait(to, from, I915_FENCE_GFP); 1346 + if (ret < 0) 1347 + return ret; 1348 + 1349 + return 0; 1350 + } 1351 + 1352 + int 1353 + i915_request_await_dma_fence(struct i915_request *rq, struct dma_fence *fence) 1354 + { 1355 + struct dma_fence **child = &fence; 1356 + unsigned int nchild = 1; 1357 + int ret; 1358 + 1359 + /* 1360 + * Note that if the fence-array was created in signal-on-any mode, 1361 + * we should *not* decompose it into its individual fences. However, 1362 + * we don't currently store which mode the fence-array is operating 1363 + * in. Fortunately, the only user of signal-on-any is private to 1364 + * amdgpu and we should not see any incoming fence-array from 1365 + * sync-file being in signal-on-any mode. 1366 + */ 1367 + if (dma_fence_is_array(fence)) { 1368 + struct dma_fence_array *array = to_dma_fence_array(fence); 1369 + 1370 + child = array->fences; 1371 + nchild = array->num_fences; 1372 + GEM_BUG_ON(!nchild); 1373 + } 1374 + 1375 + do { 1376 + fence = *child++; 1377 + if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) { 1378 + i915_sw_fence_set_error_once(&rq->submit, fence->error); 1379 + continue; 1380 + } 1381 + 1382 + /* 1383 + * Requests on the same timeline are explicitly ordered, along 1384 + * with their dependencies, by i915_request_add() which ensures 1385 + * that requests are submitted in-order through each ring. 1386 + */ 1387 + if (fence->context == rq->fence.context) 1388 + continue; 1389 + 1390 + /* Squash repeated waits to the same timelines */ 1391 + if (fence->context && 1392 + intel_timeline_sync_is_later(i915_request_timeline(rq), 1393 + fence)) 1394 + continue; 1395 + 1396 + if (dma_fence_is_i915(fence)) 1397 + ret = i915_request_await_request(rq, to_request(fence)); 1398 + else 1399 + ret = i915_request_await_external(rq, fence); 1400 + if (ret < 0) 1401 + return ret; 1402 + 1403 + /* Record the latest fence used against each timeline */ 1404 + if (fence->context) 1405 + intel_timeline_sync_set(i915_request_timeline(rq), 1406 + fence); 1282 1407 } while (--nchild); 1283 1408 1284 1409 return 0;
+8 -8
drivers/gpu/drm/i915/i915_scheduler.c
··· 209 209 if (!inflight) 210 210 goto unlock; 211 211 212 - ENGINE_TRACE(engine, 213 - "bumping queue-priority-hint:%d for rq:%llx:%lld, inflight:%llx:%lld prio %d\n", 214 - prio, 215 - rq->fence.context, rq->fence.seqno, 216 - inflight->fence.context, inflight->fence.seqno, 217 - inflight->sched.attr.priority); 218 - engine->execlists.queue_priority_hint = prio; 219 - 220 212 /* 221 213 * If we are already the currently executing context, don't 222 214 * bother evaluating if we should preempt ourselves. ··· 216 224 if (inflight->context == rq->context) 217 225 goto unlock; 218 226 227 + ENGINE_TRACE(engine, 228 + "bumping queue-priority-hint:%d for rq:%llx:%lld, inflight:%llx:%lld prio %d\n", 229 + prio, 230 + rq->fence.context, rq->fence.seqno, 231 + inflight->fence.context, inflight->fence.seqno, 232 + inflight->sched.attr.priority); 233 + 234 + engine->execlists.queue_priority_hint = prio; 219 235 if (need_preempt(prio, rq_prio(inflight))) 220 236 tasklet_hi_schedule(&engine->execlists.tasklet); 221 237