drm/nouveau/pmu: be more strict about locking
When we start communicating with the pmu a bit more, the current code is a real issue. I encountered a dead lock here, while testing my dynamic reclocking code Signed-off-by: Karol Herbst <nouveau@karolherbst.de> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
parent
c6007dc4e5
commit
7d28dbae22
|
@ -40,21 +40,23 @@ nvkm_pmu_send(struct nvkm_pmu *pmu, u32 reply[2],
|
||||||
struct nvkm_device *device = subdev->device;
|
struct nvkm_device *device = subdev->device;
|
||||||
u32 addr;
|
u32 addr;
|
||||||
|
|
||||||
|
mutex_lock(&subdev->mutex);
|
||||||
/* wait for a free slot in the fifo */
|
/* wait for a free slot in the fifo */
|
||||||
addr = nvkm_rd32(device, 0x10a4a0);
|
addr = nvkm_rd32(device, 0x10a4a0);
|
||||||
if (nvkm_msec(device, 2000,
|
if (nvkm_msec(device, 2000,
|
||||||
u32 tmp = nvkm_rd32(device, 0x10a4b0);
|
u32 tmp = nvkm_rd32(device, 0x10a4b0);
|
||||||
if (tmp != (addr ^ 8))
|
if (tmp != (addr ^ 8))
|
||||||
break;
|
break;
|
||||||
) < 0)
|
) < 0) {
|
||||||
|
mutex_unlock(&subdev->mutex);
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
|
||||||
/* we currently only support a single process at a time waiting
|
/* we currently only support a single process at a time waiting
|
||||||
* on a synchronous reply, take the PMU mutex and tell the
|
* on a synchronous reply, take the PMU mutex and tell the
|
||||||
* receive handler what we're waiting for
|
* receive handler what we're waiting for
|
||||||
*/
|
*/
|
||||||
if (reply) {
|
if (reply) {
|
||||||
mutex_lock(&subdev->mutex);
|
|
||||||
pmu->recv.message = message;
|
pmu->recv.message = message;
|
||||||
pmu->recv.process = process;
|
pmu->recv.process = process;
|
||||||
}
|
}
|
||||||
|
@ -81,9 +83,9 @@ nvkm_pmu_send(struct nvkm_pmu *pmu, u32 reply[2],
|
||||||
wait_event(pmu->recv.wait, (pmu->recv.process == 0));
|
wait_event(pmu->recv.wait, (pmu->recv.process == 0));
|
||||||
reply[0] = pmu->recv.data[0];
|
reply[0] = pmu->recv.data[0];
|
||||||
reply[1] = pmu->recv.data[1];
|
reply[1] = pmu->recv.data[1];
|
||||||
mutex_unlock(&subdev->mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mutex_unlock(&subdev->mutex);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue