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 #include "mana_sysctl.h" 32 33 static int mana_sysctl_cleanup_thread_cpu(SYSCTL_HANDLER_ARGS); 34 35 int mana_log_level = MANA_ALERT | MANA_WARNING | MANA_INFO; 36 37 SYSCTL_NODE(_hw, OID_AUTO, mana, CTLFLAG_RD | CTLFLAG_MPSAFE, 0, 38 "MANA driver parameters"); 39 40 /* 41 * Logging level for changing verbosity of the output 42 */ 43 SYSCTL_INT(_hw_mana, OID_AUTO, log_level, CTLFLAG_RWTUN, 44 &mana_log_level, 0, "Logging level indicating verbosity of the logs"); 45 46 SYSCTL_CONST_STRING(_hw_mana, OID_AUTO, driver_version, CTLFLAG_RD, 47 DRV_MODULE_VERSION, "MANA driver version"); 48 49 void 50 mana_sysctl_add_port(struct mana_port_context *apc) 51 { 52 struct gdma_context *gc = apc->ac->gdma_dev->gdma_context; 53 device_t dev = gc->dev; 54 struct sysctl_ctx_list *ctx; 55 struct sysctl_oid *tree; 56 struct sysctl_oid_list *child; 57 struct mana_port_stats *port_stats; 58 char node_name[32]; 59 60 struct sysctl_oid *port_node, *stats_node; 61 struct sysctl_oid_list *stats_list; 62 63 ctx = device_get_sysctl_ctx(dev); 64 tree = device_get_sysctl_tree(dev); 65 child = SYSCTL_CHILDREN(tree); 66 67 port_stats = &apc->port_stats; 68 69 snprintf(node_name, 32, "port%d", apc->port_idx); 70 71 port_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, 72 node_name, CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "Port Name"); 73 apc->port_list = SYSCTL_CHILDREN(port_node); 74 75 SYSCTL_ADD_BOOL(ctx, apc->port_list, OID_AUTO, 76 "enable_altq", CTLFLAG_RW, &apc->enable_tx_altq, 0, 77 "Choose alternative txq under heavy load"); 78 79 SYSCTL_ADD_PROC(ctx, apc->port_list, OID_AUTO, 80 "bind_cleanup_thread_cpu", 81 CTLTYPE_U8 | CTLFLAG_RW | CTLFLAG_MPSAFE, 82 apc, 0, mana_sysctl_cleanup_thread_cpu, "I", 83 "Bind cleanup thread to a cpu. 0 disables it."); 84 85 stats_node = SYSCTL_ADD_NODE(ctx, apc->port_list, OID_AUTO, 86 "port_stats", CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 87 "Statistics of port"); 88 stats_list = SYSCTL_CHILDREN(stats_node); 89 90 SYSCTL_ADD_COUNTER_U64(ctx, stats_list, OID_AUTO, "rx_packets", 91 CTLFLAG_RD, &port_stats->rx_packets, "Packets received"); 92 SYSCTL_ADD_COUNTER_U64(ctx, stats_list, OID_AUTO, "tx_packets", 93 CTLFLAG_RD, &port_stats->tx_packets, "Packets transmitted"); 94 SYSCTL_ADD_COUNTER_U64(ctx, stats_list, OID_AUTO, "rx_bytes", 95 CTLFLAG_RD, &port_stats->rx_bytes, "Bytes received"); 96 SYSCTL_ADD_COUNTER_U64(ctx, stats_list, OID_AUTO, "tx_bytes", 97 CTLFLAG_RD, &port_stats->tx_bytes, "Bytes transmitted"); 98 SYSCTL_ADD_COUNTER_U64(ctx, stats_list, OID_AUTO, "rx_drops", 99 CTLFLAG_RD, &port_stats->rx_drops, "Receive packet drops"); 100 SYSCTL_ADD_COUNTER_U64(ctx, stats_list, OID_AUTO, "tx_drops", 101 CTLFLAG_RD, &port_stats->tx_drops, "Transmit packet drops"); 102 } 103 104 void 105 mana_sysctl_add_queues(struct mana_port_context *apc) 106 { 107 struct sysctl_ctx_list *ctx = &apc->que_sysctl_ctx; 108 struct sysctl_oid_list *child = apc->port_list; 109 110 struct sysctl_oid *queue_node, *tx_node, *rx_node; 111 struct sysctl_oid_list *queue_list, *tx_list, *rx_list; 112 struct mana_txq *txq; 113 struct mana_rxq *rxq; 114 struct mana_stats *tx_stats, *rx_stats; 115 char que_name[32]; 116 int i; 117 118 sysctl_ctx_init(ctx); 119 120 for (i = 0; i < apc->num_queues; i++) { 121 rxq = apc->rxqs[i]; 122 txq = &apc->tx_qp[i].txq; 123 124 snprintf(que_name, 32, "queue%d", i); 125 126 queue_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, 127 que_name, CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "Queue Name"); 128 queue_list = SYSCTL_CHILDREN(queue_node); 129 130 /* TX stats */ 131 tx_node = SYSCTL_ADD_NODE(ctx, queue_list, OID_AUTO, 132 "txq", CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "TX queue"); 133 tx_list = SYSCTL_CHILDREN(tx_node); 134 135 tx_stats = &txq->stats; 136 137 SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO, "count", 138 CTLFLAG_RD, &tx_stats->packets, "Packets sent"); 139 SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO, "bytes", 140 CTLFLAG_RD, &tx_stats->bytes, "Bytes sent"); 141 SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO, "queue_wakeups", 142 CTLFLAG_RD, &tx_stats->wakeup, "Queue wakeups"); 143 SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO, "queue_stops", 144 CTLFLAG_RD, &tx_stats->stop, "Queue stops"); 145 SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO, "mbuf_collapse", 146 CTLFLAG_RD, &tx_stats->collapse, "Mbuf collapse count"); 147 SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO, 148 "mbuf_collapse_err", CTLFLAG_RD, 149 &tx_stats->collapse_err, "Mbuf collapse failures"); 150 SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO, 151 "dma_mapping_err", CTLFLAG_RD, 152 &tx_stats->dma_mapping_err, "DMA mapping failures"); 153 SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO, 154 "alt_chg", CTLFLAG_RD, 155 &tx_stats->alt_chg, "Switch to alternative txq"); 156 SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO, 157 "alt_reset", CTLFLAG_RD, 158 &tx_stats->alt_reset, "Reset to self txq"); 159 160 /* RX stats */ 161 rx_node = SYSCTL_ADD_NODE(ctx, queue_list, OID_AUTO, 162 "rxq", CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "RX queue"); 163 rx_list = SYSCTL_CHILDREN(rx_node); 164 165 rx_stats = &rxq->stats; 166 167 SYSCTL_ADD_COUNTER_U64(ctx, rx_list, OID_AUTO, "count", 168 CTLFLAG_RD, &rx_stats->packets, "Packets received"); 169 SYSCTL_ADD_COUNTER_U64(ctx, rx_list, OID_AUTO, "bytes", 170 CTLFLAG_RD, &rx_stats->bytes, "Bytes received"); 171 SYSCTL_ADD_COUNTER_U64(ctx, rx_list, OID_AUTO, 172 "mbuf_alloc_fail", CTLFLAG_RD, 173 &rx_stats->mbuf_alloc_fail, "Failed mbuf allocs"); 174 SYSCTL_ADD_COUNTER_U64(ctx, rx_list, OID_AUTO, 175 "dma_mapping_err", CTLFLAG_RD, 176 &rx_stats->dma_mapping_err, "DMA mapping errors"); 177 } 178 } 179 180 /* 181 * Free all queues' sysctl trees attached to the port's tree. 182 */ 183 void 184 mana_sysctl_free_queues(struct mana_port_context *apc) 185 { 186 sysctl_ctx_free(&apc->que_sysctl_ctx); 187 } 188 189 static int 190 mana_sysctl_cleanup_thread_cpu(SYSCTL_HANDLER_ARGS) 191 { 192 struct mana_port_context *apc = arg1; 193 bool bind_cpu = false; 194 uint8_t val; 195 int err; 196 197 val = 0; 198 err = sysctl_wire_old_buffer(req, sizeof(val)); 199 if (err == 0) { 200 val = apc->bind_cleanup_thread_cpu; 201 err = sysctl_handle_8(oidp, &val, 0, req); 202 } 203 204 if (err != 0 || req->newptr == NULL) 205 return (err); 206 207 if (val != 0) 208 bind_cpu = true; 209 210 if (bind_cpu != apc->bind_cleanup_thread_cpu) { 211 apc->bind_cleanup_thread_cpu = bind_cpu; 212 err = mana_restart(apc); 213 } 214 215 return (err); 216 } 217