nouveau: change fence destruction logic on screen destroy

With the drm shim, we can't actually wait for the hardware to do
anything. But why wait for it at all? We just need to make sure to
execute all the work and clean up any resources. Add a helper to do
that.

Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
Reviewed-by: Karol Herbst <kherbst@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8406>
This commit is contained in:
Ilia Mirkin 2021-01-09 13:13:42 -05:00 committed by Marge Bot
parent c7e1ef7c0c
commit 28a781323f
5 changed files with 19 additions and 31 deletions

View file

@ -108,6 +108,21 @@ nouveau_fence_del(struct nouveau_fence *fence)
FREE(fence); FREE(fence);
} }
void
nouveau_fence_cleanup(struct nouveau_screen *screen)
{
struct nouveau_fence *fence, *next;
for (fence = screen->fence.head; fence; fence = next) {
next = fence->next;
nouveau_fence_trigger_work(fence);
nouveau_fence_ref(NULL, &fence);
}
screen->fence.head = NULL;
screen->fence.tail = NULL;
nouveau_fence_ref(NULL, &screen->fence.current);
}
void void
nouveau_fence_update(struct nouveau_screen *screen, bool flushed) nouveau_fence_update(struct nouveau_screen *screen, bool flushed)
{ {

View file

@ -33,6 +33,7 @@ void nouveau_fence_emit(struct nouveau_fence *);
void nouveau_fence_del(struct nouveau_fence *); void nouveau_fence_del(struct nouveau_fence *);
bool nouveau_fence_new(struct nouveau_screen *, struct nouveau_fence **); bool nouveau_fence_new(struct nouveau_screen *, struct nouveau_fence **);
void nouveau_fence_cleanup(struct nouveau_screen *);
bool nouveau_fence_work(struct nouveau_fence *, void (*)(void *), void *); bool nouveau_fence_work(struct nouveau_fence *, void (*)(void *), void *);
void nouveau_fence_update(struct nouveau_screen *, bool flushed); void nouveau_fence_update(struct nouveau_screen *, bool flushed);
void nouveau_fence_next(struct nouveau_screen *); void nouveau_fence_next(struct nouveau_screen *);

View file

@ -495,17 +495,7 @@ nv30_screen_destroy(struct pipe_screen *pscreen)
if (!nouveau_drm_screen_unref(&screen->base)) if (!nouveau_drm_screen_unref(&screen->base))
return; return;
if (screen->base.fence.current) { nouveau_fence_cleanup(&screen->base);
struct nouveau_fence *current = NULL;
/* nouveau_fence_wait will create a new current fence, so wait on the
* _current_ one, and remove both.
*/
nouveau_fence_ref(screen->base.fence.current, &current);
nouveau_fence_wait(current, NULL);
nouveau_fence_ref(NULL, &current);
nouveau_fence_ref(NULL, &screen->base.fence.current);
}
nouveau_bo_ref(NULL, &screen->notify); nouveau_bo_ref(NULL, &screen->notify);

View file

@ -555,17 +555,8 @@ nv50_screen_destroy(struct pipe_screen *pscreen)
if (!nouveau_drm_screen_unref(&screen->base)) if (!nouveau_drm_screen_unref(&screen->base))
return; return;
if (screen->base.fence.current) { nouveau_fence_cleanup(&screen->base);
struct nouveau_fence *current = NULL;
/* nouveau_fence_wait will create a new current fence, so wait on the
* _current_ one, and remove both.
*/
nouveau_fence_ref(screen->base.fence.current, &current);
nouveau_fence_wait(current, NULL);
nouveau_fence_ref(NULL, &current);
nouveau_fence_ref(NULL, &screen->base.fence.current);
}
if (screen->base.pushbuf) if (screen->base.pushbuf)
screen->base.pushbuf->user_priv = NULL; screen->base.pushbuf->user_priv = NULL;

View file

@ -673,17 +673,8 @@ nvc0_screen_destroy(struct pipe_screen *pscreen)
if (!nouveau_drm_screen_unref(&screen->base)) if (!nouveau_drm_screen_unref(&screen->base))
return; return;
if (screen->base.fence.current) { nouveau_fence_cleanup(&screen->base);
struct nouveau_fence *current = NULL;
/* nouveau_fence_wait will create a new current fence, so wait on the
* _current_ one, and remove both.
*/
nouveau_fence_ref(screen->base.fence.current, &current);
nouveau_fence_wait(current, NULL);
nouveau_fence_ref(NULL, &current);
nouveau_fence_ref(NULL, &screen->base.fence.current);
}
if (screen->base.pushbuf) if (screen->base.pushbuf)
screen->base.pushbuf->user_priv = NULL; screen->base.pushbuf->user_priv = NULL;