Skip to content

Commit 9fc7f45

Browse files
committed
drm/i915/guc: Handle race condition where wakeref count drops below 0
From Jesus Narvaez 798fd944fbcffdfffeef0b7a5cfdfab1c9dbc56b in linux-6.12.y/6.12.34 0323a5127e7c534cfc88efe0f850a0cb777e938b in mainline linux
1 parent 95272e9 commit 9fc7f45

File tree

1 file changed

+14
-3
lines changed

1 file changed

+14
-3
lines changed

sys/dev/pci/drm/i915/gt/uc/intel_guc_submission.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3422,18 +3422,29 @@ static inline int guc_lrc_desc_unpin(struct intel_context *ce)
34223422
* GuC is active, lets destroy this context, but at this point we can still be racing
34233423
* with suspend, so we undo everything if the H2G fails in deregister_context so
34243424
* that GuC reset will find this context during clean up.
3425+
*
3426+
* There is a race condition where the reset code could have altered
3427+
* this context's state and done a wakeref put before we try to
3428+
* deregister it here. So check if the context is still set to be
3429+
* destroyed before undoing earlier changes, to avoid two wakeref puts
3430+
* on the same context.
34253431
*/
34263432
ret = deregister_context(ce, ce->guc_id.id);
34273433
if (ret) {
3434+
bool pending_destroyed;
34283435
spin_lock_irqsave(&ce->guc_state.lock, flags);
3429-
set_context_registered(ce);
3430-
clr_context_destroyed(ce);
3436+
pending_destroyed = context_destroyed(ce);
3437+
if (pending_destroyed) {
3438+
set_context_registered(ce);
3439+
clr_context_destroyed(ce);
3440+
}
34313441
spin_unlock_irqrestore(&ce->guc_state.lock, flags);
34323442
/*
34333443
* As gt-pm is awake at function entry, intel_wakeref_put_async merely decrements
34343444
* the wakeref immediately but per function spec usage call this after unlock.
34353445
*/
3436-
intel_wakeref_put_async(&gt->wakeref);
3446+
if (pending_destroyed)
3447+
intel_wakeref_put_async(&gt->wakeref);
34373448
}
34383449

34393450
return ret;

0 commit comments

Comments
 (0)