Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e4860cf8 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: kgsl: Keep private intact until last refcount is put"

parents a5923817 9607ab92
Loading
Loading
Loading
Loading
+34 −34
Original line number Diff line number Diff line
@@ -904,11 +904,27 @@ 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 */
	spin_lock(&kgsl_driver.proclist_lock);
	list_del(&private->list);
	spin_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);

@@ -951,13 +967,6 @@ static struct kgsl_process_private *kgsl_process_private_new(
	struct kgsl_process_private *private;
	struct pid *cur_pid = get_task_pid(current->group_leader, PIDTYPE_PID);

	/*
	 * Flush mem_workqueue to make sure that any lingering
	 * structs (process pagetable etc) are released before
	 * starting over again.
	 */
	flush_workqueue(kgsl_driver.mem_workqueue);

	/* Search in the process list */
	list_for_each_entry(private, &kgsl_driver.process_list, list) {
		if (private->pid == cur_pid) {
@@ -1006,9 +1015,17 @@ static struct kgsl_process_private *kgsl_process_private_new(
		put_pid(private->pid);

		kfree(private);
		private = ERR_PTR(err);
		return ERR_PTR(err);
	}

	/* create the debug directories and add it to the process list */
	kgsl_process_init_sysfs(device, private);
	kgsl_process_init_debugfs(private);

	spin_lock(&kgsl_driver.proclist_lock);
	list_add(&private->list, &kgsl_driver.process_list);
	spin_unlock(&kgsl_driver.proclist_lock);

	return private;
}

@@ -1062,18 +1079,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 */
	spin_lock(&kgsl_driver.proclist_lock);
	list_del(&private->list);
	spin_unlock(&kgsl_driver.proclist_lock);

	mutex_unlock(&kgsl_driver.process_mutex);

	kgsl_process_private_put(private);
@@ -1085,25 +1090,20 @@ static struct kgsl_process_private *kgsl_process_private_open(
{
	struct kgsl_process_private *private;

	/*
	 * Flush mem_workqueue to make sure that any lingering
	 * structs (process pagetable etc) are released before
	 * starting over again.
	 */
	flush_workqueue(kgsl_driver.mem_workqueue);

	mutex_lock(&kgsl_driver.process_mutex);
	private = kgsl_process_private_new(device);

	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);

		spin_lock(&kgsl_driver.proclist_lock);
		list_add(&private->list, &kgsl_driver.process_list);
		spin_unlock(&kgsl_driver.proclist_lock);
	}
	private->fd_count++;

done:
	mutex_unlock(&kgsl_driver.process_mutex);
+2 −9
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2002,2007-2020, The Linux Foundation. All rights reserved.
 * Copyright (c) 2002,2007-2021, The Linux Foundation. All rights reserved.
 */

#include <asm/cacheflush.h>
@@ -247,13 +247,9 @@ static ssize_t process_sysfs_store(struct kobject *kobj,
	return -EIO;
}

/* Dummy release function - we have nothing to do here */
static void process_sysfs_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 process_sysfs_ops = {
@@ -301,9 +297,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, &process_ktype,
		kgsl_driver.prockobj, "%d", pid_nr(private->pid))) {
		dev_err(device->dev, "Unable to add sysfs for process %d\n",