diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index 3a466a20d8a6..03302654e960 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -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; } diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h index 6140fc2b8055..c639b5112977 100644 --- a/drivers/gpu/msm/kgsl_device.h +++ b/drivers/gpu/msm/kgsl_device.h @@ -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; diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c index c4d3ee7e6967..0ddc99248f54 100644 --- a/drivers/gpu/msm/kgsl_sharedmem.c +++ b/drivers/gpu/msm/kgsl_sharedmem.c @@ -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)); } /**