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