[PATCH] present: Don't stash the MSC value when present_get_ust_msc fails

Michel Dänzer michel at daenzer.net
Mon Sep 28 20:32:57 PDT 2015


On 29.09.2015 11:55, Fredrik Höglund wrote:
> On Friday 11 September 2015, Michel Dänzer wrote:
>> On 11.09.2015 06:33, Fredrik Höglund wrote:
>>> Otherwise we stash an uninitalized value, and later use it to compute
>>> the msc_offset for the window.  Also initialize ust and crtc_msc so we
>>> never use uninitalized values when present_get_ust_msc fails.
>>>
>>> This fixes clients getting stuck waiting indefinitely for an idle
>>> event when a CRTC is turned off.
>>>
>>> Signed-off-by: Fredrik Höglund <fredrik at kde.org>
>>> ---
>>>  present/present.c | 14 ++++++++------
>>>  1 file changed, 8 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/present/present.c b/present/present.c
>>> index a634601..7ddffbd 100644
>>> --- a/present/present.c
>>> +++ b/present/present.c
>>> @@ -710,9 +710,9 @@ present_pixmap(WindowPtr window,
>>>                 present_notify_ptr notifies,
>>>                 int num_notifies)
>>>  {
>>> -    uint64_t                    ust;
>>> +    uint64_t                    ust = 0;
>>>      uint64_t                    target_msc;
>>> -    uint64_t                    crtc_msc;
>>> +    uint64_t                    crtc_msc = 0;
>>>      int                         ret;
>>>      present_vblank_ptr          vblank, tmp;
>>>      ScreenPtr                   screen = window->drawable.pScreen;
>>> @@ -734,13 +734,15 @@ present_pixmap(WindowPtr window,
>>>              target_crtc = present_get_crtc(window);
>>>      }
>>>  
>>> -    present_get_ust_msc(screen, target_crtc, &ust, &crtc_msc);
>>> +    ret = present_get_ust_msc(screen, target_crtc, &ust, &crtc_msc);
>>>  
>>>      target_msc = present_window_to_crtc_msc(window, target_crtc, window_msc, crtc_msc);
>>>  
>>> -    /* Stash the current MSC away in case we need it later
>>> -     */
>>> -    window_priv->msc = crtc_msc;
>>> +    if (ret == Success) {
>>> +        /* Stash the current MSC away in case we need it later
>>> +         */
>>> +        window_priv->msc = crtc_msc;
>>> +    }
>>>  
>>>      /* Adjust target_msc to match modulus
>>>       */
>>>
>>
>> My only doubt is about present_window_to_crtc_msc(). If target_msc
>> doesn't match window_priv->crtc, presumably present_get_ust_msc() will
>> fail there as well, so window_priv->msc (the last recorded valid MSC
>> value for the window) will be added to window_priv->msc_offset. I
>> suspect that's not right and might still cause similar trouble down the
>> road.
> 
> window_priv->msc is updated after the call to present_window_to_crtc_msc(),
> so the old MSC value will hopefully be valid in that call.  The bigger
> issue is that crtc_msc is not valid, so we still set msc_offset to an
> incorrect value.
> 
> I'm not sure if it's possible to fully fix this issue while still allowing
> present_get_ust_msc() to fail.

Maybe not.


> The deadlock I'm seeing happens with an application that alternates
> between calling GetSyncValuesOML() and SwapBuffersMscOML().  In the
> GetSyncValuesOML() call, pixmap is NULL, so present_pixmap() picks the
> CRTC stored in window_priv.  It's when that CRTC is off that we end up
> storing an uninitialized value in window_priv->msc.  Note that
> present_window_to_crtc_msc() doesn't update window_priv->msc_offset
> in this case since the CRTC's match.  In the next call to SwapBuffersOML(),
> pixmap is not NULL, so present_pixmap() calls present_get_crtc() which
> returns NULL.  This causes present_window_to_crtc_msc() to update
> window_priv->msc_offset using the now invalid window_priv->msc value.
> As a result we compute a target MSC for the vblank that's several weeks
> into the future.

Thanks for the detailed explanation. It might be nice to work that into
the Git commit log, but either way,

Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>


-- 
Earthling Michel Dänzer               |               http://www.amd.com
Libre software enthusiast             |             Mesa and X developer


More information about the xorg-devel mailing list