snic_debugfs.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. // Copyright 2014 Cisco Systems, Inc. All rights reserved.
  3. #include <linux/module.h>
  4. #include <linux/errno.h>
  5. #include <linux/debugfs.h>
  6. #include "snic.h"
  7. /*
  8. * snic_debugfs_init - Initialize debugfs for snic debug logging
  9. *
  10. * Description:
  11. * When Debugfs is configured this routine sets up fnic debugfs
  12. * filesystem. If not already created. this routine will crate the
  13. * fnic directory and statistics directory for trace buffer and
  14. * stats logging
  15. */
  16. void snic_debugfs_init(void)
  17. {
  18. snic_glob->trc_root = debugfs_create_dir("snic", NULL);
  19. snic_glob->stats_root = debugfs_create_dir("statistics",
  20. snic_glob->trc_root);
  21. }
  22. /*
  23. * snic_debugfs_term - Tear down debugfs intrastructure
  24. *
  25. * Description:
  26. * When Debufs is configured this routine removes debugfs file system
  27. * elements that are specific to snic
  28. */
  29. void
  30. snic_debugfs_term(void)
  31. {
  32. debugfs_remove(snic_glob->stats_root);
  33. snic_glob->stats_root = NULL;
  34. debugfs_remove(snic_glob->trc_root);
  35. snic_glob->trc_root = NULL;
  36. }
  37. /*
  38. * snic_reset_stats_open - Open the reset_stats file
  39. */
  40. static int
  41. snic_reset_stats_open(struct inode *inode, struct file *filp)
  42. {
  43. SNIC_BUG_ON(!inode->i_private);
  44. filp->private_data = inode->i_private;
  45. return 0;
  46. }
  47. /*
  48. * snic_reset_stats_read - Read a reset_stats debugfs file
  49. * @filp: The file pointer to read from.
  50. * @ubuf: The buffer tocopy the data to.
  51. * @cnt: The number of bytes to read.
  52. * @ppos: The position in the file to start reading frm.
  53. *
  54. * Description:
  55. * This routine reads value of variable reset_stats
  56. * and stores into local @buf. It will start reading file @ppos and
  57. * copy up to @cnt of data to @ubuf from @buf.
  58. *
  59. * Returns:
  60. * This function returns the amount of data that was read.
  61. */
  62. static ssize_t
  63. snic_reset_stats_read(struct file *filp,
  64. char __user *ubuf,
  65. size_t cnt,
  66. loff_t *ppos)
  67. {
  68. struct snic *snic = (struct snic *) filp->private_data;
  69. char buf[64];
  70. int len;
  71. len = sprintf(buf, "%u\n", snic->reset_stats);
  72. return simple_read_from_buffer(ubuf, cnt, ppos, buf, len);
  73. }
  74. /*
  75. * snic_reset_stats_write - Write to reset_stats debugfs file
  76. * @filp: The file pointer to write from
  77. * @ubuf: The buffer to copy the data from.
  78. * @cnt: The number of bytes to write.
  79. * @ppos: The position in the file to start writing to.
  80. *
  81. * Description:
  82. * This routine writes data from user buffer @ubuf to buffer @buf and
  83. * resets cumulative stats of snic.
  84. *
  85. * Returns:
  86. * This function returns the amount of data that was written.
  87. */
  88. static ssize_t
  89. snic_reset_stats_write(struct file *filp,
  90. const char __user *ubuf,
  91. size_t cnt,
  92. loff_t *ppos)
  93. {
  94. struct snic *snic = (struct snic *) filp->private_data;
  95. struct snic_stats *stats = &snic->s_stats;
  96. u64 *io_stats_p = (u64 *) &stats->io;
  97. u64 *fw_stats_p = (u64 *) &stats->fw;
  98. char buf[64];
  99. unsigned long val;
  100. int ret;
  101. if (cnt >= sizeof(buf))
  102. return -EINVAL;
  103. if (copy_from_user(&buf, ubuf, cnt))
  104. return -EFAULT;
  105. buf[cnt] = '\0';
  106. ret = kstrtoul(buf, 10, &val);
  107. if (ret < 0)
  108. return ret;
  109. snic->reset_stats = val;
  110. if (snic->reset_stats) {
  111. /* Skip variable is used to avoid descrepancies to Num IOs
  112. * and IO Completions stats. Skip incrementing No IO Compls
  113. * for pending active IOs after reset_stats
  114. */
  115. atomic64_set(&snic->io_cmpl_skip,
  116. atomic64_read(&stats->io.active));
  117. memset(&stats->abts, 0, sizeof(struct snic_abort_stats));
  118. memset(&stats->reset, 0, sizeof(struct snic_reset_stats));
  119. memset(&stats->misc, 0, sizeof(struct snic_misc_stats));
  120. memset(io_stats_p+1,
  121. 0,
  122. sizeof(struct snic_io_stats) - sizeof(u64));
  123. memset(fw_stats_p+1,
  124. 0,
  125. sizeof(struct snic_fw_stats) - sizeof(u64));
  126. }
  127. (*ppos)++;
  128. SNIC_HOST_INFO(snic->shost, "Reset Op: Driver statistics.\n");
  129. return cnt;
  130. }
  131. static int
  132. snic_reset_stats_release(struct inode *inode, struct file *filp)
  133. {
  134. filp->private_data = NULL;
  135. return 0;
  136. }
  137. /*
  138. * snic_stats_show - Formats and prints per host specific driver stats.
  139. */
  140. static int
  141. snic_stats_show(struct seq_file *sfp, void *data)
  142. {
  143. struct snic *snic = (struct snic *) sfp->private;
  144. struct snic_stats *stats = &snic->s_stats;
  145. struct timespec64 last_isr_tms, last_ack_tms;
  146. u64 maxio_tm;
  147. int i;
  148. /* Dump IO Stats */
  149. seq_printf(sfp,
  150. "------------------------------------------\n"
  151. "\t\t IO Statistics\n"
  152. "------------------------------------------\n");
  153. maxio_tm = (u64) atomic64_read(&stats->io.max_time);
  154. seq_printf(sfp,
  155. "Active IOs : %lld\n"
  156. "Max Active IOs : %lld\n"
  157. "Total IOs : %lld\n"
  158. "IOs Completed : %lld\n"
  159. "IOs Failed : %lld\n"
  160. "IOs Not Found : %lld\n"
  161. "Memory Alloc Failures : %lld\n"
  162. "REQs Null : %lld\n"
  163. "SCSI Cmd Pointers Null : %lld\n"
  164. "Max SGL for any IO : %lld\n"
  165. "Max IO Size : %lld Sectors\n"
  166. "Max Queuing Time : %lld\n"
  167. "Max Completion Time : %lld\n"
  168. "Max IO Process Time(FW) : %lld (%u msec)\n",
  169. (u64) atomic64_read(&stats->io.active),
  170. (u64) atomic64_read(&stats->io.max_active),
  171. (u64) atomic64_read(&stats->io.num_ios),
  172. (u64) atomic64_read(&stats->io.compl),
  173. (u64) atomic64_read(&stats->io.fail),
  174. (u64) atomic64_read(&stats->io.io_not_found),
  175. (u64) atomic64_read(&stats->io.alloc_fail),
  176. (u64) atomic64_read(&stats->io.req_null),
  177. (u64) atomic64_read(&stats->io.sc_null),
  178. (u64) atomic64_read(&stats->io.max_sgl),
  179. (u64) atomic64_read(&stats->io.max_io_sz),
  180. (u64) atomic64_read(&stats->io.max_qtime),
  181. (u64) atomic64_read(&stats->io.max_cmpl_time),
  182. maxio_tm,
  183. jiffies_to_msecs(maxio_tm));
  184. seq_puts(sfp, "\nSGL Counters\n");
  185. for (i = 0; i < SNIC_MAX_SG_DESC_CNT; i++) {
  186. seq_printf(sfp,
  187. "%10lld ",
  188. (u64) atomic64_read(&stats->io.sgl_cnt[i]));
  189. if ((i + 1) % 8 == 0)
  190. seq_puts(sfp, "\n");
  191. }
  192. /* Dump Abort Stats */
  193. seq_printf(sfp,
  194. "\n-------------------------------------------\n"
  195. "\t\t Abort Statistics\n"
  196. "---------------------------------------------\n");
  197. seq_printf(sfp,
  198. "Aborts : %lld\n"
  199. "Aborts Fail : %lld\n"
  200. "Aborts Driver Timeout : %lld\n"
  201. "Abort FW Timeout : %lld\n"
  202. "Abort IO NOT Found : %lld\n"
  203. "Abort Queuing Failed : %lld\n",
  204. (u64) atomic64_read(&stats->abts.num),
  205. (u64) atomic64_read(&stats->abts.fail),
  206. (u64) atomic64_read(&stats->abts.drv_tmo),
  207. (u64) atomic64_read(&stats->abts.fw_tmo),
  208. (u64) atomic64_read(&stats->abts.io_not_found),
  209. (u64) atomic64_read(&stats->abts.q_fail));
  210. /* Dump Reset Stats */
  211. seq_printf(sfp,
  212. "\n-------------------------------------------\n"
  213. "\t\t Reset Statistics\n"
  214. "---------------------------------------------\n");
  215. seq_printf(sfp,
  216. "HBA Resets : %lld\n"
  217. "HBA Reset Cmpls : %lld\n"
  218. "HBA Reset Fail : %lld\n",
  219. (u64) atomic64_read(&stats->reset.hba_resets),
  220. (u64) atomic64_read(&stats->reset.hba_reset_cmpl),
  221. (u64) atomic64_read(&stats->reset.hba_reset_fail));
  222. /* Dump Firmware Stats */
  223. seq_printf(sfp,
  224. "\n-------------------------------------------\n"
  225. "\t\t Firmware Statistics\n"
  226. "---------------------------------------------\n");
  227. seq_printf(sfp,
  228. "Active FW Requests : %lld\n"
  229. "Max FW Requests : %lld\n"
  230. "FW Out Of Resource Errs : %lld\n"
  231. "FW IO Errors : %lld\n"
  232. "FW SCSI Errors : %lld\n",
  233. (u64) atomic64_read(&stats->fw.actv_reqs),
  234. (u64) atomic64_read(&stats->fw.max_actv_reqs),
  235. (u64) atomic64_read(&stats->fw.out_of_res),
  236. (u64) atomic64_read(&stats->fw.io_errs),
  237. (u64) atomic64_read(&stats->fw.scsi_errs));
  238. /* Dump Miscellenous Stats */
  239. seq_printf(sfp,
  240. "\n---------------------------------------------\n"
  241. "\t\t Other Statistics\n"
  242. "\n---------------------------------------------\n");
  243. jiffies_to_timespec64(stats->misc.last_isr_time, &last_isr_tms);
  244. jiffies_to_timespec64(stats->misc.last_ack_time, &last_ack_tms);
  245. seq_printf(sfp,
  246. "Last ISR Time : %llu (%8llu.%09lu)\n"
  247. "Last Ack Time : %llu (%8llu.%09lu)\n"
  248. "Ack ISRs : %llu\n"
  249. "IO Cmpl ISRs : %llu\n"
  250. "Err Notify ISRs : %llu\n"
  251. "Max CQ Entries : %lld\n"
  252. "Data Count Mismatch : %lld\n"
  253. "IOs w/ Timeout Status : %lld\n"
  254. "IOs w/ Aborted Status : %lld\n"
  255. "IOs w/ SGL Invalid Stat : %lld\n"
  256. "WQ Desc Alloc Fail : %lld\n"
  257. "Queue Full : %lld\n"
  258. "Queue Ramp Up : %lld\n"
  259. "Queue Ramp Down : %lld\n"
  260. "Queue Last Queue Depth : %lld\n"
  261. "Target Not Ready : %lld\n",
  262. (u64) stats->misc.last_isr_time,
  263. last_isr_tms.tv_sec, last_isr_tms.tv_nsec,
  264. (u64)stats->misc.last_ack_time,
  265. last_ack_tms.tv_sec, last_ack_tms.tv_nsec,
  266. (u64) atomic64_read(&stats->misc.ack_isr_cnt),
  267. (u64) atomic64_read(&stats->misc.cmpl_isr_cnt),
  268. (u64) atomic64_read(&stats->misc.errnotify_isr_cnt),
  269. (u64) atomic64_read(&stats->misc.max_cq_ents),
  270. (u64) atomic64_read(&stats->misc.data_cnt_mismat),
  271. (u64) atomic64_read(&stats->misc.io_tmo),
  272. (u64) atomic64_read(&stats->misc.io_aborted),
  273. (u64) atomic64_read(&stats->misc.sgl_inval),
  274. (u64) atomic64_read(&stats->misc.wq_alloc_fail),
  275. (u64) atomic64_read(&stats->misc.qfull),
  276. (u64) atomic64_read(&stats->misc.qsz_rampup),
  277. (u64) atomic64_read(&stats->misc.qsz_rampdown),
  278. (u64) atomic64_read(&stats->misc.last_qsz),
  279. (u64) atomic64_read(&stats->misc.tgt_not_rdy));
  280. return 0;
  281. }
  282. DEFINE_SHOW_ATTRIBUTE(snic_stats);
  283. static const struct file_operations snic_reset_stats_fops = {
  284. .owner = THIS_MODULE,
  285. .open = snic_reset_stats_open,
  286. .read = snic_reset_stats_read,
  287. .write = snic_reset_stats_write,
  288. .release = snic_reset_stats_release,
  289. };
  290. /*
  291. * snic_stats_init - Initialize stats struct and create stats file
  292. * per snic
  293. *
  294. * Description:
  295. * When debugfs is cofigured this routine sets up the stats file per snic
  296. * It will create file stats and reset_stats under statistics/host# directory
  297. * to log per snic stats
  298. */
  299. void snic_stats_debugfs_init(struct snic *snic)
  300. {
  301. char name[16];
  302. snprintf(name, sizeof(name), "host%d", snic->shost->host_no);
  303. snic->stats_host = debugfs_create_dir(name, snic_glob->stats_root);
  304. snic->stats_file = debugfs_create_file("stats", S_IFREG|S_IRUGO,
  305. snic->stats_host, snic,
  306. &snic_stats_fops);
  307. snic->reset_stats_file = debugfs_create_file("reset_stats",
  308. S_IFREG|S_IRUGO|S_IWUSR,
  309. snic->stats_host, snic,
  310. &snic_reset_stats_fops);
  311. }
  312. /*
  313. * snic_stats_debugfs_remove - Tear down debugfs infrastructure of stats
  314. *
  315. * Description:
  316. * When Debufs is configured this routine removes debugfs file system
  317. * elements that are specific to to snic stats
  318. */
  319. void
  320. snic_stats_debugfs_remove(struct snic *snic)
  321. {
  322. debugfs_remove(snic->stats_file);
  323. snic->stats_file = NULL;
  324. debugfs_remove(snic->reset_stats_file);
  325. snic->reset_stats_file = NULL;
  326. debugfs_remove(snic->stats_host);
  327. snic->stats_host = NULL;
  328. }
  329. /* Trace Facility related API */
  330. static void *
  331. snic_trc_seq_start(struct seq_file *sfp, loff_t *pos)
  332. {
  333. return &snic_glob->trc;
  334. }
  335. static void *
  336. snic_trc_seq_next(struct seq_file *sfp, void *data, loff_t *pos)
  337. {
  338. return NULL;
  339. }
  340. static void
  341. snic_trc_seq_stop(struct seq_file *sfp, void *data)
  342. {
  343. }
  344. #define SNIC_TRC_PBLEN 256
  345. static int
  346. snic_trc_seq_show(struct seq_file *sfp, void *data)
  347. {
  348. char buf[SNIC_TRC_PBLEN];
  349. if (snic_get_trc_data(buf, SNIC_TRC_PBLEN) > 0)
  350. seq_printf(sfp, "%s\n", buf);
  351. return 0;
  352. }
  353. static const struct seq_operations snic_trc_sops = {
  354. .start = snic_trc_seq_start,
  355. .next = snic_trc_seq_next,
  356. .stop = snic_trc_seq_stop,
  357. .show = snic_trc_seq_show,
  358. };
  359. DEFINE_SEQ_ATTRIBUTE(snic_trc);
  360. #define TRC_ENABLE_FILE "tracing_enable"
  361. #define TRC_FILE "trace"
  362. /*
  363. * snic_trc_debugfs_init : creates trace/tracing_enable files for trace
  364. * under debugfs
  365. */
  366. void snic_trc_debugfs_init(void)
  367. {
  368. debugfs_create_bool(TRC_ENABLE_FILE, S_IFREG | S_IRUGO | S_IWUSR,
  369. snic_glob->trc_root, &snic_glob->trc.enable);
  370. debugfs_create_file(TRC_FILE, S_IFREG | S_IRUGO | S_IWUSR,
  371. snic_glob->trc_root, NULL, &snic_trc_fops);
  372. }
  373. /*
  374. * snic_trc_debugfs_term : cleans up the files created for trace under debugfs
  375. */
  376. void
  377. snic_trc_debugfs_term(void)
  378. {
  379. debugfs_lookup_and_remove(TRC_FILE, snic_glob->trc_root);
  380. debugfs_lookup_and_remove(TRC_ENABLE_FILE, snic_glob->trc_root);
  381. }