msm: kgsl: Avoid global process lock for close
Currently, resources for processes are freed within global process lock. This can block resources of multiple other processes. Ideally, there is no global resource that is being protected. Introduce a process private level lock to protect the private information. Change-Id: Ib28da1e346269eaa0a638b32ebc7471ff676afb0 Signed-off-by: Kamal Agrawal <quic_kamaagra@quicinc.com>
This commit is contained in:
parent
6c9426c7dc
commit
5af7b2f049
24
kgsl.c
24
kgsl.c
@ -963,7 +963,7 @@ static struct kgsl_process_private *kgsl_process_private_new(
|
||||
/* Search in the process list */
|
||||
list_for_each_entry(private, &kgsl_driver.process_list, list) {
|
||||
if (private->pid == cur_pid) {
|
||||
if (!kgsl_process_private_get(private))
|
||||
if (!kgsl_process_private_get(private)) {
|
||||
/*
|
||||
* This will happen only if refcount is zero
|
||||
* i.e. destroy is triggered but didn't complete
|
||||
@ -972,6 +972,12 @@ static struct kgsl_process_private *kgsl_process_private_new(
|
||||
* appropriate action.
|
||||
*/
|
||||
private = ERR_PTR(-EEXIST);
|
||||
} else {
|
||||
mutex_lock(&private->private_mutex);
|
||||
private->fd_count++;
|
||||
mutex_unlock(&private->private_mutex);
|
||||
}
|
||||
|
||||
/*
|
||||
* We need to hold only one reference to the PID for
|
||||
* each process struct to avoid overflowing the
|
||||
@ -991,12 +997,14 @@ static struct kgsl_process_private *kgsl_process_private_new(
|
||||
|
||||
kref_init(&private->refcount);
|
||||
|
||||
private->fd_count = 1;
|
||||
private->pid = cur_pid;
|
||||
get_task_comm(private->comm, current->group_leader);
|
||||
|
||||
spin_lock_init(&private->mem_lock);
|
||||
spin_lock_init(&private->syncsource_lock);
|
||||
spin_lock_init(&private->ctxt_count_lock);
|
||||
mutex_init(&private->private_mutex);
|
||||
|
||||
idr_init(&private->mem_idr);
|
||||
idr_init(&private->syncsource_idr);
|
||||
@ -1058,10 +1066,10 @@ static void process_release_memory(struct kgsl_process_private *private)
|
||||
static void kgsl_process_private_close(struct kgsl_device_private *dev_priv,
|
||||
struct kgsl_process_private *private)
|
||||
{
|
||||
mutex_lock(&kgsl_driver.process_mutex);
|
||||
mutex_lock(&private->private_mutex);
|
||||
|
||||
if (--private->fd_count > 0) {
|
||||
mutex_unlock(&kgsl_driver.process_mutex);
|
||||
mutex_unlock(&private->private_mutex);
|
||||
kgsl_process_private_put(private);
|
||||
return;
|
||||
}
|
||||
@ -1075,7 +1083,7 @@ static void kgsl_process_private_close(struct kgsl_device_private *dev_priv,
|
||||
/* Release all syncsource objects from process private */
|
||||
kgsl_syncsource_process_release_syncsources(private);
|
||||
|
||||
mutex_unlock(&kgsl_driver.process_mutex);
|
||||
mutex_unlock(&private->private_mutex);
|
||||
|
||||
kgsl_process_private_put(private);
|
||||
}
|
||||
@ -1087,14 +1095,8 @@ static struct kgsl_process_private *_process_private_open(
|
||||
|
||||
mutex_lock(&kgsl_driver.process_mutex);
|
||||
private = kgsl_process_private_new(device);
|
||||
|
||||
if (IS_ERR(private))
|
||||
goto done;
|
||||
|
||||
private->fd_count++;
|
||||
|
||||
done:
|
||||
mutex_unlock(&kgsl_driver.process_mutex);
|
||||
|
||||
return private;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2002,2007-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
#ifndef __KGSL_DEVICE_H
|
||||
#define __KGSL_DEVICE_H
|
||||
@ -489,6 +490,10 @@ struct kgsl_process_private {
|
||||
* process
|
||||
*/
|
||||
struct kobject kobj_memtype;
|
||||
/**
|
||||
* @private_mutex: Mutex lock to protect kgsl_process_private
|
||||
*/
|
||||
struct mutex private_mutex;
|
||||
};
|
||||
|
||||
struct kgsl_device_private {
|
||||
|
Loading…
Reference in New Issue
Block a user