2 * QLogic FCoE Offload Driver
3 * Copyright (c) 2016-2017 QLogic Corporation
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
11 #include <linux/uaccess.h>
12 #include <linux/debugfs.h>
13 #include <linux/module.h>
18 static struct dentry
*qedf_dbg_root
;
21 * qedf_dbg_host_init - setup the debugfs file for the pf
22 * @pf: the pf that is starting up
25 qedf_dbg_host_init(struct qedf_dbg_ctx
*qedf
,
26 struct qedf_debugfs_ops
*dops
,
27 struct file_operations
*fops
)
29 char host_dirname
[32];
30 struct dentry
*file_dentry
= NULL
;
32 QEDF_INFO(qedf
, QEDF_LOG_DEBUGFS
, "Creating debugfs host node\n");
34 sprintf(host_dirname
, "host%u", qedf
->host_no
);
35 qedf
->bdf_dentry
= debugfs_create_dir(host_dirname
, qedf_dbg_root
);
36 if (!qedf
->bdf_dentry
)
39 /* create debugfs files */
44 file_dentry
= debugfs_create_file(dops
->name
, 0600,
45 qedf
->bdf_dentry
, qedf
,
48 QEDF_INFO(qedf
, QEDF_LOG_DEBUGFS
,
49 "Debugfs entry %s creation failed\n",
51 debugfs_remove_recursive(qedf
->bdf_dentry
);
60 * qedf_dbg_host_exit - clear out the pf's debugfs entries
61 * @pf: the pf that is stopping
64 qedf_dbg_host_exit(struct qedf_dbg_ctx
*qedf
)
66 QEDF_INFO(qedf
, QEDF_LOG_DEBUGFS
, "Destroying debugfs host "
68 /* remove debugfs entries of this PF */
69 debugfs_remove_recursive(qedf
->bdf_dentry
);
70 qedf
->bdf_dentry
= NULL
;
74 * qedf_dbg_init - start up debugfs for the driver
77 qedf_dbg_init(char *drv_name
)
79 QEDF_INFO(NULL
, QEDF_LOG_DEBUGFS
, "Creating debugfs root node\n");
81 /* create qed dir in root of debugfs. NULL means debugfs root */
82 qedf_dbg_root
= debugfs_create_dir(drv_name
, NULL
);
84 QEDF_INFO(NULL
, QEDF_LOG_DEBUGFS
, "Init of debugfs "
89 * qedf_dbg_exit - clean out the driver's debugfs entries
94 QEDF_INFO(NULL
, QEDF_LOG_DEBUGFS
, "Destroying debugfs root "
97 /* remove qed dir in root of debugfs */
98 debugfs_remove_recursive(qedf_dbg_root
);
102 struct qedf_debugfs_ops qedf_debugfs_ops
[] = {
104 { "io_trace", NULL
},
106 { "stop_io_on_error", NULL
},
107 { "driver_stats", NULL
},
108 { "clear_stats", NULL
},
109 { "offload_stats", NULL
},
110 /* This must be last */
114 DECLARE_PER_CPU(struct qedf_percpu_iothread_s
, qedf_percpu_iothreads
);
117 qedf_dbg_fp_int_cmd_read(struct file
*filp
, char __user
*buffer
, size_t count
,
122 struct qedf_fastpath
*fp
= NULL
;
123 struct qedf_dbg_ctx
*qedf_dbg
=
124 (struct qedf_dbg_ctx
*)filp
->private_data
;
125 struct qedf_ctx
*qedf
= container_of(qedf_dbg
,
126 struct qedf_ctx
, dbg_ctx
);
128 QEDF_INFO(qedf_dbg
, QEDF_LOG_DEBUGFS
, "entered\n");
130 cnt
= sprintf(buffer
, "\nFastpath I/O completions\n\n");
132 for (id
= 0; id
< qedf
->num_queues
; id
++) {
133 fp
= &(qedf
->fp_array
[id
]);
134 if (fp
->sb_id
== QEDF_SB_ID_NULL
)
136 cnt
+= sprintf((buffer
+ cnt
), "#%d: %lu\n", id
,
140 cnt
= min_t(int, count
, cnt
- *ppos
);
146 qedf_dbg_fp_int_cmd_write(struct file
*filp
, const char __user
*buffer
,
147 size_t count
, loff_t
*ppos
)
156 qedf_dbg_debug_cmd_read(struct file
*filp
, char __user
*buffer
, size_t count
,
160 struct qedf_dbg_ctx
*qedf
=
161 (struct qedf_dbg_ctx
*)filp
->private_data
;
163 QEDF_INFO(qedf
, QEDF_LOG_DEBUGFS
, "entered\n");
164 cnt
= sprintf(buffer
, "debug mask = 0x%x\n", qedf_debug
);
166 cnt
= min_t(int, count
, cnt
- *ppos
);
172 qedf_dbg_debug_cmd_write(struct file
*filp
, const char __user
*buffer
,
173 size_t count
, loff_t
*ppos
)
178 struct qedf_dbg_ctx
*qedf
=
179 (struct qedf_dbg_ctx
*)filp
->private_data
;
184 kern_buf
= memdup_user(buffer
, count
);
185 if (IS_ERR(kern_buf
))
186 return PTR_ERR(kern_buf
);
188 rval
= kstrtouint(kern_buf
, 10, &val
);
194 qedf_debug
= QEDF_DEFAULT_LOG_MASK
;
198 QEDF_INFO(qedf
, QEDF_LOG_DEBUGFS
, "Setting debug=0x%x.\n", val
);
203 qedf_dbg_stop_io_on_error_cmd_read(struct file
*filp
, char __user
*buffer
,
204 size_t count
, loff_t
*ppos
)
207 struct qedf_dbg_ctx
*qedf_dbg
=
208 (struct qedf_dbg_ctx
*)filp
->private_data
;
209 struct qedf_ctx
*qedf
= container_of(qedf_dbg
,
210 struct qedf_ctx
, dbg_ctx
);
212 QEDF_INFO(qedf_dbg
, QEDF_LOG_DEBUGFS
, "entered\n");
213 cnt
= sprintf(buffer
, "%s\n",
214 qedf
->stop_io_on_error
? "true" : "false");
216 cnt
= min_t(int, count
, cnt
- *ppos
);
222 qedf_dbg_stop_io_on_error_cmd_write(struct file
*filp
,
223 const char __user
*buffer
, size_t count
,
227 struct qedf_dbg_ctx
*qedf_dbg
=
228 (struct qedf_dbg_ctx
*)filp
->private_data
;
229 struct qedf_ctx
*qedf
= container_of(qedf_dbg
, struct qedf_ctx
,
232 QEDF_INFO(qedf_dbg
, QEDF_LOG_DEBUGFS
, "entered\n");
237 kern_buf
= memdup_user(buffer
, 6);
238 if (IS_ERR(kern_buf
))
239 return PTR_ERR(kern_buf
);
241 if (strncmp(kern_buf
, "false", 5) == 0)
242 qedf
->stop_io_on_error
= false;
243 else if (strncmp(kern_buf
, "true", 4) == 0)
244 qedf
->stop_io_on_error
= true;
245 else if (strncmp(kern_buf
, "now", 3) == 0)
246 /* Trigger from user to stop all I/O on this host */
247 set_bit(QEDF_DBG_STOP_IO
, &qedf
->flags
);
254 qedf_io_trace_show(struct seq_file
*s
, void *unused
)
257 struct qedf_ctx
*qedf
= s
->private;
258 struct qedf_dbg_ctx
*qedf_dbg
= &qedf
->dbg_ctx
;
259 struct qedf_io_log
*io_log
;
262 if (!qedf_io_tracing
) {
263 seq_puts(s
, "I/O tracing not enabled.\n");
267 QEDF_INFO(qedf_dbg
, QEDF_LOG_DEBUGFS
, "entered\n");
269 spin_lock_irqsave(&qedf
->io_trace_lock
, flags
);
270 idx
= qedf
->io_trace_idx
;
271 for (i
= 0; i
< QEDF_IO_TRACE_SIZE
; i
++) {
272 io_log
= &qedf
->io_trace_buf
[idx
];
273 seq_printf(s
, "%d:", io_log
->direction
);
274 seq_printf(s
, "0x%x:", io_log
->task_id
);
275 seq_printf(s
, "0x%06x:", io_log
->port_id
);
276 seq_printf(s
, "%d:", io_log
->lun
);
277 seq_printf(s
, "0x%02x:", io_log
->op
);
278 seq_printf(s
, "0x%02x%02x%02x%02x:", io_log
->lba
[0],
279 io_log
->lba
[1], io_log
->lba
[2], io_log
->lba
[3]);
280 seq_printf(s
, "%d:", io_log
->bufflen
);
281 seq_printf(s
, "%d:", io_log
->sg_count
);
282 seq_printf(s
, "0x%08x:", io_log
->result
);
283 seq_printf(s
, "%lu:", io_log
->jiffies
);
284 seq_printf(s
, "%d:", io_log
->refcount
);
285 seq_printf(s
, "%d:", io_log
->req_cpu
);
286 seq_printf(s
, "%d:", io_log
->int_cpu
);
287 seq_printf(s
, "%d:", io_log
->rsp_cpu
);
288 seq_printf(s
, "%d\n", io_log
->sge_type
);
291 if (idx
== QEDF_IO_TRACE_SIZE
)
294 spin_unlock_irqrestore(&qedf
->io_trace_lock
, flags
);
301 qedf_dbg_io_trace_open(struct inode
*inode
, struct file
*file
)
303 struct qedf_dbg_ctx
*qedf_dbg
= inode
->i_private
;
304 struct qedf_ctx
*qedf
= container_of(qedf_dbg
,
305 struct qedf_ctx
, dbg_ctx
);
307 return single_open(file
, qedf_io_trace_show
, qedf
);
311 qedf_driver_stats_show(struct seq_file
*s
, void *unused
)
313 struct qedf_ctx
*qedf
= s
->private;
314 struct qedf_rport
*fcport
;
315 struct fc_rport_priv
*rdata
;
317 seq_printf(s
, "cmg_mgr free io_reqs: %d\n",
318 atomic_read(&qedf
->cmd_mgr
->free_list_cnt
));
319 seq_printf(s
, "slow SGEs: %d\n", qedf
->slow_sge_ios
);
320 seq_printf(s
, "single SGEs: %d\n", qedf
->single_sge_ios
);
321 seq_printf(s
, "fast SGEs: %d\n\n", qedf
->fast_sge_ios
);
323 seq_puts(s
, "Offloaded ports:\n\n");
326 list_for_each_entry_rcu(fcport
, &qedf
->fcports
, peers
) {
327 rdata
= fcport
->rdata
;
330 seq_printf(s
, "%06x: free_sqes: %d, num_active_ios: %d\n",
331 rdata
->ids
.port_id
, atomic_read(&fcport
->free_sqes
),
332 atomic_read(&fcport
->num_active_ios
));
340 qedf_dbg_driver_stats_open(struct inode
*inode
, struct file
*file
)
342 struct qedf_dbg_ctx
*qedf_dbg
= inode
->i_private
;
343 struct qedf_ctx
*qedf
= container_of(qedf_dbg
,
344 struct qedf_ctx
, dbg_ctx
);
346 return single_open(file
, qedf_driver_stats_show
, qedf
);
350 qedf_dbg_clear_stats_cmd_read(struct file
*filp
, char __user
*buffer
,
351 size_t count
, loff_t
*ppos
)
355 /* Essentially a read stub */
356 cnt
= min_t(int, count
, cnt
- *ppos
);
362 qedf_dbg_clear_stats_cmd_write(struct file
*filp
,
363 const char __user
*buffer
, size_t count
,
366 struct qedf_dbg_ctx
*qedf_dbg
=
367 (struct qedf_dbg_ctx
*)filp
->private_data
;
368 struct qedf_ctx
*qedf
= container_of(qedf_dbg
, struct qedf_ctx
,
371 QEDF_INFO(qedf_dbg
, QEDF_LOG_DEBUGFS
, "Clearing stat counters.\n");
376 /* Clear stat counters exposed by 'stats' node */
377 qedf
->slow_sge_ios
= 0;
378 qedf
->single_sge_ios
= 0;
379 qedf
->fast_sge_ios
= 0;
385 qedf_offload_stats_show(struct seq_file
*s
, void *unused
)
387 struct qedf_ctx
*qedf
= s
->private;
388 struct qed_fcoe_stats
*fw_fcoe_stats
;
390 fw_fcoe_stats
= kmalloc(sizeof(struct qed_fcoe_stats
), GFP_KERNEL
);
391 if (!fw_fcoe_stats
) {
392 QEDF_ERR(&(qedf
->dbg_ctx
), "Could not allocate memory for "
397 /* Query firmware for offload stats */
398 qed_ops
->get_stats(qedf
->cdev
, fw_fcoe_stats
);
400 seq_printf(s
, "fcoe_rx_byte_cnt=%llu\n"
401 "fcoe_rx_data_pkt_cnt=%llu\n"
402 "fcoe_rx_xfer_pkt_cnt=%llu\n"
403 "fcoe_rx_other_pkt_cnt=%llu\n"
404 "fcoe_silent_drop_pkt_cmdq_full_cnt=%u\n"
405 "fcoe_silent_drop_pkt_crc_error_cnt=%u\n"
406 "fcoe_silent_drop_pkt_task_invalid_cnt=%u\n"
407 "fcoe_silent_drop_total_pkt_cnt=%u\n"
408 "fcoe_silent_drop_pkt_rq_full_cnt=%u\n"
409 "fcoe_tx_byte_cnt=%llu\n"
410 "fcoe_tx_data_pkt_cnt=%llu\n"
411 "fcoe_tx_xfer_pkt_cnt=%llu\n"
412 "fcoe_tx_other_pkt_cnt=%llu\n",
413 fw_fcoe_stats
->fcoe_rx_byte_cnt
,
414 fw_fcoe_stats
->fcoe_rx_data_pkt_cnt
,
415 fw_fcoe_stats
->fcoe_rx_xfer_pkt_cnt
,
416 fw_fcoe_stats
->fcoe_rx_other_pkt_cnt
,
417 fw_fcoe_stats
->fcoe_silent_drop_pkt_cmdq_full_cnt
,
418 fw_fcoe_stats
->fcoe_silent_drop_pkt_crc_error_cnt
,
419 fw_fcoe_stats
->fcoe_silent_drop_pkt_task_invalid_cnt
,
420 fw_fcoe_stats
->fcoe_silent_drop_total_pkt_cnt
,
421 fw_fcoe_stats
->fcoe_silent_drop_pkt_rq_full_cnt
,
422 fw_fcoe_stats
->fcoe_tx_byte_cnt
,
423 fw_fcoe_stats
->fcoe_tx_data_pkt_cnt
,
424 fw_fcoe_stats
->fcoe_tx_xfer_pkt_cnt
,
425 fw_fcoe_stats
->fcoe_tx_other_pkt_cnt
);
427 kfree(fw_fcoe_stats
);
433 qedf_dbg_offload_stats_open(struct inode
*inode
, struct file
*file
)
435 struct qedf_dbg_ctx
*qedf_dbg
= inode
->i_private
;
436 struct qedf_ctx
*qedf
= container_of(qedf_dbg
,
437 struct qedf_ctx
, dbg_ctx
);
439 return single_open(file
, qedf_offload_stats_show
, qedf
);
443 const struct file_operations qedf_dbg_fops
[] = {
444 qedf_dbg_fileops(qedf
, fp_int
),
445 qedf_dbg_fileops_seq(qedf
, io_trace
),
446 qedf_dbg_fileops(qedf
, debug
),
447 qedf_dbg_fileops(qedf
, stop_io_on_error
),
448 qedf_dbg_fileops_seq(qedf
, driver_stats
),
449 qedf_dbg_fileops(qedf
, clear_stats
),
450 qedf_dbg_fileops_seq(qedf
, offload_stats
),
451 /* This must be last */
455 #else /* CONFIG_DEBUG_FS */
456 void qedf_dbg_host_init(struct qedf_dbg_ctx
*);
457 void qedf_dbg_host_exit(struct qedf_dbg_ctx
*);
458 void qedf_dbg_init(char *);
459 void qedf_dbg_exit(void);
460 #endif /* CONFIG_DEBUG_FS */