* [PATCH] nouveau: Fix race with fence signaling
@ 2013-10-22 19:15 Jeff Mahoney
0 siblings, 0 replies; only message in thread
From: Jeff Mahoney @ 2013-10-22 19:15 UTC (permalink / raw)
To: Ben Skeggs, dri-devel, Linux Kernel Mailing List
There exists a tight race between the call to nouveau_fence_done from
nouveau_fence_wait and the call to nouveau_fence_wait_uevent.
nouveau_fence_done checks to see if fence->channel is NULL before calling
nouveau_fence_wait_uevent, but it's not good enough since the dereference
in nouveau_fence_wait_uevent is done outside the lock. Another thread
may have signaled the fence in that tight window and then we Oops
while dereferencing fence->channel->drm at the beginning of
nouveau_fence_wait_uevent.
The good news is that nouveau_fence_wait_uevent only uses fence->channel
directly to grab the chan->drm pointer. If we pass that in directly as
a known good pointer, we can avoid the race. Passing the nouveau_fence_done
check in the caller ensures that the chan pointer is valid.
Original bug report at: https://bugzilla.novell.com/show_bug.cgi?id=844177
Cc: <stable@vger.kernel.org> # 3.9+
Cc: Ben Skeggs <bskeggs@redhat.com>
Signed-off-by: Jeff Mahoney <jeffm@suse.com>
---
drivers/gpu/drm/nouveau/nouveau_fence.c | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
--- a/drivers/gpu/drm/nouveau/nouveau_fence.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fence.c
@@ -180,12 +180,11 @@ nouveau_fence_wait_uevent_handler(struct
}
static int
-nouveau_fence_wait_uevent(struct nouveau_fence *fence, bool intr)
-
+nouveau_fence_wait_uevent(struct nouveau_fence *fence,
+ struct nouveau_drm *drm, bool intr)
{
- struct nouveau_channel *chan = fence->channel;
- struct nouveau_fifo *pfifo = nouveau_fifo(chan->drm->device);
- struct nouveau_fence_priv *priv = chan->drm->fence;
+ struct nouveau_fifo *pfifo = nouveau_fifo(drm->device);
+ struct nouveau_fence_priv *priv = drm->fence;
struct nouveau_fence_uevent uevent = {
.handler.func = nouveau_fence_wait_uevent_handler,
.priv = priv,
@@ -241,7 +240,7 @@ nouveau_fence_wait(struct nouveau_fence
int ret = 0;
while (priv && priv->uevent && lazy && !nouveau_fence_done(fence)) {
- ret = nouveau_fence_wait_uevent(fence, intr);
+ ret = nouveau_fence_wait_uevent(fence, chan->drm, intr);
if (ret < 0)
return ret;
}
--
Jeff Mahoney
SUSE Labs
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2013-10-22 19:15 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-10-22 19:15 [PATCH] nouveau: Fix race with fence signaling Jeff Mahoney
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.