Commit d6530c33 authored by Marek Olšák's avatar Marek Olšák Committed by Alex Deucher

drm/amdgpu: expose more memory stats in fdinfo

This will be used for performance investigations.
Signed-off-by: default avatarMarek Olšák <marek.olsak@amd.com>
Reviewed-by: default avatarChristian König <christian.koenig@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 28f7e897
...@@ -60,12 +60,13 @@ void amdgpu_show_fdinfo(struct seq_file *m, struct file *f) ...@@ -60,12 +60,13 @@ void amdgpu_show_fdinfo(struct seq_file *m, struct file *f)
struct amdgpu_fpriv *fpriv = file->driver_priv; struct amdgpu_fpriv *fpriv = file->driver_priv;
struct amdgpu_vm *vm = &fpriv->vm; struct amdgpu_vm *vm = &fpriv->vm;
uint64_t vram_mem = 0, gtt_mem = 0, cpu_mem = 0; struct amdgpu_mem_stats stats;
ktime_t usage[AMDGPU_HW_IP_NUM]; ktime_t usage[AMDGPU_HW_IP_NUM];
uint32_t bus, dev, fn, domain; uint32_t bus, dev, fn, domain;
unsigned int hw_ip; unsigned int hw_ip;
int ret; int ret;
memset(&stats, 0, sizeof(stats));
bus = adev->pdev->bus->number; bus = adev->pdev->bus->number;
domain = pci_domain_nr(adev->pdev->bus); domain = pci_domain_nr(adev->pdev->bus);
dev = PCI_SLOT(adev->pdev->devfn); dev = PCI_SLOT(adev->pdev->devfn);
...@@ -75,7 +76,7 @@ void amdgpu_show_fdinfo(struct seq_file *m, struct file *f) ...@@ -75,7 +76,7 @@ void amdgpu_show_fdinfo(struct seq_file *m, struct file *f)
if (ret) if (ret)
return; return;
amdgpu_vm_get_memory(vm, &vram_mem, &gtt_mem, &cpu_mem); amdgpu_vm_get_memory(vm, &stats);
amdgpu_bo_unreserve(vm->root.bo); amdgpu_bo_unreserve(vm->root.bo);
amdgpu_ctx_mgr_usage(&fpriv->ctx_mgr, usage); amdgpu_ctx_mgr_usage(&fpriv->ctx_mgr, usage);
...@@ -90,9 +91,22 @@ void amdgpu_show_fdinfo(struct seq_file *m, struct file *f) ...@@ -90,9 +91,22 @@ void amdgpu_show_fdinfo(struct seq_file *m, struct file *f)
seq_printf(m, "drm-driver:\t%s\n", file->minor->dev->driver->name); seq_printf(m, "drm-driver:\t%s\n", file->minor->dev->driver->name);
seq_printf(m, "drm-pdev:\t%04x:%02x:%02x.%d\n", domain, bus, dev, fn); seq_printf(m, "drm-pdev:\t%04x:%02x:%02x.%d\n", domain, bus, dev, fn);
seq_printf(m, "drm-client-id:\t%Lu\n", vm->immediate.fence_context); seq_printf(m, "drm-client-id:\t%Lu\n", vm->immediate.fence_context);
seq_printf(m, "drm-memory-vram:\t%llu KiB\n", vram_mem/1024UL); seq_printf(m, "drm-memory-vram:\t%llu KiB\n", stats.vram/1024UL);
seq_printf(m, "drm-memory-gtt: \t%llu KiB\n", gtt_mem/1024UL); seq_printf(m, "drm-memory-gtt: \t%llu KiB\n", stats.gtt/1024UL);
seq_printf(m, "drm-memory-cpu: \t%llu KiB\n", cpu_mem/1024UL); seq_printf(m, "drm-memory-cpu: \t%llu KiB\n", stats.cpu/1024UL);
seq_printf(m, "amd-memory-visible-vram:\t%llu KiB\n",
stats.visible_vram/1024UL);
seq_printf(m, "amd-evicted-vram:\t%llu KiB\n",
stats.evicted_vram/1024UL);
seq_printf(m, "amd-evicted-visible-vram:\t%llu KiB\n",
stats.evicted_visible_vram/1024UL);
seq_printf(m, "amd-requested-vram:\t%llu KiB\n",
stats.requested_vram/1024UL);
seq_printf(m, "amd-requested-visible-vram:\t%llu KiB\n",
stats.requested_visible_vram/1024UL);
seq_printf(m, "amd-requested-gtt:\t%llu KiB\n",
stats.requested_gtt/1024UL);
for (hw_ip = 0; hw_ip < AMDGPU_HW_IP_NUM; ++hw_ip) { for (hw_ip = 0; hw_ip < AMDGPU_HW_IP_NUM; ++hw_ip) {
if (!usage[hw_ip]) if (!usage[hw_ip])
continue; continue;
......
...@@ -1265,24 +1265,41 @@ void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, ...@@ -1265,24 +1265,41 @@ void amdgpu_bo_move_notify(struct ttm_buffer_object *bo,
trace_amdgpu_bo_move(abo, new_mem->mem_type, old_mem->mem_type); trace_amdgpu_bo_move(abo, new_mem->mem_type, old_mem->mem_type);
} }
void amdgpu_bo_get_memory(struct amdgpu_bo *bo, uint64_t *vram_mem, void amdgpu_bo_get_memory(struct amdgpu_bo *bo,
uint64_t *gtt_mem, uint64_t *cpu_mem) struct amdgpu_mem_stats *stats)
{ {
unsigned int domain; unsigned int domain;
uint64_t size = amdgpu_bo_size(bo);
domain = amdgpu_mem_type_to_domain(bo->tbo.resource->mem_type); domain = amdgpu_mem_type_to_domain(bo->tbo.resource->mem_type);
switch (domain) { switch (domain) {
case AMDGPU_GEM_DOMAIN_VRAM: case AMDGPU_GEM_DOMAIN_VRAM:
*vram_mem += amdgpu_bo_size(bo); stats->vram += size;
if (amdgpu_bo_in_cpu_visible_vram(bo))
stats->visible_vram += size;
break; break;
case AMDGPU_GEM_DOMAIN_GTT: case AMDGPU_GEM_DOMAIN_GTT:
*gtt_mem += amdgpu_bo_size(bo); stats->gtt += size;
break; break;
case AMDGPU_GEM_DOMAIN_CPU: case AMDGPU_GEM_DOMAIN_CPU:
default: default:
*cpu_mem += amdgpu_bo_size(bo); stats->cpu += size;
break; break;
} }
if (bo->preferred_domains & AMDGPU_GEM_DOMAIN_VRAM) {
stats->requested_vram += size;
if (bo->flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED)
stats->requested_visible_vram += size;
if (domain != AMDGPU_GEM_DOMAIN_VRAM) {
stats->evicted_vram += size;
if (bo->flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED)
stats->evicted_visible_vram += size;
}
} else if (bo->preferred_domains & AMDGPU_GEM_DOMAIN_GTT) {
stats->requested_gtt += size;
}
} }
/** /**
......
...@@ -126,6 +126,27 @@ struct amdgpu_bo_vm { ...@@ -126,6 +126,27 @@ struct amdgpu_bo_vm {
struct amdgpu_vm_bo_base entries[]; struct amdgpu_vm_bo_base entries[];
}; };
struct amdgpu_mem_stats {
/* current VRAM usage, includes visible VRAM */
uint64_t vram;
/* current visible VRAM usage */
uint64_t visible_vram;
/* current GTT usage */
uint64_t gtt;
/* current system memory usage */
uint64_t cpu;
/* sum of evicted buffers, includes visible VRAM */
uint64_t evicted_vram;
/* sum of evicted buffers due to CPU access */
uint64_t evicted_visible_vram;
/* how much userspace asked for, includes vis.VRAM */
uint64_t requested_vram;
/* how much userspace asked for */
uint64_t requested_visible_vram;
/* how much userspace asked for */
uint64_t requested_gtt;
};
static inline struct amdgpu_bo *ttm_to_amdgpu_bo(struct ttm_buffer_object *tbo) static inline struct amdgpu_bo *ttm_to_amdgpu_bo(struct ttm_buffer_object *tbo)
{ {
return container_of(tbo, struct amdgpu_bo, tbo); return container_of(tbo, struct amdgpu_bo, tbo);
...@@ -325,8 +346,8 @@ int amdgpu_bo_sync_wait_resv(struct amdgpu_device *adev, struct dma_resv *resv, ...@@ -325,8 +346,8 @@ int amdgpu_bo_sync_wait_resv(struct amdgpu_device *adev, struct dma_resv *resv,
int amdgpu_bo_sync_wait(struct amdgpu_bo *bo, void *owner, bool intr); int amdgpu_bo_sync_wait(struct amdgpu_bo *bo, void *owner, bool intr);
u64 amdgpu_bo_gpu_offset(struct amdgpu_bo *bo); u64 amdgpu_bo_gpu_offset(struct amdgpu_bo *bo);
u64 amdgpu_bo_gpu_offset_no_check(struct amdgpu_bo *bo); u64 amdgpu_bo_gpu_offset_no_check(struct amdgpu_bo *bo);
void amdgpu_bo_get_memory(struct amdgpu_bo *bo, uint64_t *vram_mem, void amdgpu_bo_get_memory(struct amdgpu_bo *bo,
uint64_t *gtt_mem, uint64_t *cpu_mem); struct amdgpu_mem_stats *stats);
void amdgpu_bo_add_to_shadow_list(struct amdgpu_bo_vm *vmbo); void amdgpu_bo_add_to_shadow_list(struct amdgpu_bo_vm *vmbo);
int amdgpu_bo_restore_shadow(struct amdgpu_bo *shadow, int amdgpu_bo_restore_shadow(struct amdgpu_bo *shadow,
struct dma_fence **fence); struct dma_fence **fence);
......
...@@ -920,8 +920,8 @@ int amdgpu_vm_update_range(struct amdgpu_device *adev, struct amdgpu_vm *vm, ...@@ -920,8 +920,8 @@ int amdgpu_vm_update_range(struct amdgpu_device *adev, struct amdgpu_vm *vm,
return r; return r;
} }
void amdgpu_vm_get_memory(struct amdgpu_vm *vm, uint64_t *vram_mem, void amdgpu_vm_get_memory(struct amdgpu_vm *vm,
uint64_t *gtt_mem, uint64_t *cpu_mem) struct amdgpu_mem_stats *stats)
{ {
struct amdgpu_bo_va *bo_va, *tmp; struct amdgpu_bo_va *bo_va, *tmp;
...@@ -929,41 +929,36 @@ void amdgpu_vm_get_memory(struct amdgpu_vm *vm, uint64_t *vram_mem, ...@@ -929,41 +929,36 @@ void amdgpu_vm_get_memory(struct amdgpu_vm *vm, uint64_t *vram_mem,
list_for_each_entry_safe(bo_va, tmp, &vm->idle, base.vm_status) { list_for_each_entry_safe(bo_va, tmp, &vm->idle, base.vm_status) {
if (!bo_va->base.bo) if (!bo_va->base.bo)
continue; continue;
amdgpu_bo_get_memory(bo_va->base.bo, vram_mem, amdgpu_bo_get_memory(bo_va->base.bo, stats);
gtt_mem, cpu_mem);
} }
list_for_each_entry_safe(bo_va, tmp, &vm->evicted, base.vm_status) { list_for_each_entry_safe(bo_va, tmp, &vm->evicted, base.vm_status) {
if (!bo_va->base.bo) if (!bo_va->base.bo)
continue; continue;
amdgpu_bo_get_memory(bo_va->base.bo, vram_mem, amdgpu_bo_get_memory(bo_va->base.bo, stats);
gtt_mem, cpu_mem);
} }
list_for_each_entry_safe(bo_va, tmp, &vm->relocated, base.vm_status) { list_for_each_entry_safe(bo_va, tmp, &vm->relocated, base.vm_status) {
if (!bo_va->base.bo) if (!bo_va->base.bo)
continue; continue;
amdgpu_bo_get_memory(bo_va->base.bo, vram_mem, amdgpu_bo_get_memory(bo_va->base.bo, stats);
gtt_mem, cpu_mem);
} }
list_for_each_entry_safe(bo_va, tmp, &vm->moved, base.vm_status) { list_for_each_entry_safe(bo_va, tmp, &vm->moved, base.vm_status) {
if (!bo_va->base.bo) if (!bo_va->base.bo)
continue; continue;
amdgpu_bo_get_memory(bo_va->base.bo, vram_mem, amdgpu_bo_get_memory(bo_va->base.bo, stats);
gtt_mem, cpu_mem);
} }
list_for_each_entry_safe(bo_va, tmp, &vm->invalidated, base.vm_status) { list_for_each_entry_safe(bo_va, tmp, &vm->invalidated, base.vm_status) {
if (!bo_va->base.bo) if (!bo_va->base.bo)
continue; continue;
amdgpu_bo_get_memory(bo_va->base.bo, vram_mem, amdgpu_bo_get_memory(bo_va->base.bo, stats);
gtt_mem, cpu_mem);
} }
list_for_each_entry_safe(bo_va, tmp, &vm->done, base.vm_status) { list_for_each_entry_safe(bo_va, tmp, &vm->done, base.vm_status) {
if (!bo_va->base.bo) if (!bo_va->base.bo)
continue; continue;
amdgpu_bo_get_memory(bo_va->base.bo, vram_mem, amdgpu_bo_get_memory(bo_va->base.bo, stats);
gtt_mem, cpu_mem);
} }
spin_unlock(&vm->status_lock); spin_unlock(&vm->status_lock);
} }
/** /**
* amdgpu_vm_bo_update - update all BO mappings in the vm page table * amdgpu_vm_bo_update - update all BO mappings in the vm page table
* *
......
...@@ -40,6 +40,7 @@ struct amdgpu_bo_va; ...@@ -40,6 +40,7 @@ struct amdgpu_bo_va;
struct amdgpu_job; struct amdgpu_job;
struct amdgpu_bo_list_entry; struct amdgpu_bo_list_entry;
struct amdgpu_bo_vm; struct amdgpu_bo_vm;
struct amdgpu_mem_stats;
/* /*
* GPUVM handling * GPUVM handling
...@@ -457,8 +458,8 @@ void amdgpu_vm_set_task_info(struct amdgpu_vm *vm); ...@@ -457,8 +458,8 @@ void amdgpu_vm_set_task_info(struct amdgpu_vm *vm);
void amdgpu_vm_move_to_lru_tail(struct amdgpu_device *adev, void amdgpu_vm_move_to_lru_tail(struct amdgpu_device *adev,
struct amdgpu_vm *vm); struct amdgpu_vm *vm);
void amdgpu_vm_get_memory(struct amdgpu_vm *vm, uint64_t *vram_mem, void amdgpu_vm_get_memory(struct amdgpu_vm *vm,
uint64_t *gtt_mem, uint64_t *cpu_mem); struct amdgpu_mem_stats *stats);
int amdgpu_vm_pt_clear(struct amdgpu_device *adev, struct amdgpu_vm *vm, int amdgpu_vm_pt_clear(struct amdgpu_device *adev, struct amdgpu_vm *vm,
struct amdgpu_bo_vm *vmbo, bool immediate); struct amdgpu_bo_vm *vmbo, bool immediate);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment