msm: kgsl: Allow I/O coherency on imported buffers if we can

Allow I/O coherency to be enabled on imported buffers if I/O coherency
is enabled and we can determine the cache characteristics of the
imported buffer. The caller should check the flags after allocation
to determine if I/O coherency was enabled.

Change-Id: Ic0dedbade77189bd51dddad64d15f0835601e925
Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
This commit is contained in:
Jordan Crouse 2020-08-19 17:19:55 -06:00
commit bfd51517d4

View file

@ -2419,9 +2419,12 @@ static int kgsl_setup_dmabuf_useraddr(struct kgsl_device *device,
entry->memdesc.useraddr = hostptr;
_setup_cache_mode(entry, vma);
if (IS_ENABLED(CONFIG_QCOM_KGSL_IOCOHERENCY_DEFAULT) &&
kgsl_cachemode_is_cached(entry->memdesc.flags))
if (kgsl_mmu_has_feature(device, KGSL_MMU_IO_COHERENT) &&
(IS_ENABLED(CONFIG_QCOM_KGSL_IOCOHERENCY_DEFAULT) &&
kgsl_cachemode_is_cached(entry->memdesc.flags)))
entry->memdesc.flags |= KGSL_MEMFLAGS_IOCOHERENT;
else
entry->memdesc.flags &= ~((u64) KGSL_MEMFLAGS_IOCOHERENT);
up_read(&current->mm->mmap_sem);
return 0;
@ -2465,6 +2468,7 @@ static long _gpuobj_map_useraddr(struct kgsl_device *device,
param->flags &= KGSL_MEMFLAGS_GPUREADONLY
| KGSL_CACHEMODE_MASK
| KGSL_MEMFLAGS_USE_CPU_MAP
| KGSL_MEMTYPE_MASK
| KGSL_MEMFLAGS_FORCE_32BIT
| KGSL_MEMFLAGS_IOCOHERENT;
@ -2473,6 +2477,8 @@ static long _gpuobj_map_useraddr(struct kgsl_device *device,
if (param->flags & KGSL_MEMFLAGS_SECURE)
return -ENOTSUPP;
kgsl_memdesc_init(device, &entry->memdesc, param->flags);
ret = kgsl_copy_from_user(&useraddr,
u64_to_user_ptr(param->priv), sizeof(useraddr),
param->priv_len);
@ -2494,11 +2500,21 @@ static long _gpuobj_map_dma_buf(struct kgsl_device *device,
struct kgsl_gpuobj_import *param,
int *fd)
{
bool iocoherent = (param->flags & KGSL_MEMFLAGS_IOCOHERENT);
struct kgsl_gpuobj_import_dma_buf buf;
struct dma_buf *dmabuf;
unsigned long flags = 0;
int ret;
param->flags &= KGSL_MEMFLAGS_GPUREADONLY |
KGSL_MEMTYPE_MASK |
KGSL_MEMALIGN_MASK |
KGSL_MEMFLAGS_SECURE |
KGSL_MEMFLAGS_FORCE_32BIT |
KGSL_MEMFLAGS_GUARD_PAGE;
kgsl_memdesc_init(device, &entry->memdesc, param->flags);
/*
* If content protection is not enabled and secure buffer
* is requested to be mapped return error.
@ -2533,10 +2549,20 @@ static long _gpuobj_map_dma_buf(struct kgsl_device *device,
* fails.
*/
dma_buf_get_flags(dmabuf, &flags);
if (flags & ION_FLAG_CACHED)
if (flags & ION_FLAG_CACHED) {
entry->memdesc.flags |=
KGSL_CACHEMODE_WRITEBACK << KGSL_CACHEMODE_SHIFT;
/*
* Enable I/O coherency if it is 1) a thing, and either
* 2) enabled by default or 3) enabled by the caller
*/
if (kgsl_mmu_has_feature(device, KGSL_MMU_IO_COHERENT) &&
(IS_ENABLED(CONFIG_QCOM_KGSL_IOCOHERENCY_DEFAULT) ||
iocoherent))
entry->memdesc.flags |= KGSL_MEMFLAGS_IOCOHERENT;
}
ret = kgsl_setup_dma_buf(device, pagetable, entry, dmabuf);
if (ret)
dma_buf_put(dmabuf);
@ -2572,28 +2598,20 @@ long kgsl_ioctl_gpuobj_import(struct kgsl_device_private *dev_priv,
struct kgsl_mem_entry *entry;
int ret, fd = -1;
if (param->type != KGSL_USER_MEM_TYPE_ADDR &&
param->type != KGSL_USER_MEM_TYPE_DMABUF)
return -ENOTSUPP;
entry = kgsl_mem_entry_create();
if (entry == NULL)
return -ENOMEM;
param->flags &= KGSL_MEMFLAGS_GPUREADONLY
| KGSL_MEMTYPE_MASK
| KGSL_MEMALIGN_MASK
| KGSL_MEMFLAGS_USE_CPU_MAP
| KGSL_MEMFLAGS_SECURE
| KGSL_MEMFLAGS_FORCE_32BIT
| KGSL_MEMFLAGS_IOCOHERENT
| KGSL_MEMFLAGS_GUARD_PAGE;
kgsl_memdesc_init(dev_priv->device, &entry->memdesc, param->flags);
if (param->type == KGSL_USER_MEM_TYPE_ADDR)
ret = _gpuobj_map_useraddr(dev_priv->device, private->pagetable,
entry, param);
else if (param->type == KGSL_USER_MEM_TYPE_DMABUF)
else
ret = _gpuobj_map_dma_buf(dev_priv->device, private->pagetable,
entry, param, &fd);
else
ret = -ENOTSUPP;
if (ret)
goto out;