msm: kgsl: make per process stats atomic

There is a chance of messing up per process stats if something
like a free and allocation happen at the same time for memory
belonging to the same process. So make per process stats atomic.
Decrement process stats when mem entry is destroyed. Also make
sure that mapsize is updated for all the memdescs.

Change-Id: I5da1cf368d523768d0b267b314394612934a620d
Signed-off-by: Puranam V G Tejaswi <pvgtejas@codeaurora.org>
This commit is contained in:
Puranam V G Tejaswi 2020-10-08 17:20:18 +05:30
commit d08f8cd31c
3 changed files with 23 additions and 20 deletions

View file

@ -343,6 +343,8 @@ kgsl_mem_entry_destroy(struct kref *kref)
/* pull out the memtype before the flags get cleared */
memtype = kgsl_memdesc_usermem_type(&entry->memdesc);
atomic64_sub(entry->memdesc.size, &entry->priv->stats[memtype].cur);
/* Detach from process list */
kgsl_mem_entry_detach_process(entry);
@ -491,8 +493,6 @@ static void kgsl_mem_entry_detach_process(struct kgsl_mem_entry *entry)
idr_remove(&entry->priv->mem_idr, entry->id);
entry->id = 0;
entry->priv->gpumem_mapped -= entry->memdesc.mapsize;
spin_unlock(&entry->priv->mem_lock);
kgsl_mmu_put_gpuaddr(&entry->memdesc);
@ -2676,9 +2676,10 @@ static long _gpuobj_map_dma_buf(struct kgsl_device *device,
static void kgsl_process_add_stats(struct kgsl_process_private *priv,
unsigned int type, uint64_t size)
{
priv->stats[type].cur += size;
if (priv->stats[type].max < priv->stats[type].cur)
priv->stats[type].max = priv->stats[type].cur;
u64 ret = atomic64_add_return(size, &priv->stats[type].cur);
if (ret > priv->stats[type].max)
priv->stats[type].max = ret;
}
@ -3710,18 +3711,13 @@ static vm_fault_t
kgsl_gpumem_vm_fault(struct vm_fault *vmf)
{
struct kgsl_mem_entry *entry = vmf->vma->vm_private_data;
vm_fault_t ret;
if (!entry)
return VM_FAULT_SIGBUS;
if (!entry->memdesc.ops || !entry->memdesc.ops->vmfault)
return VM_FAULT_SIGBUS;
ret = entry->memdesc.ops->vmfault(&entry->memdesc, vmf->vma, vmf);
if (!ret || ret == VM_FAULT_NOPAGE)
entry->priv->gpumem_mapped += PAGE_SIZE;
return ret;
return entry->memdesc.ops->vmfault(&entry->memdesc, vmf->vma, vmf);
}
static void
@ -3733,6 +3729,8 @@ kgsl_gpumem_vm_close(struct vm_area_struct *vma)
return;
entry->memdesc.useraddr = 0;
atomic64_sub(entry->memdesc.mapsize, &entry->priv->gpumem_mapped);
entry->memdesc.mapsize = 0;
kgsl_mem_entry_put(entry);
}
@ -4017,14 +4015,15 @@ static int kgsl_mmap(struct file *file, struct vm_area_struct *vma)
vm_insert_page(vma, addr, page);
addr += PAGE_SIZE;
}
m->mapsize = m->size;
entry->priv->gpumem_mapped += m->mapsize;
}
vma->vm_file = file;
entry->memdesc.useraddr = vma->vm_start;
entry->memdesc.mapsize += entry->memdesc.size;
atomic64_add(entry->memdesc.mapsize, &entry->priv->gpumem_mapped);
trace_kgsl_mem_mmap(entry);
return 0;
}

View file

@ -437,10 +437,10 @@ struct kgsl_process_private {
struct kobject kobj;
struct dentry *debug_root;
struct {
uint64_t cur;
atomic64_t cur;
uint64_t max;
} stats[KGSL_MEM_ENTRY_MAX];
uint64_t gpumem_mapped;
atomic64_t gpumem_mapped;
struct idr syncsource_idr;
spinlock_t syncsource_lock;
int fd_count;

View file

@ -113,18 +113,21 @@ static ssize_t
gpumem_mapped_show(struct kgsl_process_private *priv,
int type, char *buf)
{
return scnprintf(buf, PAGE_SIZE, "%llu\n",
priv->gpumem_mapped);
return scnprintf(buf, PAGE_SIZE, "%lld\n",
atomic64_read(&priv->gpumem_mapped));
}
static ssize_t
gpumem_unmapped_show(struct kgsl_process_private *priv, int type, char *buf)
{
if (priv->gpumem_mapped > priv->stats[type].cur)
u64 gpumem_total = atomic64_read(&priv->stats[type].cur);
u64 gpumem_mapped = atomic64_read(&priv->gpumem_mapped);
if (gpumem_mapped > gpumem_total)
return -EIO;
return scnprintf(buf, PAGE_SIZE, "%llu\n",
priv->stats[type].cur - priv->gpumem_mapped);
gpumem_total - gpumem_mapped);
}
static struct kgsl_mem_entry_attribute debug_memstats[] = {
@ -141,7 +144,8 @@ static struct kgsl_mem_entry_attribute debug_memstats[] = {
static ssize_t
mem_entry_show(struct kgsl_process_private *priv, int type, char *buf)
{
return scnprintf(buf, PAGE_SIZE, "%llu\n", priv->stats[type].cur);
return scnprintf(buf, PAGE_SIZE, "%lld\n",
atomic64_read(&priv->stats[type].cur));
}
/**