mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-10 06:09:23 -04:00
Merge "msm: kgsl: Keep private intact until last refcount is put"
This commit is contained in:
commit
3b7468e324
2 changed files with 34 additions and 44 deletions
|
|
@ -869,11 +869,25 @@ static void kgsl_destroy_process_private(struct kref *kref)
|
|||
struct kgsl_process_private *private = container_of(kref,
|
||||
struct kgsl_process_private, refcount);
|
||||
|
||||
mutex_lock(&kgsl_driver.process_mutex);
|
||||
debugfs_remove_recursive(private->debug_root);
|
||||
kgsl_process_uninit_sysfs(private);
|
||||
|
||||
/* When using global pagetables, do not detach global pagetable */
|
||||
if (private->pagetable->name != KGSL_MMU_GLOBAL_PT)
|
||||
kgsl_mmu_detach_pagetable(private->pagetable);
|
||||
|
||||
/* Remove the process struct from the master list */
|
||||
write_lock(&kgsl_driver.proclist_lock);
|
||||
list_del(&private->list);
|
||||
write_unlock(&kgsl_driver.proclist_lock);
|
||||
mutex_unlock(&kgsl_driver.process_mutex);
|
||||
|
||||
put_pid(private->pid);
|
||||
idr_destroy(&private->mem_idr);
|
||||
idr_destroy(&private->syncsource_idr);
|
||||
|
||||
/* When using global pagetables, do not detach global pagetable */
|
||||
/* When using global pagetables, do not put global pagetable */
|
||||
if (private->pagetable->name != KGSL_MMU_GLOBAL_PT)
|
||||
kgsl_mmu_putpagetable(private->pagetable);
|
||||
|
||||
|
|
@ -962,8 +976,15 @@ static struct kgsl_process_private *kgsl_process_private_new(
|
|||
|
||||
kfree(private);
|
||||
private = ERR_PTR(err);
|
||||
return private;
|
||||
}
|
||||
|
||||
kgsl_process_init_sysfs(device, private);
|
||||
kgsl_process_init_debugfs(private);
|
||||
write_lock(&kgsl_driver.proclist_lock);
|
||||
list_add(&private->list, &kgsl_driver.process_list);
|
||||
write_unlock(&kgsl_driver.proclist_lock);
|
||||
|
||||
return private;
|
||||
}
|
||||
|
||||
|
|
@ -1008,8 +1029,8 @@ static void kgsl_process_private_close(struct kgsl_device_private *dev_priv,
|
|||
}
|
||||
|
||||
/*
|
||||
* If this is the last file on the process take down the debug
|
||||
* directories and garbage collect any outstanding resources
|
||||
* If this is the last file on the process garbage collect
|
||||
* any outstanding resources
|
||||
*/
|
||||
|
||||
process_release_memory(private);
|
||||
|
|
@ -1017,18 +1038,6 @@ 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);
|
||||
|
||||
debugfs_remove_recursive(private->debug_root);
|
||||
kgsl_process_uninit_sysfs(private);
|
||||
|
||||
/* When using global pagetables, do not detach global pagetable */
|
||||
if (private->pagetable->name != KGSL_MMU_GLOBAL_PT)
|
||||
kgsl_mmu_detach_pagetable(private->pagetable);
|
||||
|
||||
/* Remove the process struct from the master list */
|
||||
write_lock(&kgsl_driver.proclist_lock);
|
||||
list_del(&private->list);
|
||||
write_unlock(&kgsl_driver.proclist_lock);
|
||||
|
||||
mutex_unlock(&kgsl_driver.process_mutex);
|
||||
|
||||
kgsl_process_private_put(private);
|
||||
|
|
@ -1046,19 +1055,7 @@ static struct kgsl_process_private *kgsl_process_private_open(
|
|||
if (IS_ERR(private))
|
||||
goto done;
|
||||
|
||||
/*
|
||||
* If this is a new process create the debug directories and add it to
|
||||
* the process list
|
||||
*/
|
||||
|
||||
if (private->fd_count++ == 0) {
|
||||
kgsl_process_init_sysfs(device, private);
|
||||
kgsl_process_init_debugfs(private);
|
||||
|
||||
write_lock(&kgsl_driver.proclist_lock);
|
||||
list_add(&private->list, &kgsl_driver.process_list);
|
||||
write_unlock(&kgsl_driver.proclist_lock);
|
||||
}
|
||||
private->fd_count++;
|
||||
|
||||
done:
|
||||
mutex_unlock(&kgsl_driver.process_mutex);
|
||||
|
|
|
|||
|
|
@ -202,10 +202,10 @@ static ssize_t mem_entry_sysfs_show(struct kobject *kobj,
|
|||
ssize_t ret;
|
||||
|
||||
/*
|
||||
* kgsl_process_init_sysfs takes a refcount to the process_private,
|
||||
* which is put when the kobj is released. This implies that priv will
|
||||
* not be freed until this function completes, and no further locking
|
||||
* is needed.
|
||||
* sysfs_remove_file waits for reads to complete before the node is
|
||||
* deleted and process private is freed only once kobj is released.
|
||||
* This implies that priv will not be freed until this function
|
||||
* completes, and no further locking is needed.
|
||||
*/
|
||||
priv = kobj ? container_of(kobj, struct kgsl_process_private, kobj) :
|
||||
NULL;
|
||||
|
|
@ -228,10 +228,10 @@ static ssize_t memtype_sysfs_show(struct kobject *kobj,
|
|||
int id = 0;
|
||||
|
||||
/*
|
||||
* kgsl_process_init_sysfs takes a refcount to the process_private,
|
||||
* which is put when the kobj is released. This implies that priv will
|
||||
* not be freed until this function completes, and no further locking
|
||||
* is needed.
|
||||
* sysfs_remove_file waits for reads to complete before the node is
|
||||
* deleted and process private is freed only once kobj is released.
|
||||
* This implies that priv will not be freed until this function
|
||||
* completes, and no further locking is needed.
|
||||
*/
|
||||
priv = container_of(kobj, struct kgsl_process_private, kobj_memtype);
|
||||
memtype = container_of(attr, struct kgsl_memtype, attr);
|
||||
|
|
@ -261,13 +261,9 @@ static ssize_t memtype_sysfs_show(struct kobject *kobj,
|
|||
return scnprintf(buf, PAGE_SIZE, "%llu\n", size);
|
||||
}
|
||||
|
||||
/* Dummy release function - we have nothing to do here */
|
||||
static void mem_entry_release(struct kobject *kobj)
|
||||
{
|
||||
struct kgsl_process_private *priv;
|
||||
|
||||
priv = container_of(kobj, struct kgsl_process_private, kobj);
|
||||
/* Put the refcount we got in kgsl_process_init_sysfs */
|
||||
kgsl_process_private_put(priv);
|
||||
}
|
||||
|
||||
static const struct sysfs_ops mem_entry_sysfs_ops = {
|
||||
|
|
@ -329,9 +325,6 @@ void kgsl_process_init_sysfs(struct kgsl_device *device,
|
|||
{
|
||||
int i;
|
||||
|
||||
/* Keep private valid until the sysfs enries are removed. */
|
||||
kgsl_process_private_get(private);
|
||||
|
||||
if (kobject_init_and_add(&private->kobj, &ktype_mem_entry,
|
||||
kgsl_driver.prockobj, "%d", pid_nr(private->pid))) {
|
||||
dev_err(device->dev, "Unable to add sysfs for process %d\n",
|
||||
|
|
|
|||
Loading…
Reference in a new issue