From 26770be44b89b83bf39c28f2fe284c8cb92ed0c0 Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Wed, 29 Aug 2018 18:49:19 +0200 Subject: Don't use xorg_list_for_each_entry_safe for signalled flips drm_wait_pending_flip can get called from drm_handle_event, in which case xorg_list_for_each_entry_safe can end up processing the same entry in both. To avoid this, just process the first list entry until the list is empty. --- src/amdgpu_drm_queue.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/amdgpu_drm_queue.c b/src/amdgpu_drm_queue.c index f9db81c..ba841d1 100644 --- a/src/amdgpu_drm_queue.c +++ b/src/amdgpu_drm_queue.c @@ -257,8 +257,11 @@ amdgpu_drm_handle_event(int fd, drmEventContext *event_context) r = drmHandleEvent(fd, event_context); - xorg_list_for_each_entry_safe(e, tmp, &amdgpu_drm_flip_signalled, list) + while (!xorg_list_is_empty(&amdgpu_drm_flip_signalled)) { + e = xorg_list_first_entry(&amdgpu_drm_flip_signalled, + struct amdgpu_drm_queue_entry, list); amdgpu_drm_queue_handle_one(e); + } xorg_list_for_each_entry_safe(e, tmp, &amdgpu_drm_vblank_signalled, list) { drmmode_crtc_private_ptr drmmode_crtc = e->crtc->driver_private; @@ -277,12 +280,15 @@ void amdgpu_drm_wait_pending_flip(xf86CrtcPtr crtc) { drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(crtc->scrn); - struct amdgpu_drm_queue_entry *e, *tmp; + struct amdgpu_drm_queue_entry *e; drmmode_crtc->wait_flip_nesting_level++; - xorg_list_for_each_entry_safe(e, tmp, &amdgpu_drm_flip_signalled, list) + while (!xorg_list_is_empty(&amdgpu_drm_flip_signalled)) { + e = xorg_list_first_entry(&amdgpu_drm_flip_signalled, + struct amdgpu_drm_queue_entry, list); amdgpu_drm_queue_handle_one(e); + } while (drmmode_crtc->flip_pending && amdgpu_drm_handle_event(pAMDGPUEnt->fd, -- cgit v1.2.3