Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Leap:42.1:Update
Mesa.6057
U_nouveau-avoid-queueing-too-much-work-onto-a-s...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File U_nouveau-avoid-queueing-too-much-work-onto-a-single-fence.patch of Package Mesa.6057
From: Ilia Mirkin <imirkin@alum.mit.edu> Date: Fri Nov 6 00:44:10 2015 -0500 Subject: [PATCH]nouveau: avoid queueing too much work onto a single fence Patch-mainline: Upstream Git-commit: 53cbb11707a502a31bb9f0380d730840245ee9b2 Git-repo: git://anongit.freedesktop.org/mesa/mesa References: boo#977047 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@alum.mit.edu> Signed-off-by: Max Staudt <mstaudt@suse.de> --- src/gallium/drivers/nouveau/nouveau_fence.c | 66 ++++++++++++++++++----------- src/gallium/drivers/nouveau/nouveau_fence.h | 1 + 2 files changed, 42 insertions(+), 25 deletions(-) diff --git a/src/gallium/drivers/nouveau/nouveau_fence.c b/src/gallium/drivers/nouveau/nouveau_fence.c index 21cf2b9..18a4b6e 100644 --- a/src/gallium/drivers/nouveau/nouveau_fence.c +++ b/src/gallium/drivers/nouveau/nouveau_fence.c @@ -58,26 +58,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) { @@ -181,11 +161,10 @@ nouveau_fence_signalled(struct nouveau_fence *fence) return fence->state == NOUVEAU_FENCE_STATE_SIGNALLED; } -bool -nouveau_fence_wait(struct nouveau_fence *fence) +static bool +nouveau_fence_kick(struct nouveau_fence *fence) { struct nouveau_screen *screen = fence->screen; - uint32_t spins = 0; /* wtf, someone is waiting on a fence in flush_notify handler? */ assert(fence->state != NOUVEAU_FENCE_STATE_EMITTING); @@ -206,9 +185,21 @@ nouveau_fence_wait(struct nouveau_fence *fence) if (fence == screen->fence.current) nouveau_fence_next(screen); - do { - nouveau_fence_update(screen, false); + nouveau_fence_update(screen, false); + return true; +} + +bool +nouveau_fence_wait(struct nouveau_fence *fence) +{ + struct nouveau_screen *screen = fence->screen; + uint32_t spins = 0; + + if (!nouveau_fence_kick(fence)) + return false; + + do { if (fence->state == NOUVEAU_FENCE_STATE_SIGNALLED) return true; if (!spins) @@ -218,6 +209,8 @@ nouveau_fence_wait(struct nouveau_fence *fence) 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", @@ -249,3 +242,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) + 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 2efcab2..c5904e9 100644 --- a/src/gallium/drivers/nouveau/nouveau_fence.h +++ b/src/gallium/drivers/nouveau/nouveau_fence.h @@ -23,6 +23,7 @@ struct nouveau_fence { int state; int ref; uint32_t sequence; + uint32_t work_count; struct list_head work; };
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor