Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright (c) 2013 - 2017 Intel Corporation.  All rights reserved.
0003  *
0004  * This software is available to you under a choice of one of two
0005  * licenses.  You may choose to be licensed under the terms of the GNU
0006  * General Public License (GPL) Version 2, available from the file
0007  * COPYING in the main directory of this source tree, or the
0008  * OpenIB.org BSD license below:
0009  *
0010  *     Redistribution and use in source and binary forms, with or
0011  *     without modification, are permitted provided that the following
0012  *     conditions are met:
0013  *
0014  *      - Redistributions of source code must retain the above
0015  *        copyright notice, this list of conditions and the following
0016  *        disclaimer.
0017  *
0018  *      - Redistributions in binary form must reproduce the above
0019  *        copyright notice, this list of conditions and the following
0020  *        disclaimer in the documentation and/or other materials
0021  *        provided with the distribution.
0022  *
0023  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
0024  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
0025  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
0026  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
0027  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
0028  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
0029  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
0030  * SOFTWARE.
0031  */
0032 #include <linux/debugfs.h>
0033 #include <linux/seq_file.h>
0034 #include <linux/kernel.h>
0035 #include <linux/export.h>
0036 
0037 #include "qib.h"
0038 #include "qib_verbs.h"
0039 #include "qib_debugfs.h"
0040 
0041 static struct dentry *qib_dbg_root;
0042 
0043 #define DEBUGFS_FILE(name) \
0044 static const struct seq_operations _##name##_seq_ops = { \
0045     .start = _##name##_seq_start, \
0046     .next  = _##name##_seq_next, \
0047     .stop  = _##name##_seq_stop, \
0048     .show  = _##name##_seq_show \
0049 }; \
0050 static int _##name##_open(struct inode *inode, struct file *s) \
0051 { \
0052     struct seq_file *seq; \
0053     int ret; \
0054     ret =  seq_open(s, &_##name##_seq_ops); \
0055     if (ret) \
0056         return ret; \
0057     seq = s->private_data; \
0058     seq->private = inode->i_private; \
0059     return 0; \
0060 } \
0061 static const struct file_operations _##name##_file_ops = { \
0062     .owner   = THIS_MODULE, \
0063     .open    = _##name##_open, \
0064     .read    = seq_read, \
0065     .llseek  = seq_lseek, \
0066     .release = seq_release \
0067 };
0068 
0069 static void *_opcode_stats_seq_start(struct seq_file *s, loff_t *pos)
0070 {
0071     struct qib_opcode_stats_perctx *opstats;
0072 
0073     if (*pos >= ARRAY_SIZE(opstats->stats))
0074         return NULL;
0075     return pos;
0076 }
0077 
0078 static void *_opcode_stats_seq_next(struct seq_file *s, void *v, loff_t *pos)
0079 {
0080     struct qib_opcode_stats_perctx *opstats;
0081 
0082     ++*pos;
0083     if (*pos >= ARRAY_SIZE(opstats->stats))
0084         return NULL;
0085     return pos;
0086 }
0087 
0088 
0089 static void _opcode_stats_seq_stop(struct seq_file *s, void *v)
0090 {
0091     /* nothing allocated */
0092 }
0093 
0094 static int _opcode_stats_seq_show(struct seq_file *s, void *v)
0095 {
0096     loff_t *spos = v;
0097     loff_t i = *spos, j;
0098     u64 n_packets = 0, n_bytes = 0;
0099     struct qib_ibdev *ibd = (struct qib_ibdev *)s->private;
0100     struct qib_devdata *dd = dd_from_dev(ibd);
0101 
0102     for (j = 0; j < dd->first_user_ctxt; j++) {
0103         if (!dd->rcd[j])
0104             continue;
0105         n_packets += dd->rcd[j]->opstats->stats[i].n_packets;
0106         n_bytes += dd->rcd[j]->opstats->stats[i].n_bytes;
0107     }
0108     if (!n_packets && !n_bytes)
0109         return SEQ_SKIP;
0110     seq_printf(s, "%02llx %llu/%llu\n", i,
0111         (unsigned long long) n_packets,
0112         (unsigned long long) n_bytes);
0113 
0114     return 0;
0115 }
0116 
0117 DEBUGFS_FILE(opcode_stats)
0118 
0119 static void *_ctx_stats_seq_start(struct seq_file *s, loff_t *pos)
0120 {
0121     struct qib_ibdev *ibd = (struct qib_ibdev *)s->private;
0122     struct qib_devdata *dd = dd_from_dev(ibd);
0123 
0124     if (!*pos)
0125         return SEQ_START_TOKEN;
0126     if (*pos >= dd->first_user_ctxt)
0127         return NULL;
0128     return pos;
0129 }
0130 
0131 static void *_ctx_stats_seq_next(struct seq_file *s, void *v, loff_t *pos)
0132 {
0133     struct qib_ibdev *ibd = (struct qib_ibdev *)s->private;
0134     struct qib_devdata *dd = dd_from_dev(ibd);
0135 
0136     if (v == SEQ_START_TOKEN)
0137         return pos;
0138 
0139     ++*pos;
0140     if (*pos >= dd->first_user_ctxt)
0141         return NULL;
0142     return pos;
0143 }
0144 
0145 static void _ctx_stats_seq_stop(struct seq_file *s, void *v)
0146 {
0147     /* nothing allocated */
0148 }
0149 
0150 static int _ctx_stats_seq_show(struct seq_file *s, void *v)
0151 {
0152     loff_t *spos;
0153     loff_t i, j;
0154     u64 n_packets = 0;
0155     struct qib_ibdev *ibd = (struct qib_ibdev *)s->private;
0156     struct qib_devdata *dd = dd_from_dev(ibd);
0157 
0158     if (v == SEQ_START_TOKEN) {
0159         seq_puts(s, "Ctx:npkts\n");
0160         return 0;
0161     }
0162 
0163     spos = v;
0164     i = *spos;
0165 
0166     if (!dd->rcd[i])
0167         return SEQ_SKIP;
0168 
0169     for (j = 0; j < ARRAY_SIZE(dd->rcd[i]->opstats->stats); j++)
0170         n_packets += dd->rcd[i]->opstats->stats[j].n_packets;
0171 
0172     if (!n_packets)
0173         return SEQ_SKIP;
0174 
0175     seq_printf(s, "  %llu:%llu\n", i, n_packets);
0176     return 0;
0177 }
0178 
0179 DEBUGFS_FILE(ctx_stats)
0180 
0181 static void *_qp_stats_seq_start(struct seq_file *s, loff_t *pos)
0182     __acquires(RCU)
0183 {
0184     struct rvt_qp_iter *iter;
0185     loff_t n = *pos;
0186 
0187     iter = rvt_qp_iter_init(s->private, 0, NULL);
0188 
0189     /* stop calls rcu_read_unlock */
0190     rcu_read_lock();
0191 
0192     if (!iter)
0193         return NULL;
0194 
0195     do {
0196         if (rvt_qp_iter_next(iter)) {
0197             kfree(iter);
0198             return NULL;
0199         }
0200     } while (n--);
0201 
0202     return iter;
0203 }
0204 
0205 static void *_qp_stats_seq_next(struct seq_file *s, void *iter_ptr,
0206                    loff_t *pos)
0207     __must_hold(RCU)
0208 {
0209     struct rvt_qp_iter *iter = iter_ptr;
0210 
0211     (*pos)++;
0212 
0213     if (rvt_qp_iter_next(iter)) {
0214         kfree(iter);
0215         return NULL;
0216     }
0217 
0218     return iter;
0219 }
0220 
0221 static void _qp_stats_seq_stop(struct seq_file *s, void *iter_ptr)
0222     __releases(RCU)
0223 {
0224     rcu_read_unlock();
0225 }
0226 
0227 static int _qp_stats_seq_show(struct seq_file *s, void *iter_ptr)
0228 {
0229     struct rvt_qp_iter *iter = iter_ptr;
0230 
0231     if (!iter)
0232         return 0;
0233 
0234     qib_qp_iter_print(s, iter);
0235 
0236     return 0;
0237 }
0238 
0239 DEBUGFS_FILE(qp_stats)
0240 
0241 void qib_dbg_ibdev_init(struct qib_ibdev *ibd)
0242 {
0243     struct dentry *root;
0244     char name[10];
0245 
0246     snprintf(name, sizeof(name), "qib%d", dd_from_dev(ibd)->unit);
0247     root = debugfs_create_dir(name, qib_dbg_root);
0248     ibd->qib_ibdev_dbg = root;
0249 
0250     debugfs_create_file("opcode_stats", 0400, root, ibd,
0251                 &_opcode_stats_file_ops);
0252     debugfs_create_file("ctx_stats", 0400, root, ibd, &_ctx_stats_file_ops);
0253     debugfs_create_file("qp_stats", 0400, root, ibd, &_qp_stats_file_ops);
0254 }
0255 
0256 void qib_dbg_ibdev_exit(struct qib_ibdev *ibd)
0257 {
0258     if (!qib_dbg_root)
0259         goto out;
0260     debugfs_remove_recursive(ibd->qib_ibdev_dbg);
0261 out:
0262     ibd->qib_ibdev_dbg = NULL;
0263 }
0264 
0265 void qib_dbg_init(void)
0266 {
0267     qib_dbg_root = debugfs_create_dir(QIB_DRV_NAME, NULL);
0268 }
0269 
0270 void qib_dbg_exit(void)
0271 {
0272     debugfs_remove_recursive(qib_dbg_root);
0273     qib_dbg_root = NULL;
0274 }