Commit 1dcaeab1 authored by Ben Skeggs's avatar Ben Skeggs Committed by Luis Henriques

drm/nouveau/fifo/gf100-: protect channel preempt with subdev mutex

BugLink: http://bugs.launchpad.net/bugs/1655041

commit b27add13 upstream.

This avoids an issue that occurs when we're attempting to preempt multiple
channels simultaneously.  HW seems to ignore preempt requests while it's
still processing a previous one, which, well, makes sense.

Fixes random "fifo: SCHED_ERROR 0d []" + GPCCS page faults during parallel
piglit runs on (at least) GM107.
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarTim Gardner <tim.gardner@canonical.com>
Signed-off-by: default avatarLuis Henriques <luis.henriques@canonical.com>
parent f209941e
...@@ -59,6 +59,7 @@ gf100_fifo_gpfifo_engine_fini(struct nvkm_fifo_chan *base, ...@@ -59,6 +59,7 @@ gf100_fifo_gpfifo_engine_fini(struct nvkm_fifo_chan *base,
struct nvkm_gpuobj *inst = chan->base.inst; struct nvkm_gpuobj *inst = chan->base.inst;
int ret = 0; int ret = 0;
mutex_lock(&subdev->mutex);
nvkm_wr32(device, 0x002634, chan->base.chid); nvkm_wr32(device, 0x002634, chan->base.chid);
if (nvkm_msec(device, 2000, if (nvkm_msec(device, 2000,
if (nvkm_rd32(device, 0x002634) == chan->base.chid) if (nvkm_rd32(device, 0x002634) == chan->base.chid)
...@@ -66,10 +67,12 @@ gf100_fifo_gpfifo_engine_fini(struct nvkm_fifo_chan *base, ...@@ -66,10 +67,12 @@ gf100_fifo_gpfifo_engine_fini(struct nvkm_fifo_chan *base,
) < 0) { ) < 0) {
nvkm_error(subdev, "channel %d [%s] kick timeout\n", nvkm_error(subdev, "channel %d [%s] kick timeout\n",
chan->base.chid, chan->base.object.client->name); chan->base.chid, chan->base.object.client->name);
ret = -EBUSY; ret = -ETIMEDOUT;
if (suspend)
return ret;
} }
mutex_unlock(&subdev->mutex);
if (ret && suspend)
return ret;
if (offset) { if (offset) {
nvkm_kmap(inst); nvkm_kmap(inst);
......
...@@ -39,7 +39,9 @@ gk104_fifo_gpfifo_kick(struct gk104_fifo_chan *chan) ...@@ -39,7 +39,9 @@ gk104_fifo_gpfifo_kick(struct gk104_fifo_chan *chan)
struct nvkm_subdev *subdev = &fifo->base.engine.subdev; struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
struct nvkm_device *device = subdev->device; struct nvkm_device *device = subdev->device;
struct nvkm_client *client = chan->base.object.client; struct nvkm_client *client = chan->base.object.client;
int ret = 0;
mutex_lock(&subdev->mutex);
nvkm_wr32(device, 0x002634, chan->base.chid); nvkm_wr32(device, 0x002634, chan->base.chid);
if (nvkm_msec(device, 2000, if (nvkm_msec(device, 2000,
if (!(nvkm_rd32(device, 0x002634) & 0x00100000)) if (!(nvkm_rd32(device, 0x002634) & 0x00100000))
...@@ -47,10 +49,10 @@ gk104_fifo_gpfifo_kick(struct gk104_fifo_chan *chan) ...@@ -47,10 +49,10 @@ gk104_fifo_gpfifo_kick(struct gk104_fifo_chan *chan)
) < 0) { ) < 0) {
nvkm_error(subdev, "channel %d [%s] kick timeout\n", nvkm_error(subdev, "channel %d [%s] kick timeout\n",
chan->base.chid, client->name); chan->base.chid, client->name);
return -EBUSY; ret = -ETIMEDOUT;
} }
mutex_unlock(&subdev->mutex);
return 0; return ret;
} }
static u32 static u32
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment