From e03bf6d9ec0656aaf60fb60bc5c8d1054a3cb63d Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 31 Mar 2010 16:56:53 +0300 Subject: [PATCH] gpu: pvr: fix locking on the HW interrupt path - take pvr_lock in the interrupt handling work (MISR) thread, as from there we can call functions accessing HW and SW state tracking objects. An example is the SGX HW recovery function. - make SGXOSTimerCancel asynchronous. This is safe now as a previous patch made sure that the timer will not run after cancelled. We can't do synchronous cancellation, because there would be an ABBA lockdep problem involving the SGXOSTimer's mutex and pvr_lock: MISR / IOCTL thread: 1. pvr_lock in PVRSRV_BridgeDispatchKM 2. timer's lock through SGXPrePowerState -> SGXOSTimerCancel SGXOSTimer's thread: 1. timer's lock already taken when SGXOSTimer is called 2. pvr_lock in SGXOSTimer Signed-off-by: Imre Deak --- pvr/pvrsrv.c | 4 ++++ pvr/sgxinit.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/pvr/pvrsrv.c b/pvr/pvrsrv.c index 6db31c0..411d9a0 100644 --- a/pvr/pvrsrv.c +++ b/pvr/pvrsrv.c @@ -791,6 +791,8 @@ void PVRSRVMISR(void *pvSysData) return; } + pvr_lock(); + psDeviceNode = psSysData->psDeviceNodeList; while (psDeviceNode != NULL) { if (psDeviceNode->pfnDeviceMISR != NULL) @@ -809,6 +811,8 @@ void PVRSRVMISR(void *pvSysData) if (hOSEventKM) OSEventObjectSignal(hOSEventKM); } + + pvr_unlock(); } enum PVRSRV_ERROR PVRSRVProcessConnect(u32 ui32PID) diff --git a/pvr/sgxinit.c b/pvr/sgxinit.c index d00cf76..c4a19c3 100644 --- a/pvr/sgxinit.c +++ b/pvr/sgxinit.c @@ -823,7 +823,7 @@ enum PVRSRV_ERROR SGXOSTimerCancel(struct timer_work_data *data) return PVRSRV_ERROR_GENERIC; data->armed = false; - cancel_delayed_work_sync(&data->work); + cancel_delayed_work(&data->work); return PVRSRV_OK; } -- 2.39.5