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

Commit 699281e7 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: kgsl: Get reference to process private when attaching mem entry"

parents 0d443dc2 af1ba47f
Loading
Loading
Loading
Loading
+39 −27
Original line number Diff line number Diff line
@@ -343,22 +343,29 @@ kgsl_mem_entry_untrack_gpuaddr(struct kgsl_process_private *process,
 */
static int
kgsl_mem_entry_attach_process(struct kgsl_mem_entry *entry,
				   struct kgsl_process_private *process)
				   struct kgsl_device_private *dev_priv)
{
	int id;
	int ret;
	struct kgsl_process_private *process = dev_priv->process_priv;

	ret = kref_get_unless_zero(&process->refcount);
	if (!ret)
		return -EBADF;
	idr_preload(GFP_KERNEL);
	spin_lock(&process->mem_lock);
	id = idr_alloc(&process->mem_idr, entry, 1, 0, GFP_NOWAIT);
	spin_unlock(&process->mem_lock);
	idr_preload_end();

	if (id < 0)
		return id;
	if (id < 0) {
		ret = id;
		goto err_put_proc_priv;
	}

	entry->id = id;
	entry->priv = process;
	entry->dev_priv = dev_priv;

	spin_lock(&process->mem_lock);
	ret = kgsl_mem_entry_track_gpuaddr(process, entry);
@@ -366,14 +373,17 @@ kgsl_mem_entry_attach_process(struct kgsl_mem_entry *entry,
		idr_remove(&process->mem_idr, entry->id);
	spin_unlock(&process->mem_lock);
	if (ret)
		goto err;
		goto err_put_proc_priv;
	/* map the memory after unlocking if gpuaddr has been assigned */
	if (entry->memdesc.gpuaddr) {
		ret = kgsl_mmu_map(process->pagetable, &entry->memdesc);
		if (ret)
			kgsl_mem_entry_detach_process(entry);
	}
err:
	return ret;

err_put_proc_priv:
	kgsl_put_process_private(dev_priv->device, process);
	return ret;
}

@@ -396,6 +406,7 @@ static void kgsl_mem_entry_detach_process(struct kgsl_mem_entry *entry)

	entry->priv->stats[entry->memtype].cur -= entry->memdesc.size;
	spin_unlock(&entry->priv->mem_lock);
	kgsl_put_process_private(entry->dev_priv->device, entry->priv);

	entry->priv = NULL;
}
@@ -748,11 +759,6 @@ EXPORT_SYMBOL(kgsl_resume_driver);
 */
static void kgsl_destroy_process_private(struct kref *kref)
{

	struct kgsl_mem_entry *entry = NULL;
	int next = 0;


	struct kgsl_process_private *private = container_of(kref,
			struct kgsl_process_private, refcount);

@@ -776,20 +782,6 @@ static void kgsl_destroy_process_private(struct kref *kref)
	if (private->debug_root)
		debugfs_remove_recursive(private->debug_root);

	while (1) {
		spin_lock(&private->mem_lock);
		entry = idr_get_next(&private->mem_idr, &next);
		spin_unlock(&private->mem_lock);
		if (entry == NULL)
			break;
		kgsl_mem_entry_put(entry);
		/*
		 * Always start back at the beginning, to
		 * ensure all entries are removed,
		 * like list_for_each_entry_safe.
		 */
		next = 0;
	}
	idr_destroy(&private->mem_idr);
	kgsl_mmu_putpagetable(private->pagetable);

@@ -939,6 +931,7 @@ static int kgsl_release(struct inode *inodep, struct file *filep)
	struct kgsl_process_private *private = dev_priv->process_priv;
	struct kgsl_device *device = dev_priv->device;
	struct kgsl_context *context;
	struct kgsl_mem_entry *entry;
	int next = 0;

	filep->private_data = NULL;
@@ -968,6 +961,25 @@ static int kgsl_release(struct inode *inodep, struct file *filep)

		next = next + 1;
	}
	next = 0;
	while (1) {
		spin_lock(&private->mem_lock);
		entry = idr_get_next(&private->mem_idr, &next);
		spin_unlock(&private->mem_lock);
		if (entry == NULL)
			break;
		/*
		 * If the free pending flag is not set it means that user space
		 * did not free it's reference to this entry, in that case
		 * free a reference to this entry, other references are from
		 * within kgsl so they will be freed eventually by kgsl
		 */
		if (entry->dev_priv == dev_priv && !entry->pending_free) {
			entry->pending_free = 1;
			kgsl_mem_entry_put(entry);
		}
		next = next + 1;
	}
	/*
	 * Clean up any to-be-freed entries that belong to this
	 * process and this device. This is done after the context
@@ -2736,7 +2748,7 @@ static long kgsl_ioctl_map_user_mem(struct kgsl_device_private *dev_priv,
	/* echo back flags */
	param->flags = entry->memdesc.flags;

	result = kgsl_mem_entry_attach_process(entry, private);
	result = kgsl_mem_entry_attach_process(entry, dev_priv);
	if (result)
		goto error_attach;

@@ -3024,7 +3036,7 @@ kgsl_ioctl_gpumem_alloc(struct kgsl_device_private *dev_priv,
	if (result)
		return result;

	result = kgsl_mem_entry_attach_process(entry, private);
	result = kgsl_mem_entry_attach_process(entry, dev_priv);
	if (result != 0)
		goto err;

@@ -3057,7 +3069,7 @@ kgsl_ioctl_gpumem_alloc_id(struct kgsl_device_private *dev_priv,
	if (result != 0)
		goto err;

	result = kgsl_mem_entry_attach_process(entry, private);
	result = kgsl_mem_entry_attach_process(entry, dev_priv);
	if (result != 0)
		goto err;

+1 −0
Original line number Diff line number Diff line
@@ -202,6 +202,7 @@ struct kgsl_mem_entry {
	struct kgsl_process_private *priv;
	/* Initialized to 0, set to 1 when entry is marked for freeing */
	int pending_free;
	struct kgsl_device_private *dev_priv;
};

#ifdef CONFIG_MSM_KGSL_MMU_PAGE_FAULT