Add five counters to the fdinfo for amdgpu device files. They are: amd-vmfault-counter: %llu amd-queue-eviction-counter: %llu amd-svm-migrate-counter: %llu amd-svm-page-fault-counter: %llu amd-svm-unmap-counter: %llu
These counters begin at 0 when a device file is opened. They are for use by profiling applications. Signed-off-by: David Francis <[email protected]> --- drivers/gpu/drm/amd/amdgpu/amdgpu_fdinfo.c | 15 ++++++++++- drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 5 ++++ drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c | 3 +++ drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 31 ++++++++++++++++++++-- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h | 26 ++++++++++++++++-- drivers/gpu/drm/amd/amdkfd/kfd_migrate.c | 6 +++++ drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 11 ++++++-- 7 files changed, 90 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fdinfo.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fdinfo.c index b349bb3676d5..96d6063ecaa8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fdinfo.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fdinfo.c @@ -61,6 +61,7 @@ void amdgpu_show_fdinfo(struct drm_printer *p, struct drm_file *file) struct amdgpu_vm *vm = &fpriv->vm; struct amdgpu_mem_stats stats[__AMDGPU_PL_NUM]; + struct amdgpu_process_stats process_stats; ktime_t usage[AMDGPU_HW_IP_NUM]; const char *pl_name[] = { [TTM_PL_VRAM] = "vram", @@ -74,7 +75,7 @@ void amdgpu_show_fdinfo(struct drm_printer *p, struct drm_file *file) }; unsigned int hw_ip, i; - amdgpu_vm_get_memory(vm, stats); + amdgpu_vm_get_memory(vm, stats, &process_stats); amdgpu_ctx_mgr_usage(&fpriv->ctx_mgr, usage); /* @@ -114,6 +115,18 @@ void amdgpu_show_fdinfo(struct drm_printer *p, struct drm_file *file) (stats[TTM_PL_TT].drm.shared + stats[TTM_PL_TT].drm.private) / 1024UL); + /* Amdgpu specific counters: */ + drm_printf(p, "amd-vmfault-counter:\t%llu\n", + process_stats.vmfault_counter); + drm_printf(p, "amd-queue-eviction-counter:\t%llu\n", + process_stats.queue_eviction_counter); + drm_printf(p, "amd-svm-migrate-counter:\t%llu\n", + process_stats.svm_migrate_counter); + drm_printf(p, "amd-svm-page-fault-counter:\t%llu\n", + process_stats.svm_page_fault_counter); + drm_printf(p, "amd-svm-unmap-counter:\t%llu\n", + process_stats.svm_unmap_counter); + for (hw_ip = 0; hw_ip < AMDGPU_HW_IP_NUM; ++hw_ip) { if (!usage[hw_ip]) continue; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c index 82bc6d657e5a..ad1042639dbe 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c @@ -476,6 +476,7 @@ void amdgpu_irq_dispatch(struct amdgpu_device *adev, struct amdgpu_iv_entry entry; unsigned int client_id, src_id; struct amdgpu_irq_src *src; + struct amdgpu_vm *vm; bool handled = false; int r; @@ -513,6 +514,10 @@ void amdgpu_irq_dispatch(struct amdgpu_device *adev, client_id, src_id); } else if ((src = adev->irq.client[client_id].sources[src_id])) { + vm = amdgpu_vm_get_vm_from_pasid(adev, entry.pasid); + if (vm) + amdgpu_vm_increment_process_counter(vm, AMDGPU_VM_VMFAULT_COUNTER); + r = src->funcs->process(adev, src, &entry); if (r < 0) dev_err(adev->dev, "error processing interrupt (%d)\n", diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c index 001fcfcbde0f..9ba6f166cb5c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c @@ -1300,6 +1300,9 @@ amdgpu_userq_evict_all(struct amdgpu_userq_mgr *uq_mgr) queue = amdgpu_userq_get(uq_mgr, queue_id); if (!queue) continue; + + amdgpu_vm_increment_process_counter(queue->fw_obj.obj->vm_bo->vm, AMDGPU_VM_QUEUE_EVICTION_COUNTER); + r = amdgpu_userq_preempt_helper(queue); if (r) ret = r; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 01fef0e4f408..d7d82f23377f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -1241,10 +1241,12 @@ int amdgpu_vm_update_range(struct amdgpu_device *adev, struct amdgpu_vm *vm, } void amdgpu_vm_get_memory(struct amdgpu_vm *vm, - struct amdgpu_mem_stats stats[__AMDGPU_PL_NUM]) + struct amdgpu_mem_stats stats[__AMDGPU_PL_NUM], + struct amdgpu_process_stats *process_stats) { spin_lock(&vm->status_lock); memcpy(stats, vm->stats, sizeof(*stats) * __AMDGPU_PL_NUM); + memcpy(process_stats, &vm->process_stats, sizeof(*process_stats)); spin_unlock(&vm->status_lock); } @@ -2472,7 +2474,7 @@ static void amdgpu_vm_destroy_task_info(struct kref *kref) kfree(ti); } -static inline struct amdgpu_vm * +inline struct amdgpu_vm * amdgpu_vm_get_vm_from_pasid(struct amdgpu_device *adev, u32 pasid) { struct amdgpu_vm *vm; @@ -3234,3 +3236,28 @@ void amdgpu_sdma_set_vm_pte_scheds(struct amdgpu_device *adev, adev->vm_manager.vm_pte_num_scheds = adev->sdma.num_instances; adev->vm_manager.vm_pte_funcs = vm_pte_funcs; } + +void amdgpu_vm_increment_process_counter(struct amdgpu_vm *vm, enum amdgpu_process_stat_type stat_type) +{ + spin_lock(&vm->status_lock); + switch (stat_type) { + case AMDGPU_VM_VMFAULT_COUNTER: + vm->process_stats.vmfault_counter++; + break; + case AMDGPU_VM_QUEUE_EVICTION_COUNTER: + vm->process_stats.queue_eviction_counter++; + break; + case AMDGPU_VM_SVM_MIGRATE_COUNTER: + vm->process_stats.svm_migrate_counter++; + break; + case AMDGPU_VM_SVM_PAGE_FAULT_COUNTER: + vm->process_stats.svm_page_fault_counter++; + break; + case AMDGPU_VM_SVM_UNMAP_COUNTER: + vm->process_stats.svm_unmap_counter++; + break; + default: + pr_debug("unknown process stat type 0x%x\n", stat_type); + } + spin_unlock(&vm->status_lock); +} diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h index dc4b0ec672ec..4a63f0384c7d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h @@ -334,6 +334,14 @@ struct amdgpu_mem_stats { uint64_t evicted; }; +struct amdgpu_process_stats { + uint64_t vmfault_counter; + uint64_t queue_eviction_counter; + uint64_t svm_migrate_counter; + uint64_t svm_page_fault_counter; + uint64_t svm_unmap_counter; +}; + struct amdgpu_vm { /* tree of virtual addresses mapped */ struct rb_root_cached va; @@ -348,8 +356,9 @@ struct amdgpu_vm { /* Lock to protect vm_bo add/del/move on all lists of vm */ spinlock_t status_lock; - /* Memory statistics for this vm, protected by status_lock */ + /* Statistics for this vm, protected by stats_lock */ struct amdgpu_mem_stats stats[__AMDGPU_PL_NUM]; + struct amdgpu_process_stats process_stats; /* * The following lists contain amdgpu_vm_bo_base objects for either @@ -586,6 +595,8 @@ amdgpu_vm_get_task_info_vm(struct amdgpu_vm *vm); void amdgpu_vm_put_task_info(struct amdgpu_task_info *task_info); +struct amdgpu_vm *amdgpu_vm_get_vm_from_pasid(struct amdgpu_device *adev, u32 pasid); + bool amdgpu_vm_handle_fault(struct amdgpu_device *adev, u32 pasid, u32 vmid, u32 node_id, uint64_t addr, uint64_t ts, bool write_fault); @@ -595,7 +606,8 @@ void amdgpu_vm_set_task_info(struct amdgpu_vm *vm); void amdgpu_vm_move_to_lru_tail(struct amdgpu_device *adev, struct amdgpu_vm *vm); void amdgpu_vm_get_memory(struct amdgpu_vm *vm, - struct amdgpu_mem_stats stats[__AMDGPU_PL_NUM]); + struct amdgpu_mem_stats stats[__AMDGPU_PL_NUM], + struct amdgpu_process_stats *process_stats); int amdgpu_vm_pt_clear(struct amdgpu_device *adev, struct amdgpu_vm *vm, struct amdgpu_bo_vm *vmbo, bool immediate); @@ -621,6 +633,16 @@ int amdgpu_vm_pt_map_tables(struct amdgpu_device *adev, struct amdgpu_vm *vm); bool amdgpu_vm_is_bo_always_valid(struct amdgpu_vm *vm, struct amdgpu_bo *bo); +enum amdgpu_process_stat_type { + AMDGPU_VM_VMFAULT_COUNTER, + AMDGPU_VM_QUEUE_EVICTION_COUNTER, + AMDGPU_VM_SVM_MIGRATE_COUNTER, + AMDGPU_VM_SVM_PAGE_FAULT_COUNTER, + AMDGPU_VM_SVM_UNMAP_COUNTER, +}; + +void amdgpu_vm_increment_process_counter(struct amdgpu_vm *vm, enum amdgpu_process_stat_type stat_type); + /** * amdgpu_vm_tlb_seq - return tlb flush sequence number * @vm: the amdgpu_vm structure to query diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c index b3d304aab686..c341b6842460 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c @@ -427,6 +427,9 @@ svm_migrate_vma_to_vram(struct kfd_node *node, struct svm_range *prange, start >> PAGE_SHIFT, end >> PAGE_SHIFT, 0, node->id, prange->prefetch_loc, prange->preferred_loc, trigger); + pdd = svm_range_get_pdd_by_node(prange, node); + if (pdd) + amdgpu_vm_increment_process_counter(drm_priv_to_vm(pdd->drm_priv), AMDGPU_VM_SVM_MIGRATE_COUNTER); r = migrate_vma_setup(&migrate); if (r) { @@ -729,6 +732,9 @@ svm_migrate_vma_to_ram(struct kfd_node *node, struct svm_range *prange, start >> PAGE_SHIFT, end >> PAGE_SHIFT, node->id, 0, prange->prefetch_loc, prange->preferred_loc, trigger); + pdd = svm_range_get_pdd_by_node(prange, node); + if (pdd) + amdgpu_vm_increment_process_counter(drm_priv_to_vm(pdd->drm_priv), AMDGPU_VM_SVM_MIGRATE_COUNTER); r = migrate_vma_setup(&migrate); if (r) { diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c index fcddb54a439f..499882a76581 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c @@ -1375,9 +1375,11 @@ svm_range_unmap_from_gpus(struct svm_range *prange, unsigned long start, struct kfd_process_device *pdd; struct dma_fence *fence = NULL; struct kfd_process *p; + struct amdgpu_vm *vm; uint32_t gpuidx; int r = 0; + if (!prange->mapped_to_gpu) { pr_debug("prange 0x%p [0x%lx 0x%lx] not mapped to GPU\n", prange, prange->start, prange->last); @@ -1398,13 +1400,14 @@ svm_range_unmap_from_gpus(struct svm_range *prange, unsigned long start, pr_debug("failed to find device idx %d\n", gpuidx); return -EINVAL; } + vm = drm_priv_to_vm(pdd->drm_priv); kfd_smi_event_unmap_from_gpu(pdd->dev, p->lead_thread->pid, start, last, trigger); + amdgpu_vm_increment_process_counter(vm, AMDGPU_VM_SVM_UNMAP_COUNTER); r = svm_range_unmap_from_gpu(pdd->dev->adev, - drm_priv_to_vm(pdd->drm_priv), - start, last, &fence); + vm, start, last, &fence); if (r) break; @@ -3039,6 +3042,7 @@ svm_range_restore_pages(struct amdgpu_device *adev, unsigned int pasid, struct svm_range_list *svms; struct svm_range *prange; struct kfd_process *p; + struct kfd_process_device *pdd; ktime_t timestamp = ktime_get_boottime(); struct kfd_node *node; int32_t best_loc; @@ -3193,6 +3197,9 @@ svm_range_restore_pages(struct amdgpu_device *adev, unsigned int pasid, kfd_smi_event_page_fault_start(node, p->lead_thread->pid, addr, write_fault, timestamp); + pdd = svm_range_get_pdd_by_node(prange, node); + if (pdd) + amdgpu_vm_increment_process_counter(drm_priv_to_vm(pdd->drm_priv), AMDGPU_VM_SVM_MIGRATE_COUNTER); /* Align migration range start and size to granularity size */ size = 1UL << prange->granularity; -- 2.34.1
