From 1757ab898b49d68cad7082a962bb9a114f4e3aba Mon Sep 17 00:00:00 2001 From: Tarun Karra Date: Thu, 22 Oct 2015 12:22:08 -0700 Subject: [PATCH] msm: kgsl: Prevent deadlock in cmdbatch timer Dispatcher can acquire drawctxt->lock if context is pending and the fence it is waiting on just got signalled. Dispatcher acquires drawctxt->lock and tries to delete the cmdbatch timer using delete_timer_sync(). Delete_timer_sync() waits till timer and its pending handlers are deleted. But if the timer expires at the same time, timer handler could be waiting on drawctxt->lock leading to a deadlock. To prevent this use spin_trylock_bh() instead of spin_lock_bh(). spin_trylock_bh() does not wait for the lock if it does not get it and allows the timer handler to finish. This prevents the deadlock. Change-Id: Ic2344fed5fccb581b58ec0b66b45ba68af9f1459 Signed-off-by: Tarun Karra --- drivers/gpu/msm/adreno_drawctxt.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/msm/adreno_drawctxt.c b/drivers/gpu/msm/adreno_drawctxt.c index 505fd5473a78..b53494eadf78 100644 --- a/drivers/gpu/msm/adreno_drawctxt.c +++ b/drivers/gpu/msm/adreno_drawctxt.c @@ -64,8 +64,22 @@ void adreno_drawctxt_dump(struct kgsl_device *device, * We may have cmdbatch timer running, which also uses same * lock, take a lock with software interrupt disabled (bh) * to avoid spin lock recursion. + * + * Use Spin trylock because dispatcher can acquire drawctxt->lock + * if context is pending and the fence it is waiting on just got + * signalled. Dispatcher acquires drawctxt->lock and tries to + * delete the cmdbatch timer using del_timer_sync(). + * del_timer_sync() waits till timer and its pending handlers + * are deleted. But if the timer expires at the same time, + * timer handler could be waiting on drawctxt->lock leading to a + * deadlock. To prevent this use spin_trylock_bh. */ - spin_lock_bh(&drawctxt->lock); + if (!spin_trylock_bh(&drawctxt->lock)) { + dev_err(device->dev, " context[%d]: could not get lock\n", + context->id); + return; + } + dev_err(device->dev, " context[%d]: queue=%d, submit=%d, start=%d, retire=%d\n", context->id, queue, drawctxt->submitted_timestamp,