[Mesa-dev] [PATCH] nouveau: avoid queueing too much work onto a single fence
Jan Vesely
jan.vesely at rutgers.edu
Thu Nov 5 22:27:00 PST 2015
On Fri, 2015-11-06 at 00:46 -0500, Ilia Mirkin wrote:
> Force the fence to get kicked off, which won't actually wait for its
> completion, but any additional work will be put onto a fresh list.
>
> This fixes crashes in teximage-colors --benchmark with too many
> active
> maps.
>
> Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu>
> ---
> src/gallium/drivers/nouveau/nouveau_fence.c | 68 ++++++++++++++++++-
> ----------
> src/gallium/drivers/nouveau/nouveau_fence.h | 1 +
> 2 files changed, 43 insertions(+), 26 deletions(-)
>
> diff --git a/src/gallium/drivers/nouveau/nouveau_fence.c
> b/src/gallium/drivers/nouveau/nouveau_fence.c
> index d3a3406..691553a 100644
> --- a/src/gallium/drivers/nouveau/nouveau_fence.c
> +++ b/src/gallium/drivers/nouveau/nouveau_fence.c
> @@ -59,26 +59,6 @@ nouveau_fence_trigger_work(struct nouveau_fence
> *fence)
> }
> }
>
> -bool
> -nouveau_fence_work(struct nouveau_fence *fence,
> - void (*func)(void *), void *data)
> -{
> - struct nouveau_fence_work *work;
> -
> - if (!fence || fence->state == NOUVEAU_FENCE_STATE_SIGNALLED) {
> - func(data);
> - return true;
> - }
> -
> - work = CALLOC_STRUCT(nouveau_fence_work);
> - if (!work)
> - return false;
> - work->func = func;
> - work->data = data;
> - LIST_ADD(&work->list, &fence->work);
> - return true;
> -}
> -
> void
> nouveau_fence_emit(struct nouveau_fence *fence)
> {
> @@ -182,12 +162,10 @@ nouveau_fence_signalled(struct nouveau_fence
> *fence)
> return fence->state == NOUVEAU_FENCE_STATE_SIGNALLED;
> }
>
> -bool
> -nouveau_fence_wait(struct nouveau_fence *fence, struct
> pipe_debug_callback *debug)
> +static bool
> +nouveau_fence_kick(struct nouveau_fence *fence)
> {
> struct nouveau_screen *screen = fence->screen;
> - uint32_t spins = 0;
> - int64_t start = 0;
>
> /* wtf, someone is waiting on a fence in flush_notify handler? */
> assert(fence->state != NOUVEAU_FENCE_STATE_EMITTING);
> @@ -208,12 +186,25 @@ nouveau_fence_wait(struct nouveau_fence *fence,
> struct pipe_debug_callback *debu
> if (fence == screen->fence.current)
> nouveau_fence_next(screen);
>
> + nouveau_fence_update(screen, false);
> +
> + return true;
> +}
> +
> +bool
> +nouveau_fence_wait(struct nouveau_fence *fence, struct
> pipe_debug_callback *debug)
> +{
> + struct nouveau_screen *screen = fence->screen;
> + uint32_t spins = 0;
> + int64_t start = 0;
> +
> if (debug && debug->debug_message)
> start = os_time_get_nano();
>
> - do {
> - nouveau_fence_update(screen, false);
> + if (!nouveau_fence_kick(fence))
> + return false;
>
> + do {
> if (fence->state == NOUVEAU_FENCE_STATE_SIGNALLED) {
> if (debug && debug->debug_message)
> pipe_debug_message(debug, PERF_INFO,
> @@ -228,6 +219,8 @@ nouveau_fence_wait(struct nouveau_fence *fence,
> struct pipe_debug_callback *debu
> if (!(spins % 8)) /* donate a few cycles */
> sched_yield();
> #endif
> +
> + nouveau_fence_update(screen, false);
> } while (spins < NOUVEAU_FENCE_MAX_SPINS);
>
> debug_printf("Wait on fence %u (ack = %u, next = %u) timed out
> !\n",
> @@ -259,3 +252,26 @@ nouveau_fence_unref_bo(void *data)
>
> nouveau_bo_ref(NULL, &bo);
> }
> +
> +bool
> +nouveau_fence_work(struct nouveau_fence *fence,
> + void (*func)(void *), void *data)
> +{
> + struct nouveau_fence_work *work;
> +
> + if (!fence || fence->state == NOUVEAU_FENCE_STATE_SIGNALLED) {
> + func(data);
> + return true;
> + }
> +
> + work = CALLOC_STRUCT(nouveau_fence_work);
> + if (!work)
> + return false;
> + work->func = func;
> + work->data = data;
> + LIST_ADD(&work->list, &fence->work);
> + p_atomic_inc(&fence->work_count);
> + if (fence->work_count > 64)
Is 64 just an arbitrary number?
> + nouveau_fence_kick(fence);
> + return true;
> +}
> diff --git a/src/gallium/drivers/nouveau/nouveau_fence.h
> b/src/gallium/drivers/nouveau/nouveau_fence.h
> index 0fa9d02..f10016d 100644
> --- a/src/gallium/drivers/nouveau/nouveau_fence.h
> +++ b/src/gallium/drivers/nouveau/nouveau_fence.h
> @@ -25,6 +25,7 @@ struct nouveau_fence {
> int state;
> int ref;
> uint32_t sequence;
> + uint32_t work_count;
> struct list_head work;
> };
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: This is a digitally signed message part
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20151106/daa8483e/attachment.sig>
More information about the mesa-dev
mailing list