0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
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
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
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
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 }