On 6/17/26 21:27, Leo Li wrote:
> 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?
> 
> [...]
> >> 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.

That is a problem.

If the flip programming could be done while holding event_lock, this could be 
made 100% reliable, avoiding the issue below.


> 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.

Yep. Hopefully won't happen too often in practice?


>>>> 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.

Gotcha, I was fooled by the acrtc_attach->base.state->event disguise. :)


-- 
Earthling Michel Dänzer       \        GNOME / Xwayland / Mesa developer
https://redhat.com             \               Libre software enthusiast

Reply via email to