xref: /linux/drivers/gpu/drm/xe/xe_gt_stats.c (revision 53597deca0e38c30e6cd4ba2114fa42d2bcd85bb)
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(&gt_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