1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2024 Intel Corporation 4 */ 5 6 #include <drm/drm_managed.h> 7 #include <drm/drm_print.h> 8 9 #include "xe_device.h" 10 #include "xe_gt_stats.h" 11 12 static void xe_gt_stats_fini(struct drm_device *drm, void *arg) 13 { 14 struct xe_gt *gt = arg; 15 16 free_percpu(gt->stats); 17 } 18 19 /** 20 * xe_gt_stats_init() - Initialize GT statistics 21 * @gt: GT structure 22 * 23 * Allocate per-CPU GT statistics. Using per-CPU stats allows increments 24 * to occur without cross-CPU atomics. 25 * 26 * Return: 0 on success, -ENOMEM on failure. 27 */ 28 int xe_gt_stats_init(struct xe_gt *gt) 29 { 30 gt->stats = alloc_percpu(struct xe_gt_stats); 31 if (!gt->stats) 32 return -ENOMEM; 33 34 return drmm_add_action_or_reset(>_to_xe(gt)->drm, xe_gt_stats_fini, 35 gt); 36 } 37 38 /** 39 * xe_gt_stats_incr - Increments the specified stats counter 40 * @gt: GT structure 41 * @id: xe_gt_stats_id type id that needs to be incremented 42 * @incr: value to be incremented with 43 * 44 * Increments the specified stats counter. 45 */ 46 void xe_gt_stats_incr(struct xe_gt *gt, const enum xe_gt_stats_id id, int incr) 47 { 48 if (id >= __XE_GT_STATS_NUM_IDS) 49 return; 50 51 this_cpu_add(gt->stats->counters[id], incr); 52 } 53 54 #define DEF_STAT_STR(ID, name) [XE_GT_STATS_ID_##ID] = name 55 56 static const char *const stat_description[__XE_GT_STATS_NUM_IDS] = { 57 DEF_STAT_STR(SVM_PAGEFAULT_COUNT, "svm_pagefault_count"), 58 DEF_STAT_STR(TLB_INVAL, "tlb_inval_count"), 59 DEF_STAT_STR(SVM_TLB_INVAL_COUNT, "svm_tlb_inval_count"), 60 DEF_STAT_STR(SVM_TLB_INVAL_US, "svm_tlb_inval_us"), 61 DEF_STAT_STR(VMA_PAGEFAULT_COUNT, "vma_pagefault_count"), 62 DEF_STAT_STR(VMA_PAGEFAULT_KB, "vma_pagefault_kb"), 63 DEF_STAT_STR(INVALID_PREFETCH_PAGEFAULT_COUNT, "invalid_prefetch_pagefault_count"), 64 DEF_STAT_STR(SVM_4K_PAGEFAULT_COUNT, "svm_4K_pagefault_count"), 65 DEF_STAT_STR(SVM_64K_PAGEFAULT_COUNT, "svm_64K_pagefault_count"), 66 DEF_STAT_STR(SVM_2M_PAGEFAULT_COUNT, "svm_2M_pagefault_count"), 67 DEF_STAT_STR(SVM_4K_VALID_PAGEFAULT_COUNT, "svm_4K_valid_pagefault_count"), 68 DEF_STAT_STR(SVM_64K_VALID_PAGEFAULT_COUNT, "svm_64K_valid_pagefault_count"), 69 DEF_STAT_STR(SVM_2M_VALID_PAGEFAULT_COUNT, "svm_2M_valid_pagefault_count"), 70 DEF_STAT_STR(SVM_4K_PAGEFAULT_US, "svm_4K_pagefault_us"), 71 DEF_STAT_STR(SVM_64K_PAGEFAULT_US, "svm_64K_pagefault_us"), 72 DEF_STAT_STR(SVM_2M_PAGEFAULT_US, "svm_2M_pagefault_us"), 73 DEF_STAT_STR(SVM_4K_MIGRATE_COUNT, "svm_4K_migrate_count"), 74 DEF_STAT_STR(SVM_64K_MIGRATE_COUNT, "svm_64K_migrate_count"), 75 DEF_STAT_STR(SVM_2M_MIGRATE_COUNT, "svm_2M_migrate_count"), 76 DEF_STAT_STR(SVM_4K_MIGRATE_US, "svm_4K_migrate_us"), 77 DEF_STAT_STR(SVM_64K_MIGRATE_US, "svm_64K_migrate_us"), 78 DEF_STAT_STR(SVM_2M_MIGRATE_US, "svm_2M_migrate_us"), 79 DEF_STAT_STR(SVM_DEVICE_COPY_US, "svm_device_copy_us"), 80 DEF_STAT_STR(SVM_4K_DEVICE_COPY_US, "svm_4K_device_copy_us"), 81 DEF_STAT_STR(SVM_64K_DEVICE_COPY_US, "svm_64K_device_copy_us"), 82 DEF_STAT_STR(SVM_2M_DEVICE_COPY_US, "svm_2M_device_copy_us"), 83 DEF_STAT_STR(SVM_CPU_COPY_US, "svm_cpu_copy_us"), 84 DEF_STAT_STR(SVM_4K_CPU_COPY_US, "svm_4K_cpu_copy_us"), 85 DEF_STAT_STR(SVM_64K_CPU_COPY_US, "svm_64K_cpu_copy_us"), 86 DEF_STAT_STR(SVM_2M_CPU_COPY_US, "svm_2M_cpu_copy_us"), 87 DEF_STAT_STR(SVM_DEVICE_COPY_KB, "svm_device_copy_kb"), 88 DEF_STAT_STR(SVM_4K_DEVICE_COPY_KB, "svm_4K_device_copy_kb"), 89 DEF_STAT_STR(SVM_64K_DEVICE_COPY_KB, "svm_64K_device_copy_kb"), 90 DEF_STAT_STR(SVM_2M_DEVICE_COPY_KB, "svm_2M_device_copy_kb"), 91 DEF_STAT_STR(SVM_CPU_COPY_KB, "svm_cpu_copy_kb"), 92 DEF_STAT_STR(SVM_4K_CPU_COPY_KB, "svm_4K_cpu_copy_kb"), 93 DEF_STAT_STR(SVM_64K_CPU_COPY_KB, "svm_64K_cpu_copy_kb"), 94 DEF_STAT_STR(SVM_2M_CPU_COPY_KB, "svm_2M_cpu_copy_kb"), 95 DEF_STAT_STR(SVM_4K_GET_PAGES_US, "svm_4K_get_pages_us"), 96 DEF_STAT_STR(SVM_64K_GET_PAGES_US, "svm_64K_get_pages_us"), 97 DEF_STAT_STR(SVM_2M_GET_PAGES_US, "svm_2M_get_pages_us"), 98 DEF_STAT_STR(SVM_4K_BIND_US, "svm_4K_bind_us"), 99 DEF_STAT_STR(SVM_64K_BIND_US, "svm_64K_bind_us"), 100 DEF_STAT_STR(SVM_2M_BIND_US, "svm_2M_bind_us"), 101 DEF_STAT_STR(HW_ENGINE_GROUP_SUSPEND_LR_QUEUE_COUNT, 102 "hw_engine_group_suspend_lr_queue_count"), 103 DEF_STAT_STR(HW_ENGINE_GROUP_SKIP_LR_QUEUE_COUNT, 104 "hw_engine_group_skip_lr_queue_count"), 105 DEF_STAT_STR(HW_ENGINE_GROUP_WAIT_DMA_QUEUE_COUNT, 106 "hw_engine_group_wait_dma_queue_count"), 107 DEF_STAT_STR(HW_ENGINE_GROUP_SUSPEND_LR_QUEUE_US, 108 "hw_engine_group_suspend_lr_queue_us"), 109 DEF_STAT_STR(HW_ENGINE_GROUP_WAIT_DMA_QUEUE_US, 110 "hw_engine_group_wait_dma_queue_us"), 111 DEF_STAT_STR(PRL_4K_ENTRY_COUNT, "prl_4k_entry_count"), 112 DEF_STAT_STR(PRL_64K_ENTRY_COUNT, "prl_64k_entry_count"), 113 DEF_STAT_STR(PRL_2M_ENTRY_COUNT, "prl_2m_entry_count"), 114 DEF_STAT_STR(PRL_ISSUED_COUNT, "prl_issued_count"), 115 DEF_STAT_STR(PRL_ABORTED_COUNT, "prl_aborted_count"), 116 }; 117 118 /** 119 * xe_gt_stats_print_info - Print the GT stats 120 * @gt: GT structure 121 * @p: drm_printer where it will be printed out. 122 * 123 * This prints out all the available GT stats. 124 */ 125 int xe_gt_stats_print_info(struct xe_gt *gt, struct drm_printer *p) 126 { 127 enum xe_gt_stats_id id; 128 129 for (id = 0; id < __XE_GT_STATS_NUM_IDS; ++id) { 130 u64 total = 0; 131 int cpu; 132 133 for_each_possible_cpu(cpu) { 134 struct xe_gt_stats *s = per_cpu_ptr(gt->stats, cpu); 135 136 total += s->counters[id]; 137 } 138 139 drm_printf(p, "%s: %lld\n", stat_description[id], total); 140 } 141 142 return 0; 143 } 144 145 /** 146 * xe_gt_stats_clear() - Clear the GT stats 147 * @gt: GT structure 148 * 149 * Clear (zero) all available GT stats. Note that if the stats are being 150 * updated while this function is running, the results may be unpredictable. 151 * Intended to be called on an idle GPU. 152 */ 153 void xe_gt_stats_clear(struct xe_gt *gt) 154 { 155 int cpu; 156 157 for_each_possible_cpu(cpu) { 158 struct xe_gt_stats *s = per_cpu_ptr(gt->stats, cpu); 159 160 memset(s, 0, sizeof(*s)); 161 } 162 } 163