brintos

brintos / linux-shallow public Read only

0
0
Text · 6.3 KiB · caeb77d Raw
275 lines · c
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 two5 * licenses.  You may choose to be licensed under the terms of the GNU6 * General Public License (GPL) Version 2, available from the file7 * COPYING in the main directory of this source tree, or the8 * OpenIB.org BSD license below:9 *10 *     Redistribution and use in source and binary forms, with or11 *     without modification, are permitted provided that the following12 *     conditions are met:13 *14 *      - Redistributions of source code must retain the above15 *        copyright notice, this list of conditions and the following16 *        disclaimer.17 *18 *      - Redistributions in binary form must reproduce the above19 *        copyright notice, this list of conditions and the following20 *        disclaimer in the documentation and/or other materials21 *        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 OF25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE30 * 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 41static struct dentry *qib_dbg_root;42 43#define DEBUGFS_FILE(name) \44static 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}; \50static 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} \61static 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 69static 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 78static 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 89static void _opcode_stats_seq_stop(struct seq_file *s, void *v)90{91	/* nothing allocated */92}93 94static 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 117DEBUGFS_FILE(opcode_stats)118 119static 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 131static 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 145static void _ctx_stats_seq_stop(struct seq_file *s, void *v)146{147	/* nothing allocated */148}149 150static 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 179DEBUGFS_FILE(ctx_stats)180 181static 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 205static 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 221static void _qp_stats_seq_stop(struct seq_file *s, void *iter_ptr)222	__releases(RCU)223{224	rcu_read_unlock();225}226 227static 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 239DEBUGFS_FILE(qp_stats)240 241void 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 256void 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);261out:262	ibd->qib_ibdev_dbg = NULL;263}264 265void qib_dbg_init(void)266{267	qib_dbg_root = debugfs_create_dir(QIB_DRV_NAME, NULL);268}269 270void qib_dbg_exit(void)271{272	debugfs_remove_recursive(qib_dbg_root);273	qib_dbg_root = NULL;274}275