From 9849f366cbfd781ebeca725058029b70c96836f9 Mon Sep 17 00:00:00 2001 From: Marcin Slusarz Date: Sat, 8 Oct 2011 23:05:25 +0200 Subject: nouveau: fix fence hang If there is not enough space in pushbuffer for fence emission (nouveau_fence_emit -> nv50_screen_fence_emit -> MARK_RING), the pushbuffer is flushed, which through flush_notify -> nv50_default_flush_notify -> nouveau_fence_update marks currently emitting fence as flushed. But actual emission is done after this mark. So later when there is a need to wait on this fence and pushbuffer was not flushed in between, fence wait will never finish causing application to hang. To fix this, introduce new fence state between AVAILABLE and EMITTED, set it before emission and handle it everywhere. Additionally obtain fence sequence numbers after possible flush in MARK_RING, because we want to emit fences in correct order. Reviewed-by: Christoph Bumiller Note: This is a candidate for the 7.11 branch. --- src/gallium/drivers/nv50/nv50_screen.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/gallium/drivers/nv50') diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index c36f3cd4a04..7ff11ea4b0b 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -261,16 +261,20 @@ nv50_screen_destroy(struct pipe_screen *pscreen) } static void -nv50_screen_fence_emit(struct pipe_screen *pscreen, u32 sequence) +nv50_screen_fence_emit(struct pipe_screen *pscreen, u32 *sequence) { struct nv50_screen *screen = nv50_screen(pscreen); struct nouveau_channel *chan = screen->base.channel; MARK_RING (chan, 5, 2); + + /* we need to do it after possible flush in MARK_RING */ + *sequence = ++screen->base.fence.sequence; + BEGIN_RING(chan, RING_3D(QUERY_ADDRESS_HIGH), 4); OUT_RELOCh(chan, screen->fence.bo, 0, NOUVEAU_BO_WR); OUT_RELOCl(chan, screen->fence.bo, 0, NOUVEAU_BO_WR); - OUT_RING (chan, sequence); + OUT_RING (chan, *sequence); OUT_RING (chan, NV50_3D_QUERY_GET_MODE_WRITE_UNK0 | NV50_3D_QUERY_GET_UNK4 | NV50_3D_QUERY_GET_UNIT_CROP | -- cgit v1.2.3