1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2021 Microsoft Corp. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 #include <sys/cdefs.h> 31 __FBSDID("$FreeBSD$"); 32 33 34 #include "mana_sysctl.h" 35 36 static int mana_sysctl_cleanup_thread_cpu(SYSCTL_HANDLER_ARGS); 37 38 int mana_log_level = MANA_ALERT | MANA_WARNING | MANA_INFO; 39 40 SYSCTL_NODE(_hw, OID_AUTO, mana, CTLFLAG_RD | CTLFLAG_MPSAFE, 0, 41 "MANA driver parameters"); 42 43 /* 44 * Logging level for changing verbosity of the output 45 */ 46 SYSCTL_INT(_hw_mana, OID_AUTO, log_level, CTLFLAG_RWTUN, 47 &mana_log_level, 0, "Logging level indicating verbosity of the logs"); 48 49 SYSCTL_CONST_STRING(_hw_mana, OID_AUTO, driver_version, CTLFLAG_RD, 50 DRV_MODULE_VERSION, "MANA driver version"); 51 52 void 53 mana_sysctl_add_port(struct mana_port_context *apc) 54 { 55 struct gdma_context *gc = apc->ac->gdma_dev->gdma_context; 56 device_t dev = gc->dev; 57 struct sysctl_ctx_list *ctx; 58 struct sysctl_oid *tree; 59 struct sysctl_oid_list *child; 60 struct mana_port_stats *port_stats; 61 char node_name[32]; 62 63 struct sysctl_oid *port_node, *stats_node; 64 struct sysctl_oid_list *stats_list; 65 66 ctx = device_get_sysctl_ctx(dev); 67 tree = device_get_sysctl_tree(dev); 68 child = SYSCTL_CHILDREN(tree); 69 70 port_stats = &apc->port_stats; 71 72 snprintf(node_name, 32, "port%d", apc->port_idx); 73 74 port_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, 75 node_name, CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "Port Name"); 76 apc->port_list = SYSCTL_CHILDREN(port_node); 77 78 SYSCTL_ADD_BOOL(ctx, apc->port_list, OID_AUTO, 79 "enable_altq", CTLFLAG_RW, &apc->enable_tx_altq, 0, 80 "Choose alternative txq under heavy load"); 81 82 SYSCTL_ADD_PROC(ctx, apc->port_list, OID_AUTO, 83 "bind_cleanup_thread_cpu", 84 CTLTYPE_U8 | CTLFLAG_RW | CTLFLAG_MPSAFE, 85 apc, 0, mana_sysctl_cleanup_thread_cpu, "I", 86 "Bind cleanup thread to a cpu. 0 disables it."); 87 88 stats_node = SYSCTL_ADD_NODE(ctx, apc->port_list, OID_AUTO, 89 "port_stats", CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 90 "Statistics of port"); 91 stats_list = SYSCTL_CHILDREN(stats_node); 92 93 SYSCTL_ADD_COUNTER_U64(ctx, stats_list, OID_AUTO, "rx_packets", 94 CTLFLAG_RD, &port_stats->rx_packets, "Packets received"); 95 SYSCTL_ADD_COUNTER_U64(ctx, stats_list, OID_AUTO, "tx_packets", 96 CTLFLAG_RD, &port_stats->tx_packets, "Packets transmitted"); 97 SYSCTL_ADD_COUNTER_U64(ctx, stats_list, OID_AUTO, "rx_bytes", 98 CTLFLAG_RD, &port_stats->rx_bytes, "Bytes received"); 99 SYSCTL_ADD_COUNTER_U64(ctx, stats_list, OID_AUTO, "tx_bytes", 100 CTLFLAG_RD, &port_stats->tx_bytes, "Bytes transmitted"); 101 SYSCTL_ADD_COUNTER_U64(ctx, stats_list, OID_AUTO, "rx_drops", 102 CTLFLAG_RD, &port_stats->rx_drops, "Receive packet drops"); 103 SYSCTL_ADD_COUNTER_U64(ctx, stats_list, OID_AUTO, "tx_drops", 104 CTLFLAG_RD, &port_stats->tx_drops, "Transmit packet drops"); 105 } 106 107 void 108 mana_sysctl_add_queues(struct mana_port_context *apc) 109 { 110 struct sysctl_ctx_list *ctx = &apc->que_sysctl_ctx; 111 struct sysctl_oid_list *child = apc->port_list; 112 113 struct sysctl_oid *queue_node, *tx_node, *rx_node; 114 struct sysctl_oid_list *queue_list, *tx_list, *rx_list; 115 struct mana_txq *txq; 116 struct mana_rxq *rxq; 117 struct mana_stats *tx_stats, *rx_stats; 118 char que_name[32]; 119 int i; 120 121 sysctl_ctx_init(ctx); 122 123 for (i = 0; i < apc->num_queues; i++) { 124 rxq = apc->rxqs[i]; 125 txq = &apc->tx_qp[i].txq; 126 127 snprintf(que_name, 32, "queue%d", i); 128 129 queue_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, 130 que_name, CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "Queue Name"); 131 queue_list = SYSCTL_CHILDREN(queue_node); 132 133 /* TX stats */ 134 tx_node = SYSCTL_ADD_NODE(ctx, queue_list, OID_AUTO, 135 "txq", CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "TX queue"); 136 tx_list = SYSCTL_CHILDREN(tx_node); 137 138 tx_stats = &txq->stats; 139 140 SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO, "count", 141 CTLFLAG_RD, &tx_stats->packets, "Packets sent"); 142 SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO, "bytes", 143 CTLFLAG_RD, &tx_stats->bytes, "Bytes sent"); 144 SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO, "queue_wakeups", 145 CTLFLAG_RD, &tx_stats->wakeup, "Queue wakeups"); 146 SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO, "queue_stops", 147 CTLFLAG_RD, &tx_stats->stop, "Queue stops"); 148 SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO, "mbuf_collapse", 149 CTLFLAG_RD, &tx_stats->collapse, "Mbuf collapse count"); 150 SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO, 151 "mbuf_collapse_err", CTLFLAG_RD, 152 &tx_stats->collapse_err, "Mbuf collapse failures"); 153 SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO, 154 "dma_mapping_err", CTLFLAG_RD, 155 &tx_stats->dma_mapping_err, "DMA mapping failures"); 156 SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO, 157 "alt_chg", CTLFLAG_RD, 158 &tx_stats->alt_chg, "Switch to alternative txq"); 159 SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO, 160 "alt_reset", CTLFLAG_RD, 161 &tx_stats->alt_reset, "Reset to self txq"); 162 163 /* RX stats */ 164 rx_node = SYSCTL_ADD_NODE(ctx, queue_list, OID_AUTO, 165 "rxq", CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "RX queue"); 166 rx_list = SYSCTL_CHILDREN(rx_node); 167 168 rx_stats = &rxq->stats; 169 170 SYSCTL_ADD_COUNTER_U64(ctx, rx_list, OID_AUTO, "count", 171 CTLFLAG_RD, &rx_stats->packets, "Packets received"); 172 SYSCTL_ADD_COUNTER_U64(ctx, rx_list, OID_AUTO, "bytes", 173 CTLFLAG_RD, &rx_stats->bytes, "Bytes received"); 174 SYSCTL_ADD_COUNTER_U64(ctx, rx_list, OID_AUTO, 175 "mbuf_alloc_fail", CTLFLAG_RD, 176 &rx_stats->mbuf_alloc_fail, "Failed mbuf allocs"); 177 SYSCTL_ADD_COUNTER_U64(ctx, rx_list, OID_AUTO, 178 "dma_mapping_err", CTLFLAG_RD, 179 &rx_stats->dma_mapping_err, "DMA mapping errors"); 180 } 181 } 182 183 /* 184 * Free all queues' sysctl trees attached to the port's tree. 185 */ 186 void 187 mana_sysctl_free_queues(struct mana_port_context *apc) 188 { 189 sysctl_ctx_free(&apc->que_sysctl_ctx); 190 } 191 192 static int 193 mana_sysctl_cleanup_thread_cpu(SYSCTL_HANDLER_ARGS) 194 { 195 struct mana_port_context *apc = arg1; 196 bool bind_cpu = false; 197 uint8_t val; 198 int err; 199 200 val = 0; 201 err = sysctl_wire_old_buffer(req, sizeof(val)); 202 if (err == 0) { 203 val = apc->bind_cleanup_thread_cpu; 204 err = sysctl_handle_8(oidp, &val, 0, req); 205 } 206 207 if (err != 0 || req->newptr == NULL) 208 return (err); 209 210 if (val != 0) 211 bind_cpu = true; 212 213 if (bind_cpu != apc->bind_cleanup_thread_cpu) { 214 apc->bind_cleanup_thread_cpu = bind_cpu; 215 err = mana_restart(apc); 216 } 217 218 return (err); 219 } 220