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

drm/i915: Protect access to driver and timeline name

Protect the access to driver and timeline name which otherwise could be
freed as dma-fence exported is signalling fences.

This prepares the code for incoming dma-fence API changes which will start
asserting these accesses are done from a RCU locked section.

Now that the safe access is handled in the dma-fence API, the external
callers such as sync_file, and our internal code paths, we can drop the
similar protection from i915_fence_get_timeline_name().

This prepares the code for incoming dma-fence API changes which will start
asserting these accesses are done from a RCU locked section.

Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
Reviewed-by: Andi Shyti <andi.shyti@linux.intel.com> # v1
Signed-off-by: Tvrtko Ursulin <tursulin@ursulin.net>
Link: https://lore.kernel.org/r/20250610164226.10817-3-tvrtko.ursulin@igalia.com

authored by

Tvrtko Ursulin and committed by
Tvrtko Ursulin
4d2f8bc6 ad10976d

+21 -6
+8 -2
drivers/gpu/drm/i915/gt/intel_gt_requests.c
··· 250 250 llist_for_each_entry_safe(rq, rn, first, watchdog.link) { 251 251 if (!i915_request_completed(rq)) { 252 252 struct dma_fence *f = &rq->fence; 253 + const char __rcu *timeline; 254 + const char __rcu *driver; 253 255 256 + rcu_read_lock(); 257 + driver = dma_fence_driver_name(f); 258 + timeline = dma_fence_timeline_name(f); 254 259 pr_notice("Fence expiration time out i915-%s:%s:%llx!\n", 255 - dma_fence_driver_name(f), 256 - dma_fence_timeline_name(f), 260 + rcu_dereference(driver), 261 + rcu_dereference(timeline), 257 262 f->seqno); 263 + rcu_read_unlock(); 258 264 i915_request_cancel(rq, -EINTR); 259 265 } 260 266 i915_request_put(rq);
+5 -2
drivers/gpu/drm/i915/i915_request.c
··· 2184 2184 const char *prefix, 2185 2185 int indent) 2186 2186 { 2187 - const char *name = dma_fence_timeline_name((struct dma_fence *)&rq->fence); 2187 + const char __rcu *timeline; 2188 2188 char buf[80] = ""; 2189 2189 int x = 0; 2190 2190 ··· 2220 2220 2221 2221 x = print_sched_attr(&rq->sched.attr, buf, x, sizeof(buf)); 2222 2222 2223 + rcu_read_lock(); 2224 + timeline = dma_fence_timeline_name((struct dma_fence *)&rq->fence); 2223 2225 drm_printf(m, "%s%.*s%c %llx:%lld%s%s %s @ %dms: %s\n", 2224 2226 prefix, indent, " ", 2225 2227 queue_status(rq), ··· 2230 2228 fence_status(rq), 2231 2229 buf, 2232 2230 jiffies_to_msecs(jiffies - rq->emitted_jiffies), 2233 - name); 2231 + rcu_dereference(timeline)); 2232 + rcu_read_unlock(); 2234 2233 } 2235 2234 2236 2235 static bool engine_match_ring(struct intel_engine_cs *engine, struct i915_request *rq)
+8 -2
drivers/gpu/drm/i915/i915_sw_fence.c
··· 430 430 struct i915_sw_dma_fence_cb_timer *cb = timer_container_of(cb, t, 431 431 timer); 432 432 struct i915_sw_fence *fence; 433 + const char __rcu *timeline; 434 + const char __rcu *driver; 433 435 434 436 fence = xchg(&cb->base.fence, NULL); 435 437 if (!fence) 436 438 return; 437 439 440 + rcu_read_lock(); 441 + driver = dma_fence_driver_name(cb->dma); 442 + timeline = dma_fence_timeline_name(cb->dma); 438 443 pr_notice("Asynchronous wait on fence %s:%s:%llx timed out (hint:%ps)\n", 439 - dma_fence_driver_name(cb->dma), 440 - dma_fence_timeline_name(cb->dma), 444 + rcu_dereference(driver), 445 + rcu_dereference(timeline), 441 446 cb->dma->seqno, 442 447 i915_sw_fence_debug_hint(fence)); 448 + rcu_read_unlock(); 443 449 444 450 i915_sw_fence_set_error_once(fence, -ETIMEDOUT); 445 451 i915_sw_fence_complete(fence);