mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
msm: kgsl: Fail if sysfs or debugfs initialization fails
While creating a new process struct for kgsl, clean up resources and bail if sysfs or debugfs initialization fails. This prevents errors further down the line. CRs-fixed: 509931 Change-Id: If0857628a56eecf4855013aaf313de28ac9ad108 Signed-off-by: Harsh Vardhan Dwivedi <hdwivedi@codeaurora.org> Signed-off-by: Carter Cooper <ccooper@codeaurora.org>
This commit is contained in:
parent
96fbf74221
commit
dfeec65dc1
5 changed files with 75 additions and 28 deletions
|
@ -755,7 +755,7 @@ static void kgsl_destroy_process_private(struct kref *kref)
|
|||
list_del(&private->list);
|
||||
mutex_unlock(&kgsl_driver.process_mutex);
|
||||
|
||||
if (private->kobj.parent)
|
||||
if (private->kobj.state_in_sysfs)
|
||||
kgsl_process_uninit_sysfs(private);
|
||||
if (private->debug_root)
|
||||
debugfs_remove_recursive(private->debug_root);
|
||||
|
@ -869,21 +869,23 @@ kgsl_get_process_private(struct kgsl_device_private *cur_dev_priv)
|
|||
|
||||
pt_name = task_tgid_nr(current);
|
||||
private->pagetable = kgsl_mmu_getpagetable(mmu, pt_name);
|
||||
if (private->pagetable == NULL) {
|
||||
mutex_unlock(&private->process_private_mutex);
|
||||
kgsl_put_process_private(cur_dev_priv->device,
|
||||
private);
|
||||
return NULL;
|
||||
}
|
||||
if (private->pagetable == NULL)
|
||||
goto error;
|
||||
}
|
||||
|
||||
kgsl_process_init_sysfs(private);
|
||||
kgsl_process_init_debugfs(private);
|
||||
if (kgsl_process_init_sysfs(cur_dev_priv->device, private))
|
||||
goto error;
|
||||
if (kgsl_process_init_debugfs(private))
|
||||
goto error;
|
||||
|
||||
done:
|
||||
mutex_unlock(&private->process_private_mutex);
|
||||
|
||||
return private;
|
||||
|
||||
error:
|
||||
mutex_unlock(&private->process_private_mutex);
|
||||
kgsl_put_process_private(cur_dev_priv->device, private);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int kgsl_close_device(struct kgsl_device *device)
|
||||
|
|
|
@ -322,25 +322,53 @@ static const struct file_operations process_mem_fops = {
|
|||
.release = single_release,
|
||||
};
|
||||
|
||||
void
|
||||
|
||||
/**
|
||||
* kgsl_process_init_debugfs() - Initialize debugfs for a process
|
||||
* @private: Pointer to process private structure created for the process
|
||||
*
|
||||
* @returns: 0 on success, error code otherwise
|
||||
*
|
||||
* kgsl_process_init_debugfs() is called at the time of creating the
|
||||
* process struct when a process opens kgsl device for the first time.
|
||||
* The function creates the debugfs files for the process. If debugfs is
|
||||
* disabled in the kernel, we ignore that error and return as successful.
|
||||
*/
|
||||
int
|
||||
kgsl_process_init_debugfs(struct kgsl_process_private *private)
|
||||
{
|
||||
unsigned char name[16];
|
||||
struct dentry *mem_dentry;
|
||||
int ret = 0;
|
||||
struct dentry *dentry;
|
||||
|
||||
snprintf(name, sizeof(name), "%d", private->pid);
|
||||
|
||||
private->debug_root = debugfs_create_dir(name, proc_d_debugfs);
|
||||
if (private->debug_root) {
|
||||
private->debug_root->d_inode->i_uid = proc_d_debugfs->d_inode->i_uid;
|
||||
private->debug_root->d_inode->i_gid = proc_d_debugfs->d_inode->i_gid;
|
||||
}
|
||||
mem_dentry = debugfs_create_file("mem", 0400, private->debug_root, private,
|
||||
|
||||
if (!private->debug_root)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* debugfs_create_dir() and debugfs_create_file() both
|
||||
* return -ENODEV if debugfs is disabled in the kernel.
|
||||
* We make a distinction between these two functions
|
||||
* failing and debugfs being disabled in the kernel.
|
||||
* In the first case, we abort process private struct
|
||||
* creation, in the second we continue without any changes.
|
||||
* So if debugfs is disabled in kernel, return as
|
||||
* success.
|
||||
*/
|
||||
dentry = debugfs_create_file("mem", 0400, private->debug_root, private,
|
||||
&process_mem_fops);
|
||||
if (mem_dentry) {
|
||||
mem_dentry->d_inode->i_uid = proc_d_debugfs->d_inode->i_uid;
|
||||
mem_dentry->d_inode->i_gid = proc_d_debugfs->d_inode->i_gid;
|
||||
|
||||
if (IS_ERR(dentry)) {
|
||||
ret = PTR_ERR(dentry);
|
||||
|
||||
if (ret == -ENODEV)
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void kgsl_core_debugfs_init(void)
|
||||
|
|
|
@ -21,7 +21,7 @@ struct kgsl_process_private;
|
|||
void kgsl_core_debugfs_init(void);
|
||||
void kgsl_core_debugfs_close(void);
|
||||
|
||||
void kgsl_device_debugfs_init(struct kgsl_device *device);
|
||||
int kgsl_device_debugfs_init(struct kgsl_device *device);
|
||||
|
||||
extern struct dentry *kgsl_debugfs_dir;
|
||||
static inline struct dentry *kgsl_get_debugfs_dir(void)
|
||||
|
|
|
@ -170,17 +170,32 @@ kgsl_process_uninit_sysfs(struct kgsl_process_private *private)
|
|||
kobject_put(&private->kobj);
|
||||
}
|
||||
|
||||
void
|
||||
kgsl_process_init_sysfs(struct kgsl_process_private *private)
|
||||
/**
|
||||
* kgsl_process_init_sysfs() - Initialize and create sysfs files for a process
|
||||
*
|
||||
* @device: Pointer to kgsl device struct
|
||||
* @private: Pointer to the structure for the process
|
||||
*
|
||||
* @returns: 0 on success, error code otherwise
|
||||
*
|
||||
* kgsl_process_init_sysfs() is called at the time of creating the
|
||||
* process struct when a process opens the kgsl device for the first time.
|
||||
* This function creates the sysfs files for the process.
|
||||
*/
|
||||
int
|
||||
kgsl_process_init_sysfs(struct kgsl_device *device,
|
||||
struct kgsl_process_private *private)
|
||||
{
|
||||
unsigned char name[16];
|
||||
int i, ret;
|
||||
int i, ret = 0;
|
||||
|
||||
snprintf(name, sizeof(name), "%d", private->pid);
|
||||
|
||||
if (kobject_init_and_add(&private->kobj, &ktype_mem_entry,
|
||||
kgsl_driver.prockobj, name))
|
||||
return;
|
||||
ret = kobject_init_and_add(&private->kobj, &ktype_mem_entry,
|
||||
kgsl_driver.prockobj, name);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(mem_stats); i++) {
|
||||
/* We need to check the value of sysfs_create_file, but we
|
||||
|
@ -191,6 +206,7 @@ kgsl_process_init_sysfs(struct kgsl_process_private *private)
|
|||
ret = sysfs_create_file(&private->kobj,
|
||||
&mem_stats[i].max_attr.attr);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int kgsl_drv_memstat_show(struct device *dev,
|
||||
|
|
|
@ -65,7 +65,8 @@ int kgsl_sharedmem_set(const struct kgsl_memdesc *memdesc,
|
|||
|
||||
void kgsl_cache_range_op(struct kgsl_memdesc *memdesc, int op);
|
||||
|
||||
void kgsl_process_init_sysfs(struct kgsl_process_private *private);
|
||||
int kgsl_process_init_sysfs(struct kgsl_device *device,
|
||||
struct kgsl_process_private *private);
|
||||
void kgsl_process_uninit_sysfs(struct kgsl_process_private *private);
|
||||
|
||||
int kgsl_sharedmem_init_sysfs(void);
|
||||
|
|
Loading…
Reference in a new issue