aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorHiral Patel <hiralpat@cisco.com>2013-09-12 20:45:42 -0400
committerJames Bottomley <JBottomley@Parallels.com>2013-10-25 04:57:57 -0400
commit67125b0287a9e6506c4f5afca7376667bf6dab5b (patch)
tree2a6e4e38136649cc82762b521248a361919c2a54 /drivers
parent441fbd25954c30d821187203f7dc941bf7b6d792 (diff)
[SCSI] fnic: Fnic Statistics Collection
This feature gathers active and cumulative per fnic stats for io, abort, terminate, reset, vlan discovery path and it also includes various important stats for debugging issues. It also provided debugfs and ioctl interface for user to retrieve these stats. It also provides functionality to reset cumulative stats through user interface. Signed-off-by: Hiral Patel <hiralpat@cisco.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/fnic/fnic.h8
-rw-r--r--drivers/scsi/fnic/fnic_debugfs.c390
-rw-r--r--drivers/scsi/fnic/fnic_fcs.c12
-rw-r--r--drivers/scsi/fnic/fnic_isr.c18
-rw-r--r--drivers/scsi/fnic/fnic_main.c19
-rw-r--r--drivers/scsi/fnic/fnic_scsi.c244
-rw-r--r--drivers/scsi/fnic/fnic_stats.h116
-rw-r--r--drivers/scsi/fnic/fnic_trace.c185
-rw-r--r--drivers/scsi/fnic/fnic_trace.h3
9 files changed, 971 insertions, 24 deletions
diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h
index e4dd3d7cd236..db7a9506ccd3 100644
--- a/drivers/scsi/fnic/fnic.h
+++ b/drivers/scsi/fnic/fnic.h
@@ -27,6 +27,7 @@
27#include "fnic_io.h" 27#include "fnic_io.h"
28#include "fnic_res.h" 28#include "fnic_res.h"
29#include "fnic_trace.h" 29#include "fnic_trace.h"
30#include "fnic_stats.h"
30#include "vnic_dev.h" 31#include "vnic_dev.h"
31#include "vnic_wq.h" 32#include "vnic_wq.h"
32#include "vnic_rq.h" 33#include "vnic_rq.h"
@@ -232,6 +233,13 @@ struct fnic {
232 unsigned int wq_count; 233 unsigned int wq_count;
233 unsigned int cq_count; 234 unsigned int cq_count;
234 235
236 struct dentry *fnic_stats_debugfs_host;
237 struct dentry *fnic_stats_debugfs_file;
238 struct dentry *fnic_reset_debugfs_file;
239 unsigned int reset_stats;
240 atomic64_t io_cmpl_skip;
241 struct fnic_stats fnic_stats;
242
235 u32 vlan_hw_insert:1; /* let hw insert the tag */ 243 u32 vlan_hw_insert:1; /* let hw insert the tag */
236 u32 in_remove:1; /* fnic device in removal */ 244 u32 in_remove:1; /* fnic device in removal */
237 u32 stop_rx_link_events:1; /* stop proc. rx frames, link events */ 245 u32 stop_rx_link_events:1; /* stop proc. rx frames, link events */
diff --git a/drivers/scsi/fnic/fnic_debugfs.c b/drivers/scsi/fnic/fnic_debugfs.c
index cbcb0121c84d..b6073f875761 100644
--- a/drivers/scsi/fnic/fnic_debugfs.c
+++ b/drivers/scsi/fnic/fnic_debugfs.c
@@ -23,6 +23,58 @@
23static struct dentry *fnic_trace_debugfs_root; 23static struct dentry *fnic_trace_debugfs_root;
24static struct dentry *fnic_trace_debugfs_file; 24static struct dentry *fnic_trace_debugfs_file;
25static struct dentry *fnic_trace_enable; 25static struct dentry *fnic_trace_enable;
26static struct dentry *fnic_stats_debugfs_root;
27
28/*
29 * fnic_debugfs_init - Initialize debugfs for fnic debug logging
30 *
31 * Description:
32 * When Debugfs is configured this routine sets up the fnic debugfs
33 * file system. If not already created, this routine will create the
34 * fnic directory and statistics directory for trace buffer and
35 * stats logging.
36 */
37int fnic_debugfs_init(void)
38{
39 int rc = -1;
40 fnic_trace_debugfs_root = debugfs_create_dir("fnic", NULL);
41 if (!fnic_trace_debugfs_root) {
42 printk(KERN_DEBUG "Cannot create debugfs root\n");
43 return rc;
44 }
45
46 if (!fnic_trace_debugfs_root) {
47 printk(KERN_DEBUG
48 "fnic root directory doesn't exist in debugfs\n");
49 return rc;
50 }
51
52 fnic_stats_debugfs_root = debugfs_create_dir("statistics",
53 fnic_trace_debugfs_root);
54 if (!fnic_stats_debugfs_root) {
55 printk(KERN_DEBUG "Cannot create Statistics directory\n");
56 return rc;
57 }
58
59 rc = 0;
60 return rc;
61}
62
63/*
64 * fnic_debugfs_terminate - Tear down debugfs infrastructure
65 *
66 * Description:
67 * When Debugfs is configured this routine removes debugfs file system
68 * elements that are specific to fnic.
69 */
70void fnic_debugfs_terminate(void)
71{
72 debugfs_remove(fnic_stats_debugfs_root);
73 fnic_stats_debugfs_root = NULL;
74
75 debugfs_remove(fnic_trace_debugfs_root);
76 fnic_trace_debugfs_root = NULL;
77}
26 78
27/* 79/*
28 * fnic_trace_ctrl_open - Open the trace_enable file 80 * fnic_trace_ctrl_open - Open the trace_enable file
@@ -241,16 +293,16 @@ static const struct file_operations fnic_trace_debugfs_fops = {
241 * Description: 293 * Description:
242 * When Debugfs is configured this routine sets up the fnic debugfs 294 * When Debugfs is configured this routine sets up the fnic debugfs
243 * file system. If not already created, this routine will create the 295 * file system. If not already created, this routine will create the
244 * fnic directory. It will create file trace to log fnic trace buffer 296 * create file trace to log fnic trace buffer output into debugfs and
245 * output into debugfs and it will also create file trace_enable to 297 * it will also create file trace_enable to control enable/disable of
246 * control enable/disable of trace logging into trace buffer. 298 * trace logging into trace buffer.
247 */ 299 */
248int fnic_trace_debugfs_init(void) 300int fnic_trace_debugfs_init(void)
249{ 301{
250 int rc = -1; 302 int rc = -1;
251 fnic_trace_debugfs_root = debugfs_create_dir("fnic", NULL);
252 if (!fnic_trace_debugfs_root) { 303 if (!fnic_trace_debugfs_root) {
253 printk(KERN_DEBUG "Cannot create debugfs root\n"); 304 printk(KERN_DEBUG
305 "FNIC Debugfs root directory doesn't exist\n");
254 return rc; 306 return rc;
255 } 307 }
256 fnic_trace_enable = debugfs_create_file("tracing_enable", 308 fnic_trace_enable = debugfs_create_file("tracing_enable",
@@ -259,8 +311,8 @@ int fnic_trace_debugfs_init(void)
259 NULL, &fnic_trace_ctrl_fops); 311 NULL, &fnic_trace_ctrl_fops);
260 312
261 if (!fnic_trace_enable) { 313 if (!fnic_trace_enable) {
262 printk(KERN_DEBUG "Cannot create trace_enable file" 314 printk(KERN_DEBUG
263 " under debugfs"); 315 "Cannot create trace_enable file under debugfs\n");
264 return rc; 316 return rc;
265 } 317 }
266 318
@@ -271,7 +323,8 @@ int fnic_trace_debugfs_init(void)
271 &fnic_trace_debugfs_fops); 323 &fnic_trace_debugfs_fops);
272 324
273 if (!fnic_trace_debugfs_file) { 325 if (!fnic_trace_debugfs_file) {
274 printk(KERN_DEBUG "Cannot create trace file under debugfs"); 326 printk(KERN_DEBUG
327 "Cannot create trace file under debugfs\n");
275 return rc; 328 return rc;
276 } 329 }
277 rc = 0; 330 rc = 0;
@@ -295,8 +348,323 @@ void fnic_trace_debugfs_terminate(void)
295 debugfs_remove(fnic_trace_enable); 348 debugfs_remove(fnic_trace_enable);
296 fnic_trace_enable = NULL; 349 fnic_trace_enable = NULL;
297 } 350 }
298 if (fnic_trace_debugfs_root) { 351}
299 debugfs_remove(fnic_trace_debugfs_root); 352
300 fnic_trace_debugfs_root = NULL; 353/*
354 * fnic_reset_stats_open - Open the reset_stats file
355 * @inode: The inode pointer.
356 * @file: The file pointer to attach the stats reset flag.
357 *
358 * Description:
359 * This routine opens a debugsfs file reset_stats and stores i_private data
360 * to debug structure to retrieve later for while performing other
361 * file oprations.
362 *
363 * Returns:
364 * This function returns zero if successful.
365 */
366static int fnic_reset_stats_open(struct inode *inode, struct file *file)
367{
368 struct stats_debug_info *debug;
369
370 debug = kzalloc(sizeof(struct stats_debug_info), GFP_KERNEL);
371 if (!debug)
372 return -ENOMEM;
373
374 debug->i_private = inode->i_private;
375
376 file->private_data = debug;
377
378 return 0;
379}
380
381/*
382 * fnic_reset_stats_read - Read a reset_stats debugfs file
383 * @filp: The file pointer to read from.
384 * @ubuf: The buffer to copy the data to.
385 * @cnt: The number of bytes to read.
386 * @ppos: The position in the file to start reading from.
387 *
388 * Description:
389 * This routine reads value of variable reset_stats
390 * and stores into local @buf. It will start reading file at @ppos and
391 * copy up to @cnt of data to @ubuf from @buf.
392 *
393 * Returns:
394 * This function returns the amount of data that was read.
395 */
396static ssize_t fnic_reset_stats_read(struct file *file,
397 char __user *ubuf,
398 size_t cnt, loff_t *ppos)
399{
400 struct stats_debug_info *debug = file->private_data;
401 struct fnic *fnic = (struct fnic *)debug->i_private;
402 char buf[64];
403 int len;
404
405 len = sprintf(buf, "%u\n", fnic->reset_stats);
406
407 return simple_read_from_buffer(ubuf, cnt, ppos, buf, len);
408}
409
410/*
411 * fnic_reset_stats_write - Write to reset_stats debugfs file
412 * @filp: The file pointer to write from.
413 * @ubuf: The buffer to copy the data from.
414 * @cnt: The number of bytes to write.
415 * @ppos: The position in the file to start writing to.
416 *
417 * Description:
418 * This routine writes data from user buffer @ubuf to buffer @buf and
419 * resets cumulative stats of fnic.
420 *
421 * Returns:
422 * This function returns the amount of data that was written.
423 */
424static ssize_t fnic_reset_stats_write(struct file *file,
425 const char __user *ubuf,
426 size_t cnt, loff_t *ppos)
427{
428 struct stats_debug_info *debug = file->private_data;
429 struct fnic *fnic = (struct fnic *)debug->i_private;
430 struct fnic_stats *stats = &fnic->fnic_stats;
431 u64 *io_stats_p = (u64 *)&stats->io_stats;
432 u64 *fw_stats_p = (u64 *)&stats->fw_stats;
433 char buf[64];
434 unsigned long val;
435 int ret;
436
437 if (cnt >= sizeof(buf))
438 return -EINVAL;
439
440 if (copy_from_user(&buf, ubuf, cnt))
441 return -EFAULT;
442
443 buf[cnt] = 0;
444
445 ret = kstrtoul(buf, 10, &val);
446 if (ret < 0)
447 return ret;
448
449 fnic->reset_stats = val;
450
451 if (fnic->reset_stats) {
452 /* Skip variable is used to avoid descrepancies to Num IOs
453 * and IO Completions stats. Skip incrementing No IO Compls
454 * for pending active IOs after reset stats
455 */
456 atomic64_set(&fnic->io_cmpl_skip,
457 atomic64_read(&stats->io_stats.active_ios));
458 memset(&stats->abts_stats, 0, sizeof(struct abort_stats));
459 memset(&stats->term_stats, 0,
460 sizeof(struct terminate_stats));
461 memset(&stats->reset_stats, 0, sizeof(struct reset_stats));
462 memset(&stats->misc_stats, 0, sizeof(struct misc_stats));
463 memset(&stats->vlan_stats, 0, sizeof(struct vlan_stats));
464 memset(io_stats_p+1, 0,
465 sizeof(struct io_path_stats) - sizeof(u64));
466 memset(fw_stats_p+1, 0,
467 sizeof(struct fw_stats) - sizeof(u64));
301 } 468 }
469
470 (*ppos)++;
471 return cnt;
472}
473
474/*
475 * fnic_reset_stats_release - Release the buffer used to store
476 * debugfs file data
477 * @inode: The inode pointer
478 * @file: The file pointer that contains the buffer to release
479 *
480 * Description:
481 * This routine frees the buffer that was allocated when the debugfs
482 * file was opened.
483 *
484 * Returns:
485 * This function returns zero.
486 */
487static int fnic_reset_stats_release(struct inode *inode,
488 struct file *file)
489{
490 struct stats_debug_info *debug = file->private_data;
491 kfree(debug);
492 return 0;
493}
494
495/*
496 * fnic_stats_debugfs_open - Open the stats file for specific host
497 * and get fnic stats.
498 * @inode: The inode pointer.
499 * @file: The file pointer to attach the specific host statistics.
500 *
501 * Description:
502 * This routine opens a debugsfs file stats of specific host and print
503 * fnic stats.
504 *
505 * Returns:
506 * This function returns zero if successful.
507 */
508static int fnic_stats_debugfs_open(struct inode *inode,
509 struct file *file)
510{
511 struct fnic *fnic = inode->i_private;
512 struct fnic_stats *fnic_stats = &fnic->fnic_stats;
513 struct stats_debug_info *debug;
514 int buf_size = 2 * PAGE_SIZE;
515
516 debug = kzalloc(sizeof(struct stats_debug_info), GFP_KERNEL);
517 if (!debug)
518 return -ENOMEM;
519
520 debug->debug_buffer = vmalloc(buf_size);
521 if (!debug->debug_buffer) {
522 kfree(debug);
523 return -ENOMEM;
524 }
525
526 debug->buf_size = buf_size;
527 memset((void *)debug->debug_buffer, 0, buf_size);
528 debug->buffer_len = fnic_get_stats_data(debug, fnic_stats);
529
530 file->private_data = debug;
531
532 return 0;
533}
534
535/*
536 * fnic_stats_debugfs_read - Read a debugfs file
537 * @file: The file pointer to read from.
538 * @ubuf: The buffer to copy the data to.
539 * @nbytes: The number of bytes to read.
540 * @pos: The position in the file to start reading from.
541 *
542 * Description:
543 * This routine reads data from the buffer indicated in the private_data
544 * field of @file. It will start reading at @pos and copy up to @nbytes of
545 * data to @ubuf.
546 *
547 * Returns:
548 * This function returns the amount of data that was read (this could be
549 * less than @nbytes if the end of the file was reached).
550 */
551static ssize_t fnic_stats_debugfs_read(struct file *file,
552 char __user *ubuf,
553 size_t nbytes,
554 loff_t *pos)
555{
556 struct stats_debug_info *debug = file->private_data;
557 int rc = 0;
558 rc = simple_read_from_buffer(ubuf, nbytes, pos,
559 debug->debug_buffer,
560 debug->buffer_len);
561 return rc;
562}
563
564/*
565 * fnic_stats_stats_release - Release the buffer used to store
566 * debugfs file data
567 * @inode: The inode pointer
568 * @file: The file pointer that contains the buffer to release
569 *
570 * Description:
571 * This routine frees the buffer that was allocated when the debugfs
572 * file was opened.
573 *
574 * Returns:
575 * This function returns zero.
576 */
577static int fnic_stats_debugfs_release(struct inode *inode,
578 struct file *file)
579{
580 struct stats_debug_info *debug = file->private_data;
581 vfree(debug->debug_buffer);
582 kfree(debug);
583 return 0;
584}
585
586static const struct file_operations fnic_stats_debugfs_fops = {
587 .owner = THIS_MODULE,
588 .open = fnic_stats_debugfs_open,
589 .read = fnic_stats_debugfs_read,
590 .release = fnic_stats_debugfs_release,
591};
592
593static const struct file_operations fnic_reset_debugfs_fops = {
594 .owner = THIS_MODULE,
595 .open = fnic_reset_stats_open,
596 .read = fnic_reset_stats_read,
597 .write = fnic_reset_stats_write,
598 .release = fnic_reset_stats_release,
599};
600
601/*
602 * fnic_stats_init - Initialize stats struct and create stats file per fnic
603 *
604 * Description:
605 * When Debugfs is configured this routine sets up the stats file per fnic
606 * It will create file stats and reset_stats under statistics/host# directory
607 * to log per fnic stats.
608 */
609int fnic_stats_debugfs_init(struct fnic *fnic)
610{
611 int rc = -1;
612 char name[16];
613
614 snprintf(name, sizeof(name), "host%d", fnic->lport->host->host_no);
615
616 if (!fnic_stats_debugfs_root) {
617 printk(KERN_DEBUG "fnic_stats root doesn't exist\n");
618 return rc;
619 }
620 fnic->fnic_stats_debugfs_host = debugfs_create_dir(name,
621 fnic_stats_debugfs_root);
622 if (!fnic->fnic_stats_debugfs_host) {
623 printk(KERN_DEBUG "Cannot create host directory\n");
624 return rc;
625 }
626
627 fnic->fnic_stats_debugfs_file = debugfs_create_file("stats",
628 S_IFREG|S_IRUGO|S_IWUSR,
629 fnic->fnic_stats_debugfs_host,
630 fnic,
631 &fnic_stats_debugfs_fops);
632 if (!fnic->fnic_stats_debugfs_file) {
633 printk(KERN_DEBUG "Cannot create host stats file\n");
634 return rc;
635 }
636
637 fnic->fnic_reset_debugfs_file = debugfs_create_file("reset_stats",
638 S_IFREG|S_IRUGO|S_IWUSR,
639 fnic->fnic_stats_debugfs_host,
640 fnic,
641 &fnic_reset_debugfs_fops);
642 if (!fnic->fnic_reset_debugfs_file) {
643 printk(KERN_DEBUG "Cannot create host stats file\n");
644 return rc;
645 }
646 rc = 0;
647 return rc;
648}
649
650/*
651 * fnic_stats_debugfs_remove - Tear down debugfs infrastructure of stats
652 *
653 * Description:
654 * When Debugfs is configured this routine removes debugfs file system
655 * elements that are specific to fnic stats.
656 */
657void fnic_stats_debugfs_remove(struct fnic *fnic)
658{
659 if (!fnic)
660 return;
661
662 debugfs_remove(fnic->fnic_stats_debugfs_file);
663 fnic->fnic_stats_debugfs_file = NULL;
664
665 debugfs_remove(fnic->fnic_reset_debugfs_file);
666 fnic->fnic_reset_debugfs_file = NULL;
667
668 debugfs_remove(fnic->fnic_stats_debugfs_host);
669 fnic->fnic_stats_debugfs_host = NULL;
302} 670}
diff --git a/drivers/scsi/fnic/fnic_fcs.c b/drivers/scsi/fnic/fnic_fcs.c
index 006fa92a02df..60a1c50aa68f 100644
--- a/drivers/scsi/fnic/fnic_fcs.c
+++ b/drivers/scsi/fnic/fnic_fcs.c
@@ -302,6 +302,7 @@ static inline int is_fnic_fip_flogi_reject(struct fcoe_ctlr *fip,
302static void fnic_fcoe_send_vlan_req(struct fnic *fnic) 302static void fnic_fcoe_send_vlan_req(struct fnic *fnic)
303{ 303{
304 struct fcoe_ctlr *fip = &fnic->ctlr; 304 struct fcoe_ctlr *fip = &fnic->ctlr;
305 struct fnic_stats *fnic_stats = &fnic->fnic_stats;
305 struct sk_buff *skb; 306 struct sk_buff *skb;
306 char *eth_fr; 307 char *eth_fr;
307 int fr_len; 308 int fr_len;
@@ -337,6 +338,7 @@ static void fnic_fcoe_send_vlan_req(struct fnic *fnic)
337 vlan->desc.wwnn.fd_desc.fip_dtype = FIP_DT_NAME; 338 vlan->desc.wwnn.fd_desc.fip_dtype = FIP_DT_NAME;
338 vlan->desc.wwnn.fd_desc.fip_dlen = sizeof(vlan->desc.wwnn) / FIP_BPW; 339 vlan->desc.wwnn.fd_desc.fip_dlen = sizeof(vlan->desc.wwnn) / FIP_BPW;
339 put_unaligned_be64(fip->lp->wwnn, &vlan->desc.wwnn.fd_wwn); 340 put_unaligned_be64(fip->lp->wwnn, &vlan->desc.wwnn.fd_wwn);
341 atomic64_inc(&fnic_stats->vlan_stats.vlan_disc_reqs);
340 342
341 skb_put(skb, sizeof(*vlan)); 343 skb_put(skb, sizeof(*vlan));
342 skb->protocol = htons(ETH_P_FIP); 344 skb->protocol = htons(ETH_P_FIP);
@@ -354,6 +356,7 @@ static void fnic_fcoe_process_vlan_resp(struct fnic *fnic, struct sk_buff *skb)
354 struct fcoe_ctlr *fip = &fnic->ctlr; 356 struct fcoe_ctlr *fip = &fnic->ctlr;
355 struct fip_header *fiph; 357 struct fip_header *fiph;
356 struct fip_desc *desc; 358 struct fip_desc *desc;
359 struct fnic_stats *fnic_stats = &fnic->fnic_stats;
357 u16 vid; 360 u16 vid;
358 size_t rlen; 361 size_t rlen;
359 size_t dlen; 362 size_t dlen;
@@ -402,6 +405,7 @@ static void fnic_fcoe_process_vlan_resp(struct fnic *fnic, struct sk_buff *skb)
402 /* any VLAN descriptors present ? */ 405 /* any VLAN descriptors present ? */
403 if (list_empty(&fnic->vlans)) { 406 if (list_empty(&fnic->vlans)) {
404 /* retry from timer */ 407 /* retry from timer */
408 atomic64_inc(&fnic_stats->vlan_stats.resp_withno_vlanID);
405 FNIC_FCS_DBG(KERN_INFO, fnic->lport->host, 409 FNIC_FCS_DBG(KERN_INFO, fnic->lport->host,
406 "No VLAN descriptors in FIP VLAN response\n"); 410 "No VLAN descriptors in FIP VLAN response\n");
407 spin_unlock_irqrestore(&fnic->vlans_lock, flags); 411 spin_unlock_irqrestore(&fnic->vlans_lock, flags);
@@ -533,6 +537,7 @@ drop:
533void fnic_handle_fip_frame(struct work_struct *work) 537void fnic_handle_fip_frame(struct work_struct *work)
534{ 538{
535 struct fnic *fnic = container_of(work, struct fnic, fip_frame_work); 539 struct fnic *fnic = container_of(work, struct fnic, fip_frame_work);
540 struct fnic_stats *fnic_stats = &fnic->fnic_stats;
536 unsigned long flags; 541 unsigned long flags;
537 struct sk_buff *skb; 542 struct sk_buff *skb;
538 struct ethhdr *eh; 543 struct ethhdr *eh;
@@ -567,6 +572,8 @@ void fnic_handle_fip_frame(struct work_struct *work)
567 * fcf's & restart from scratch 572 * fcf's & restart from scratch
568 */ 573 */
569 if (is_fnic_fip_flogi_reject(&fnic->ctlr, skb)) { 574 if (is_fnic_fip_flogi_reject(&fnic->ctlr, skb)) {
575 atomic64_inc(
576 &fnic_stats->vlan_stats.flogi_rejects);
570 shost_printk(KERN_INFO, fnic->lport->host, 577 shost_printk(KERN_INFO, fnic->lport->host,
571 "Trigger a Link down - VLAN Disc\n"); 578 "Trigger a Link down - VLAN Disc\n");
572 fcoe_ctlr_link_down(&fnic->ctlr); 579 fcoe_ctlr_link_down(&fnic->ctlr);
@@ -753,6 +760,7 @@ static void fnic_rq_cmpl_frame_recv(struct vnic_rq *rq, struct cq_desc
753 struct fnic *fnic = vnic_dev_priv(rq->vdev); 760 struct fnic *fnic = vnic_dev_priv(rq->vdev);
754 struct sk_buff *skb; 761 struct sk_buff *skb;
755 struct fc_frame *fp; 762 struct fc_frame *fp;
763 struct fnic_stats *fnic_stats = &fnic->fnic_stats;
756 unsigned int eth_hdrs_stripped; 764 unsigned int eth_hdrs_stripped;
757 u8 type, color, eop, sop, ingress_port, vlan_stripped; 765 u8 type, color, eop, sop, ingress_port, vlan_stripped;
758 u8 fcoe = 0, fcoe_sof, fcoe_eof; 766 u8 fcoe = 0, fcoe_sof, fcoe_eof;
@@ -803,6 +811,7 @@ static void fnic_rq_cmpl_frame_recv(struct vnic_rq *rq, struct cq_desc
803 eth_hdrs_stripped = 0; 811 eth_hdrs_stripped = 0;
804 skb_trim(skb, bytes_written); 812 skb_trim(skb, bytes_written);
805 if (!fcs_ok) { 813 if (!fcs_ok) {
814 atomic64_inc(&fnic_stats->misc_stats.frame_errors);
806 FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, 815 FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host,
807 "fcs error. dropping packet.\n"); 816 "fcs error. dropping packet.\n");
808 goto drop; 817 goto drop;
@@ -818,6 +827,7 @@ static void fnic_rq_cmpl_frame_recv(struct vnic_rq *rq, struct cq_desc
818 } 827 }
819 828
820 if (!fcs_ok || packet_error || !fcoe_fc_crc_ok || fcoe_enc_error) { 829 if (!fcs_ok || packet_error || !fcoe_fc_crc_ok || fcoe_enc_error) {
830 atomic64_inc(&fnic_stats->misc_stats.frame_errors);
821 FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, 831 FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host,
822 "fnic rq_cmpl fcoe x%x fcsok x%x" 832 "fnic rq_cmpl fcoe x%x fcsok x%x"
823 " pkterr x%x fcoe_fc_crc_ok x%x, fcoe_enc_err" 833 " pkterr x%x fcoe_fc_crc_ok x%x, fcoe_enc_err"
@@ -1205,6 +1215,7 @@ void fnic_handle_fip_timer(struct fnic *fnic)
1205{ 1215{
1206 unsigned long flags; 1216 unsigned long flags;
1207 struct fcoe_vlan *vlan; 1217 struct fcoe_vlan *vlan;
1218 struct fnic_stats *fnic_stats = &fnic->fnic_stats;
1208 u64 sol_time; 1219 u64 sol_time;
1209 1220
1210 spin_lock_irqsave(&fnic->fnic_lock, flags); 1221 spin_lock_irqsave(&fnic->fnic_lock, flags);
@@ -1273,6 +1284,7 @@ void fnic_handle_fip_timer(struct fnic *fnic)
1273 vlan->state = FIP_VLAN_SENT; /* sent now */ 1284 vlan->state = FIP_VLAN_SENT; /* sent now */
1274 } 1285 }
1275 spin_unlock_irqrestore(&fnic->vlans_lock, flags); 1286 spin_unlock_irqrestore(&fnic->vlans_lock, flags);
1287 atomic64_inc(&fnic_stats->vlan_stats.sol_expiry_count);
1276 vlan->sol_count++; 1288 vlan->sol_count++;
1277 sol_time = jiffies + msecs_to_jiffies 1289 sol_time = jiffies + msecs_to_jiffies
1278 (FCOE_CTLR_START_DELAY); 1290 (FCOE_CTLR_START_DELAY);
diff --git a/drivers/scsi/fnic/fnic_isr.c b/drivers/scsi/fnic/fnic_isr.c
index 5c1f223cabce..7d9b54ae7f62 100644
--- a/drivers/scsi/fnic/fnic_isr.c
+++ b/drivers/scsi/fnic/fnic_isr.c
@@ -37,6 +37,9 @@ static irqreturn_t fnic_isr_legacy(int irq, void *data)
37 if (!pba) 37 if (!pba)
38 return IRQ_NONE; 38 return IRQ_NONE;
39 39
40 fnic->fnic_stats.misc_stats.last_isr_time = jiffies;
41 atomic64_inc(&fnic->fnic_stats.misc_stats.isr_count);
42
40 if (pba & (1 << FNIC_INTX_NOTIFY)) { 43 if (pba & (1 << FNIC_INTX_NOTIFY)) {
41 vnic_intr_return_all_credits(&fnic->intr[FNIC_INTX_NOTIFY]); 44 vnic_intr_return_all_credits(&fnic->intr[FNIC_INTX_NOTIFY]);
42 fnic_handle_link_event(fnic); 45 fnic_handle_link_event(fnic);
@@ -66,6 +69,9 @@ static irqreturn_t fnic_isr_msi(int irq, void *data)
66 struct fnic *fnic = data; 69 struct fnic *fnic = data;
67 unsigned long work_done = 0; 70 unsigned long work_done = 0;
68 71
72 fnic->fnic_stats.misc_stats.last_isr_time = jiffies;
73 atomic64_inc(&fnic->fnic_stats.misc_stats.isr_count);
74
69 work_done += fnic_wq_copy_cmpl_handler(fnic, -1); 75 work_done += fnic_wq_copy_cmpl_handler(fnic, -1);
70 work_done += fnic_wq_cmpl_handler(fnic, -1); 76 work_done += fnic_wq_cmpl_handler(fnic, -1);
71 work_done += fnic_rq_cmpl_handler(fnic, -1); 77 work_done += fnic_rq_cmpl_handler(fnic, -1);
@@ -83,6 +89,9 @@ static irqreturn_t fnic_isr_msix_rq(int irq, void *data)
83 struct fnic *fnic = data; 89 struct fnic *fnic = data;
84 unsigned long rq_work_done = 0; 90 unsigned long rq_work_done = 0;
85 91
92 fnic->fnic_stats.misc_stats.last_isr_time = jiffies;
93 atomic64_inc(&fnic->fnic_stats.misc_stats.isr_count);
94
86 rq_work_done = fnic_rq_cmpl_handler(fnic, -1); 95 rq_work_done = fnic_rq_cmpl_handler(fnic, -1);
87 vnic_intr_return_credits(&fnic->intr[FNIC_MSIX_RQ], 96 vnic_intr_return_credits(&fnic->intr[FNIC_MSIX_RQ],
88 rq_work_done, 97 rq_work_done,
@@ -97,6 +106,9 @@ static irqreturn_t fnic_isr_msix_wq(int irq, void *data)
97 struct fnic *fnic = data; 106 struct fnic *fnic = data;
98 unsigned long wq_work_done = 0; 107 unsigned long wq_work_done = 0;
99 108
109 fnic->fnic_stats.misc_stats.last_isr_time = jiffies;
110 atomic64_inc(&fnic->fnic_stats.misc_stats.isr_count);
111
100 wq_work_done = fnic_wq_cmpl_handler(fnic, -1); 112 wq_work_done = fnic_wq_cmpl_handler(fnic, -1);
101 vnic_intr_return_credits(&fnic->intr[FNIC_MSIX_WQ], 113 vnic_intr_return_credits(&fnic->intr[FNIC_MSIX_WQ],
102 wq_work_done, 114 wq_work_done,
@@ -110,6 +122,9 @@ static irqreturn_t fnic_isr_msix_wq_copy(int irq, void *data)
110 struct fnic *fnic = data; 122 struct fnic *fnic = data;
111 unsigned long wq_copy_work_done = 0; 123 unsigned long wq_copy_work_done = 0;
112 124
125 fnic->fnic_stats.misc_stats.last_isr_time = jiffies;
126 atomic64_inc(&fnic->fnic_stats.misc_stats.isr_count);
127
113 wq_copy_work_done = fnic_wq_copy_cmpl_handler(fnic, -1); 128 wq_copy_work_done = fnic_wq_copy_cmpl_handler(fnic, -1);
114 vnic_intr_return_credits(&fnic->intr[FNIC_MSIX_WQ_COPY], 129 vnic_intr_return_credits(&fnic->intr[FNIC_MSIX_WQ_COPY],
115 wq_copy_work_done, 130 wq_copy_work_done,
@@ -122,6 +137,9 @@ static irqreturn_t fnic_isr_msix_err_notify(int irq, void *data)
122{ 137{
123 struct fnic *fnic = data; 138 struct fnic *fnic = data;
124 139
140 fnic->fnic_stats.misc_stats.last_isr_time = jiffies;
141 atomic64_inc(&fnic->fnic_stats.misc_stats.isr_count);
142
125 vnic_intr_return_all_credits(&fnic->intr[FNIC_MSIX_ERR_NOTIFY]); 143 vnic_intr_return_all_credits(&fnic->intr[FNIC_MSIX_ERR_NOTIFY]);
126 fnic_log_q_error(fnic); 144 fnic_log_q_error(fnic);
127 fnic_handle_link_event(fnic); 145 fnic_handle_link_event(fnic);
diff --git a/drivers/scsi/fnic/fnic_main.c b/drivers/scsi/fnic/fnic_main.c
index bbf81ea3a252..be09b101b4a1 100644
--- a/drivers/scsi/fnic/fnic_main.c
+++ b/drivers/scsi/fnic/fnic_main.c
@@ -556,6 +556,13 @@ static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
556 556
557 host->transportt = fnic_fc_transport; 557 host->transportt = fnic_fc_transport;
558 558
559 err = fnic_stats_debugfs_init(fnic);
560 if (err) {
561 shost_printk(KERN_ERR, fnic->lport->host,
562 "Failed to initialize debugfs for stats\n");
563 fnic_stats_debugfs_remove(fnic);
564 }
565
559 /* Setup PCI resources */ 566 /* Setup PCI resources */
560 pci_set_drvdata(pdev, fnic); 567 pci_set_drvdata(pdev, fnic);
561 568
@@ -917,6 +924,7 @@ err_out_release_regions:
917err_out_disable_device: 924err_out_disable_device:
918 pci_disable_device(pdev); 925 pci_disable_device(pdev);
919err_out_free_hba: 926err_out_free_hba:
927 fnic_stats_debugfs_remove(fnic);
920 scsi_host_put(lp->host); 928 scsi_host_put(lp->host);
921err_out: 929err_out:
922 return err; 930 return err;
@@ -969,6 +977,7 @@ static void fnic_remove(struct pci_dev *pdev)
969 977
970 fcoe_ctlr_destroy(&fnic->ctlr); 978 fcoe_ctlr_destroy(&fnic->ctlr);
971 fc_lport_destroy(lp); 979 fc_lport_destroy(lp);
980 fnic_stats_debugfs_remove(fnic);
972 981
973 /* 982 /*
974 * This stops the fnic device, masks all interrupts. Completed 983 * This stops the fnic device, masks all interrupts. Completed
@@ -1014,6 +1023,14 @@ static int __init fnic_init_module(void)
1014 1023
1015 printk(KERN_INFO PFX "%s, ver %s\n", DRV_DESCRIPTION, DRV_VERSION); 1024 printk(KERN_INFO PFX "%s, ver %s\n", DRV_DESCRIPTION, DRV_VERSION);
1016 1025
1026 /* Create debugfs entries for fnic */
1027 err = fnic_debugfs_init();
1028 if (err < 0) {
1029 printk(KERN_ERR PFX "Failed to create fnic directory "
1030 "for tracing and stats logging\n");
1031 fnic_debugfs_terminate();
1032 }
1033
1017 /* Allocate memory for trace buffer */ 1034 /* Allocate memory for trace buffer */
1018 err = fnic_trace_buf_init(); 1035 err = fnic_trace_buf_init();
1019 if (err < 0) { 1036 if (err < 0) {
@@ -1102,6 +1119,7 @@ err_create_fnic_sgl_slab_max:
1102 kmem_cache_destroy(fnic_sgl_cache[FNIC_SGL_CACHE_DFLT]); 1119 kmem_cache_destroy(fnic_sgl_cache[FNIC_SGL_CACHE_DFLT]);
1103err_create_fnic_sgl_slab_dflt: 1120err_create_fnic_sgl_slab_dflt:
1104 fnic_trace_free(); 1121 fnic_trace_free();
1122 fnic_debugfs_terminate();
1105 return err; 1123 return err;
1106} 1124}
1107 1125
@@ -1118,6 +1136,7 @@ static void __exit fnic_cleanup_module(void)
1118 kmem_cache_destroy(fnic_io_req_cache); 1136 kmem_cache_destroy(fnic_io_req_cache);
1119 fc_release_transport(fnic_fc_transport); 1137 fc_release_transport(fnic_fc_transport);
1120 fnic_trace_free(); 1138 fnic_trace_free();
1139 fnic_debugfs_terminate();
1121} 1140}
1122 1141
1123module_init(fnic_init_module); 1142module_init(fnic_init_module);
diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c
index 50f3b327bd1e..0521436d05d6 100644
--- a/drivers/scsi/fnic/fnic_scsi.c
+++ b/drivers/scsi/fnic/fnic_scsi.c
@@ -226,15 +226,23 @@ int fnic_fw_reset_handler(struct fnic *fnic)
226 226
227 if (!vnic_wq_copy_desc_avail(wq)) 227 if (!vnic_wq_copy_desc_avail(wq))
228 ret = -EAGAIN; 228 ret = -EAGAIN;
229 else 229 else {
230 fnic_queue_wq_copy_desc_fw_reset(wq, SCSI_NO_TAG); 230 fnic_queue_wq_copy_desc_fw_reset(wq, SCSI_NO_TAG);
231 atomic64_inc(&fnic->fnic_stats.fw_stats.active_fw_reqs);
232 if (atomic64_read(&fnic->fnic_stats.fw_stats.active_fw_reqs) >
233 atomic64_read(&fnic->fnic_stats.fw_stats.max_fw_reqs))
234 atomic64_set(&fnic->fnic_stats.fw_stats.max_fw_reqs,
235 atomic64_read(
236 &fnic->fnic_stats.fw_stats.active_fw_reqs));
237 }
231 238
232 spin_unlock_irqrestore(&fnic->wq_copy_lock[0], flags); 239 spin_unlock_irqrestore(&fnic->wq_copy_lock[0], flags);
233 240
234 if (!ret) 241 if (!ret) {
242 atomic64_inc(&fnic->fnic_stats.reset_stats.fw_resets);
235 FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, 243 FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
236 "Issued fw reset\n"); 244 "Issued fw reset\n");
237 else { 245 } else {
238 fnic_clear_state_flags(fnic, FNIC_FLAGS_FWRESET); 246 fnic_clear_state_flags(fnic, FNIC_FLAGS_FWRESET);
239 FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, 247 FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
240 "Failed to issue fw reset\n"); 248 "Failed to issue fw reset\n");
@@ -291,6 +299,12 @@ int fnic_flogi_reg_handler(struct fnic *fnic, u32 fc_id)
291 fc_id, fnic->ctlr.map_dest, gw_mac); 299 fc_id, fnic->ctlr.map_dest, gw_mac);
292 } 300 }
293 301
302 atomic64_inc(&fnic->fnic_stats.fw_stats.active_fw_reqs);
303 if (atomic64_read(&fnic->fnic_stats.fw_stats.active_fw_reqs) >
304 atomic64_read(&fnic->fnic_stats.fw_stats.max_fw_reqs))
305 atomic64_set(&fnic->fnic_stats.fw_stats.max_fw_reqs,
306 atomic64_read(&fnic->fnic_stats.fw_stats.active_fw_reqs));
307
294flogi_reg_ioreq_end: 308flogi_reg_ioreq_end:
295 spin_unlock_irqrestore(&fnic->wq_copy_lock[0], flags); 309 spin_unlock_irqrestore(&fnic->wq_copy_lock[0], flags);
296 return ret; 310 return ret;
@@ -310,6 +324,7 @@ static inline int fnic_queue_wq_copy_desc(struct fnic *fnic,
310 struct fc_rport *rport = starget_to_rport(scsi_target(sc->device)); 324 struct fc_rport *rport = starget_to_rport(scsi_target(sc->device));
311 struct fc_rport_libfc_priv *rp = rport->dd_data; 325 struct fc_rport_libfc_priv *rp = rport->dd_data;
312 struct host_sg_desc *desc; 326 struct host_sg_desc *desc;
327 struct misc_stats *misc_stats = &fnic->fnic_stats.misc_stats;
313 u8 pri_tag = 0; 328 u8 pri_tag = 0;
314 unsigned int i; 329 unsigned int i;
315 unsigned long intr_flags; 330 unsigned long intr_flags;
@@ -358,6 +373,7 @@ static inline int fnic_queue_wq_copy_desc(struct fnic *fnic,
358 spin_unlock_irqrestore(&fnic->wq_copy_lock[0], intr_flags); 373 spin_unlock_irqrestore(&fnic->wq_copy_lock[0], intr_flags);
359 FNIC_SCSI_DBG(KERN_INFO, fnic->lport->host, 374 FNIC_SCSI_DBG(KERN_INFO, fnic->lport->host,
360 "fnic_queue_wq_copy_desc failure - no descriptors\n"); 375 "fnic_queue_wq_copy_desc failure - no descriptors\n");
376 atomic64_inc(&misc_stats->io_cpwq_alloc_failures);
361 return SCSI_MLQUEUE_HOST_BUSY; 377 return SCSI_MLQUEUE_HOST_BUSY;
362 } 378 }
363 379
@@ -386,6 +402,12 @@ static inline int fnic_queue_wq_copy_desc(struct fnic *fnic,
386 rport->maxframe_size, rp->r_a_tov, 402 rport->maxframe_size, rp->r_a_tov,
387 rp->e_d_tov); 403 rp->e_d_tov);
388 404
405 atomic64_inc(&fnic->fnic_stats.fw_stats.active_fw_reqs);
406 if (atomic64_read(&fnic->fnic_stats.fw_stats.active_fw_reqs) >
407 atomic64_read(&fnic->fnic_stats.fw_stats.max_fw_reqs))
408 atomic64_set(&fnic->fnic_stats.fw_stats.max_fw_reqs,
409 atomic64_read(&fnic->fnic_stats.fw_stats.active_fw_reqs));
410
389 spin_unlock_irqrestore(&fnic->wq_copy_lock[0], intr_flags); 411 spin_unlock_irqrestore(&fnic->wq_copy_lock[0], intr_flags);
390 return 0; 412 return 0;
391} 413}
@@ -401,6 +423,7 @@ static int fnic_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_
401 struct fc_rport *rport; 423 struct fc_rport *rport;
402 struct fnic_io_req *io_req = NULL; 424 struct fnic_io_req *io_req = NULL;
403 struct fnic *fnic = lport_priv(lp); 425 struct fnic *fnic = lport_priv(lp);
426 struct fnic_stats *fnic_stats = &fnic->fnic_stats;
404 struct vnic_wq_copy *wq; 427 struct vnic_wq_copy *wq;
405 int ret; 428 int ret;
406 u64 cmd_trace; 429 u64 cmd_trace;
@@ -414,6 +437,7 @@ static int fnic_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_
414 rport = starget_to_rport(scsi_target(sc->device)); 437 rport = starget_to_rport(scsi_target(sc->device));
415 ret = fc_remote_port_chkready(rport); 438 ret = fc_remote_port_chkready(rport);
416 if (ret) { 439 if (ret) {
440 atomic64_inc(&fnic_stats->misc_stats.rport_not_ready);
417 sc->result = ret; 441 sc->result = ret;
418 done(sc); 442 done(sc);
419 return 0; 443 return 0;
@@ -436,6 +460,7 @@ static int fnic_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_
436 /* Get a new io_req for this SCSI IO */ 460 /* Get a new io_req for this SCSI IO */
437 io_req = mempool_alloc(fnic->io_req_pool, GFP_ATOMIC); 461 io_req = mempool_alloc(fnic->io_req_pool, GFP_ATOMIC);
438 if (!io_req) { 462 if (!io_req) {
463 atomic64_inc(&fnic_stats->io_stats.alloc_failures);
439 ret = SCSI_MLQUEUE_HOST_BUSY; 464 ret = SCSI_MLQUEUE_HOST_BUSY;
440 goto out; 465 goto out;
441 } 466 }
@@ -462,6 +487,7 @@ static int fnic_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_
462 mempool_alloc(fnic->io_sgl_pool[io_req->sgl_type], 487 mempool_alloc(fnic->io_sgl_pool[io_req->sgl_type],
463 GFP_ATOMIC); 488 GFP_ATOMIC);
464 if (!io_req->sgl_list) { 489 if (!io_req->sgl_list) {
490 atomic64_inc(&fnic_stats->io_stats.alloc_failures);
465 ret = SCSI_MLQUEUE_HOST_BUSY; 491 ret = SCSI_MLQUEUE_HOST_BUSY;
466 scsi_dma_unmap(sc); 492 scsi_dma_unmap(sc);
467 mempool_free(io_req, fnic->io_req_pool); 493 mempool_free(io_req, fnic->io_req_pool);
@@ -509,6 +535,13 @@ static int fnic_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_
509 mempool_free(io_req, fnic->io_req_pool); 535 mempool_free(io_req, fnic->io_req_pool);
510 } 536 }
511 } else { 537 } else {
538 atomic64_inc(&fnic_stats->io_stats.active_ios);
539 atomic64_inc(&fnic_stats->io_stats.num_ios);
540 if (atomic64_read(&fnic_stats->io_stats.active_ios) >
541 atomic64_read(&fnic_stats->io_stats.max_active_ios))
542 atomic64_set(&fnic_stats->io_stats.max_active_ios,
543 atomic64_read(&fnic_stats->io_stats.active_ios));
544
512 /* REVISIT: Use per IO lock in the final code */ 545 /* REVISIT: Use per IO lock in the final code */
513 CMD_FLAGS(sc) |= FNIC_IO_ISSUED; 546 CMD_FLAGS(sc) |= FNIC_IO_ISSUED;
514 } 547 }
@@ -542,12 +575,18 @@ static int fnic_fcpio_fw_reset_cmpl_handler(struct fnic *fnic,
542 struct fcpio_tag tag; 575 struct fcpio_tag tag;
543 int ret = 0; 576 int ret = 0;
544 unsigned long flags; 577 unsigned long flags;
578 struct reset_stats *reset_stats = &fnic->fnic_stats.reset_stats;
545 579
546 fcpio_header_dec(&desc->hdr, &type, &hdr_status, &tag); 580 fcpio_header_dec(&desc->hdr, &type, &hdr_status, &tag);
547 581
582 atomic64_inc(&reset_stats->fw_reset_completions);
583
548 /* Clean up all outstanding io requests */ 584 /* Clean up all outstanding io requests */
549 fnic_cleanup_io(fnic, SCSI_NO_TAG); 585 fnic_cleanup_io(fnic, SCSI_NO_TAG);
550 586
587 atomic64_set(&fnic->fnic_stats.fw_stats.active_fw_reqs, 0);
588 atomic64_set(&fnic->fnic_stats.io_stats.active_ios, 0);
589
551 spin_lock_irqsave(&fnic->fnic_lock, flags); 590 spin_lock_irqsave(&fnic->fnic_lock, flags);
552 591
553 /* fnic should be in FC_TRANS_ETH_MODE */ 592 /* fnic should be in FC_TRANS_ETH_MODE */
@@ -571,6 +610,7 @@ static int fnic_fcpio_fw_reset_cmpl_handler(struct fnic *fnic,
571 * reset the firmware. Free the cached flogi 610 * reset the firmware. Free the cached flogi
572 */ 611 */
573 fnic->state = FNIC_IN_FC_MODE; 612 fnic->state = FNIC_IN_FC_MODE;
613 atomic64_inc(&reset_stats->fw_reset_failures);
574 ret = -1; 614 ret = -1;
575 } 615 }
576 } else { 616 } else {
@@ -578,6 +618,7 @@ static int fnic_fcpio_fw_reset_cmpl_handler(struct fnic *fnic,
578 fnic->lport->host, 618 fnic->lport->host,
579 "Unexpected state %s while processing" 619 "Unexpected state %s while processing"
580 " reset cmpl\n", fnic_state_to_str(fnic->state)); 620 " reset cmpl\n", fnic_state_to_str(fnic->state));
621 atomic64_inc(&reset_stats->fw_reset_failures);
581 ret = -1; 622 ret = -1;
582 } 623 }
583 624
@@ -701,10 +742,14 @@ static inline void fnic_fcpio_ack_handler(struct fnic *fnic,
701 wq = &fnic->wq_copy[cq_index - fnic->raw_wq_count - fnic->rq_count]; 742 wq = &fnic->wq_copy[cq_index - fnic->raw_wq_count - fnic->rq_count];
702 spin_lock_irqsave(&fnic->wq_copy_lock[0], flags); 743 spin_lock_irqsave(&fnic->wq_copy_lock[0], flags);
703 744
745 fnic->fnic_stats.misc_stats.last_ack_time = jiffies;
704 if (is_ack_index_in_range(wq, request_out)) { 746 if (is_ack_index_in_range(wq, request_out)) {
705 fnic->fw_ack_index[0] = request_out; 747 fnic->fw_ack_index[0] = request_out;
706 fnic->fw_ack_recd[0] = 1; 748 fnic->fw_ack_recd[0] = 1;
707 } 749 } else
750 atomic64_inc(
751 &fnic->fnic_stats.misc_stats.ack_index_out_of_range);
752
708 spin_unlock_irqrestore(&fnic->wq_copy_lock[0], flags); 753 spin_unlock_irqrestore(&fnic->wq_copy_lock[0], flags);
709 FNIC_TRACE(fnic_fcpio_ack_handler, 754 FNIC_TRACE(fnic_fcpio_ack_handler,
710 fnic->lport->host->host_no, 0, 0, ox_id_tag[2], ox_id_tag[3], 755 fnic->lport->host->host_no, 0, 0, ox_id_tag[2], ox_id_tag[3],
@@ -726,6 +771,7 @@ static void fnic_fcpio_icmnd_cmpl_handler(struct fnic *fnic,
726 struct fcpio_icmnd_cmpl *icmnd_cmpl; 771 struct fcpio_icmnd_cmpl *icmnd_cmpl;
727 struct fnic_io_req *io_req; 772 struct fnic_io_req *io_req;
728 struct scsi_cmnd *sc; 773 struct scsi_cmnd *sc;
774 struct fnic_stats *fnic_stats = &fnic->fnic_stats;
729 unsigned long flags; 775 unsigned long flags;
730 spinlock_t *io_lock; 776 spinlock_t *io_lock;
731 u64 cmd_trace; 777 u64 cmd_trace;
@@ -746,6 +792,7 @@ static void fnic_fcpio_icmnd_cmpl_handler(struct fnic *fnic,
746 sc = scsi_host_find_tag(fnic->lport->host, id); 792 sc = scsi_host_find_tag(fnic->lport->host, id);
747 WARN_ON_ONCE(!sc); 793 WARN_ON_ONCE(!sc);
748 if (!sc) { 794 if (!sc) {
795 atomic64_inc(&fnic_stats->io_stats.sc_null);
749 shost_printk(KERN_ERR, fnic->lport->host, 796 shost_printk(KERN_ERR, fnic->lport->host,
750 "icmnd_cmpl sc is null - " 797 "icmnd_cmpl sc is null - "
751 "hdr status = %s tag = 0x%x desc = 0x%p\n", 798 "hdr status = %s tag = 0x%x desc = 0x%p\n",
@@ -766,6 +813,7 @@ static void fnic_fcpio_icmnd_cmpl_handler(struct fnic *fnic,
766 io_req = (struct fnic_io_req *)CMD_SP(sc); 813 io_req = (struct fnic_io_req *)CMD_SP(sc);
767 WARN_ON_ONCE(!io_req); 814 WARN_ON_ONCE(!io_req);
768 if (!io_req) { 815 if (!io_req) {
816 atomic64_inc(&fnic_stats->io_stats.ioreq_null);
769 CMD_FLAGS(sc) |= FNIC_IO_REQ_NULL; 817 CMD_FLAGS(sc) |= FNIC_IO_REQ_NULL;
770 spin_unlock_irqrestore(io_lock, flags); 818 spin_unlock_irqrestore(io_lock, flags);
771 shost_printk(KERN_ERR, fnic->lport->host, 819 shost_printk(KERN_ERR, fnic->lport->host,
@@ -824,31 +872,54 @@ static void fnic_fcpio_icmnd_cmpl_handler(struct fnic *fnic,
824 if (icmnd_cmpl->flags & FCPIO_ICMND_CMPL_RESID_UNDER) 872 if (icmnd_cmpl->flags & FCPIO_ICMND_CMPL_RESID_UNDER)
825 xfer_len -= icmnd_cmpl->residual; 873 xfer_len -= icmnd_cmpl->residual;
826 874
875 if (icmnd_cmpl->scsi_status == SAM_STAT_TASK_SET_FULL)
876 atomic64_inc(&fnic_stats->misc_stats.queue_fulls);
827 break; 877 break;
828 878
829 case FCPIO_TIMEOUT: /* request was timed out */ 879 case FCPIO_TIMEOUT: /* request was timed out */
880 atomic64_inc(&fnic_stats->misc_stats.fcpio_timeout);
830 sc->result = (DID_TIME_OUT << 16) | icmnd_cmpl->scsi_status; 881 sc->result = (DID_TIME_OUT << 16) | icmnd_cmpl->scsi_status;
831 break; 882 break;
832 883
833 case FCPIO_ABORTED: /* request was aborted */ 884 case FCPIO_ABORTED: /* request was aborted */
885 atomic64_inc(&fnic_stats->misc_stats.fcpio_aborted);
834 sc->result = (DID_ERROR << 16) | icmnd_cmpl->scsi_status; 886 sc->result = (DID_ERROR << 16) | icmnd_cmpl->scsi_status;
835 break; 887 break;
836 888
837 case FCPIO_DATA_CNT_MISMATCH: /* recv/sent more/less data than exp. */ 889 case FCPIO_DATA_CNT_MISMATCH: /* recv/sent more/less data than exp. */
890 atomic64_inc(&fnic_stats->misc_stats.data_count_mismatch);
838 scsi_set_resid(sc, icmnd_cmpl->residual); 891 scsi_set_resid(sc, icmnd_cmpl->residual);
839 sc->result = (DID_ERROR << 16) | icmnd_cmpl->scsi_status; 892 sc->result = (DID_ERROR << 16) | icmnd_cmpl->scsi_status;
840 break; 893 break;
841 894
842 case FCPIO_OUT_OF_RESOURCE: /* out of resources to complete request */ 895 case FCPIO_OUT_OF_RESOURCE: /* out of resources to complete request */
896 atomic64_inc(&fnic_stats->fw_stats.fw_out_of_resources);
843 sc->result = (DID_REQUEUE << 16) | icmnd_cmpl->scsi_status; 897 sc->result = (DID_REQUEUE << 16) | icmnd_cmpl->scsi_status;
844 break; 898 break;
845 case FCPIO_INVALID_HEADER: /* header contains invalid data */ 899
846 case FCPIO_INVALID_PARAM: /* some parameter in request invalid */
847 case FCPIO_REQ_NOT_SUPPORTED:/* request type is not supported */
848 case FCPIO_IO_NOT_FOUND: /* requested I/O was not found */ 900 case FCPIO_IO_NOT_FOUND: /* requested I/O was not found */
901 atomic64_inc(&fnic_stats->io_stats.io_not_found);
902 sc->result = (DID_ERROR << 16) | icmnd_cmpl->scsi_status;
903 break;
904
849 case FCPIO_SGL_INVALID: /* request was aborted due to sgl error */ 905 case FCPIO_SGL_INVALID: /* request was aborted due to sgl error */
850 case FCPIO_MSS_INVALID: /* request was aborted due to mss error */ 906 atomic64_inc(&fnic_stats->misc_stats.sgl_invalid);
907 sc->result = (DID_ERROR << 16) | icmnd_cmpl->scsi_status;
908 break;
909
851 case FCPIO_FW_ERR: /* request was terminated due fw error */ 910 case FCPIO_FW_ERR: /* request was terminated due fw error */
911 atomic64_inc(&fnic_stats->fw_stats.io_fw_errs);
912 sc->result = (DID_ERROR << 16) | icmnd_cmpl->scsi_status;
913 break;
914
915 case FCPIO_MSS_INVALID: /* request was aborted due to mss error */
916 atomic64_inc(&fnic_stats->misc_stats.mss_invalid);
917 sc->result = (DID_ERROR << 16) | icmnd_cmpl->scsi_status;
918 break;
919
920 case FCPIO_INVALID_HEADER: /* header contains invalid data */
921 case FCPIO_INVALID_PARAM: /* some parameter in request invalid */
922 case FCPIO_REQ_NOT_SUPPORTED:/* request type is not supported */
852 default: 923 default:
853 shost_printk(KERN_ERR, fnic->lport->host, "hdr status = %s\n", 924 shost_printk(KERN_ERR, fnic->lport->host, "hdr status = %s\n",
854 fnic_fcpio_status_to_str(hdr_status)); 925 fnic_fcpio_status_to_str(hdr_status));
@@ -856,6 +927,11 @@ static void fnic_fcpio_icmnd_cmpl_handler(struct fnic *fnic,
856 break; 927 break;
857 } 928 }
858 929
930 if (hdr_status != FCPIO_SUCCESS) {
931 atomic64_inc(&fnic_stats->io_stats.io_failures);
932 shost_printk(KERN_ERR, fnic->lport->host, "hdr status = %s\n",
933 fnic_fcpio_status_to_str(hdr_status));
934 }
859 /* Break link with the SCSI command */ 935 /* Break link with the SCSI command */
860 CMD_SP(sc) = NULL; 936 CMD_SP(sc) = NULL;
861 CMD_FLAGS(sc) |= FNIC_IO_DONE; 937 CMD_FLAGS(sc) |= FNIC_IO_DONE;
@@ -889,6 +965,12 @@ static void fnic_fcpio_icmnd_cmpl_handler(struct fnic *fnic,
889 } else 965 } else
890 fnic->lport->host_stats.fcp_control_requests++; 966 fnic->lport->host_stats.fcp_control_requests++;
891 967
968 atomic64_dec(&fnic_stats->io_stats.active_ios);
969 if (atomic64_read(&fnic->io_cmpl_skip))
970 atomic64_dec(&fnic->io_cmpl_skip);
971 else
972 atomic64_inc(&fnic_stats->io_stats.io_completions);
973
892 /* Call SCSI completion function to complete the IO */ 974 /* Call SCSI completion function to complete the IO */
893 if (sc->scsi_done) 975 if (sc->scsi_done)
894 sc->scsi_done(sc); 976 sc->scsi_done(sc);
@@ -906,6 +988,10 @@ static void fnic_fcpio_itmf_cmpl_handler(struct fnic *fnic,
906 u32 id; 988 u32 id;
907 struct scsi_cmnd *sc; 989 struct scsi_cmnd *sc;
908 struct fnic_io_req *io_req; 990 struct fnic_io_req *io_req;
991 struct fnic_stats *fnic_stats = &fnic->fnic_stats;
992 struct abort_stats *abts_stats = &fnic->fnic_stats.abts_stats;
993 struct terminate_stats *term_stats = &fnic->fnic_stats.term_stats;
994 struct misc_stats *misc_stats = &fnic->fnic_stats.misc_stats;
909 unsigned long flags; 995 unsigned long flags;
910 spinlock_t *io_lock; 996 spinlock_t *io_lock;
911 unsigned long start_time; 997 unsigned long start_time;
@@ -923,6 +1009,7 @@ static void fnic_fcpio_itmf_cmpl_handler(struct fnic *fnic,
923 sc = scsi_host_find_tag(fnic->lport->host, id & FNIC_TAG_MASK); 1009 sc = scsi_host_find_tag(fnic->lport->host, id & FNIC_TAG_MASK);
924 WARN_ON_ONCE(!sc); 1010 WARN_ON_ONCE(!sc);
925 if (!sc) { 1011 if (!sc) {
1012 atomic64_inc(&fnic_stats->io_stats.sc_null);
926 shost_printk(KERN_ERR, fnic->lport->host, 1013 shost_printk(KERN_ERR, fnic->lport->host,
927 "itmf_cmpl sc is null - hdr status = %s tag = 0x%x\n", 1014 "itmf_cmpl sc is null - hdr status = %s tag = 0x%x\n",
928 fnic_fcpio_status_to_str(hdr_status), id); 1015 fnic_fcpio_status_to_str(hdr_status), id);
@@ -933,6 +1020,7 @@ static void fnic_fcpio_itmf_cmpl_handler(struct fnic *fnic,
933 io_req = (struct fnic_io_req *)CMD_SP(sc); 1020 io_req = (struct fnic_io_req *)CMD_SP(sc);
934 WARN_ON_ONCE(!io_req); 1021 WARN_ON_ONCE(!io_req);
935 if (!io_req) { 1022 if (!io_req) {
1023 atomic64_inc(&fnic_stats->io_stats.ioreq_null);
936 spin_unlock_irqrestore(io_lock, flags); 1024 spin_unlock_irqrestore(io_lock, flags);
937 CMD_FLAGS(sc) |= FNIC_IO_ABT_TERM_REQ_NULL; 1025 CMD_FLAGS(sc) |= FNIC_IO_ABT_TERM_REQ_NULL;
938 shost_printk(KERN_ERR, fnic->lport->host, 1026 shost_printk(KERN_ERR, fnic->lport->host,
@@ -957,6 +1045,31 @@ static void fnic_fcpio_itmf_cmpl_handler(struct fnic *fnic,
957 spin_unlock_irqrestore(io_lock, flags); 1045 spin_unlock_irqrestore(io_lock, flags);
958 } else if (id & FNIC_TAG_ABORT) { 1046 } else if (id & FNIC_TAG_ABORT) {
959 /* Completion of abort cmd */ 1047 /* Completion of abort cmd */
1048 switch (hdr_status) {
1049 case FCPIO_SUCCESS:
1050 break;
1051 case FCPIO_TIMEOUT:
1052 if (CMD_FLAGS(sc) & FNIC_IO_ABTS_ISSUED)
1053 atomic64_inc(&abts_stats->abort_fw_timeouts);
1054 else
1055 atomic64_inc(
1056 &term_stats->terminate_fw_timeouts);
1057 break;
1058 case FCPIO_IO_NOT_FOUND:
1059 if (CMD_FLAGS(sc) & FNIC_IO_ABTS_ISSUED)
1060 atomic64_inc(&abts_stats->abort_io_not_found);
1061 else
1062 atomic64_inc(
1063 &term_stats->terminate_io_not_found);
1064 break;
1065 default:
1066 if (CMD_FLAGS(sc) & FNIC_IO_ABTS_ISSUED)
1067 atomic64_inc(&abts_stats->abort_failures);
1068 else
1069 atomic64_inc(
1070 &term_stats->terminate_failures);
1071 break;
1072 }
960 if (CMD_STATE(sc) != FNIC_IOREQ_ABTS_PENDING) { 1073 if (CMD_STATE(sc) != FNIC_IOREQ_ABTS_PENDING) {
961 /* This is a late completion. Ignore it */ 1074 /* This is a late completion. Ignore it */
962 spin_unlock_irqrestore(io_lock, flags); 1075 spin_unlock_irqrestore(io_lock, flags);
@@ -964,6 +1077,16 @@ static void fnic_fcpio_itmf_cmpl_handler(struct fnic *fnic,
964 } 1077 }
965 CMD_ABTS_STATUS(sc) = hdr_status; 1078 CMD_ABTS_STATUS(sc) = hdr_status;
966 CMD_FLAGS(sc) |= FNIC_IO_ABT_TERM_DONE; 1079 CMD_FLAGS(sc) |= FNIC_IO_ABT_TERM_DONE;
1080
1081 atomic64_dec(&fnic_stats->io_stats.active_ios);
1082 if (atomic64_read(&fnic->io_cmpl_skip))
1083 atomic64_dec(&fnic->io_cmpl_skip);
1084 else
1085 atomic64_inc(&fnic_stats->io_stats.io_completions);
1086
1087 if (!(CMD_FLAGS(sc) & (FNIC_IO_ABORTED | FNIC_IO_DONE)))
1088 atomic64_inc(&misc_stats->no_icmnd_itmf_cmpls);
1089
967 FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, 1090 FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
968 "abts cmpl recd. id %d status %s\n", 1091 "abts cmpl recd. id %d status %s\n",
969 (int)(id & FNIC_TAG_MASK), 1092 (int)(id & FNIC_TAG_MASK),
@@ -1067,6 +1190,18 @@ static int fnic_fcpio_cmpl_handler(struct vnic_dev *vdev,
1067 struct fnic *fnic = vnic_dev_priv(vdev); 1190 struct fnic *fnic = vnic_dev_priv(vdev);
1068 1191
1069 switch (desc->hdr.type) { 1192 switch (desc->hdr.type) {
1193 case FCPIO_ICMND_CMPL: /* fw completed a command */
1194 case FCPIO_ITMF_CMPL: /* fw completed itmf (abort cmd, lun reset)*/
1195 case FCPIO_FLOGI_REG_CMPL: /* fw completed flogi_reg */
1196 case FCPIO_FLOGI_FIP_REG_CMPL: /* fw completed flogi_fip_reg */
1197 case FCPIO_RESET_CMPL: /* fw completed reset */
1198 atomic64_dec(&fnic->fnic_stats.fw_stats.active_fw_reqs);
1199 break;
1200 default:
1201 break;
1202 }
1203
1204 switch (desc->hdr.type) {
1070 case FCPIO_ACK: /* fw copied copy wq desc to its queue */ 1205 case FCPIO_ACK: /* fw copied copy wq desc to its queue */
1071 fnic_fcpio_ack_handler(fnic, cq_index, desc); 1206 fnic_fcpio_ack_handler(fnic, cq_index, desc);
1072 break; 1207 break;
@@ -1126,6 +1261,7 @@ static void fnic_cleanup_io(struct fnic *fnic, int exclude_id)
1126 struct scsi_cmnd *sc; 1261 struct scsi_cmnd *sc;
1127 spinlock_t *io_lock; 1262 spinlock_t *io_lock;
1128 unsigned long start_time = 0; 1263 unsigned long start_time = 0;
1264 struct fnic_stats *fnic_stats = &fnic->fnic_stats;
1129 1265
1130 for (i = 0; i < fnic->fnic_max_tag_id; i++) { 1266 for (i = 0; i < fnic->fnic_max_tag_id; i++) {
1131 if (i == exclude_id) 1267 if (i == exclude_id)
@@ -1179,6 +1315,11 @@ cleanup_scsi_cmd:
1179 FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, "fnic_cleanup_io:" 1315 FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, "fnic_cleanup_io:"
1180 " DID_TRANSPORT_DISRUPTED\n"); 1316 " DID_TRANSPORT_DISRUPTED\n");
1181 1317
1318 if (atomic64_read(&fnic->io_cmpl_skip))
1319 atomic64_dec(&fnic->io_cmpl_skip);
1320 else
1321 atomic64_inc(&fnic_stats->io_stats.io_completions);
1322
1182 /* Complete the command to SCSI */ 1323 /* Complete the command to SCSI */
1183 if (sc->scsi_done) { 1324 if (sc->scsi_done) {
1184 FNIC_TRACE(fnic_cleanup_io, 1325 FNIC_TRACE(fnic_cleanup_io,
@@ -1262,6 +1403,7 @@ static inline int fnic_queue_abort_io_req(struct fnic *fnic, int tag,
1262{ 1403{
1263 struct vnic_wq_copy *wq = &fnic->wq_copy[0]; 1404 struct vnic_wq_copy *wq = &fnic->wq_copy[0];
1264 struct Scsi_Host *host = fnic->lport->host; 1405 struct Scsi_Host *host = fnic->lport->host;
1406 struct misc_stats *misc_stats = &fnic->fnic_stats.misc_stats;
1265 unsigned long flags; 1407 unsigned long flags;
1266 1408
1267 spin_lock_irqsave(host->host_lock, flags); 1409 spin_lock_irqsave(host->host_lock, flags);
@@ -1283,12 +1425,19 @@ static inline int fnic_queue_abort_io_req(struct fnic *fnic, int tag,
1283 atomic_dec(&fnic->in_flight); 1425 atomic_dec(&fnic->in_flight);
1284 FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, 1426 FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
1285 "fnic_queue_abort_io_req: failure: no descriptors\n"); 1427 "fnic_queue_abort_io_req: failure: no descriptors\n");
1428 atomic64_inc(&misc_stats->abts_cpwq_alloc_failures);
1286 return 1; 1429 return 1;
1287 } 1430 }
1288 fnic_queue_wq_copy_desc_itmf(wq, tag | FNIC_TAG_ABORT, 1431 fnic_queue_wq_copy_desc_itmf(wq, tag | FNIC_TAG_ABORT,
1289 0, task_req, tag, fc_lun, io_req->port_id, 1432 0, task_req, tag, fc_lun, io_req->port_id,
1290 fnic->config.ra_tov, fnic->config.ed_tov); 1433 fnic->config.ra_tov, fnic->config.ed_tov);
1291 1434
1435 atomic64_inc(&fnic->fnic_stats.fw_stats.active_fw_reqs);
1436 if (atomic64_read(&fnic->fnic_stats.fw_stats.active_fw_reqs) >
1437 atomic64_read(&fnic->fnic_stats.fw_stats.max_fw_reqs))
1438 atomic64_set(&fnic->fnic_stats.fw_stats.max_fw_reqs,
1439 atomic64_read(&fnic->fnic_stats.fw_stats.active_fw_reqs));
1440
1292 spin_unlock_irqrestore(&fnic->wq_copy_lock[0], flags); 1441 spin_unlock_irqrestore(&fnic->wq_copy_lock[0], flags);
1293 atomic_dec(&fnic->in_flight); 1442 atomic_dec(&fnic->in_flight);
1294 1443
@@ -1299,10 +1448,13 @@ static void fnic_rport_exch_reset(struct fnic *fnic, u32 port_id)
1299{ 1448{
1300 int tag; 1449 int tag;
1301 int abt_tag; 1450 int abt_tag;
1451 int term_cnt = 0;
1302 struct fnic_io_req *io_req; 1452 struct fnic_io_req *io_req;
1303 spinlock_t *io_lock; 1453 spinlock_t *io_lock;
1304 unsigned long flags; 1454 unsigned long flags;
1305 struct scsi_cmnd *sc; 1455 struct scsi_cmnd *sc;
1456 struct reset_stats *reset_stats = &fnic->fnic_stats.reset_stats;
1457 struct terminate_stats *term_stats = &fnic->fnic_stats.term_stats;
1306 struct scsi_lun fc_lun; 1458 struct scsi_lun fc_lun;
1307 enum fnic_ioreq_state old_ioreq_state; 1459 enum fnic_ioreq_state old_ioreq_state;
1308 1460
@@ -1366,6 +1518,7 @@ static void fnic_rport_exch_reset(struct fnic *fnic, u32 port_id)
1366 CMD_STATE(sc) = FNIC_IOREQ_ABTS_PENDING; 1518 CMD_STATE(sc) = FNIC_IOREQ_ABTS_PENDING;
1367 CMD_ABTS_STATUS(sc) = FCPIO_INVALID_CODE; 1519 CMD_ABTS_STATUS(sc) = FCPIO_INVALID_CODE;
1368 if (CMD_FLAGS(sc) & FNIC_DEVICE_RESET) { 1520 if (CMD_FLAGS(sc) & FNIC_DEVICE_RESET) {
1521 atomic64_inc(&reset_stats->device_reset_terminates);
1369 abt_tag = (tag | FNIC_TAG_DEV_RST); 1522 abt_tag = (tag | FNIC_TAG_DEV_RST);
1370 FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, 1523 FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
1371 "fnic_rport_exch_reset dev rst sc 0x%p\n", 1524 "fnic_rport_exch_reset dev rst sc 0x%p\n",
@@ -1402,8 +1555,12 @@ static void fnic_rport_exch_reset(struct fnic *fnic, u32 port_id)
1402 else 1555 else
1403 CMD_FLAGS(sc) |= FNIC_IO_INTERNAL_TERM_ISSUED; 1556 CMD_FLAGS(sc) |= FNIC_IO_INTERNAL_TERM_ISSUED;
1404 spin_unlock_irqrestore(io_lock, flags); 1557 spin_unlock_irqrestore(io_lock, flags);
1558 atomic64_inc(&term_stats->terminates);
1559 term_cnt++;
1405 } 1560 }
1406 } 1561 }
1562 if (term_cnt > atomic64_read(&term_stats->max_terminates))
1563 atomic64_set(&term_stats->max_terminates, term_cnt);
1407 1564
1408} 1565}
1409 1566
@@ -1411,6 +1568,7 @@ void fnic_terminate_rport_io(struct fc_rport *rport)
1411{ 1568{
1412 int tag; 1569 int tag;
1413 int abt_tag; 1570 int abt_tag;
1571 int term_cnt = 0;
1414 struct fnic_io_req *io_req; 1572 struct fnic_io_req *io_req;
1415 spinlock_t *io_lock; 1573 spinlock_t *io_lock;
1416 unsigned long flags; 1574 unsigned long flags;
@@ -1420,6 +1578,8 @@ void fnic_terminate_rport_io(struct fc_rport *rport)
1420 struct fc_lport *lport; 1578 struct fc_lport *lport;
1421 struct fnic *fnic; 1579 struct fnic *fnic;
1422 struct fc_rport *cmd_rport; 1580 struct fc_rport *cmd_rport;
1581 struct reset_stats *reset_stats;
1582 struct terminate_stats *term_stats;
1423 enum fnic_ioreq_state old_ioreq_state; 1583 enum fnic_ioreq_state old_ioreq_state;
1424 1584
1425 if (!rport) { 1585 if (!rport) {
@@ -1448,6 +1608,9 @@ void fnic_terminate_rport_io(struct fc_rport *rport)
1448 if (fnic->in_remove) 1608 if (fnic->in_remove)
1449 return; 1609 return;
1450 1610
1611 reset_stats = &fnic->fnic_stats.reset_stats;
1612 term_stats = &fnic->fnic_stats.term_stats;
1613
1451 for (tag = 0; tag < fnic->fnic_max_tag_id; tag++) { 1614 for (tag = 0; tag < fnic->fnic_max_tag_id; tag++) {
1452 abt_tag = tag; 1615 abt_tag = tag;
1453 io_lock = fnic_io_lock_tag(fnic, tag); 1616 io_lock = fnic_io_lock_tag(fnic, tag);
@@ -1504,6 +1667,7 @@ void fnic_terminate_rport_io(struct fc_rport *rport)
1504 CMD_STATE(sc) = FNIC_IOREQ_ABTS_PENDING; 1667 CMD_STATE(sc) = FNIC_IOREQ_ABTS_PENDING;
1505 CMD_ABTS_STATUS(sc) = FCPIO_INVALID_CODE; 1668 CMD_ABTS_STATUS(sc) = FCPIO_INVALID_CODE;
1506 if (CMD_FLAGS(sc) & FNIC_DEVICE_RESET) { 1669 if (CMD_FLAGS(sc) & FNIC_DEVICE_RESET) {
1670 atomic64_inc(&reset_stats->device_reset_terminates);
1507 abt_tag = (tag | FNIC_TAG_DEV_RST); 1671 abt_tag = (tag | FNIC_TAG_DEV_RST);
1508 FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, 1672 FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
1509 "fnic_terminate_rport_io dev rst sc 0x%p\n", sc); 1673 "fnic_terminate_rport_io dev rst sc 0x%p\n", sc);
@@ -1540,8 +1704,12 @@ void fnic_terminate_rport_io(struct fc_rport *rport)
1540 else 1704 else
1541 CMD_FLAGS(sc) |= FNIC_IO_INTERNAL_TERM_ISSUED; 1705 CMD_FLAGS(sc) |= FNIC_IO_INTERNAL_TERM_ISSUED;
1542 spin_unlock_irqrestore(io_lock, flags); 1706 spin_unlock_irqrestore(io_lock, flags);
1707 atomic64_inc(&term_stats->terminates);
1708 term_cnt++;
1543 } 1709 }
1544 } 1710 }
1711 if (term_cnt > atomic64_read(&term_stats->max_terminates))
1712 atomic64_set(&term_stats->max_terminates, term_cnt);
1545 1713
1546} 1714}
1547 1715
@@ -1562,6 +1730,9 @@ int fnic_abort_cmd(struct scsi_cmnd *sc)
1562 int ret = SUCCESS; 1730 int ret = SUCCESS;
1563 u32 task_req = 0; 1731 u32 task_req = 0;
1564 struct scsi_lun fc_lun; 1732 struct scsi_lun fc_lun;
1733 struct fnic_stats *fnic_stats;
1734 struct abort_stats *abts_stats;
1735 struct terminate_stats *term_stats;
1565 int tag; 1736 int tag;
1566 DECLARE_COMPLETION_ONSTACK(tm_done); 1737 DECLARE_COMPLETION_ONSTACK(tm_done);
1567 1738
@@ -1572,6 +1743,10 @@ int fnic_abort_cmd(struct scsi_cmnd *sc)
1572 lp = shost_priv(sc->device->host); 1743 lp = shost_priv(sc->device->host);
1573 1744
1574 fnic = lport_priv(lp); 1745 fnic = lport_priv(lp);
1746 fnic_stats = &fnic->fnic_stats;
1747 abts_stats = &fnic->fnic_stats.abts_stats;
1748 term_stats = &fnic->fnic_stats.term_stats;
1749
1575 rport = starget_to_rport(scsi_target(sc->device)); 1750 rport = starget_to_rport(scsi_target(sc->device));
1576 tag = sc->request->tag; 1751 tag = sc->request->tag;
1577 FNIC_SCSI_DBG(KERN_DEBUG, 1752 FNIC_SCSI_DBG(KERN_DEBUG,
@@ -1630,8 +1805,10 @@ int fnic_abort_cmd(struct scsi_cmnd *sc)
1630 */ 1805 */
1631 if (fc_remote_port_chkready(rport) == 0) 1806 if (fc_remote_port_chkready(rport) == 0)
1632 task_req = FCPIO_ITMF_ABT_TASK; 1807 task_req = FCPIO_ITMF_ABT_TASK;
1633 else 1808 else {
1809 atomic64_inc(&fnic_stats->misc_stats.rport_not_ready);
1634 task_req = FCPIO_ITMF_ABT_TASK_TERM; 1810 task_req = FCPIO_ITMF_ABT_TASK_TERM;
1811 }
1635 1812
1636 /* Now queue the abort command to firmware */ 1813 /* Now queue the abort command to firmware */
1637 int_to_scsilun(sc->device->lun, &fc_lun); 1814 int_to_scsilun(sc->device->lun, &fc_lun);
@@ -1646,10 +1823,13 @@ int fnic_abort_cmd(struct scsi_cmnd *sc)
1646 ret = FAILED; 1823 ret = FAILED;
1647 goto fnic_abort_cmd_end; 1824 goto fnic_abort_cmd_end;
1648 } 1825 }
1649 if (task_req == FCPIO_ITMF_ABT_TASK) 1826 if (task_req == FCPIO_ITMF_ABT_TASK) {
1650 CMD_FLAGS(sc) |= FNIC_IO_ABTS_ISSUED; 1827 CMD_FLAGS(sc) |= FNIC_IO_ABTS_ISSUED;
1651 else 1828 atomic64_inc(&fnic_stats->abts_stats.aborts);
1829 } else {
1652 CMD_FLAGS(sc) |= FNIC_IO_TERM_ISSUED; 1830 CMD_FLAGS(sc) |= FNIC_IO_TERM_ISSUED;
1831 atomic64_inc(&fnic_stats->term_stats.terminates);
1832 }
1653 1833
1654 /* 1834 /*
1655 * We queued an abort IO, wait for its completion. 1835 * We queued an abort IO, wait for its completion.
@@ -1667,6 +1847,7 @@ int fnic_abort_cmd(struct scsi_cmnd *sc)
1667 1847
1668 io_req = (struct fnic_io_req *)CMD_SP(sc); 1848 io_req = (struct fnic_io_req *)CMD_SP(sc);
1669 if (!io_req) { 1849 if (!io_req) {
1850 atomic64_inc(&fnic_stats->io_stats.ioreq_null);
1670 spin_unlock_irqrestore(io_lock, flags); 1851 spin_unlock_irqrestore(io_lock, flags);
1671 CMD_FLAGS(sc) |= FNIC_IO_ABT_TERM_REQ_NULL; 1852 CMD_FLAGS(sc) |= FNIC_IO_ABT_TERM_REQ_NULL;
1672 ret = FAILED; 1853 ret = FAILED;
@@ -1677,6 +1858,15 @@ int fnic_abort_cmd(struct scsi_cmnd *sc)
1677 /* fw did not complete abort, timed out */ 1858 /* fw did not complete abort, timed out */
1678 if (CMD_ABTS_STATUS(sc) == FCPIO_INVALID_CODE) { 1859 if (CMD_ABTS_STATUS(sc) == FCPIO_INVALID_CODE) {
1679 spin_unlock_irqrestore(io_lock, flags); 1860 spin_unlock_irqrestore(io_lock, flags);
1861 if (task_req == FCPIO_ITMF_ABT_TASK) {
1862 FNIC_SCSI_DBG(KERN_INFO,
1863 fnic->lport->host, "Abort Driver Timeout\n");
1864 atomic64_inc(&abts_stats->abort_drv_timeouts);
1865 } else {
1866 FNIC_SCSI_DBG(KERN_INFO, fnic->lport->host,
1867 "Terminate Driver Timeout\n");
1868 atomic64_inc(&term_stats->terminate_drv_timeouts);
1869 }
1680 CMD_FLAGS(sc) |= FNIC_IO_ABT_TERM_TIMED_OUT; 1870 CMD_FLAGS(sc) |= FNIC_IO_ABT_TERM_TIMED_OUT;
1681 ret = FAILED; 1871 ret = FAILED;
1682 goto fnic_abort_cmd_end; 1872 goto fnic_abort_cmd_end;
@@ -1721,6 +1911,7 @@ static inline int fnic_queue_dr_io_req(struct fnic *fnic,
1721{ 1911{
1722 struct vnic_wq_copy *wq = &fnic->wq_copy[0]; 1912 struct vnic_wq_copy *wq = &fnic->wq_copy[0];
1723 struct Scsi_Host *host = fnic->lport->host; 1913 struct Scsi_Host *host = fnic->lport->host;
1914 struct misc_stats *misc_stats = &fnic->fnic_stats.misc_stats;
1724 struct scsi_lun fc_lun; 1915 struct scsi_lun fc_lun;
1725 int ret = 0; 1916 int ret = 0;
1726 unsigned long intr_flags; 1917 unsigned long intr_flags;
@@ -1742,6 +1933,7 @@ static inline int fnic_queue_dr_io_req(struct fnic *fnic,
1742 if (!vnic_wq_copy_desc_avail(wq)) { 1933 if (!vnic_wq_copy_desc_avail(wq)) {
1743 FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, 1934 FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
1744 "queue_dr_io_req failure - no descriptors\n"); 1935 "queue_dr_io_req failure - no descriptors\n");
1936 atomic64_inc(&misc_stats->devrst_cpwq_alloc_failures);
1745 ret = -EAGAIN; 1937 ret = -EAGAIN;
1746 goto lr_io_req_end; 1938 goto lr_io_req_end;
1747 } 1939 }
@@ -1754,6 +1946,12 @@ static inline int fnic_queue_dr_io_req(struct fnic *fnic,
1754 fc_lun.scsi_lun, io_req->port_id, 1946 fc_lun.scsi_lun, io_req->port_id,
1755 fnic->config.ra_tov, fnic->config.ed_tov); 1947 fnic->config.ra_tov, fnic->config.ed_tov);
1756 1948
1949 atomic64_inc(&fnic->fnic_stats.fw_stats.active_fw_reqs);
1950 if (atomic64_read(&fnic->fnic_stats.fw_stats.active_fw_reqs) >
1951 atomic64_read(&fnic->fnic_stats.fw_stats.max_fw_reqs))
1952 atomic64_set(&fnic->fnic_stats.fw_stats.max_fw_reqs,
1953 atomic64_read(&fnic->fnic_stats.fw_stats.active_fw_reqs));
1954
1757lr_io_req_end: 1955lr_io_req_end:
1758 spin_unlock_irqrestore(&fnic->wq_copy_lock[0], intr_flags); 1956 spin_unlock_irqrestore(&fnic->wq_copy_lock[0], intr_flags);
1759 atomic_dec(&fnic->in_flight); 1957 atomic_dec(&fnic->in_flight);
@@ -1988,6 +2186,8 @@ int fnic_device_reset(struct scsi_cmnd *sc)
1988 unsigned long flags; 2186 unsigned long flags;
1989 unsigned long start_time = 0; 2187 unsigned long start_time = 0;
1990 struct scsi_lun fc_lun; 2188 struct scsi_lun fc_lun;
2189 struct fnic_stats *fnic_stats;
2190 struct reset_stats *reset_stats;
1991 int tag = 0; 2191 int tag = 0;
1992 DECLARE_COMPLETION_ONSTACK(tm_done); 2192 DECLARE_COMPLETION_ONSTACK(tm_done);
1993 int tag_gen_flag = 0; /*to track tags allocated by fnic driver*/ 2193 int tag_gen_flag = 0; /*to track tags allocated by fnic driver*/
@@ -1999,6 +2199,10 @@ int fnic_device_reset(struct scsi_cmnd *sc)
1999 lp = shost_priv(sc->device->host); 2199 lp = shost_priv(sc->device->host);
2000 2200
2001 fnic = lport_priv(lp); 2201 fnic = lport_priv(lp);
2202 fnic_stats = &fnic->fnic_stats;
2203 reset_stats = &fnic->fnic_stats.reset_stats;
2204
2205 atomic64_inc(&reset_stats->device_resets);
2002 2206
2003 rport = starget_to_rport(scsi_target(sc->device)); 2207 rport = starget_to_rport(scsi_target(sc->device));
2004 FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, 2208 FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
@@ -2009,8 +2213,10 @@ int fnic_device_reset(struct scsi_cmnd *sc)
2009 goto fnic_device_reset_end; 2213 goto fnic_device_reset_end;
2010 2214
2011 /* Check if remote port up */ 2215 /* Check if remote port up */
2012 if (fc_remote_port_chkready(rport)) 2216 if (fc_remote_port_chkready(rport)) {
2217 atomic64_inc(&fnic_stats->misc_stats.rport_not_ready);
2013 goto fnic_device_reset_end; 2218 goto fnic_device_reset_end;
2219 }
2014 2220
2015 CMD_FLAGS(sc) = FNIC_DEVICE_RESET; 2221 CMD_FLAGS(sc) = FNIC_DEVICE_RESET;
2016 /* Allocate tag if not present */ 2222 /* Allocate tag if not present */
@@ -2086,6 +2292,7 @@ int fnic_device_reset(struct scsi_cmnd *sc)
2086 * gets cleaned up during higher levels of EH 2292 * gets cleaned up during higher levels of EH
2087 */ 2293 */
2088 if (status == FCPIO_INVALID_CODE) { 2294 if (status == FCPIO_INVALID_CODE) {
2295 atomic64_inc(&reset_stats->device_reset_timeouts);
2089 FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, 2296 FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
2090 "Device reset timed out\n"); 2297 "Device reset timed out\n");
2091 CMD_FLAGS(sc) |= FNIC_DEV_RST_TIMED_OUT; 2298 CMD_FLAGS(sc) |= FNIC_DEV_RST_TIMED_OUT;
@@ -2199,6 +2406,10 @@ fnic_device_reset_end:
2199 "Returning from device reset %s\n", 2406 "Returning from device reset %s\n",
2200 (ret == SUCCESS) ? 2407 (ret == SUCCESS) ?
2201 "SUCCESS" : "FAILED"); 2408 "SUCCESS" : "FAILED");
2409
2410 if (ret == FAILED)
2411 atomic64_inc(&reset_stats->device_reset_failures);
2412
2202 return ret; 2413 return ret;
2203} 2414}
2204 2415
@@ -2208,13 +2419,17 @@ int fnic_reset(struct Scsi_Host *shost)
2208 struct fc_lport *lp; 2419 struct fc_lport *lp;
2209 struct fnic *fnic; 2420 struct fnic *fnic;
2210 int ret = 0; 2421 int ret = 0;
2422 struct reset_stats *reset_stats;
2211 2423
2212 lp = shost_priv(shost); 2424 lp = shost_priv(shost);
2213 fnic = lport_priv(lp); 2425 fnic = lport_priv(lp);
2426 reset_stats = &fnic->fnic_stats.reset_stats;
2214 2427
2215 FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, 2428 FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
2216 "fnic_reset called\n"); 2429 "fnic_reset called\n");
2217 2430
2431 atomic64_inc(&reset_stats->fnic_resets);
2432
2218 /* 2433 /*
2219 * Reset local port, this will clean up libFC exchanges, 2434 * Reset local port, this will clean up libFC exchanges,
2220 * reset remote port sessions, and if link is up, begin flogi 2435 * reset remote port sessions, and if link is up, begin flogi
@@ -2226,6 +2441,11 @@ int fnic_reset(struct Scsi_Host *shost)
2226 (ret == 0) ? 2441 (ret == 0) ?
2227 "SUCCESS" : "FAILED"); 2442 "SUCCESS" : "FAILED");
2228 2443
2444 if (ret == 0)
2445 atomic64_inc(&reset_stats->fnic_reset_completions);
2446 else
2447 atomic64_inc(&reset_stats->fnic_reset_failures);
2448
2229 return ret; 2449 return ret;
2230} 2450}
2231 2451
diff --git a/drivers/scsi/fnic/fnic_stats.h b/drivers/scsi/fnic/fnic_stats.h
new file mode 100644
index 000000000000..540cceb843cd
--- /dev/null
+++ b/drivers/scsi/fnic/fnic_stats.h
@@ -0,0 +1,116 @@
1/*
2 * Copyright 2013 Cisco Systems, Inc. All rights reserved.
3 *
4 * This program is free software; you may redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
9 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
10 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
11 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
12 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
13 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
14 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
15 * SOFTWARE.
16 */
17#ifndef _FNIC_STATS_H_
18#define _FNIC_STATS_H_
19struct io_path_stats {
20 atomic64_t active_ios;
21 atomic64_t max_active_ios;
22 atomic64_t io_completions;
23 atomic64_t io_failures;
24 atomic64_t ioreq_null;
25 atomic64_t alloc_failures;
26 atomic64_t sc_null;
27 atomic64_t io_not_found;
28 atomic64_t num_ios;
29};
30
31struct abort_stats {
32 atomic64_t aborts;
33 atomic64_t abort_failures;
34 atomic64_t abort_drv_timeouts;
35 atomic64_t abort_fw_timeouts;
36 atomic64_t abort_io_not_found;
37};
38
39struct terminate_stats {
40 atomic64_t terminates;
41 atomic64_t max_terminates;
42 atomic64_t terminate_drv_timeouts;
43 atomic64_t terminate_fw_timeouts;
44 atomic64_t terminate_io_not_found;
45 atomic64_t terminate_failures;
46};
47
48struct reset_stats {
49 atomic64_t device_resets;
50 atomic64_t device_reset_failures;
51 atomic64_t device_reset_aborts;
52 atomic64_t device_reset_timeouts;
53 atomic64_t device_reset_terminates;
54 atomic64_t fw_resets;
55 atomic64_t fw_reset_completions;
56 atomic64_t fw_reset_failures;
57 atomic64_t fnic_resets;
58 atomic64_t fnic_reset_completions;
59 atomic64_t fnic_reset_failures;
60};
61
62struct fw_stats {
63 atomic64_t active_fw_reqs;
64 atomic64_t max_fw_reqs;
65 atomic64_t fw_out_of_resources;
66 atomic64_t io_fw_errs;
67};
68
69struct vlan_stats {
70 atomic64_t vlan_disc_reqs;
71 atomic64_t resp_withno_vlanID;
72 atomic64_t sol_expiry_count;
73 atomic64_t flogi_rejects;
74};
75
76struct misc_stats {
77 u64 last_isr_time;
78 u64 last_ack_time;
79 atomic64_t isr_count;
80 atomic64_t max_cq_entries;
81 atomic64_t ack_index_out_of_range;
82 atomic64_t data_count_mismatch;
83 atomic64_t fcpio_timeout;
84 atomic64_t fcpio_aborted;
85 atomic64_t sgl_invalid;
86 atomic64_t mss_invalid;
87 atomic64_t abts_cpwq_alloc_failures;
88 atomic64_t devrst_cpwq_alloc_failures;
89 atomic64_t io_cpwq_alloc_failures;
90 atomic64_t no_icmnd_itmf_cmpls;
91 atomic64_t queue_fulls;
92 atomic64_t rport_not_ready;
93 atomic64_t frame_errors;
94};
95
96struct fnic_stats {
97 struct io_path_stats io_stats;
98 struct abort_stats abts_stats;
99 struct terminate_stats term_stats;
100 struct reset_stats reset_stats;
101 struct fw_stats fw_stats;
102 struct vlan_stats vlan_stats;
103 struct misc_stats misc_stats;
104};
105
106struct stats_debug_info {
107 char *debug_buffer;
108 void *i_private;
109 int buf_size;
110 int buffer_len;
111};
112
113int fnic_get_stats_data(struct stats_debug_info *, struct fnic_stats *);
114int fnic_stats_debugfs_init(struct fnic *);
115void fnic_stats_debugfs_remove(struct fnic *);
116#endif /* _FNIC_STATS_H_ */
diff --git a/drivers/scsi/fnic/fnic_trace.c b/drivers/scsi/fnic/fnic_trace.c
index 23a60e3d8527..e002e7187dc0 100644
--- a/drivers/scsi/fnic/fnic_trace.c
+++ b/drivers/scsi/fnic/fnic_trace.c
@@ -189,6 +189,191 @@ int fnic_get_trace_data(fnic_dbgfs_t *fnic_dbgfs_prt)
189} 189}
190 190
191/* 191/*
192 * fnic_get_stats_data - Copy fnic stats buffer to a memory file
193 * @fnic_dbgfs_t: pointer to debugfs fnic stats buffer
194 *
195 * Description:
196 * This routine gathers the fnic stats debugfs data from the fnic_stats struct
197 * and dumps it to stats_debug_info.
198 *
199 * Return Value:
200 * This routine returns the amount of bytes that were dumped into
201 * stats_debug_info
202 */
203int fnic_get_stats_data(struct stats_debug_info *debug,
204 struct fnic_stats *stats)
205{
206 int len = 0;
207 int buf_size = debug->buf_size;
208 struct timespec val1, val2;
209
210 len = snprintf(debug->debug_buffer + len, buf_size - len,
211 "------------------------------------------\n"
212 "\t\tIO Statistics\n"
213 "------------------------------------------\n");
214 len += snprintf(debug->debug_buffer + len, buf_size - len,
215 "Number of Active IOs: %lld\nMaximum Active IOs: %lld\n"
216 "Number of IOs: %lld\nNumber of IO Completions: %lld\n"
217 "Number of IO Failures: %lld\nNumber of IO NOT Found: %lld\n"
218 "Number of Memory alloc Failures: %lld\n"
219 "Number of IOREQ Null: %lld\n"
220 "Number of SCSI cmd pointer Null: %lld\n",
221 (u64)atomic64_read(&stats->io_stats.active_ios),
222 (u64)atomic64_read(&stats->io_stats.max_active_ios),
223 (u64)atomic64_read(&stats->io_stats.num_ios),
224 (u64)atomic64_read(&stats->io_stats.io_completions),
225 (u64)atomic64_read(&stats->io_stats.io_failures),
226 (u64)atomic64_read(&stats->io_stats.io_not_found),
227 (u64)atomic64_read(&stats->io_stats.alloc_failures),
228 (u64)atomic64_read(&stats->io_stats.ioreq_null),
229 (u64)atomic64_read(&stats->io_stats.sc_null));
230
231 len += snprintf(debug->debug_buffer + len, buf_size - len,
232 "\n------------------------------------------\n"
233 "\t\tAbort Statistics\n"
234 "------------------------------------------\n");
235 len += snprintf(debug->debug_buffer + len, buf_size - len,
236 "Number of Aborts: %lld\n"
237 "Number of Abort Failures: %lld\n"
238 "Number of Abort Driver Timeouts: %lld\n"
239 "Number of Abort FW Timeouts: %lld\n"
240 "Number of Abort IO NOT Found: %lld\n",
241 (u64)atomic64_read(&stats->abts_stats.aborts),
242 (u64)atomic64_read(&stats->abts_stats.abort_failures),
243 (u64)atomic64_read(&stats->abts_stats.abort_drv_timeouts),
244 (u64)atomic64_read(&stats->abts_stats.abort_fw_timeouts),
245 (u64)atomic64_read(&stats->abts_stats.abort_io_not_found));
246
247 len += snprintf(debug->debug_buffer + len, buf_size - len,
248 "\n------------------------------------------\n"
249 "\t\tTerminate Statistics\n"
250 "------------------------------------------\n");
251 len += snprintf(debug->debug_buffer + len, buf_size - len,
252 "Number of Terminates: %lld\n"
253 "Maximum Terminates: %lld\n"
254 "Number of Terminate Driver Timeouts: %lld\n"
255 "Number of Terminate FW Timeouts: %lld\n"
256 "Number of Terminate IO NOT Found: %lld\n"
257 "Number of Terminate Failures: %lld\n",
258 (u64)atomic64_read(&stats->term_stats.terminates),
259 (u64)atomic64_read(&stats->term_stats.max_terminates),
260 (u64)atomic64_read(&stats->term_stats.terminate_drv_timeouts),
261 (u64)atomic64_read(&stats->term_stats.terminate_fw_timeouts),
262 (u64)atomic64_read(&stats->term_stats.terminate_io_not_found),
263 (u64)atomic64_read(&stats->term_stats.terminate_failures));
264
265 len += snprintf(debug->debug_buffer + len, buf_size - len,
266 "\n------------------------------------------\n"
267 "\t\tReset Statistics\n"
268 "------------------------------------------\n");
269
270 len += snprintf(debug->debug_buffer + len, buf_size - len,
271 "Number of Device Resets: %lld\n"
272 "Number of Device Reset Failures: %lld\n"
273 "Number of Device Reset Aborts: %lld\n"
274 "Number of Device Reset Timeouts: %lld\n"
275 "Number of Device Reset Terminates: %lld\n"
276 "Number of FW Resets: %lld\n"
277 "Number of FW Reset Completions: %lld\n"
278 "Number of FW Reset Failures: %lld\n"
279 "Number of Fnic Reset: %lld\n"
280 "Number of Fnic Reset Completions: %lld\n"
281 "Number of Fnic Reset Failures: %lld\n",
282 (u64)atomic64_read(&stats->reset_stats.device_resets),
283 (u64)atomic64_read(&stats->reset_stats.device_reset_failures),
284 (u64)atomic64_read(&stats->reset_stats.device_reset_aborts),
285 (u64)atomic64_read(&stats->reset_stats.device_reset_timeouts),
286 (u64)atomic64_read(
287 &stats->reset_stats.device_reset_terminates),
288 (u64)atomic64_read(&stats->reset_stats.fw_resets),
289 (u64)atomic64_read(&stats->reset_stats.fw_reset_completions),
290 (u64)atomic64_read(&stats->reset_stats.fw_reset_failures),
291 (u64)atomic64_read(&stats->reset_stats.fnic_resets),
292 (u64)atomic64_read(
293 &stats->reset_stats.fnic_reset_completions),
294 (u64)atomic64_read(&stats->reset_stats.fnic_reset_failures));
295
296 len += snprintf(debug->debug_buffer + len, buf_size - len,
297 "\n------------------------------------------\n"
298 "\t\tFirmware Statistics\n"
299 "------------------------------------------\n");
300
301 len += snprintf(debug->debug_buffer + len, buf_size - len,
302 "Number of Active FW Requests %lld\n"
303 "Maximum FW Requests: %lld\n"
304 "Number of FW out of resources: %lld\n"
305 "Number of FW IO errors: %lld\n",
306 (u64)atomic64_read(&stats->fw_stats.active_fw_reqs),
307 (u64)atomic64_read(&stats->fw_stats.max_fw_reqs),
308 (u64)atomic64_read(&stats->fw_stats.fw_out_of_resources),
309 (u64)atomic64_read(&stats->fw_stats.io_fw_errs));
310
311 len += snprintf(debug->debug_buffer + len, buf_size - len,
312 "\n------------------------------------------\n"
313 "\t\tVlan Discovery Statistics\n"
314 "------------------------------------------\n");
315
316 len += snprintf(debug->debug_buffer + len, buf_size - len,
317 "Number of Vlan Discovery Requests Sent %lld\n"
318 "Vlan Response Received with no FCF VLAN ID: %lld\n"
319 "No solicitations recvd after vlan set, expiry count: %lld\n"
320 "Flogi rejects count: %lld\n",
321 (u64)atomic64_read(&stats->vlan_stats.vlan_disc_reqs),
322 (u64)atomic64_read(&stats->vlan_stats.resp_withno_vlanID),
323 (u64)atomic64_read(&stats->vlan_stats.sol_expiry_count),
324 (u64)atomic64_read(&stats->vlan_stats.flogi_rejects));
325
326 len += snprintf(debug->debug_buffer + len, buf_size - len,
327 "\n------------------------------------------\n"
328 "\t\tOther Important Statistics\n"
329 "------------------------------------------\n");
330
331 jiffies_to_timespec(stats->misc_stats.last_isr_time, &val1);
332 jiffies_to_timespec(stats->misc_stats.last_ack_time, &val2);
333
334 len += snprintf(debug->debug_buffer + len, buf_size - len,
335 "Last ISR time: %llu (%8lu.%8lu)\n"
336 "Last ACK time: %llu (%8lu.%8lu)\n"
337 "Number of ISRs: %lld\n"
338 "Maximum CQ Entries: %lld\n"
339 "Number of ACK index out of range: %lld\n"
340 "Number of data count mismatch: %lld\n"
341 "Number of FCPIO Timeouts: %lld\n"
342 "Number of FCPIO Aborted: %lld\n"
343 "Number of SGL Invalid: %lld\n"
344 "Number of Copy WQ Alloc Failures for ABTs: %lld\n"
345 "Number of Copy WQ Alloc Failures for Device Reset: %lld\n"
346 "Number of Copy WQ Alloc Failures for IOs: %lld\n"
347 "Number of no icmnd itmf Completions: %lld\n"
348 "Number of QUEUE Fulls: %lld\n"
349 "Number of rport not ready: %lld\n"
350 "Number of receive frame errors: %lld\n",
351 (u64)stats->misc_stats.last_isr_time,
352 val1.tv_sec, val1.tv_nsec,
353 (u64)stats->misc_stats.last_ack_time,
354 val2.tv_sec, val2.tv_nsec,
355 (u64)atomic64_read(&stats->misc_stats.isr_count),
356 (u64)atomic64_read(&stats->misc_stats.max_cq_entries),
357 (u64)atomic64_read(&stats->misc_stats.ack_index_out_of_range),
358 (u64)atomic64_read(&stats->misc_stats.data_count_mismatch),
359 (u64)atomic64_read(&stats->misc_stats.fcpio_timeout),
360 (u64)atomic64_read(&stats->misc_stats.fcpio_aborted),
361 (u64)atomic64_read(&stats->misc_stats.sgl_invalid),
362 (u64)atomic64_read(
363 &stats->misc_stats.abts_cpwq_alloc_failures),
364 (u64)atomic64_read(
365 &stats->misc_stats.devrst_cpwq_alloc_failures),
366 (u64)atomic64_read(&stats->misc_stats.io_cpwq_alloc_failures),
367 (u64)atomic64_read(&stats->misc_stats.no_icmnd_itmf_cmpls),
368 (u64)atomic64_read(&stats->misc_stats.queue_fulls),
369 (u64)atomic64_read(&stats->misc_stats.rport_not_ready),
370 (u64)atomic64_read(&stats->misc_stats.frame_errors));
371
372 return len;
373
374}
375
376/*
192 * fnic_trace_buf_init - Initialize fnic trace buffer logging facility 377 * fnic_trace_buf_init - Initialize fnic trace buffer logging facility
193 * 378 *
194 * Description: 379 * Description:
diff --git a/drivers/scsi/fnic/fnic_trace.h b/drivers/scsi/fnic/fnic_trace.h
index cef42b4c4d6c..d412f2ee3c4f 100644
--- a/drivers/scsi/fnic/fnic_trace.h
+++ b/drivers/scsi/fnic/fnic_trace.h
@@ -84,7 +84,8 @@ fnic_trace_data_t *fnic_trace_get_buf(void);
84int fnic_get_trace_data(fnic_dbgfs_t *); 84int fnic_get_trace_data(fnic_dbgfs_t *);
85int fnic_trace_buf_init(void); 85int fnic_trace_buf_init(void);
86void fnic_trace_free(void); 86void fnic_trace_free(void);
87int fnic_debugfs_init(void);
88void fnic_debugfs_terminate(void);
87int fnic_trace_debugfs_init(void); 89int fnic_trace_debugfs_init(void);
88void fnic_trace_debugfs_terminate(void); 90void fnic_trace_debugfs_terminate(void);
89
90#endif 91#endif