- N_01-WIP-nouveau-add-locking.patch

N_02-nouveau-more-locking-make-sure-that-fence-work-is-always-done-with-the-push-mutex-acquired.patch
  N_03-nv30-locking-fixes.patch
  N_04-nv50-Fix-double-lock-in-nv50_hw_sm_get_query_result.patch
  N_05-Use-nv50_render_condition-in-nv50_blitctx_post_blit.patch

  Backport nouveau locking workaround to enable multithreading.

  Source: https://github.com/imirkin/mesa/commits/locking

  According to the author, crashes may still happen, but much more rarely.

  Tested on GK107.

  N_04-* and N_05-* include untested fixes for nv50.

  Fixes (boo#997171) as suggested in (fdo#91632).

OBS-URL: https://build.opensuse.org/package/show/X11:XOrg/Mesa?expand=0&rev=540
This commit is contained in:
Max Staudt 2016-10-14 09:11:02 +00:00 committed by Git OBS Bridge
parent 76eb5ddec5
commit 12a58d062e
7 changed files with 2065 additions and 0 deletions

View File

@ -1,3 +1,24 @@
-------------------------------------------------------------------
Fri Oct 14 09:10:46 UTC 2016 - mstaudt@suse.com
- N_01-WIP-nouveau-add-locking.patch
N_02-nouveau-more-locking-make-sure-that-fence-work-is-always-done-with-the-push-mutex-acquired.patch
N_03-nv30-locking-fixes.patch
N_04-nv50-Fix-double-lock-in-nv50_hw_sm_get_query_result.patch
N_05-Use-nv50_render_condition-in-nv50_blitctx_post_blit.patch
Backport nouveau locking workaround to enable multithreading.
Source: https://github.com/imirkin/mesa/commits/locking
According to the author, crashes may still happen, but much more rarely.
Tested on GK107.
N_04-* and N_05-* include untested fixes for nv50.
Fixes (boo#997171) as suggested in (fdo#91632).
-------------------------------------------------------------------
Mon Sep 19 10:00:05 UTC 2016 - zaitor@opensuse.org

View File

@ -71,6 +71,12 @@ Patch15: u_mesa-8.0-llvmpipe-shmget.patch
Patch18: n_VDPAU-XVMC-libs-Replace-hardlinks-with-copies.patch
# never to be upstreamed
Patch21: n_Define-GLAPIVAR-separate-from-GLAPI.patch
# Nouveau multithreading workarounds from https://github.com/imirkin/mesa/commits/locking
Patch61: N_01-WIP-nouveau-add-locking.patch
Patch62: N_02-nouveau-more-locking-make-sure-that-fence-work-is-always-done-with-the-push-mutex-acquired.patch
Patch63: N_03-nv30-locking-fixes.patch
Patch64: N_04-nv50-Fix-double-lock-in-nv50_hw_sm_get_query_result.patch
Patch65: N_05-Use-nv50_render_condition-in-nv50_blitctx_post_blit.patch
BuildRequires: autoconf >= 2.60
BuildRequires: automake
@ -583,6 +589,11 @@ rm -rf docs/README.{VMS,WIN32,OS2}
%patch12 -p1
%patch18 -p1
%patch21 -p1
%patch61 -p1
%patch62 -p1
%patch63 -p1
%patch64 -p1
%patch65 -p1
%build
%if 0%{?suse_version} >= 1310

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,96 @@
From: Ilia Mirkin <imirkin@alum.mit.edu>
Date: Mon Jun 6 20:30:48 2016 -0400
Subject: [PATCH 2/5]nouveau: more locking - make sure that fence work is always done with the push mutex acquired
Patch-mainline: N/A
References: boo#997171
Signed-off-by: Max Staudt <mstaudt@suse.de>
Cherry-picked from 2733e5483e1c2b80e4b0ae21187ec5e3e1579397
at https://github.com/imirkin/mesa.git
Signed-off-by: Max Staudt <mstaudt@suse.de>
---
src/gallium/drivers/nouveau/nouveau_buffer.c | 4 ++++
src/gallium/drivers/nouveau/nv50/nv50_miptree.c | 7 +++++--
src/gallium/drivers/nouveau/nv50/nv50_query_hw.c | 5 ++++-
src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c | 5 ++++-
4 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/src/gallium/drivers/nouveau/nouveau_buffer.c b/src/gallium/drivers/nouveau/nouveau_buffer.c
index b54c19b..a5a06cf 100644
--- a/src/gallium/drivers/nouveau/nouveau_buffer.c
+++ b/src/gallium/drivers/nouveau/nouveau_buffer.c
@@ -80,6 +80,8 @@ release_allocation(struct nouveau_mm_allocation **mm,
inline void
nouveau_buffer_release_gpu_storage(struct nv04_resource *buf)
{
+ if (buf->fence)
+ pipe_mutex_lock(buf->fence->screen->push_mutex);
if (buf->fence && buf->fence->state < NOUVEAU_FENCE_STATE_FLUSHED) {
nouveau_fence_work(buf->fence, nouveau_fence_unref_bo, buf->bo);
buf->bo = NULL;
@@ -89,6 +91,8 @@ nouveau_buffer_release_gpu_storage(struct nv04_resource *buf)
if (buf->mm)
release_allocation(&buf->mm, buf->fence);
+ if (buf->fence)
+ pipe_mutex_unlock(buf->fence->screen->push_mutex);
if (buf->domain == NOUVEAU_BO_VRAM)
NOUVEAU_DRV_STAT_RES(buf, buf_obj_current_bytes_vid, -(uint64_t)buf->base.width0);
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_miptree.c b/src/gallium/drivers/nouveau/nv50/nv50_miptree.c
index 7450119..38e4faf 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_miptree.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_miptree.c
@@ -163,10 +163,13 @@ nv50_miptree_destroy(struct pipe_screen *pscreen, struct pipe_resource *pt)
{
struct nv50_miptree *mt = nv50_miptree(pt);
- if (mt->base.fence && mt->base.fence->state < NOUVEAU_FENCE_STATE_FLUSHED)
+ if (mt->base.fence && mt->base.fence->state < NOUVEAU_FENCE_STATE_FLUSHED) {
+ pipe_mutex_lock(nouveau_screen(pscreen)->push_mutex);
nouveau_fence_work(mt->base.fence, nouveau_fence_unref_bo, mt->base.bo);
- else
+ pipe_mutex_unlock(nouveau_screen(pscreen)->push_mutex);
+ } else {
nouveau_bo_ref(NULL, &mt->base.bo);
+ }
nouveau_fence_ref(NULL, &mt->base.fence);
nouveau_fence_ref(NULL, &mt->base.fence_wr);
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c b/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c
index 9067bcc..d2ad72e 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c
@@ -56,9 +56,12 @@ nv50_hw_query_allocate(struct nv50_context *nv50, struct nv50_query *q,
if (hq->mm) {
if (hq->state == NV50_HW_QUERY_STATE_READY)
nouveau_mm_free(hq->mm);
- else
+ else {
+ pipe_mutex_lock(screen->base.push_mutex);
nouveau_fence_work(screen->base.fence.current,
nouveau_mm_free_work, hq->mm);
+ pipe_mutex_unlock(screen->base.push_mutex);
+ }
}
}
if (size) {
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c b/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c
index f2584cb..4b51a67 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c
@@ -48,9 +48,12 @@ nvc0_hw_query_allocate(struct nvc0_context *nvc0, struct nvc0_query *q,
if (hq->mm) {
if (hq->state == NVC0_HW_QUERY_STATE_READY)
nouveau_mm_free(hq->mm);
- else
+ else {
+ pipe_mutex_lock(screen->base.push_mutex);
nouveau_fence_work(screen->base.fence.current,
nouveau_mm_free_work, hq->mm);
+ pipe_mutex_unlock(screen->base.push_mutex);
+ }
}
}
if (size) {

View File

@ -0,0 +1,120 @@
From: Ilia Mirkin <imirkin@alum.mit.edu>
Date: Tue Jun 21 22:59:50 2016 -0400
Subject: [PATCH 3/5]nv30 locking fixes
Patch-mainline: N/A
References: boo#997171
Signed-off-by: Max Staudt <mstaudt@suse.de>
Cherry-picked from 940b3a773f264f3f52574160f0d06c48f8e8aeb2
at https://github.com/imirkin/mesa.git
Signed-off-by: Max Staudt <mstaudt@suse.de>
---
src/gallium/drivers/nouveau/nv30/nv30_draw.c | 20 ++++++++++++++++++--
src/gallium/drivers/nouveau/nv30/nv30_fragprog.c | 4 ++++
2 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_draw.c b/src/gallium/drivers/nouveau/nv30/nv30_draw.c
index 7b0d074..1c71534 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_draw.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_draw.c
@@ -127,6 +127,8 @@ nv30_render_draw_elements(struct vbuf_render *render,
struct nouveau_pushbuf *push = nv30->screen->base.pushbuf;
unsigned i;
+ pipe_mutex_lock(nv30->screen->base.push_mutex);
+
BEGIN_NV04(push, NV30_3D(VTXBUF(0)), r->vertex_info.num_attribs);
for (i = 0; i < r->vertex_info.num_attribs; i++) {
PUSH_RESRC(push, NV30_3D(VTXBUF(i)), BUFCTX_VTXTMP,
@@ -134,8 +136,10 @@ nv30_render_draw_elements(struct vbuf_render *render,
NOUVEAU_BO_LOW | NOUVEAU_BO_RD, 0, NV30_3D_VTXBUF_DMA1);
}
- if (!nv30_state_validate(nv30, ~0, false))
+ if (!nv30_state_validate(nv30, ~0, false)) {
+ pipe_mutex_unlock(nv30->screen->base.push_mutex);
return;
+ }
BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
PUSH_DATA (push, r->prim);
@@ -160,6 +164,8 @@ nv30_render_draw_elements(struct vbuf_render *render,
BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
PUSH_DATA (push, NV30_3D_VERTEX_BEGIN_END_STOP);
PUSH_RESET(push, BUFCTX_VTXTMP);
+
+ pipe_mutex_unlock(nv30->screen->base.push_mutex);
}
static void
@@ -172,6 +178,8 @@ nv30_render_draw_arrays(struct vbuf_render *render, unsigned start, uint nr)
unsigned ps = fn + (pn ? 1 : 0);
unsigned i;
+ pipe_mutex_lock(nv30->screen->base.push_mutex);
+
BEGIN_NV04(push, NV30_3D(VTXBUF(0)), r->vertex_info.num_attribs);
for (i = 0; i < r->vertex_info.num_attribs; i++) {
PUSH_RESRC(push, NV30_3D(VTXBUF(i)), BUFCTX_VTXTMP,
@@ -179,8 +187,10 @@ nv30_render_draw_arrays(struct vbuf_render *render, unsigned start, uint nr)
NOUVEAU_BO_LOW | NOUVEAU_BO_RD, 0, NV30_3D_VTXBUF_DMA1);
}
- if (!nv30_state_validate(nv30, ~0, false))
+ if (!nv30_state_validate(nv30, ~0, false)) {
+ pipe_mutex_unlock(nv30->screen->base.push_mutex);
return;
+ }
BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
PUSH_DATA (push, r->prim);
@@ -197,6 +207,8 @@ nv30_render_draw_arrays(struct vbuf_render *render, unsigned start, uint nr)
BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
PUSH_DATA (push, NV30_3D_VERTEX_BEGIN_END_STOP);
PUSH_RESET(push, BUFCTX_VTXTMP);
+
+ pipe_mutex_unlock(nv30->screen->base.push_mutex);
}
static void
@@ -383,6 +395,8 @@ nv30_render_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
nv30_render_validate(nv30);
+ pipe_mutex_unlock(nv30->screen->base.push_mutex);
+
if (nv30->draw_dirty & NV30_NEW_VIEWPORT)
draw_set_viewport_states(draw, 0, 1, &nv30->viewport);
if (nv30->draw_dirty & NV30_NEW_RASTERIZER)
@@ -448,6 +462,8 @@ nv30_render_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
if (transfer[i])
pipe_buffer_unmap(pipe, transfer[i]);
+ pipe_mutex_lock(nv30->screen->base.push_mutex);
+
nv30->draw_dirty = 0;
nv30_state_release(nv30);
}
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_fragprog.c b/src/gallium/drivers/nouveau/nv30/nv30_fragprog.c
index 6de61bc..fd21f99 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_fragprog.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_fragprog.c
@@ -38,6 +38,8 @@ nv30_fragprog_upload(struct nv30_context *nv30)
struct nv30_fragprog *fp = nv30->fragprog.program;
struct pipe_context *pipe = &nv30->base.pipe;
+ pipe_mutex_unlock(nv->screen->push_mutex);
+
if (unlikely(!fp->buffer))
fp->buffer = pipe_buffer_create(pipe->screen, 0, 0, fp->insn_len * 4);
@@ -60,6 +62,8 @@ nv30_fragprog_upload(struct nv30_context *nv30)
if (nv04_resource(fp->buffer)->domain != NOUVEAU_BO_VRAM)
nouveau_buffer_migrate(nv, nv04_resource(fp->buffer), NOUVEAU_BO_VRAM);
+
+ pipe_mutex_lock(nv->screen->push_mutex);
}
void

View File

@ -0,0 +1,25 @@
From: Max Staudt <mstaudt@suse.de>
Date: Wed Oct 5 18:49:41 2016 +0200
Subject: [PATCH 4/5]nv50: Fix double lock in nv50_hw_sm_get_query_result()
Patch-mainline: N/A
References: boo#997171
Signed-off-by: Max Staudt <mstaudt@suse.de>
Signed-off-by: Max Staudt <mstaudt@suse.de>
---
src/gallium/drivers/nouveau/nv50/nv50_query_hw_sm.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_query_hw_sm.c b/src/gallium/drivers/nouveau/nv50/nv50_query_hw_sm.c
index 31445eb..acc64ac 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_query_hw_sm.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_query_hw_sm.c
@@ -351,7 +351,7 @@ nv50_hw_sm_get_query_result(struct nv50_context *nv50, struct nv50_hw_query *hq,
pipe_mutex_lock(nv50->screen->base.push_mutex);
ret = nv50_hw_sm_query_read_data(count, nv50, wait, hq, cfg, mp_count);
- pipe_mutex_lock(nv50->screen->base.push_mutex);
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
if (!ret)
return false;

View File

@ -0,0 +1,29 @@
From: Max Staudt <mstaudt@suse.de>
Date: Wed Oct 5 18:51:38 2016 +0200
Subject: [PATCH 5/5]Use nv50_render_condition() in nv50_blitctx_post_blit()
Patch-mainline: N/A
References: boo#997171
Signed-off-by: Max Staudt <mstaudt@suse.de>
Analogous to what happens in nvc0_blitctx_post_blit()
Signed-off-by: Max Staudt <mstaudt@suse.de>
---
src/gallium/drivers/nouveau/nv50/nv50_surface.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_surface.c b/src/gallium/drivers/nouveau/nv50/nv50_surface.c
index d6b9de0..36cd72b 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_surface.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_surface.c
@@ -1328,8 +1328,8 @@ nv50_blitctx_post_blit(struct nv50_blitctx *blit)
nv50->samplers[2][1] = blit->saved.sampler[1];
if (nv50->cond_query && !blit->render_condition_enable)
- nv50->base.pipe.render_condition(&nv50->base.pipe, nv50->cond_query,
- nv50->cond_cond, nv50->cond_mode);
+ nv50_render_condition(&nv50->base.pipe, nv50->cond_query,
+ nv50->cond_cond, nv50->cond_mode);
nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_3D_FB);
nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_3D_TEXTURES);