From e4f4b83ee11954634242fcbdf700a4cdf57db135 Mon Sep 17 00:00:00 2001 From: Deepak Kumar Date: Fri, 30 Apr 2021 12:46:24 +0530 Subject: [PATCH] msm: kgsl: Fix race between kgsl device open and close In current code, kgsl_close_device holds device mutex and calls last_close in case open_count goes to zero. But as part of last_close call, device mutex is released intermittently to wait for active count to go to zero and also for dispatcher idle. This intermittent release of device mutex opens up a window where a kgsl_open_device call can go ahead and call first_open. As this first_open is triggered before last_close could finish it messes up the complete state machine. To fix this, move decrement of open_count after last_close to allow any open/close happening when last_close is in progress to just increment/decrement open_count without triggering first_open or last_close. Change-Id: Ibb2567e3ef0dc1864f2bfca346b0682792d0b675 Signed-off-by: Deepak Kumar --- drivers/gpu/msm/kgsl.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index 5fabee5b84ac..f25a36bcc863 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -1047,10 +1047,20 @@ static int kgsl_close_device(struct kgsl_device *device) int result = 0; mutex_lock(&device->mutex); - device->open_count--; - if (device->open_count == 0) + if (device->open_count == 1) result = device->ftbl->last_close(device); + /* + * We must decrement the open_count after last_close() has finished. + * This is because last_close() relinquishes device mutex while + * waiting for active count to become 0. This opens up a window + * where a new process can come in, see that open_count is 0, and + * initiate a first_open(). This can potentially mess up the power + * state machine. To avoid a first_open() from happening before + * last_close() has finished, decrement the open_count after + * last_close(). + */ + device->open_count--; mutex_unlock(&device->mutex); return result;