root/drivers/infiniband/hw/qib/qib_debugfs.c

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

DEFINITIONS

This source file includes following definitions.
  1. _opcode_stats_seq_start
  2. _opcode_stats_seq_next
  3. _opcode_stats_seq_stop
  4. _opcode_stats_seq_show
  5. DEBUGFS_FILE
  6. _ctx_stats_seq_next
  7. _ctx_stats_seq_stop
  8. _ctx_stats_seq_show
  9. DEBUGFS_FILE
  10. _qp_stats_seq_next
  11. _qp_stats_seq_stop
  12. _qp_stats_seq_show
  13. DEBUGFS_FILE
  14. qib_dbg_ibdev_exit
  15. qib_dbg_init
  16. qib_dbg_exit

   1 /*
   2  * Copyright (c) 2013 - 2017 Intel Corporation.  All rights reserved.
   3  *
   4  * This software is available to you under a choice of one of two
   5  * licenses.  You may choose to be licensed under the terms of the GNU
   6  * General Public License (GPL) Version 2, available from the file
   7  * COPYING in the main directory of this source tree, or the
   8  * OpenIB.org BSD license below:
   9  *
  10  *     Redistribution and use in source and binary forms, with or
  11  *     without modification, are permitted provided that the following
  12  *     conditions are met:
  13  *
  14  *      - Redistributions of source code must retain the above
  15  *        copyright notice, this list of conditions and the following
  16  *        disclaimer.
  17  *
  18  *      - Redistributions in binary form must reproduce the above
  19  *        copyright notice, this list of conditions and the following
  20  *        disclaimer in the documentation and/or other materials
  21  *        provided with the distribution.
  22  *
  23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  24  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  25  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  26  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  27  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  28  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  29  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  30  * SOFTWARE.
  31  */
  32 #include <linux/debugfs.h>
  33 #include <linux/seq_file.h>
  34 #include <linux/kernel.h>
  35 #include <linux/export.h>
  36 
  37 #include "qib.h"
  38 #include "qib_verbs.h"
  39 #include "qib_debugfs.h"
  40 
  41 static struct dentry *qib_dbg_root;
  42 
  43 #define DEBUGFS_FILE(name) \
  44 static const struct seq_operations _##name##_seq_ops = { \
  45         .start = _##name##_seq_start, \
  46         .next  = _##name##_seq_next, \
  47         .stop  = _##name##_seq_stop, \
  48         .show  = _##name##_seq_show \
  49 }; \
  50 static int _##name##_open(struct inode *inode, struct file *s) \
  51 { \
  52         struct seq_file *seq; \
  53         int ret; \
  54         ret =  seq_open(s, &_##name##_seq_ops); \
  55         if (ret) \
  56                 return ret; \
  57         seq = s->private_data; \
  58         seq->private = inode->i_private; \
  59         return 0; \
  60 } \
  61 static const struct file_operations _##name##_file_ops = { \
  62         .owner   = THIS_MODULE, \
  63         .open    = _##name##_open, \
  64         .read    = seq_read, \
  65         .llseek  = seq_lseek, \
  66         .release = seq_release \
  67 };
  68 
  69 static void *_opcode_stats_seq_start(struct seq_file *s, loff_t *pos)
  70 {
  71         struct qib_opcode_stats_perctx *opstats;
  72 
  73         if (*pos >= ARRAY_SIZE(opstats->stats))
  74                 return NULL;
  75         return pos;
  76 }
  77 
  78 static void *_opcode_stats_seq_next(struct seq_file *s, void *v, loff_t *pos)
  79 {
  80         struct qib_opcode_stats_perctx *opstats;
  81 
  82         ++*pos;
  83         if (*pos >= ARRAY_SIZE(opstats->stats))
  84                 return NULL;
  85         return pos;
  86 }
  87 
  88 
  89 static void _opcode_stats_seq_stop(struct seq_file *s, void *v)
  90 {
  91         /* nothing allocated */
  92 }
  93 
  94 static int _opcode_stats_seq_show(struct seq_file *s, void *v)
  95 {
  96         loff_t *spos = v;
  97         loff_t i = *spos, j;
  98         u64 n_packets = 0, n_bytes = 0;
  99         struct qib_ibdev *ibd = (struct qib_ibdev *)s->private;
 100         struct qib_devdata *dd = dd_from_dev(ibd);
 101 
 102         for (j = 0; j < dd->first_user_ctxt; j++) {
 103                 if (!dd->rcd[j])
 104                         continue;
 105                 n_packets += dd->rcd[j]->opstats->stats[i].n_packets;
 106                 n_bytes += dd->rcd[j]->opstats->stats[i].n_bytes;
 107         }
 108         if (!n_packets && !n_bytes)
 109                 return SEQ_SKIP;
 110         seq_printf(s, "%02llx %llu/%llu\n", i,
 111                 (unsigned long long) n_packets,
 112                 (unsigned long long) n_bytes);
 113 
 114         return 0;
 115 }
 116 
 117 DEBUGFS_FILE(opcode_stats)
 118 
 119 static void *_ctx_stats_seq_start(struct seq_file *s, loff_t *pos)
 120 {
 121         struct qib_ibdev *ibd = (struct qib_ibdev *)s->private;
 122         struct qib_devdata *dd = dd_from_dev(ibd);
 123 
 124         if (!*pos)
 125                 return SEQ_START_TOKEN;
 126         if (*pos >= dd->first_user_ctxt)
 127                 return NULL;
 128         return pos;
 129 }
 130 
 131 static void *_ctx_stats_seq_next(struct seq_file *s, void *v, loff_t *pos)
 132 {
 133         struct qib_ibdev *ibd = (struct qib_ibdev *)s->private;
 134         struct qib_devdata *dd = dd_from_dev(ibd);
 135 
 136         if (v == SEQ_START_TOKEN)
 137                 return pos;
 138 
 139         ++*pos;
 140         if (*pos >= dd->first_user_ctxt)
 141                 return NULL;
 142         return pos;
 143 }
 144 
 145 static void _ctx_stats_seq_stop(struct seq_file *s, void *v)
 146 {
 147         /* nothing allocated */
 148 }
 149 
 150 static int _ctx_stats_seq_show(struct seq_file *s, void *v)
 151 {
 152         loff_t *spos;
 153         loff_t i, j;
 154         u64 n_packets = 0;
 155         struct qib_ibdev *ibd = (struct qib_ibdev *)s->private;
 156         struct qib_devdata *dd = dd_from_dev(ibd);
 157 
 158         if (v == SEQ_START_TOKEN) {
 159                 seq_puts(s, "Ctx:npkts\n");
 160                 return 0;
 161         }
 162 
 163         spos = v;
 164         i = *spos;
 165 
 166         if (!dd->rcd[i])
 167                 return SEQ_SKIP;
 168 
 169         for (j = 0; j < ARRAY_SIZE(dd->rcd[i]->opstats->stats); j++)
 170                 n_packets += dd->rcd[i]->opstats->stats[j].n_packets;
 171 
 172         if (!n_packets)
 173                 return SEQ_SKIP;
 174 
 175         seq_printf(s, "  %llu:%llu\n", i, n_packets);
 176         return 0;
 177 }
 178 
 179 DEBUGFS_FILE(ctx_stats)
 180 
 181 static void *_qp_stats_seq_start(struct seq_file *s, loff_t *pos)
 182         __acquires(RCU)
 183 {
 184         struct rvt_qp_iter *iter;
 185         loff_t n = *pos;
 186 
 187         iter = rvt_qp_iter_init(s->private, 0, NULL);
 188 
 189         /* stop calls rcu_read_unlock */
 190         rcu_read_lock();
 191 
 192         if (!iter)
 193                 return NULL;
 194 
 195         do {
 196                 if (rvt_qp_iter_next(iter)) {
 197                         kfree(iter);
 198                         return NULL;
 199                 }
 200         } while (n--);
 201 
 202         return iter;
 203 }
 204 
 205 static void *_qp_stats_seq_next(struct seq_file *s, void *iter_ptr,
 206                                    loff_t *pos)
 207         __must_hold(RCU)
 208 {
 209         struct rvt_qp_iter *iter = iter_ptr;
 210 
 211         (*pos)++;
 212 
 213         if (rvt_qp_iter_next(iter)) {
 214                 kfree(iter);
 215                 return NULL;
 216         }
 217 
 218         return iter;
 219 }
 220 
 221 static void _qp_stats_seq_stop(struct seq_file *s, void *iter_ptr)
 222         __releases(RCU)
 223 {
 224         rcu_read_unlock();
 225 }
 226 
 227 static int _qp_stats_seq_show(struct seq_file *s, void *iter_ptr)
 228 {
 229         struct rvt_qp_iter *iter = iter_ptr;
 230 
 231         if (!iter)
 232                 return 0;
 233 
 234         qib_qp_iter_print(s, iter);
 235 
 236         return 0;
 237 }
 238 
 239 DEBUGFS_FILE(qp_stats)
 240 
 241 void qib_dbg_ibdev_init(struct qib_ibdev *ibd)
 242 {
 243         struct dentry *root;
 244         char name[10];
 245 
 246         snprintf(name, sizeof(name), "qib%d", dd_from_dev(ibd)->unit);
 247         root = debugfs_create_dir(name, qib_dbg_root);
 248         ibd->qib_ibdev_dbg = root;
 249 
 250         debugfs_create_file("opcode_stats", 0400, root, ibd,
 251                             &_opcode_stats_file_ops);
 252         debugfs_create_file("ctx_stats", 0400, root, ibd, &_ctx_stats_file_ops);
 253         debugfs_create_file("qp_stats", 0400, root, ibd, &_qp_stats_file_ops);
 254 }
 255 
 256 void qib_dbg_ibdev_exit(struct qib_ibdev *ibd)
 257 {
 258         if (!qib_dbg_root)
 259                 goto out;
 260         debugfs_remove_recursive(ibd->qib_ibdev_dbg);
 261 out:
 262         ibd->qib_ibdev_dbg = NULL;
 263 }
 264 
 265 void qib_dbg_init(void)
 266 {
 267         qib_dbg_root = debugfs_create_dir(QIB_DRV_NAME, NULL);
 268 }
 269 
 270 void qib_dbg_exit(void)
 271 {
 272         debugfs_remove_recursive(qib_dbg_root);
 273         qib_dbg_root = NULL;
 274 }

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