diff --git a/drivers/gpu/msm/Kconfig b/drivers/gpu/msm/Kconfig index 7231c36fbd37..fbcdea99ca6a 100644 --- a/drivers/gpu/msm/Kconfig +++ b/drivers/gpu/msm/Kconfig @@ -4,6 +4,7 @@ config QCOM_KGSL depends on ARCH_QCOM depends on QCOM_QFPROM select MSM_SUBSYSTEM_RESTART + select TRACE_GPU_MEM help 3D graphics driver for the Adreno family of GPUs from QTI. Required to use hardware accelerated OpenGL, compute and Vulkan diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index cf48604f7848..f099cab9ca81 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -262,6 +262,7 @@ static void add_dmabuf_list(struct kgsl_dma_buf_meta *meta) { struct dmabuf_list_entry *dle; struct page *page; + struct kgsl_device *device = dev_get_drvdata(meta->attach->dev); /* * Get the first page. We will use it to identify the imported @@ -291,6 +292,8 @@ static void add_dmabuf_list(struct kgsl_dma_buf_meta *meta) list_add(&dle->node, &kgsl_dmabuf_list); meta->dle = dle; list_add(&meta->node, &dle->dmabuf_list); + kgsl_trace_gpu_mem_total(device, + meta->entry->memdesc.size); } spin_unlock(&kgsl_dmabuf_lock); } @@ -298,6 +301,7 @@ static void add_dmabuf_list(struct kgsl_dma_buf_meta *meta) static void remove_dmabuf_list(struct kgsl_dma_buf_meta *meta) { struct dmabuf_list_entry *dle = meta->dle; + struct kgsl_device *device = dev_get_drvdata(meta->attach->dev); if (!dle) return; @@ -307,6 +311,8 @@ static void remove_dmabuf_list(struct kgsl_dma_buf_meta *meta) if (list_empty(&dle->dmabuf_list)) { list_del(&dle->node); kfree(dle); + kgsl_trace_gpu_mem_total(device, + -(meta->entry->memdesc.size)); } spin_unlock(&kgsl_dmabuf_lock); } diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h index 8c797739b1fb..fba0ff9cdf9e 100644 --- a/drivers/gpu/msm/kgsl_device.h +++ b/drivers/gpu/msm/kgsl_device.h @@ -7,6 +7,7 @@ #include #include +#include #include "kgsl.h" #include "kgsl_drawobj.h" @@ -251,6 +252,8 @@ struct kgsl_device { uint32_t requested_state; atomic_t active_cnt; + /** @total_mapped: To trace overall gpu memory usage */ + atomic64_t total_mapped; wait_queue_head_t active_cnt_wq; struct platform_device *pdev; @@ -997,4 +1000,24 @@ struct kgsl_pwr_limit { struct kgsl_device *device; }; +/** + * kgsl_trace_gpu_mem_total - Overall gpu memory usage tracking which includes + * process allocations, imported dmabufs and kgsl globals + * @device: A KGSL device handle + * @delta: delta of total mapped memory size + */ +#ifdef CONFIG_TRACE_GPU_MEM +static inline void kgsl_trace_gpu_mem_total(struct kgsl_device *device, + s64 delta) +{ + u64 total_size; + + total_size = atomic64_add_return(delta, &device->total_mapped); + trace_gpu_mem_total(0, 0, total_size); +} +#else +static inline void kgsl_trace_gpu_mem_total(struct kgsl_device *device, + s64 delta) {} +#endif + #endif /* __KGSL_DEVICE_H */ diff --git a/drivers/gpu/msm/kgsl_mmu.c b/drivers/gpu/msm/kgsl_mmu.c index d7623eb6111b..090a028b3c6f 100644 --- a/drivers/gpu/msm/kgsl_mmu.c +++ b/drivers/gpu/msm/kgsl_mmu.c @@ -189,6 +189,23 @@ err: return ret; } +#ifdef CONFIG_TRACE_GPU_MEM +static void kgsl_mmu_trace_gpu_mem_pagetable(struct kgsl_pagetable *pagetable) +{ + if (pagetable->name == KGSL_MMU_GLOBAL_PT || + pagetable->name == KGSL_MMU_GLOBAL_LPAC_PT || + pagetable->name == KGSL_MMU_SECURE_PT) + return; + + trace_gpu_mem_total(0, pagetable->name, + (u64)atomic_long_read(&pagetable->stats.mapped)); +} +#else +static void kgsl_mmu_trace_gpu_mem_pagetable(struct kgsl_pagetable *pagetable) +{ +} +#endif + void kgsl_mmu_detach_pagetable(struct kgsl_pagetable *pagetable) { @@ -358,6 +375,7 @@ kgsl_mmu_map(struct kgsl_pagetable *pagetable, struct kgsl_memdesc *memdesc) { int size; + struct kgsl_device *device = KGSL_MMU_DEVICE(pagetable->mmu); if (!memdesc->gpuaddr) return -EINVAL; @@ -378,6 +396,12 @@ kgsl_mmu_map(struct kgsl_pagetable *pagetable, atomic_inc(&pagetable->stats.entries); KGSL_STATS_ADD(size, &pagetable->stats.mapped, &pagetable->stats.max_mapped); + kgsl_mmu_trace_gpu_mem_pagetable(pagetable); + + if (!kgsl_memdesc_is_global(memdesc) + && !(memdesc->flags & KGSL_MEMFLAGS_USERMEM_ION)) { + kgsl_trace_gpu_mem_total(device, size); + } memdesc->priv |= KGSL_MEMDESC_MAPPED; } @@ -444,6 +468,7 @@ kgsl_mmu_unmap(struct kgsl_pagetable *pagetable, struct kgsl_memdesc *memdesc) { int ret = 0; + struct kgsl_device *device = KGSL_MMU_DEVICE(pagetable->mmu); if (memdesc->size == 0) return -EINVAL; @@ -461,9 +486,13 @@ kgsl_mmu_unmap(struct kgsl_pagetable *pagetable, atomic_dec(&pagetable->stats.entries); atomic_long_sub(size, &pagetable->stats.mapped); + kgsl_mmu_trace_gpu_mem_pagetable(pagetable); - if (!kgsl_memdesc_is_global(memdesc)) + if (!kgsl_memdesc_is_global(memdesc)) { memdesc->priv &= ~KGSL_MEMDESC_MAPPED; + if (!(memdesc->flags & KGSL_MEMFLAGS_USERMEM_ION)) + kgsl_trace_gpu_mem_total(device, -(size)); + } } return ret; diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c index 8c0cbdc26d95..76d51be3834c 100644 --- a/drivers/gpu/msm/kgsl_sharedmem.c +++ b/drivers/gpu/msm/kgsl_sharedmem.c @@ -1293,6 +1293,7 @@ kgsl_allocate_secure_global(struct kgsl_device *device, * normally */ kgsl_mmu_map_global(device, &md->memdesc, 0); + kgsl_trace_gpu_mem_total(device, md->memdesc.size); return &md->memdesc; } @@ -1332,6 +1333,7 @@ struct kgsl_memdesc *kgsl_allocate_global(struct kgsl_device *device, list_add_tail(&md->node, &device->globals); kgsl_mmu_map_global(device, &md->memdesc, padding); + kgsl_trace_gpu_mem_total(device, md->memdesc.size); return &md->memdesc; }