cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

qib_debugfs.c (6410B)


      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
     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}