diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2016-11-05 00:33:14 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2016-11-06 23:05:13 -0500 |
commit | b27add13f500469127afdf011dbcc9c649e16e54 (patch) | |
tree | 29f3d0087452fdcf7166d83c82a936af26f3e8e0 | |
parent | e137040e0d0376b404fc5155eba44ea07126e3bd (diff) |
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
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c | 8 |
2 files changed, 11 insertions, 6 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c index cbc67f262322..12d964260a29 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c | |||
@@ -60,6 +60,7 @@ gf100_fifo_gpfifo_engine_fini(struct nvkm_fifo_chan *base, | |||
60 | struct nvkm_gpuobj *inst = chan->base.inst; | 60 | struct nvkm_gpuobj *inst = chan->base.inst; |
61 | int ret = 0; | 61 | int ret = 0; |
62 | 62 | ||
63 | mutex_lock(&subdev->mutex); | ||
63 | nvkm_wr32(device, 0x002634, chan->base.chid); | 64 | nvkm_wr32(device, 0x002634, chan->base.chid); |
64 | if (nvkm_msec(device, 2000, | 65 | if (nvkm_msec(device, 2000, |
65 | if (nvkm_rd32(device, 0x002634) == chan->base.chid) | 66 | if (nvkm_rd32(device, 0x002634) == chan->base.chid) |
@@ -67,10 +68,12 @@ gf100_fifo_gpfifo_engine_fini(struct nvkm_fifo_chan *base, | |||
67 | ) < 0) { | 68 | ) < 0) { |
68 | nvkm_error(subdev, "channel %d [%s] kick timeout\n", | 69 | nvkm_error(subdev, "channel %d [%s] kick timeout\n", |
69 | chan->base.chid, chan->base.object.client->name); | 70 | chan->base.chid, chan->base.object.client->name); |
70 | ret = -EBUSY; | 71 | ret = -ETIMEDOUT; |
71 | if (suspend) | ||
72 | return ret; | ||
73 | } | 72 | } |
73 | mutex_unlock(&subdev->mutex); | ||
74 | |||
75 | if (ret && suspend) | ||
76 | return ret; | ||
74 | 77 | ||
75 | if (offset) { | 78 | if (offset) { |
76 | nvkm_kmap(inst); | 79 | nvkm_kmap(inst); |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c index ed4351032ed6..a2df4f3e7763 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c | |||
@@ -40,7 +40,9 @@ gk104_fifo_gpfifo_kick(struct gk104_fifo_chan *chan) | |||
40 | struct nvkm_subdev *subdev = &fifo->base.engine.subdev; | 40 | struct nvkm_subdev *subdev = &fifo->base.engine.subdev; |
41 | struct nvkm_device *device = subdev->device; | 41 | struct nvkm_device *device = subdev->device; |
42 | struct nvkm_client *client = chan->base.object.client; | 42 | struct nvkm_client *client = chan->base.object.client; |
43 | int ret = 0; | ||
43 | 44 | ||
45 | mutex_lock(&subdev->mutex); | ||
44 | nvkm_wr32(device, 0x002634, chan->base.chid); | 46 | nvkm_wr32(device, 0x002634, chan->base.chid); |
45 | if (nvkm_msec(device, 2000, | 47 | if (nvkm_msec(device, 2000, |
46 | if (!(nvkm_rd32(device, 0x002634) & 0x00100000)) | 48 | if (!(nvkm_rd32(device, 0x002634) & 0x00100000)) |
@@ -48,10 +50,10 @@ gk104_fifo_gpfifo_kick(struct gk104_fifo_chan *chan) | |||
48 | ) < 0) { | 50 | ) < 0) { |
49 | nvkm_error(subdev, "channel %d [%s] kick timeout\n", | 51 | nvkm_error(subdev, "channel %d [%s] kick timeout\n", |
50 | chan->base.chid, client->name); | 52 | chan->base.chid, client->name); |
51 | return -EBUSY; | 53 | ret = -ETIMEDOUT; |
52 | } | 54 | } |
53 | 55 | mutex_unlock(&subdev->mutex); | |
54 | return 0; | 56 | return ret; |
55 | } | 57 | } |
56 | 58 | ||
57 | static u32 | 59 | static u32 |