1 /* 2 * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved. 3 * 4 * This program is free software; you may redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; version 2 of the License. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 9 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 10 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 11 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 12 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 13 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 14 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 15 * SOFTWARE. 16 * 17 */ 18 19 #include <linux/debugfs.h> 20 #include <linux/module.h> 21 22 #include "usnic.h" 23 #include "usnic_log.h" 24 #include "usnic_debugfs.h" 25 #include "usnic_ib_qp_grp.h" 26 #include "usnic_transport.h" 27 28 static struct dentry *debugfs_root; 29 static struct dentry *flows_dentry; 30 31 static ssize_t usnic_debugfs_buildinfo_read(struct file *f, char __user *data, 32 size_t count, loff_t *ppos) 33 { 34 char buf[500]; 35 int res; 36 37 if (*ppos > 0) 38 return 0; 39 40 res = scnprintf(buf, sizeof(buf), 41 "version: %s\n" 42 "build date: %s\n", 43 DRV_VERSION, DRV_RELDATE); 44 45 return simple_read_from_buffer(data, count, ppos, buf, res); 46 } 47 48 static const struct file_operations usnic_debugfs_buildinfo_ops = { 49 .owner = THIS_MODULE, 50 .open = simple_open, 51 .read = usnic_debugfs_buildinfo_read 52 }; 53 54 static ssize_t flowinfo_read(struct file *f, char __user *data, 55 size_t count, loff_t *ppos) 56 { 57 struct usnic_ib_qp_grp_flow *qp_flow; 58 int n; 59 int left; 60 char *ptr; 61 char buf[512]; 62 63 qp_flow = f->private_data; 64 ptr = buf; 65 left = count; 66 67 if (*ppos > 0) 68 return 0; 69 70 spin_lock(&qp_flow->qp_grp->lock); 71 n = scnprintf(ptr, left, 72 "QP Grp ID: %d Transport: %s ", 73 qp_flow->qp_grp->grp_id, 74 usnic_transport_to_str(qp_flow->trans_type)); 75 UPDATE_PTR_LEFT(n, ptr, left); 76 if (qp_flow->trans_type == USNIC_TRANSPORT_ROCE_CUSTOM) { 77 n = scnprintf(ptr, left, "Port_Num:%hu\n", 78 qp_flow->usnic_roce.port_num); 79 UPDATE_PTR_LEFT(n, ptr, left); 80 } else if (qp_flow->trans_type == USNIC_TRANSPORT_IPV4_UDP) { 81 n = usnic_transport_sock_to_str(ptr, left, 82 qp_flow->udp.sock); 83 UPDATE_PTR_LEFT(n, ptr, left); 84 n = scnprintf(ptr, left, "\n"); 85 UPDATE_PTR_LEFT(n, ptr, left); 86 } 87 spin_unlock(&qp_flow->qp_grp->lock); 88 89 return simple_read_from_buffer(data, count, ppos, buf, ptr - buf); 90 } 91 92 static const struct file_operations flowinfo_ops = { 93 .owner = THIS_MODULE, 94 .open = simple_open, 95 .read = flowinfo_read, 96 }; 97 98 void usnic_debugfs_init(void) 99 { 100 debugfs_root = debugfs_create_dir(DRV_NAME, NULL); 101 if (IS_ERR(debugfs_root)) { 102 usnic_err("Failed to create debugfs root dir, check if debugfs is enabled in kernel configuration\n"); 103 goto out_clear_root; 104 } 105 106 flows_dentry = debugfs_create_dir("flows", debugfs_root); 107 if (IS_ERR_OR_NULL(flows_dentry)) { 108 usnic_err("Failed to create debugfs flow dir with err %ld\n", 109 PTR_ERR(flows_dentry)); 110 goto out_free_root; 111 } 112 113 debugfs_create_file("build-info", S_IRUGO, debugfs_root, 114 NULL, &usnic_debugfs_buildinfo_ops); 115 return; 116 117 out_free_root: 118 debugfs_remove_recursive(debugfs_root); 119 out_clear_root: 120 debugfs_root = NULL; 121 } 122 123 void usnic_debugfs_exit(void) 124 { 125 if (!debugfs_root) 126 return; 127 128 debugfs_remove_recursive(debugfs_root); 129 debugfs_root = NULL; 130 } 131 132 void usnic_debugfs_flow_add(struct usnic_ib_qp_grp_flow *qp_flow) 133 { 134 if (IS_ERR_OR_NULL(flows_dentry)) 135 return; 136 137 scnprintf(qp_flow->dentry_name, sizeof(qp_flow->dentry_name), 138 "%u", qp_flow->flow->flow_id); 139 qp_flow->dbgfs_dentry = debugfs_create_file(qp_flow->dentry_name, 140 S_IRUGO, 141 flows_dentry, 142 qp_flow, 143 &flowinfo_ops); 144 if (IS_ERR_OR_NULL(qp_flow->dbgfs_dentry)) { 145 usnic_err("Failed to create dbg fs entry for flow %u\n", 146 qp_flow->flow->flow_id); 147 } 148 } 149 150 void usnic_debugfs_flow_remove(struct usnic_ib_qp_grp_flow *qp_flow) 151 { 152 if (!IS_ERR_OR_NULL(qp_flow->dbgfs_dentry)) 153 debugfs_remove(qp_flow->dbgfs_dentry); 154 } 155