[PATCH 1/2] present: Improve scaling of vblank handler

Mario Kleiner mario.kleiner.de at gmail.com
Fri May 8 16:23:30 PDT 2015


On 02/14/2015 10:58 AM, Chris Wilson wrote:
> With large numbers of queued vblank, the list iteration on every
> interupt dominates processing time. If we reorder the list to be in
> ascending event order, then not only is also likely to be in order for
> notification queries (i.e. the notification will be near the start of
> the list), we can also stop iterating when past the target event_id.
>
> Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
> ---
>   present/present.c | 24 +++++++++++++++---------
>   1 file changed, 15 insertions(+), 9 deletions(-)
>
> diff --git a/present/present.c b/present/present.c
> index ba88f79..b132f4d 100644
> --- a/present/present.c
> +++ b/present/present.c
> @@ -482,19 +482,22 @@ present_flip_notify(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
>   void
>   present_event_notify(uint64_t event_id, uint64_t ust, uint64_t msc)
>   {
> -    present_vblank_ptr  vblank, tmp;
> +    present_vblank_ptr  vblank;
>       int                 s;
>
>       if (!event_id)
>           return;
>       DebugPresent(("\te %lld ust %lld msc %lld\n", event_id, ust, msc));
> -    xorg_list_for_each_entry_safe(vblank, tmp, &present_exec_queue, event_queue) {
> -        if (vblank->event_id == event_id) {
> +    xorg_list_for_each_entry(vblank, &present_exec_queue, event_queue) {
> +        int64_t match = event_id - vblank->event_id;
> +        if (match == 0) {
>               present_execute(vblank, ust, msc);
>               return;
>           }
> +        if (match < 0)
> +            break;
>       }
> -    xorg_list_for_each_entry_safe(vblank, tmp, &present_flip_queue, event_queue) {
> +    xorg_list_for_each_entry(vblank, &present_flip_queue, event_queue) {
>           if (vblank->event_id == event_id) {
>               present_flip_notify(vblank, ust, msc);
>               return;
> @@ -887,7 +890,7 @@ present_pixmap(WindowPtr window,
>                         vblank->pixmap->drawable.id, vblank->window->drawable.id,
>                         target_crtc, vblank->flip, vblank->sync_flip, vblank->serial));
>
> -    xorg_list_add(&vblank->event_queue, &present_exec_queue);
> +    xorg_list_append(&vblank->event_queue, &present_exec_queue);
>       vblank->queued = TRUE;
>       if ((pixmap && target_msc >= crtc_msc) || (!pixmap && target_msc > crtc_msc)) {
>           ret = present_queue_vblank(screen, target_crtc, vblank->event_id, target_msc);
> @@ -911,7 +914,7 @@ no_mem:
>   void
>   present_abort_vblank(ScreenPtr screen, RRCrtcPtr crtc, uint64_t event_id, uint64_t msc)
>   {
> -    present_vblank_ptr  vblank, tmp;
> +    present_vblank_ptr  vblank;
>
>       if (crtc == NULL)
>           present_fake_abort_vblank(screen, event_id, msc);
> @@ -922,14 +925,17 @@ present_abort_vblank(ScreenPtr screen, RRCrtcPtr crtc, uint64_t event_id, uint64
>           (*screen_priv->info->abort_vblank) (crtc, event_id, msc);
>       }
>
> -    xorg_list_for_each_entry_safe(vblank, tmp, &present_exec_queue, event_queue) {
> -        if (vblank->event_id == event_id) {
> +    xorg_list_for_each_entry(vblank, &present_exec_queue, event_queue) {
> +        int64_t match = event_id - vblank->event_id;
> +        if (match == 0) {
>               xorg_list_del(&vblank->event_queue);
>               vblank->queued = FALSE;
>               return;
>           }
> +        if (match < 0)
> +            break;
>       }
> -    xorg_list_for_each_entry_safe(vblank, tmp, &present_flip_queue, event_queue) {
> +    xorg_list_for_each_entry(vblank, &present_flip_queue, event_queue) {
>           if (vblank->event_id == event_id) {
>               xorg_list_del(&vblank->event_queue);
>               return;
>

Looks good to me, also no problems during testing on top of current 
master, so

Reviewed-and-tested-by: Mario Kleiner <mario.kleiner.de at gmail.com>

-mario




More information about the xorg-devel mailing list