mock_context_alloc() creates ce->ring before allocating and pinning the context timeline. mock_ring() initializes the ring reference count and returns the initial reference to the context. If intel_timeline_create() fails, mock_context_alloc() returns without dropping the ring reference. The same leak occurs when mock_timeline_pin() fails after the timeline has been created. Since context allocation did not complete, CONTEXT_ALLOC_BIT is not set and the later context teardown does not release the ring. Drop the initial ring reference with kref_put() on both failure paths. When the reference count reaches zero, intel_ring_free() releases the ring VMA and frees the ring allocation. Clear ce->ring after dropping the reference to avoid retaining a stale pointer. The issue was identified by a static analysis tool I developed and confirmed by manual review. Fixes: 75d0a7f31eec ("drm/i915: Lift timeline into intel_context") Cc: stable@vger.kernel.org Signed-off-by: Guangshuo Li --- drivers/gpu/drm/i915/gt/mock_engine.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/gt/mock_engine.c b/drivers/gpu/drm/i915/gt/mock_engine.c index 79741f043f03..fa4368730d33 100644 --- a/drivers/gpu/drm/i915/gt/mock_engine.c +++ b/drivers/gpu/drm/i915/gt/mock_engine.c @@ -170,6 +170,8 @@ static int mock_context_alloc(struct intel_context *ce) ce->timeline = intel_timeline_create(ce->engine->gt); if (IS_ERR(ce->timeline)) { + kref_put(&ce->ring->ref, intel_ring_free); + ce->ring = NULL; kfree(ce->engine); return PTR_ERR(ce->timeline); } @@ -178,6 +180,8 @@ static int mock_context_alloc(struct intel_context *ce) if (err) { intel_timeline_put(ce->timeline); ce->timeline = NULL; + kref_put(&ce->ring->ref, intel_ring_free); + ce->ring = NULL; return err; } -- 2.43.0