root/drivers/scsi/snic/snic_debugfs.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. snic_debugfs_init
  2. snic_debugfs_term
  3. snic_reset_stats_open
  4. snic_reset_stats_read
  5. snic_reset_stats_write
  6. snic_reset_stats_release
  7. snic_stats_show
  8. snic_stats_open
  9. snic_stats_debugfs_init
  10. snic_stats_debugfs_remove
  11. snic_trc_seq_start
  12. snic_trc_seq_next
  13. snic_trc_seq_stop
  14. snic_trc_seq_show
  15. snic_trc_open
  16. snic_trc_debugfs_init
  17. snic_trc_debugfs_term

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

/* [<][>][^][v][top][bottom][index][help] */