drm/nouveau/fifo/gf100-: protect channel preempt with subdev mutex
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: Ben Skeggs <bskeggs@redhat.com> Cc: stable@vger.kernel.org
This commit is contained in:
parent
e137040e0d
commit
b27add13f5
|
@ -60,6 +60,7 @@ gf100_fifo_gpfifo_engine_fini(struct nvkm_fifo_chan *base,
|
|||
struct nvkm_gpuobj *inst = chan->base.inst;
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&subdev->mutex);
|
||||
nvkm_wr32(device, 0x002634, chan->base.chid);
|
||||
if (nvkm_msec(device, 2000,
|
||||
if (nvkm_rd32(device, 0x002634) == chan->base.chid)
|
||||
|
@ -67,10 +68,12 @@ gf100_fifo_gpfifo_engine_fini(struct nvkm_fifo_chan *base,
|
|||
) < 0) {
|
||||
nvkm_error(subdev, "channel %d [%s] kick timeout\n",
|
||||
chan->base.chid, chan->base.object.client->name);
|
||||
ret = -EBUSY;
|
||||
if (suspend)
|
||||
return ret;
|
||||
ret = -ETIMEDOUT;
|
||||
}
|
||||
mutex_unlock(&subdev->mutex);
|
||||
|
||||
if (ret && suspend)
|
||||
return ret;
|
||||
|
||||
if (offset) {
|
||||
nvkm_kmap(inst);
|
||||
|
|
|
@ -40,7 +40,9 @@ gk104_fifo_gpfifo_kick(struct gk104_fifo_chan *chan)
|
|||
struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
|
||||
struct nvkm_device *device = subdev->device;
|
||||
struct nvkm_client *client = chan->base.object.client;
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&subdev->mutex);
|
||||
nvkm_wr32(device, 0x002634, chan->base.chid);
|
||||
if (nvkm_msec(device, 2000,
|
||||
if (!(nvkm_rd32(device, 0x002634) & 0x00100000))
|
||||
|
@ -48,10 +50,10 @@ gk104_fifo_gpfifo_kick(struct gk104_fifo_chan *chan)
|
|||
) < 0) {
|
||||
nvkm_error(subdev, "channel %d [%s] kick timeout\n",
|
||||
chan->base.chid, client->name);
|
||||
return -EBUSY;
|
||||
ret = -ETIMEDOUT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
mutex_unlock(&subdev->mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static u32
|
||||
|
|
Loading…
Reference in a new issue