Hi Michel, thanks for the review!

On 2026-06-17 04:56, Michel Dänzer wrote:
> On 6/17/26 10:07, Michel Dänzer wrote:
>> On 6/16/26 22:18, [email protected] wrote:
>>>
>>> * Add a flip_programmed completion. Arm it (reinit_completion) under
>>>   event_lock together with prepare_flip_isr(), and signal it
>>>   (complete_all) right after update_planes_and_stream_adapter() programs
>>>   the flip. It starts in the "completed" state at crtc init.
>>
>> Is the completion really necessary? Wouldn't moving the acrtc->pflip_status 
>> = AMDGPU_FLIP_SUBMITTED assignment after the flip programming suffice?

I think this would create a window between HW programming and arming 
acrtc->event and pflip_status, where HW latch (VUPDATE_NO_LOCK) can fire and 
run the handler:

    Thread A:        Thread B:
    PROGRAM(flip_n)
                     LATCH(flip_n)
                     vupdate_no_lock_handler(flip_n) # no event armed; skip 
sending
    ARM(flip_n)

Ah, but the flip_programmed completion has the same issue...

    Thread A:                 Thread B:
    INIT_(flip_programmed)
    ARM(flip_n)
    PROGRAM(flip_n)
                              LATCH(flip_n)
                              vupdate_no_lock_handler(flip_n) # flip_programmed 
not complete; skip sending
    COMPLETE(flip_programmed)

> 
> Or even just moving the unlocking of event_lock after the flip programming.
> 

I initially thought about doing so. But the possibility of 
update_planes_and_stream_adapter() sleeping made me think otherwise.

I suppose the worst case scenario with arming acrtc->event/pflip_status after 
programming is we deliver the event a frame later than it needs to be (which is 
also the case with the current patch), thus stalling the next commit via 
flip_done, and making userspace think it missed the programming deadline. That 
is, if the exact scenario above happens.

If it sounds good to you, I'll roll that into v2 as well.

> 
>>> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
>>> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>>> index 00f7a3b445ebf..571198c46c0c2 100644
>>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>>> @@ -4384,17 +4384,17 @@ static void amdgpu_dm_commit_planes(struct 
>>> drm_atomic_state *state,
>>>              * from 0 -> n planes we have to skip a hardware generated event
>>>              * and rely on sending it from software.
>>>              */
>>> +           spin_lock_irqsave(&pcrtc->dev->event_lock, flags);
>>>             if (acrtc_attach->base.state->event &&
>>>                 acrtc_state->active_planes > 0) {
>>>                     drm_crtc_vblank_get(pcrtc);
>>>  
>>> -                   spin_lock_irqsave(&pcrtc->dev->event_lock, flags);
>>> -
>>>                     WARN_ON(acrtc_attach->pflip_status != AMDGPU_FLIP_NONE);
>>> +                   /* Arm flip completion handling and event delivery */
>>> +                   
>>> reinit_completion(&acrtc_attach->dm_irq_params.flip_programmed);
>>>                     prepare_flip_isr(acrtc_attach);
>>> -
>>> -                   spin_unlock_irqrestore(&pcrtc->dev->event_lock, flags);
>>>             }
>>> +           spin_unlock_irqrestore(&pcrtc->dev->event_lock, flags);
>>>  
>>>             if (acrtc_state->stream) {
>>>                     if (acrtc_state->freesync_vrr_info_changed)
>> 
>> Pulling event_lock out of the if block doesn't make any difference (other 
>> than locking it unnecessarily when the block isn't entered 🙂, does it?

FWIU the crtc_state->event pointer itself should be guarded under event_lock, 
since it can be NULL'd concurrently.

- Leo

Reply via email to