diff options
author | Michel Dänzer <michel.daenzer@amd.com> | 2016-04-01 15:29:26 +0900 |
---|---|---|
committer | Michel Dänzer <michel.daenzer@amd.com> | 2016-04-01 15:29:26 +0900 |
commit | 5ba95c3abeb8df82aa8d33a47596eae6403ea7af (patch) | |
tree | 15c5bc7bbdb7263e893cbb061c51c083496b4d06 /src/amdgpu_drm_queue.c | |
parent | 8ecfa69b5a833bd4c39e773a6acfd7eef9144d13 (diff) |
Identify DRM event queue entries by sequence number instead of by pointer
If the memory for an entry was allocated at the same address as that for
a previously cancelled entry, the handler could theoretically be called
prematurely, triggered by the DRM event which was submitted for the
cancelled entry.
(Ported from radeon commit 4693b1bd5b5c381e8b7b68a6f7f0c6696d6a68df)
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'src/amdgpu_drm_queue.c')
-rw-r--r-- | src/amdgpu_drm_queue.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/src/amdgpu_drm_queue.c b/src/amdgpu_drm_queue.c index 11b74a0..562a11a 100644 --- a/src/amdgpu_drm_queue.c +++ b/src/amdgpu_drm_queue.c @@ -40,6 +40,7 @@ struct amdgpu_drm_queue_entry { struct xorg_list list; uint64_t id; + uintptr_t seq; void *data; ClientPtr client; xf86CrtcPtr crtc; @@ -49,6 +50,7 @@ struct amdgpu_drm_queue_entry { static int amdgpu_drm_queue_refcnt; static struct xorg_list amdgpu_drm_queue; +static uintptr_t amdgpu_drm_queue_seq; /* @@ -58,11 +60,11 @@ void amdgpu_drm_queue_handler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void *user_ptr) { - struct amdgpu_drm_queue_entry *user_data = user_ptr; + uintptr_t seq = (uintptr_t)user_ptr; struct amdgpu_drm_queue_entry *e, *tmp; xorg_list_for_each_entry_safe(e, tmp, &amdgpu_drm_queue, list) { - if (e == user_data) { + if (e->seq == seq) { xorg_list_del(&e->list); if (e->handler) e->handler(e->crtc, frame, @@ -80,7 +82,7 @@ amdgpu_drm_queue_handler(int fd, unsigned int frame, unsigned int sec, * Enqueue a potential drm response; when the associated response * appears, we've got data to pass to the handler from here */ -struct amdgpu_drm_queue_entry * +uintptr_t amdgpu_drm_queue_alloc(xf86CrtcPtr crtc, ClientPtr client, uint64_t id, void *data, amdgpu_drm_handler_proc handler, @@ -92,6 +94,9 @@ amdgpu_drm_queue_alloc(xf86CrtcPtr crtc, ClientPtr client, if (!e) return NULL; + if (!amdgpu_drm_queue_seq) + amdgpu_drm_queue_seq = 1; + e->seq = amdgpu_drm_queue_seq++; e->client = client; e->crtc = crtc; e->id = id; @@ -101,7 +106,7 @@ amdgpu_drm_queue_alloc(xf86CrtcPtr crtc, ClientPtr client, xorg_list_add(&e->list, &amdgpu_drm_queue); - return e; + return e->seq; } /* @@ -139,9 +144,16 @@ amdgpu_drm_abort_client(ClientPtr client) * Abort specific drm queue entry */ void -amdgpu_drm_abort_entry(struct amdgpu_drm_queue_entry *entry) +amdgpu_drm_abort_entry(uintptr_t seq) { - amdgpu_drm_abort_one(entry); + struct amdgpu_drm_queue_entry *e, *tmp; + + xorg_list_for_each_entry_safe(e, tmp, &amdgpu_drm_queue, list) { + if (e->seq == seq) { + amdgpu_drm_abort_one(e); + break; + } + } } /* |