^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Copyright(c) 2018 Intel Corporation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * This file is provided under a dual BSD/GPLv2 license. When using or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * redistributing this file, you may do so under either license.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * GPL LICENSE SUMMARY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * This program is free software; you can redistribute it and/or modify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * it under the terms of version 2 of the GNU General Public License as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * published by the Free Software Foundation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * This program is distributed in the hope that it will be useful, but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * WITHOUT ANY WARRANTY; without even the implied warranty of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * General Public License for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * BSD LICENSE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * Redistribution and use in source and binary forms, with or without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * modification, are permitted provided that the following conditions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * are met:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * - Redistributions of source code must retain the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * notice, this list of conditions and the following disclaimer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * - Redistributions in binary form must reproduce the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * notice, this list of conditions and the following disclaimer in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * the documentation and/or other materials provided with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * distribution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * - Neither the name of Intel Corporation nor the names of its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * contributors may be used to endorse or promote products derived
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * from this software without specific prior written permission.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include <linux/debugfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #include <linux/bitmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #include "debugfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #include "fault.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #include "trace.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define HFI1_FAULT_DIR_TX BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define HFI1_FAULT_DIR_RX BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define HFI1_FAULT_DIR_TXRX (HFI1_FAULT_DIR_TX | HFI1_FAULT_DIR_RX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) static void *_fault_stats_seq_start(struct seq_file *s, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct hfi1_opcode_stats_perctx *opstats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) if (*pos >= ARRAY_SIZE(opstats->stats))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) return pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) static void *_fault_stats_seq_next(struct seq_file *s, void *v, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) struct hfi1_opcode_stats_perctx *opstats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) ++*pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) if (*pos >= ARRAY_SIZE(opstats->stats))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) return pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) static void _fault_stats_seq_stop(struct seq_file *s, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) static int _fault_stats_seq_show(struct seq_file *s, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) loff_t *spos = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) loff_t i = *spos, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) u64 n_packets = 0, n_bytes = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) struct hfi1_ibdev *ibd = (struct hfi1_ibdev *)s->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) struct hfi1_devdata *dd = dd_from_dev(ibd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) struct hfi1_ctxtdata *rcd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) for (j = 0; j < dd->first_dyn_alloc_ctxt; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) rcd = hfi1_rcd_get_by_index(dd, j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) if (rcd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) n_packets += rcd->opstats->stats[i].n_packets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) n_bytes += rcd->opstats->stats[i].n_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) hfi1_rcd_put(rcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) for_each_possible_cpu(j) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) struct hfi1_opcode_stats_perctx *sp =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) per_cpu_ptr(dd->tx_opstats, j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) n_packets += sp->stats[i].n_packets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) n_bytes += sp->stats[i].n_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (!n_packets && !n_bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) return SEQ_SKIP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) if (!ibd->fault->n_rxfaults[i] && !ibd->fault->n_txfaults[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) return SEQ_SKIP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) seq_printf(s, "%02llx %llu/%llu (faults rx:%llu faults: tx:%llu)\n", i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) (unsigned long long)n_packets,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) (unsigned long long)n_bytes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) (unsigned long long)ibd->fault->n_rxfaults[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) (unsigned long long)ibd->fault->n_txfaults[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) DEBUGFS_SEQ_FILE_OPS(fault_stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) DEBUGFS_SEQ_FILE_OPEN(fault_stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) DEBUGFS_FILE_OPS(fault_stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static int fault_opcodes_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) file->private_data = inode->i_private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) return nonseekable_open(inode, file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static ssize_t fault_opcodes_write(struct file *file, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) size_t len, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) ssize_t ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) /* 1280 = 256 opcodes * 4 chars/opcode + 255 commas + NULL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) size_t copy, datalen = 1280;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) char *data, *token, *ptr, *end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) struct fault *fault = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) data = kcalloc(datalen, sizeof(*data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) copy = min(len, datalen - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if (copy_from_user(data, buf, copy)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) goto free_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) ret = debugfs_file_get(file->f_path.dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (unlikely(ret))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) goto free_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) ptr = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) token = ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) for (ptr = data; *ptr; ptr = end + 1, token = ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) char *dash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) unsigned long range_start, range_end, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) bool remove = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) unsigned long bound = 1U << BITS_PER_BYTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) end = strchr(ptr, ',');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) if (end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) *end = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (token[0] == '-') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) remove = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) token++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) dash = strchr(token, '-');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) if (dash)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) *dash = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) if (kstrtoul(token, 0, &range_start))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) if (dash) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) token = dash + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) if (kstrtoul(token, 0, &range_end))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) range_end = range_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) if (range_start == range_end && range_start == -1UL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) bitmap_zero(fault->opcodes, sizeof(fault->opcodes) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) BITS_PER_BYTE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) /* Check the inputs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) if (range_start >= bound || range_end >= bound)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) for (i = range_start; i <= range_end; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) if (remove)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) clear_bit(i, fault->opcodes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) set_bit(i, fault->opcodes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) if (!end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) ret = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) debugfs_file_put(file->f_path.dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) free_data:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) kfree(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) static ssize_t fault_opcodes_read(struct file *file, char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) size_t len, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) ssize_t ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) char *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) size_t datalen = 1280, size = 0; /* see fault_opcodes_write() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) unsigned long bit = 0, zero = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) struct fault *fault = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) size_t bitsize = sizeof(fault->opcodes) * BITS_PER_BYTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) data = kcalloc(datalen, sizeof(*data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) ret = debugfs_file_get(file->f_path.dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if (unlikely(ret))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) goto free_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) bit = find_first_bit(fault->opcodes, bitsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) while (bit < bitsize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) zero = find_next_zero_bit(fault->opcodes, bitsize, bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (zero - 1 != bit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) size += scnprintf(data + size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) datalen - size - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) "0x%lx-0x%lx,", bit, zero - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) size += scnprintf(data + size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) datalen - size - 1, "0x%lx,",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) bit = find_next_bit(fault->opcodes, bitsize, zero);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) debugfs_file_put(file->f_path.dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) data[size - 1] = '\n';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) data[size] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) ret = simple_read_from_buffer(buf, len, pos, data, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) free_data:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) kfree(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) static const struct file_operations __fault_opcodes_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) .open = fault_opcodes_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) .read = fault_opcodes_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) .write = fault_opcodes_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) .llseek = no_llseek
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) void hfi1_fault_exit_debugfs(struct hfi1_ibdev *ibd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) if (ibd->fault)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) debugfs_remove_recursive(ibd->fault->dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) kfree(ibd->fault);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) ibd->fault = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) int hfi1_fault_init_debugfs(struct hfi1_ibdev *ibd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) struct dentry *parent = ibd->hfi1_ibdev_dbg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) struct dentry *fault_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) ibd->fault = kzalloc(sizeof(*ibd->fault), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (!ibd->fault)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) ibd->fault->attr.interval = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) ibd->fault->attr.require_end = ULONG_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) ibd->fault->attr.stacktrace_depth = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) ibd->fault->attr.dname = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) ibd->fault->attr.verbose = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) ibd->fault->enable = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) ibd->fault->opcode = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) ibd->fault->fault_skip = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) ibd->fault->skip = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) ibd->fault->direction = HFI1_FAULT_DIR_TXRX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) ibd->fault->suppress_err = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) bitmap_zero(ibd->fault->opcodes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) sizeof(ibd->fault->opcodes) * BITS_PER_BYTE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) fault_dir =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) fault_create_debugfs_attr("fault", parent, &ibd->fault->attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) if (IS_ERR(fault_dir)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) kfree(ibd->fault);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) ibd->fault = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) ibd->fault->dir = fault_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) debugfs_create_file("fault_stats", 0444, fault_dir, ibd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) &_fault_stats_file_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) debugfs_create_bool("enable", 0600, fault_dir, &ibd->fault->enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) debugfs_create_bool("suppress_err", 0600, fault_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) &ibd->fault->suppress_err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) debugfs_create_bool("opcode_mode", 0600, fault_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) &ibd->fault->opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) debugfs_create_file("opcodes", 0600, fault_dir, ibd->fault,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) &__fault_opcodes_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) debugfs_create_u64("skip_pkts", 0600, fault_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) &ibd->fault->fault_skip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) debugfs_create_u64("skip_usec", 0600, fault_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) &ibd->fault->fault_skip_usec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) debugfs_create_u8("direction", 0600, fault_dir, &ibd->fault->direction);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) bool hfi1_dbg_fault_suppress_err(struct hfi1_ibdev *ibd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) if (ibd->fault)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) return ibd->fault->suppress_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) static bool __hfi1_should_fault(struct hfi1_ibdev *ibd, u32 opcode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) u8 direction)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) bool ret = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) if (!ibd->fault || !ibd->fault->enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) if (!(ibd->fault->direction & direction))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) if (ibd->fault->opcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) if (bitmap_empty(ibd->fault->opcodes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) (sizeof(ibd->fault->opcodes) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) BITS_PER_BYTE)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) if (!(test_bit(opcode, ibd->fault->opcodes)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) if (ibd->fault->fault_skip_usec &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) time_before(jiffies, ibd->fault->skip_usec))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) if (ibd->fault->fault_skip && ibd->fault->skip) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) ibd->fault->skip--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) ret = should_fail(&ibd->fault->attr, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) ibd->fault->skip = ibd->fault->fault_skip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) ibd->fault->skip_usec = jiffies +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) usecs_to_jiffies(ibd->fault->fault_skip_usec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) bool hfi1_dbg_should_fault_tx(struct rvt_qp *qp, u32 opcode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) struct hfi1_ibdev *ibd = to_idev(qp->ibqp.device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) if (__hfi1_should_fault(ibd, opcode, HFI1_FAULT_DIR_TX)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) trace_hfi1_fault_opcode(qp, opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) ibd->fault->n_txfaults[opcode]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) bool hfi1_dbg_should_fault_rx(struct hfi1_packet *packet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) struct hfi1_ibdev *ibd = &packet->rcd->dd->verbs_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) if (__hfi1_should_fault(ibd, packet->opcode, HFI1_FAULT_DIR_RX)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) trace_hfi1_fault_packet(packet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) ibd->fault->n_rxfaults[packet->opcode]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) }