mirror of
https://github.com/Divested-Mobile/DivestOS-Build.git
synced 2024-10-01 01:35:54 -04:00
255 lines
8.2 KiB
Diff
255 lines
8.2 KiB
Diff
|
From 7c4d5736d32f91f0cafe6cd86d00e26389970b00 Mon Sep 17 00:00:00 2001
|
||
|
From: Jordan Crouse <jcrouse@codeaurora.org>
|
||
|
Date: Tue, 31 May 2016 11:24:24 -0600
|
||
|
Subject: msm: kgsl: Make sure USE_CPU_MAP + MAP_USER_MEM work together
|
||
|
|
||
|
If one is mapping anonyomous user memory in the GPU with SVM enabled
|
||
|
we want to try to accommodate that request if possible. The memory
|
||
|
address was being set up correctly in the memory descriptor but
|
||
|
the GPU address was getting tripped up when getting mapped in the
|
||
|
process. This is because the memory should be treated like SVM
|
||
|
memory so it needs to be registered in the memory tree and the
|
||
|
rest of the path needs to accept the address.
|
||
|
|
||
|
Change-Id: Ic0dedbad661143977a226d50263c26b5af579ce3
|
||
|
Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
|
||
|
Signed-off-by: Sudeep Yedalapure <sudeepy@codeaurora.org>
|
||
|
---
|
||
|
drivers/gpu/msm/kgsl.c | 134 +++++++++++++++++++++----------------------------
|
||
|
1 file changed, 57 insertions(+), 77 deletions(-)
|
||
|
|
||
|
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
|
||
|
index bd022f1..db3ba02 100644
|
||
|
--- a/drivers/gpu/msm/kgsl.c
|
||
|
+++ b/drivers/gpu/msm/kgsl.c
|
||
|
@@ -166,9 +166,10 @@ int kgsl_memfree_find_entry(pid_t ptname, uint64_t *gpuaddr,
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
-static void kgsl_memfree_purge(pid_t ptname, uint64_t gpuaddr,
|
||
|
- uint64_t size)
|
||
|
+static void kgsl_memfree_purge(struct kgsl_pagetable *pagetable,
|
||
|
+ uint64_t gpuaddr, uint64_t size)
|
||
|
{
|
||
|
+ pid_t ptname = pagetable ? pagetable->name : 0;
|
||
|
int i;
|
||
|
|
||
|
if (memfree.list == NULL)
|
||
|
@@ -332,40 +333,22 @@ kgsl_mem_entry_destroy(struct kref *kref)
|
||
|
}
|
||
|
EXPORT_SYMBOL(kgsl_mem_entry_destroy);
|
||
|
|
||
|
-/**
|
||
|
- * kgsl_mem_entry_track_gpuaddr - Insert a mem_entry in the address tree and
|
||
|
- * assign it with a gpu address space before insertion
|
||
|
- * @process: the process that owns the memory
|
||
|
- * @entry: the memory entry
|
||
|
- *
|
||
|
- * @returns - 0 on succcess else error code
|
||
|
- *
|
||
|
- * Insert the kgsl_mem_entry in to the rb_tree for searching by GPU address.
|
||
|
- * The assignment of gpu address and insertion into list needs to
|
||
|
- * happen with the memory lock held to avoid race conditions between
|
||
|
- * gpu address being selected and some other thread looking through the
|
||
|
- * rb list in search of memory based on gpuaddr
|
||
|
- * This function should be called with processes memory spinlock held
|
||
|
- */
|
||
|
-static int
|
||
|
-kgsl_mem_entry_track_gpuaddr(struct kgsl_process_private *process,
|
||
|
- struct kgsl_mem_entry *entry)
|
||
|
+/* Allocate a IOVA for memory objects that don't use SVM */
|
||
|
+static int kgsl_mem_entry_track_gpuaddr(struct kgsl_device *device,
|
||
|
+ struct kgsl_process_private *process,
|
||
|
+ struct kgsl_mem_entry *entry)
|
||
|
{
|
||
|
- struct kgsl_pagetable *pagetable = process->pagetable;
|
||
|
+ struct kgsl_pagetable *pagetable;
|
||
|
|
||
|
/*
|
||
|
- * If cpu=gpu map is used then caller needs to set the
|
||
|
- * gpu address
|
||
|
+ * If SVM is enabled for this object then the address needs to be
|
||
|
+ * assigned elsewhere
|
||
|
*/
|
||
|
- if (kgsl_memdesc_use_cpu_map(&entry->memdesc)) {
|
||
|
- if (!entry->memdesc.gpuaddr)
|
||
|
- return 0;
|
||
|
- } else if (entry->memdesc.gpuaddr) {
|
||
|
- WARN_ONCE(1, "gpuaddr assigned w/o holding memory lock\n");
|
||
|
- return -EINVAL;
|
||
|
- }
|
||
|
- if (kgsl_memdesc_is_secured(&entry->memdesc))
|
||
|
- pagetable = pagetable->mmu->securepagetable;
|
||
|
+ if (kgsl_memdesc_use_cpu_map(&entry->memdesc))
|
||
|
+ return 0;
|
||
|
+
|
||
|
+ pagetable = kgsl_memdesc_is_secured(&entry->memdesc) ?
|
||
|
+ device->mmu.securepagetable : process->pagetable;
|
||
|
|
||
|
return kgsl_mmu_get_gpuaddr(pagetable, &entry->memdesc);
|
||
|
}
|
||
|
@@ -381,33 +364,25 @@ static void kgsl_mem_entry_commit_process(struct kgsl_mem_entry *entry)
|
||
|
spin_unlock(&entry->priv->mem_lock);
|
||
|
}
|
||
|
|
||
|
-/**
|
||
|
- * kgsl_mem_entry_attach_process - Attach a mem_entry to its owner process
|
||
|
- * @entry: the memory entry
|
||
|
- * @process: the owner process
|
||
|
- *
|
||
|
- * Attach a newly created mem_entry to its owner process so that
|
||
|
- * it can be found later. The mem_entry will be added to mem_idr and have
|
||
|
- * its 'id' field assigned.
|
||
|
- *
|
||
|
- * @returns - 0 on success or error code on failure.
|
||
|
+/*
|
||
|
+ * Attach the memory object to a process by (possibly) getting a GPU address and
|
||
|
+ * (possibly) mapping it
|
||
|
*/
|
||
|
-int
|
||
|
-kgsl_mem_entry_attach_process(struct kgsl_mem_entry *entry,
|
||
|
- struct kgsl_device_private *dev_priv)
|
||
|
+static int kgsl_mem_entry_attach_process(struct kgsl_device *device,
|
||
|
+ struct kgsl_process_private *process,
|
||
|
+ struct kgsl_mem_entry *entry)
|
||
|
{
|
||
|
- int id;
|
||
|
- int ret;
|
||
|
- struct kgsl_process_private *process = dev_priv->process_priv;
|
||
|
- struct kgsl_pagetable *pagetable = NULL;
|
||
|
+ int id, ret;
|
||
|
|
||
|
ret = kgsl_process_private_get(process);
|
||
|
if (!ret)
|
||
|
return -EBADF;
|
||
|
|
||
|
- ret = kgsl_mem_entry_track_gpuaddr(process, entry);
|
||
|
- if (ret)
|
||
|
- goto err_put_proc_priv;
|
||
|
+ ret = kgsl_mem_entry_track_gpuaddr(device, process, entry);
|
||
|
+ if (ret) {
|
||
|
+ kgsl_process_private_put(process);
|
||
|
+ return ret;
|
||
|
+ }
|
||
|
|
||
|
idr_preload(GFP_KERNEL);
|
||
|
spin_lock(&process->mem_lock);
|
||
|
@@ -417,40 +392,33 @@ kgsl_mem_entry_attach_process(struct kgsl_mem_entry *entry,
|
||
|
idr_preload_end();
|
||
|
|
||
|
if (id < 0) {
|
||
|
- ret = id;
|
||
|
- kgsl_mmu_put_gpuaddr(&entry->memdesc);
|
||
|
- goto err_put_proc_priv;
|
||
|
+ if (!kgsl_memdesc_use_cpu_map(&entry->memdesc))
|
||
|
+ kgsl_mmu_put_gpuaddr(&entry->memdesc);
|
||
|
+ kgsl_process_private_put(process);
|
||
|
+ return id;
|
||
|
}
|
||
|
|
||
|
entry->id = id;
|
||
|
entry->priv = process;
|
||
|
|
||
|
- /* map the memory after unlocking if gpuaddr has been assigned */
|
||
|
+ /*
|
||
|
+ * Map the memory if a GPU address is already assigned, either through
|
||
|
+ * kgsl_mem_entry_track_gpuaddr() or via some other SVM process
|
||
|
+ */
|
||
|
if (entry->memdesc.gpuaddr) {
|
||
|
- /* if a secured buffer map it to secure global pagetable */
|
||
|
- if (kgsl_memdesc_is_secured(&entry->memdesc))
|
||
|
- pagetable = process->pagetable->mmu->securepagetable;
|
||
|
- else
|
||
|
- pagetable = process->pagetable;
|
||
|
+ ret = kgsl_mmu_map(entry->memdesc.pagetable, &entry->memdesc);
|
||
|
|
||
|
- entry->memdesc.pagetable = pagetable;
|
||
|
- ret = kgsl_mmu_map(pagetable, &entry->memdesc);
|
||
|
if (ret)
|
||
|
kgsl_mem_entry_detach_process(entry);
|
||
|
}
|
||
|
|
||
|
- kgsl_memfree_purge(pagetable ? pagetable->name : 0,
|
||
|
- entry->memdesc.gpuaddr, entry->memdesc.size);
|
||
|
-
|
||
|
- return ret;
|
||
|
+ kgsl_memfree_purge(entry->memdesc.pagetable, entry->memdesc.gpuaddr,
|
||
|
+ entry->memdesc.size);
|
||
|
|
||
|
-err_put_proc_priv:
|
||
|
- kgsl_process_private_put(process);
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
/* Detach a memory entry from a process and unmap it from the MMU */
|
||
|
-
|
||
|
static void kgsl_mem_entry_detach_process(struct kgsl_mem_entry *entry)
|
||
|
{
|
||
|
unsigned int type;
|
||
|
@@ -2052,10 +2020,21 @@ static int kgsl_setup_anon_useraddr(struct kgsl_pagetable *pagetable,
|
||
|
entry->memdesc.pagetable = pagetable;
|
||
|
entry->memdesc.size = (uint64_t) size;
|
||
|
entry->memdesc.useraddr = hostptr;
|
||
|
- if (kgsl_memdesc_use_cpu_map(&entry->memdesc))
|
||
|
- entry->memdesc.gpuaddr = (uint64_t) entry->memdesc.useraddr;
|
||
|
entry->memdesc.flags |= KGSL_MEMFLAGS_USERMEM_ADDR;
|
||
|
|
||
|
+ if (kgsl_memdesc_use_cpu_map(&entry->memdesc)) {
|
||
|
+ int ret;
|
||
|
+
|
||
|
+ /* Register the address in the database */
|
||
|
+ ret = kgsl_mmu_set_svm_region(pagetable,
|
||
|
+ (uint64_t) entry->memdesc.useraddr, (uint64_t) size);
|
||
|
+
|
||
|
+ if (ret)
|
||
|
+ return ret;
|
||
|
+
|
||
|
+ entry->memdesc.gpuaddr = (uint64_t) entry->memdesc.useraddr;
|
||
|
+ }
|
||
|
+
|
||
|
return memdesc_sg_virt(&entry->memdesc, NULL);
|
||
|
}
|
||
|
|
||
|
@@ -2305,7 +2284,7 @@ long kgsl_ioctl_gpuobj_import(struct kgsl_device_private *dev_priv,
|
||
|
|
||
|
param->flags = entry->memdesc.flags;
|
||
|
|
||
|
- ret = kgsl_mem_entry_attach_process(entry, dev_priv);
|
||
|
+ ret = kgsl_mem_entry_attach_process(dev_priv->device, private, entry);
|
||
|
if (ret)
|
||
|
goto unmap;
|
||
|
|
||
|
@@ -2609,7 +2588,8 @@ long kgsl_ioctl_map_user_mem(struct kgsl_device_private *dev_priv,
|
||
|
/* echo back flags */
|
||
|
param->flags = (unsigned int) entry->memdesc.flags;
|
||
|
|
||
|
- result = kgsl_mem_entry_attach_process(entry, dev_priv);
|
||
|
+ result = kgsl_mem_entry_attach_process(dev_priv->device, private,
|
||
|
+ entry);
|
||
|
if (result)
|
||
|
goto error_attach;
|
||
|
|
||
|
@@ -3006,7 +2986,7 @@ static struct kgsl_mem_entry *gpumem_alloc_entry(
|
||
|
if (ret != 0)
|
||
|
goto err;
|
||
|
|
||
|
- ret = kgsl_mem_entry_attach_process(entry, dev_priv);
|
||
|
+ ret = kgsl_mem_entry_attach_process(dev_priv->device, private, entry);
|
||
|
if (ret != 0) {
|
||
|
kgsl_sharedmem_free(&entry->memdesc);
|
||
|
goto err;
|
||
|
@@ -3431,8 +3411,8 @@ static unsigned long _gpu_set_svm_region(struct kgsl_process_private *private,
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
- kgsl_memfree_purge(private->pagetable ? private->pagetable->name : 0,
|
||
|
- entry->memdesc.gpuaddr, entry->memdesc.size);
|
||
|
+ kgsl_memfree_purge(private->pagetable, entry->memdesc.gpuaddr,
|
||
|
+ entry->memdesc.size);
|
||
|
|
||
|
return addr;
|
||
|
}
|
||
|
--
|
||
|
cgit v1.1
|
||
|
|