xref: /linux/drivers/crypto/intel/iaa/iaa_crypto_stats.c (revision eb01fe7abbe2d0b38824d2a93fdb4cc3eaf2ccc1)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2021 Intel Corporation. All rights rsvd. */
3 
4 #include <linux/module.h>
5 #include <linux/kernel.h>
6 #include <linux/highmem.h>
7 #include <linux/mm.h>
8 #include <linux/slab.h>
9 #include <linux/delay.h>
10 #include <linux/smp.h>
11 #include <uapi/linux/idxd.h>
12 #include <linux/idxd.h>
13 #include <linux/dmaengine.h>
14 #include "../../dma/idxd/idxd.h"
15 #include <linux/debugfs.h>
16 #include <crypto/internal/acompress.h>
17 #include "iaa_crypto.h"
18 #include "iaa_crypto_stats.h"
19 
20 static u64 total_comp_calls;
21 static u64 total_decomp_calls;
22 static u64 total_sw_decomp_calls;
23 static u64 max_comp_delay_ns;
24 static u64 max_decomp_delay_ns;
25 static u64 total_comp_bytes_out;
26 static u64 total_decomp_bytes_in;
27 static u64 total_completion_einval_errors;
28 static u64 total_completion_timeout_errors;
29 static u64 total_completion_comp_buf_overflow_errors;
30 
31 static struct dentry *iaa_crypto_debugfs_root;
32 
33 void update_total_comp_calls(void)
34 {
35 	total_comp_calls++;
36 }
37 
38 void update_total_comp_bytes_out(int n)
39 {
40 	total_comp_bytes_out += n;
41 }
42 
43 void update_total_decomp_calls(void)
44 {
45 	total_decomp_calls++;
46 }
47 
48 void update_total_sw_decomp_calls(void)
49 {
50 	total_sw_decomp_calls++;
51 }
52 
53 void update_total_decomp_bytes_in(int n)
54 {
55 	total_decomp_bytes_in += n;
56 }
57 
58 void update_completion_einval_errs(void)
59 {
60 	total_completion_einval_errors++;
61 }
62 
63 void update_completion_timeout_errs(void)
64 {
65 	total_completion_timeout_errors++;
66 }
67 
68 void update_completion_comp_buf_overflow_errs(void)
69 {
70 	total_completion_comp_buf_overflow_errors++;
71 }
72 
73 void update_max_comp_delay_ns(u64 start_time_ns)
74 {
75 	u64 time_diff;
76 
77 	time_diff = ktime_get_ns() - start_time_ns;
78 
79 	if (time_diff > max_comp_delay_ns)
80 		max_comp_delay_ns = time_diff;
81 }
82 
83 void update_max_decomp_delay_ns(u64 start_time_ns)
84 {
85 	u64 time_diff;
86 
87 	time_diff = ktime_get_ns() - start_time_ns;
88 
89 	if (time_diff > max_decomp_delay_ns)
90 		max_decomp_delay_ns = time_diff;
91 }
92 
93 void update_wq_comp_calls(struct idxd_wq *idxd_wq)
94 {
95 	struct iaa_wq *wq = idxd_wq_get_private(idxd_wq);
96 
97 	wq->comp_calls++;
98 	wq->iaa_device->comp_calls++;
99 }
100 
101 void update_wq_comp_bytes(struct idxd_wq *idxd_wq, int n)
102 {
103 	struct iaa_wq *wq = idxd_wq_get_private(idxd_wq);
104 
105 	wq->comp_bytes += n;
106 	wq->iaa_device->comp_bytes += n;
107 }
108 
109 void update_wq_decomp_calls(struct idxd_wq *idxd_wq)
110 {
111 	struct iaa_wq *wq = idxd_wq_get_private(idxd_wq);
112 
113 	wq->decomp_calls++;
114 	wq->iaa_device->decomp_calls++;
115 }
116 
117 void update_wq_decomp_bytes(struct idxd_wq *idxd_wq, int n)
118 {
119 	struct iaa_wq *wq = idxd_wq_get_private(idxd_wq);
120 
121 	wq->decomp_bytes += n;
122 	wq->iaa_device->decomp_bytes += n;
123 }
124 
125 static void reset_iaa_crypto_stats(void)
126 {
127 	total_comp_calls = 0;
128 	total_decomp_calls = 0;
129 	total_sw_decomp_calls = 0;
130 	max_comp_delay_ns = 0;
131 	max_decomp_delay_ns = 0;
132 	total_comp_bytes_out = 0;
133 	total_decomp_bytes_in = 0;
134 	total_completion_einval_errors = 0;
135 	total_completion_timeout_errors = 0;
136 	total_completion_comp_buf_overflow_errors = 0;
137 }
138 
139 static void reset_wq_stats(struct iaa_wq *wq)
140 {
141 	wq->comp_calls = 0;
142 	wq->comp_bytes = 0;
143 	wq->decomp_calls = 0;
144 	wq->decomp_bytes = 0;
145 }
146 
147 static void reset_device_stats(struct iaa_device *iaa_device)
148 {
149 	struct iaa_wq *iaa_wq;
150 
151 	iaa_device->comp_calls = 0;
152 	iaa_device->comp_bytes = 0;
153 	iaa_device->decomp_calls = 0;
154 	iaa_device->decomp_bytes = 0;
155 
156 	list_for_each_entry(iaa_wq, &iaa_device->wqs, list)
157 		reset_wq_stats(iaa_wq);
158 }
159 
160 static void wq_show(struct seq_file *m, struct iaa_wq *iaa_wq)
161 {
162 	seq_printf(m, "    name: %s\n", iaa_wq->wq->name);
163 	seq_printf(m, "    comp_calls: %llu\n", iaa_wq->comp_calls);
164 	seq_printf(m, "    comp_bytes: %llu\n", iaa_wq->comp_bytes);
165 	seq_printf(m, "    decomp_calls: %llu\n", iaa_wq->decomp_calls);
166 	seq_printf(m, "    decomp_bytes: %llu\n\n", iaa_wq->decomp_bytes);
167 }
168 
169 static void device_stats_show(struct seq_file *m, struct iaa_device *iaa_device)
170 {
171 	struct iaa_wq *iaa_wq;
172 
173 	seq_puts(m, "iaa device:\n");
174 	seq_printf(m, "  id: %d\n", iaa_device->idxd->id);
175 	seq_printf(m, "  n_wqs: %d\n", iaa_device->n_wq);
176 	seq_printf(m, "  comp_calls: %llu\n", iaa_device->comp_calls);
177 	seq_printf(m, "  comp_bytes: %llu\n", iaa_device->comp_bytes);
178 	seq_printf(m, "  decomp_calls: %llu\n", iaa_device->decomp_calls);
179 	seq_printf(m, "  decomp_bytes: %llu\n", iaa_device->decomp_bytes);
180 	seq_puts(m, "  wqs:\n");
181 
182 	list_for_each_entry(iaa_wq, &iaa_device->wqs, list)
183 		wq_show(m, iaa_wq);
184 }
185 
186 static void global_stats_show(struct seq_file *m)
187 {
188 	seq_puts(m, "global stats:\n");
189 	seq_printf(m, "  total_comp_calls: %llu\n", total_comp_calls);
190 	seq_printf(m, "  total_decomp_calls: %llu\n", total_decomp_calls);
191 	seq_printf(m, "  total_sw_decomp_calls: %llu\n", total_sw_decomp_calls);
192 	seq_printf(m, "  total_comp_bytes_out: %llu\n", total_comp_bytes_out);
193 	seq_printf(m, "  total_decomp_bytes_in: %llu\n", total_decomp_bytes_in);
194 	seq_printf(m, "  total_completion_einval_errors: %llu\n",
195 		   total_completion_einval_errors);
196 	seq_printf(m, "  total_completion_timeout_errors: %llu\n",
197 		   total_completion_timeout_errors);
198 	seq_printf(m, "  total_completion_comp_buf_overflow_errors: %llu\n\n",
199 		   total_completion_comp_buf_overflow_errors);
200 }
201 
202 static int wq_stats_show(struct seq_file *m, void *v)
203 {
204 	struct iaa_device *iaa_device;
205 
206 	mutex_lock(&iaa_devices_lock);
207 
208 	global_stats_show(m);
209 
210 	list_for_each_entry(iaa_device, &iaa_devices, list)
211 		device_stats_show(m, iaa_device);
212 
213 	mutex_unlock(&iaa_devices_lock);
214 
215 	return 0;
216 }
217 
218 static int iaa_crypto_stats_reset(void *data, u64 value)
219 {
220 	struct iaa_device *iaa_device;
221 
222 	reset_iaa_crypto_stats();
223 
224 	mutex_lock(&iaa_devices_lock);
225 
226 	list_for_each_entry(iaa_device, &iaa_devices, list)
227 		reset_device_stats(iaa_device);
228 
229 	mutex_unlock(&iaa_devices_lock);
230 
231 	return 0;
232 }
233 
234 static int wq_stats_open(struct inode *inode, struct file *file)
235 {
236 	return single_open(file, wq_stats_show, file);
237 }
238 
239 static const struct file_operations wq_stats_fops = {
240 	.open = wq_stats_open,
241 	.read = seq_read,
242 	.llseek = seq_lseek,
243 	.release = single_release,
244 };
245 
246 DEFINE_DEBUGFS_ATTRIBUTE(wq_stats_reset_fops, NULL, iaa_crypto_stats_reset, "%llu\n");
247 
248 int __init iaa_crypto_debugfs_init(void)
249 {
250 	if (!debugfs_initialized())
251 		return -ENODEV;
252 
253 	iaa_crypto_debugfs_root = debugfs_create_dir("iaa_crypto", NULL);
254 
255 	debugfs_create_u64("max_comp_delay_ns", 0644,
256 			   iaa_crypto_debugfs_root, &max_comp_delay_ns);
257 	debugfs_create_u64("max_decomp_delay_ns", 0644,
258 			   iaa_crypto_debugfs_root, &max_decomp_delay_ns);
259 	debugfs_create_u64("total_comp_calls", 0644,
260 			   iaa_crypto_debugfs_root, &total_comp_calls);
261 	debugfs_create_u64("total_decomp_calls", 0644,
262 			   iaa_crypto_debugfs_root, &total_decomp_calls);
263 	debugfs_create_u64("total_sw_decomp_calls", 0644,
264 			   iaa_crypto_debugfs_root, &total_sw_decomp_calls);
265 	debugfs_create_u64("total_comp_bytes_out", 0644,
266 			   iaa_crypto_debugfs_root, &total_comp_bytes_out);
267 	debugfs_create_u64("total_decomp_bytes_in", 0644,
268 			   iaa_crypto_debugfs_root, &total_decomp_bytes_in);
269 	debugfs_create_file("wq_stats", 0644, iaa_crypto_debugfs_root, NULL,
270 			    &wq_stats_fops);
271 	debugfs_create_file("stats_reset", 0644, iaa_crypto_debugfs_root, NULL,
272 			    &wq_stats_reset_fops);
273 
274 	return 0;
275 }
276 
277 void __exit iaa_crypto_debugfs_cleanup(void)
278 {
279 	debugfs_remove_recursive(iaa_crypto_debugfs_root);
280 }
281 
282 MODULE_LICENSE("GPL");
283