qedf_debugfs.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  1. /*
  2. * QLogic FCoE Offload Driver
  3. * Copyright (c) 2016-2018 QLogic Corporation
  4. *
  5. * This software is available under the terms of the GNU General Public License
  6. * (GPL) Version 2, available from the file COPYING in the main directory of
  7. * this source tree.
  8. */
  9. #ifdef CONFIG_DEBUG_FS
  10. #include <linux/uaccess.h>
  11. #include <linux/debugfs.h>
  12. #include <linux/module.h>
  13. #include "qedf.h"
  14. #include "qedf_dbg.h"
  15. static struct dentry *qedf_dbg_root;
  16. /**
  17. * qedf_dbg_host_init - setup the debugfs file for the pf
  18. * @pf: the pf that is starting up
  19. **/
  20. void
  21. qedf_dbg_host_init(struct qedf_dbg_ctx *qedf,
  22. const struct qedf_debugfs_ops *dops,
  23. const struct file_operations *fops)
  24. {
  25. char host_dirname[32];
  26. struct dentry *file_dentry = NULL;
  27. QEDF_INFO(qedf, QEDF_LOG_DEBUGFS, "Creating debugfs host node\n");
  28. /* create pf dir */
  29. sprintf(host_dirname, "host%u", qedf->host_no);
  30. qedf->bdf_dentry = debugfs_create_dir(host_dirname, qedf_dbg_root);
  31. if (!qedf->bdf_dentry)
  32. return;
  33. /* create debugfs files */
  34. while (dops) {
  35. if (!(dops->name))
  36. break;
  37. file_dentry = debugfs_create_file(dops->name, 0600,
  38. qedf->bdf_dentry, qedf,
  39. fops);
  40. if (!file_dentry) {
  41. QEDF_INFO(qedf, QEDF_LOG_DEBUGFS,
  42. "Debugfs entry %s creation failed\n",
  43. dops->name);
  44. debugfs_remove_recursive(qedf->bdf_dentry);
  45. return;
  46. }
  47. dops++;
  48. fops++;
  49. }
  50. }
  51. /**
  52. * qedf_dbg_host_exit - clear out the pf's debugfs entries
  53. * @pf: the pf that is stopping
  54. **/
  55. void
  56. qedf_dbg_host_exit(struct qedf_dbg_ctx *qedf)
  57. {
  58. QEDF_INFO(qedf, QEDF_LOG_DEBUGFS, "Destroying debugfs host "
  59. "entry\n");
  60. /* remove debugfs entries of this PF */
  61. debugfs_remove_recursive(qedf->bdf_dentry);
  62. qedf->bdf_dentry = NULL;
  63. }
  64. /**
  65. * qedf_dbg_init - start up debugfs for the driver
  66. **/
  67. void
  68. qedf_dbg_init(char *drv_name)
  69. {
  70. QEDF_INFO(NULL, QEDF_LOG_DEBUGFS, "Creating debugfs root node\n");
  71. /* create qed dir in root of debugfs. NULL means debugfs root */
  72. qedf_dbg_root = debugfs_create_dir(drv_name, NULL);
  73. if (!qedf_dbg_root)
  74. QEDF_INFO(NULL, QEDF_LOG_DEBUGFS, "Init of debugfs "
  75. "failed\n");
  76. }
  77. /**
  78. * qedf_dbg_exit - clean out the driver's debugfs entries
  79. **/
  80. void
  81. qedf_dbg_exit(void)
  82. {
  83. QEDF_INFO(NULL, QEDF_LOG_DEBUGFS, "Destroying debugfs root "
  84. "entry\n");
  85. /* remove qed dir in root of debugfs */
  86. debugfs_remove_recursive(qedf_dbg_root);
  87. qedf_dbg_root = NULL;
  88. }
  89. const struct qedf_debugfs_ops qedf_debugfs_ops[] = {
  90. { "fp_int", NULL },
  91. { "io_trace", NULL },
  92. { "debug", NULL },
  93. { "stop_io_on_error", NULL},
  94. { "driver_stats", NULL},
  95. { "clear_stats", NULL},
  96. { "offload_stats", NULL},
  97. /* This must be last */
  98. { NULL, NULL }
  99. };
  100. DECLARE_PER_CPU(struct qedf_percpu_iothread_s, qedf_percpu_iothreads);
  101. static ssize_t
  102. qedf_dbg_fp_int_cmd_read(struct file *filp, char __user *buffer, size_t count,
  103. loff_t *ppos)
  104. {
  105. size_t cnt = 0;
  106. int id;
  107. struct qedf_fastpath *fp = NULL;
  108. struct qedf_dbg_ctx *qedf_dbg =
  109. (struct qedf_dbg_ctx *)filp->private_data;
  110. struct qedf_ctx *qedf = container_of(qedf_dbg,
  111. struct qedf_ctx, dbg_ctx);
  112. QEDF_INFO(qedf_dbg, QEDF_LOG_DEBUGFS, "entered\n");
  113. cnt = sprintf(buffer, "\nFastpath I/O completions\n\n");
  114. for (id = 0; id < qedf->num_queues; id++) {
  115. fp = &(qedf->fp_array[id]);
  116. if (fp->sb_id == QEDF_SB_ID_NULL)
  117. continue;
  118. cnt += sprintf((buffer + cnt), "#%d: %lu\n", id,
  119. fp->completions);
  120. }
  121. cnt = min_t(int, count, cnt - *ppos);
  122. *ppos += cnt;
  123. return cnt;
  124. }
  125. static ssize_t
  126. qedf_dbg_fp_int_cmd_write(struct file *filp, const char __user *buffer,
  127. size_t count, loff_t *ppos)
  128. {
  129. if (!count || *ppos)
  130. return 0;
  131. return count;
  132. }
  133. static ssize_t
  134. qedf_dbg_debug_cmd_read(struct file *filp, char __user *buffer, size_t count,
  135. loff_t *ppos)
  136. {
  137. int cnt;
  138. struct qedf_dbg_ctx *qedf =
  139. (struct qedf_dbg_ctx *)filp->private_data;
  140. QEDF_INFO(qedf, QEDF_LOG_DEBUGFS, "entered\n");
  141. cnt = sprintf(buffer, "debug mask = 0x%x\n", qedf_debug);
  142. cnt = min_t(int, count, cnt - *ppos);
  143. *ppos += cnt;
  144. return cnt;
  145. }
  146. static ssize_t
  147. qedf_dbg_debug_cmd_write(struct file *filp, const char __user *buffer,
  148. size_t count, loff_t *ppos)
  149. {
  150. uint32_t val;
  151. void *kern_buf;
  152. int rval;
  153. struct qedf_dbg_ctx *qedf =
  154. (struct qedf_dbg_ctx *)filp->private_data;
  155. if (!count || *ppos)
  156. return 0;
  157. kern_buf = memdup_user(buffer, count);
  158. if (IS_ERR(kern_buf))
  159. return PTR_ERR(kern_buf);
  160. rval = kstrtouint(kern_buf, 10, &val);
  161. kfree(kern_buf);
  162. if (rval)
  163. return rval;
  164. if (val == 1)
  165. qedf_debug = QEDF_DEFAULT_LOG_MASK;
  166. else
  167. qedf_debug = val;
  168. QEDF_INFO(qedf, QEDF_LOG_DEBUGFS, "Setting debug=0x%x.\n", val);
  169. return count;
  170. }
  171. static ssize_t
  172. qedf_dbg_stop_io_on_error_cmd_read(struct file *filp, char __user *buffer,
  173. size_t count, loff_t *ppos)
  174. {
  175. int cnt;
  176. struct qedf_dbg_ctx *qedf_dbg =
  177. (struct qedf_dbg_ctx *)filp->private_data;
  178. struct qedf_ctx *qedf = container_of(qedf_dbg,
  179. struct qedf_ctx, dbg_ctx);
  180. QEDF_INFO(qedf_dbg, QEDF_LOG_DEBUGFS, "entered\n");
  181. cnt = sprintf(buffer, "%s\n",
  182. qedf->stop_io_on_error ? "true" : "false");
  183. cnt = min_t(int, count, cnt - *ppos);
  184. *ppos += cnt;
  185. return cnt;
  186. }
  187. static ssize_t
  188. qedf_dbg_stop_io_on_error_cmd_write(struct file *filp,
  189. const char __user *buffer, size_t count,
  190. loff_t *ppos)
  191. {
  192. void *kern_buf;
  193. struct qedf_dbg_ctx *qedf_dbg =
  194. (struct qedf_dbg_ctx *)filp->private_data;
  195. struct qedf_ctx *qedf = container_of(qedf_dbg, struct qedf_ctx,
  196. dbg_ctx);
  197. QEDF_INFO(qedf_dbg, QEDF_LOG_DEBUGFS, "entered\n");
  198. if (!count || *ppos)
  199. return 0;
  200. kern_buf = memdup_user(buffer, 6);
  201. if (IS_ERR(kern_buf))
  202. return PTR_ERR(kern_buf);
  203. if (strncmp(kern_buf, "false", 5) == 0)
  204. qedf->stop_io_on_error = false;
  205. else if (strncmp(kern_buf, "true", 4) == 0)
  206. qedf->stop_io_on_error = true;
  207. else if (strncmp(kern_buf, "now", 3) == 0)
  208. /* Trigger from user to stop all I/O on this host */
  209. set_bit(QEDF_DBG_STOP_IO, &qedf->flags);
  210. kfree(kern_buf);
  211. return count;
  212. }
  213. static int
  214. qedf_io_trace_show(struct seq_file *s, void *unused)
  215. {
  216. int i, idx = 0;
  217. struct qedf_ctx *qedf = s->private;
  218. struct qedf_dbg_ctx *qedf_dbg = &qedf->dbg_ctx;
  219. struct qedf_io_log *io_log;
  220. unsigned long flags;
  221. if (!qedf_io_tracing) {
  222. seq_puts(s, "I/O tracing not enabled.\n");
  223. goto out;
  224. }
  225. QEDF_INFO(qedf_dbg, QEDF_LOG_DEBUGFS, "entered\n");
  226. spin_lock_irqsave(&qedf->io_trace_lock, flags);
  227. idx = qedf->io_trace_idx;
  228. for (i = 0; i < QEDF_IO_TRACE_SIZE; i++) {
  229. io_log = &qedf->io_trace_buf[idx];
  230. seq_printf(s, "%d:", io_log->direction);
  231. seq_printf(s, "0x%x:", io_log->task_id);
  232. seq_printf(s, "0x%06x:", io_log->port_id);
  233. seq_printf(s, "%d:", io_log->lun);
  234. seq_printf(s, "0x%02x:", io_log->op);
  235. seq_printf(s, "0x%02x%02x%02x%02x:", io_log->lba[0],
  236. io_log->lba[1], io_log->lba[2], io_log->lba[3]);
  237. seq_printf(s, "%d:", io_log->bufflen);
  238. seq_printf(s, "%d:", io_log->sg_count);
  239. seq_printf(s, "0x%08x:", io_log->result);
  240. seq_printf(s, "%lu:", io_log->jiffies);
  241. seq_printf(s, "%d:", io_log->refcount);
  242. seq_printf(s, "%d:", io_log->req_cpu);
  243. seq_printf(s, "%d:", io_log->int_cpu);
  244. seq_printf(s, "%d:", io_log->rsp_cpu);
  245. seq_printf(s, "%d\n", io_log->sge_type);
  246. idx++;
  247. if (idx == QEDF_IO_TRACE_SIZE)
  248. idx = 0;
  249. }
  250. spin_unlock_irqrestore(&qedf->io_trace_lock, flags);
  251. out:
  252. return 0;
  253. }
  254. static int
  255. qedf_dbg_io_trace_open(struct inode *inode, struct file *file)
  256. {
  257. struct qedf_dbg_ctx *qedf_dbg = inode->i_private;
  258. struct qedf_ctx *qedf = container_of(qedf_dbg,
  259. struct qedf_ctx, dbg_ctx);
  260. return single_open(file, qedf_io_trace_show, qedf);
  261. }
  262. static int
  263. qedf_driver_stats_show(struct seq_file *s, void *unused)
  264. {
  265. struct qedf_ctx *qedf = s->private;
  266. struct qedf_rport *fcport;
  267. struct fc_rport_priv *rdata;
  268. seq_printf(s, "cmg_mgr free io_reqs: %d\n",
  269. atomic_read(&qedf->cmd_mgr->free_list_cnt));
  270. seq_printf(s, "slow SGEs: %d\n", qedf->slow_sge_ios);
  271. seq_printf(s, "single SGEs: %d\n", qedf->single_sge_ios);
  272. seq_printf(s, "fast SGEs: %d\n\n", qedf->fast_sge_ios);
  273. seq_puts(s, "Offloaded ports:\n\n");
  274. rcu_read_lock();
  275. list_for_each_entry_rcu(fcport, &qedf->fcports, peers) {
  276. rdata = fcport->rdata;
  277. if (rdata == NULL)
  278. continue;
  279. seq_printf(s, "%06x: free_sqes: %d, num_active_ios: %d\n",
  280. rdata->ids.port_id, atomic_read(&fcport->free_sqes),
  281. atomic_read(&fcport->num_active_ios));
  282. }
  283. rcu_read_unlock();
  284. return 0;
  285. }
  286. static int
  287. qedf_dbg_driver_stats_open(struct inode *inode, struct file *file)
  288. {
  289. struct qedf_dbg_ctx *qedf_dbg = inode->i_private;
  290. struct qedf_ctx *qedf = container_of(qedf_dbg,
  291. struct qedf_ctx, dbg_ctx);
  292. return single_open(file, qedf_driver_stats_show, qedf);
  293. }
  294. static ssize_t
  295. qedf_dbg_clear_stats_cmd_read(struct file *filp, char __user *buffer,
  296. size_t count, loff_t *ppos)
  297. {
  298. int cnt = 0;
  299. /* Essentially a read stub */
  300. cnt = min_t(int, count, cnt - *ppos);
  301. *ppos += cnt;
  302. return cnt;
  303. }
  304. static ssize_t
  305. qedf_dbg_clear_stats_cmd_write(struct file *filp,
  306. const char __user *buffer, size_t count,
  307. loff_t *ppos)
  308. {
  309. struct qedf_dbg_ctx *qedf_dbg =
  310. (struct qedf_dbg_ctx *)filp->private_data;
  311. struct qedf_ctx *qedf = container_of(qedf_dbg, struct qedf_ctx,
  312. dbg_ctx);
  313. QEDF_INFO(qedf_dbg, QEDF_LOG_DEBUGFS, "Clearing stat counters.\n");
  314. if (!count || *ppos)
  315. return 0;
  316. /* Clear stat counters exposed by 'stats' node */
  317. qedf->slow_sge_ios = 0;
  318. qedf->single_sge_ios = 0;
  319. qedf->fast_sge_ios = 0;
  320. return count;
  321. }
  322. static int
  323. qedf_offload_stats_show(struct seq_file *s, void *unused)
  324. {
  325. struct qedf_ctx *qedf = s->private;
  326. struct qed_fcoe_stats *fw_fcoe_stats;
  327. fw_fcoe_stats = kmalloc(sizeof(struct qed_fcoe_stats), GFP_KERNEL);
  328. if (!fw_fcoe_stats) {
  329. QEDF_ERR(&(qedf->dbg_ctx), "Could not allocate memory for "
  330. "fw_fcoe_stats.\n");
  331. goto out;
  332. }
  333. /* Query firmware for offload stats */
  334. qed_ops->get_stats(qedf->cdev, fw_fcoe_stats);
  335. seq_printf(s, "fcoe_rx_byte_cnt=%llu\n"
  336. "fcoe_rx_data_pkt_cnt=%llu\n"
  337. "fcoe_rx_xfer_pkt_cnt=%llu\n"
  338. "fcoe_rx_other_pkt_cnt=%llu\n"
  339. "fcoe_silent_drop_pkt_cmdq_full_cnt=%u\n"
  340. "fcoe_silent_drop_pkt_crc_error_cnt=%u\n"
  341. "fcoe_silent_drop_pkt_task_invalid_cnt=%u\n"
  342. "fcoe_silent_drop_total_pkt_cnt=%u\n"
  343. "fcoe_silent_drop_pkt_rq_full_cnt=%u\n"
  344. "fcoe_tx_byte_cnt=%llu\n"
  345. "fcoe_tx_data_pkt_cnt=%llu\n"
  346. "fcoe_tx_xfer_pkt_cnt=%llu\n"
  347. "fcoe_tx_other_pkt_cnt=%llu\n",
  348. fw_fcoe_stats->fcoe_rx_byte_cnt,
  349. fw_fcoe_stats->fcoe_rx_data_pkt_cnt,
  350. fw_fcoe_stats->fcoe_rx_xfer_pkt_cnt,
  351. fw_fcoe_stats->fcoe_rx_other_pkt_cnt,
  352. fw_fcoe_stats->fcoe_silent_drop_pkt_cmdq_full_cnt,
  353. fw_fcoe_stats->fcoe_silent_drop_pkt_crc_error_cnt,
  354. fw_fcoe_stats->fcoe_silent_drop_pkt_task_invalid_cnt,
  355. fw_fcoe_stats->fcoe_silent_drop_total_pkt_cnt,
  356. fw_fcoe_stats->fcoe_silent_drop_pkt_rq_full_cnt,
  357. fw_fcoe_stats->fcoe_tx_byte_cnt,
  358. fw_fcoe_stats->fcoe_tx_data_pkt_cnt,
  359. fw_fcoe_stats->fcoe_tx_xfer_pkt_cnt,
  360. fw_fcoe_stats->fcoe_tx_other_pkt_cnt);
  361. kfree(fw_fcoe_stats);
  362. out:
  363. return 0;
  364. }
  365. static int
  366. qedf_dbg_offload_stats_open(struct inode *inode, struct file *file)
  367. {
  368. struct qedf_dbg_ctx *qedf_dbg = inode->i_private;
  369. struct qedf_ctx *qedf = container_of(qedf_dbg,
  370. struct qedf_ctx, dbg_ctx);
  371. return single_open(file, qedf_offload_stats_show, qedf);
  372. }
  373. const struct file_operations qedf_dbg_fops[] = {
  374. qedf_dbg_fileops(qedf, fp_int),
  375. qedf_dbg_fileops_seq(qedf, io_trace),
  376. qedf_dbg_fileops(qedf, debug),
  377. qedf_dbg_fileops(qedf, stop_io_on_error),
  378. qedf_dbg_fileops_seq(qedf, driver_stats),
  379. qedf_dbg_fileops(qedf, clear_stats),
  380. qedf_dbg_fileops_seq(qedf, offload_stats),
  381. /* This must be last */
  382. { },
  383. };
  384. #else /* CONFIG_DEBUG_FS */
  385. void qedf_dbg_host_init(struct qedf_dbg_ctx *);
  386. void qedf_dbg_host_exit(struct qedf_dbg_ctx *);
  387. void qedf_dbg_init(char *);
  388. void qedf_dbg_exit(void);
  389. #endif /* CONFIG_DEBUG_FS */