diff options
Diffstat (limited to 'sys/dev/mana/mana_sysctl.c')
| -rw-r--r-- | sys/dev/mana/mana_sysctl.c | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/sys/dev/mana/mana_sysctl.c b/sys/dev/mana/mana_sysctl.c new file mode 100644 index 000000000000..f0821f05f2d2 --- /dev/null +++ b/sys/dev/mana/mana_sysctl.c @@ -0,0 +1,219 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2021 Microsoft Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + + +#include "mana_sysctl.h" + +static int mana_sysctl_cleanup_thread_cpu(SYSCTL_HANDLER_ARGS); + +int mana_log_level = MANA_ALERT | MANA_WARNING | MANA_INFO; + +SYSCTL_NODE(_hw, OID_AUTO, mana, CTLFLAG_RD | CTLFLAG_MPSAFE, 0, + "MANA driver parameters"); + +/* + * Logging level for changing verbosity of the output + */ +SYSCTL_INT(_hw_mana, OID_AUTO, log_level, CTLFLAG_RWTUN, + &mana_log_level, 0, "Logging level indicating verbosity of the logs"); + +SYSCTL_CONST_STRING(_hw_mana, OID_AUTO, driver_version, CTLFLAG_RD, + DRV_MODULE_VERSION, "MANA driver version"); + +void +mana_sysctl_add_port(struct mana_port_context *apc) +{ + struct gdma_context *gc = apc->ac->gdma_dev->gdma_context; + device_t dev = gc->dev; + struct sysctl_ctx_list *ctx; + struct sysctl_oid *tree; + struct sysctl_oid_list *child; + struct mana_port_stats *port_stats; + char node_name[32]; + + struct sysctl_oid *port_node, *stats_node; + struct sysctl_oid_list *stats_list; + + ctx = device_get_sysctl_ctx(dev); + tree = device_get_sysctl_tree(dev); + child = SYSCTL_CHILDREN(tree); + + port_stats = &apc->port_stats; + + snprintf(node_name, 32, "port%d", apc->port_idx); + + port_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, + node_name, CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "Port Name"); + apc->port_list = SYSCTL_CHILDREN(port_node); + + SYSCTL_ADD_BOOL(ctx, apc->port_list, OID_AUTO, + "enable_altq", CTLFLAG_RW, &apc->enable_tx_altq, 0, + "Choose alternative txq under heavy load"); + + SYSCTL_ADD_PROC(ctx, apc->port_list, OID_AUTO, + "bind_cleanup_thread_cpu", + CTLTYPE_U8 | CTLFLAG_RW | CTLFLAG_MPSAFE, + apc, 0, mana_sysctl_cleanup_thread_cpu, "I", + "Bind cleanup thread to a cpu. 0 disables it."); + + stats_node = SYSCTL_ADD_NODE(ctx, apc->port_list, OID_AUTO, + "port_stats", CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, + "Statistics of port"); + stats_list = SYSCTL_CHILDREN(stats_node); + + SYSCTL_ADD_COUNTER_U64(ctx, stats_list, OID_AUTO, "rx_packets", + CTLFLAG_RD, &port_stats->rx_packets, "Packets received"); + SYSCTL_ADD_COUNTER_U64(ctx, stats_list, OID_AUTO, "tx_packets", + CTLFLAG_RD, &port_stats->tx_packets, "Packets transmitted"); + SYSCTL_ADD_COUNTER_U64(ctx, stats_list, OID_AUTO, "rx_bytes", + CTLFLAG_RD, &port_stats->rx_bytes, "Bytes received"); + SYSCTL_ADD_COUNTER_U64(ctx, stats_list, OID_AUTO, "tx_bytes", + CTLFLAG_RD, &port_stats->tx_bytes, "Bytes transmitted"); + SYSCTL_ADD_COUNTER_U64(ctx, stats_list, OID_AUTO, "rx_drops", + CTLFLAG_RD, &port_stats->rx_drops, "Receive packet drops"); + SYSCTL_ADD_COUNTER_U64(ctx, stats_list, OID_AUTO, "tx_drops", + CTLFLAG_RD, &port_stats->tx_drops, "Transmit packet drops"); +} + +void +mana_sysctl_add_queues(struct mana_port_context *apc) +{ + struct sysctl_ctx_list *ctx = &apc->que_sysctl_ctx; + struct sysctl_oid_list *child = apc->port_list; + + struct sysctl_oid *queue_node, *tx_node, *rx_node; + struct sysctl_oid_list *queue_list, *tx_list, *rx_list; + struct mana_txq *txq; + struct mana_rxq *rxq; + struct mana_stats *tx_stats, *rx_stats; + char que_name[32]; + int i; + + sysctl_ctx_init(ctx); + + for (i = 0; i < apc->num_queues; i++) { + rxq = apc->rxqs[i]; + txq = &apc->tx_qp[i].txq; + + snprintf(que_name, 32, "queue%d", i); + + queue_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, + que_name, CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "Queue Name"); + queue_list = SYSCTL_CHILDREN(queue_node); + + /* TX stats */ + tx_node = SYSCTL_ADD_NODE(ctx, queue_list, OID_AUTO, + "txq", CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "TX queue"); + tx_list = SYSCTL_CHILDREN(tx_node); + + tx_stats = &txq->stats; + + SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO, "count", + CTLFLAG_RD, &tx_stats->packets, "Packets sent"); + SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO, "bytes", + CTLFLAG_RD, &tx_stats->bytes, "Bytes sent"); + SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO, "queue_wakeups", + CTLFLAG_RD, &tx_stats->wakeup, "Queue wakeups"); + SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO, "queue_stops", + CTLFLAG_RD, &tx_stats->stop, "Queue stops"); + SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO, "mbuf_collapse", + CTLFLAG_RD, &tx_stats->collapse, "Mbuf collapse count"); + SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO, + "mbuf_collapse_err", CTLFLAG_RD, + &tx_stats->collapse_err, "Mbuf collapse failures"); + SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO, + "dma_mapping_err", CTLFLAG_RD, + &tx_stats->dma_mapping_err, "DMA mapping failures"); + SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO, + "alt_chg", CTLFLAG_RD, + &tx_stats->alt_chg, "Switch to alternative txq"); + SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO, + "alt_reset", CTLFLAG_RD, + &tx_stats->alt_reset, "Reset to self txq"); + + /* RX stats */ + rx_node = SYSCTL_ADD_NODE(ctx, queue_list, OID_AUTO, + "rxq", CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "RX queue"); + rx_list = SYSCTL_CHILDREN(rx_node); + + rx_stats = &rxq->stats; + + SYSCTL_ADD_COUNTER_U64(ctx, rx_list, OID_AUTO, "count", + CTLFLAG_RD, &rx_stats->packets, "Packets received"); + SYSCTL_ADD_COUNTER_U64(ctx, rx_list, OID_AUTO, "bytes", + CTLFLAG_RD, &rx_stats->bytes, "Bytes received"); + SYSCTL_ADD_COUNTER_U64(ctx, rx_list, OID_AUTO, + "mbuf_alloc_fail", CTLFLAG_RD, + &rx_stats->mbuf_alloc_fail, "Failed mbuf allocs"); + SYSCTL_ADD_COUNTER_U64(ctx, rx_list, OID_AUTO, + "dma_mapping_err", CTLFLAG_RD, + &rx_stats->dma_mapping_err, "DMA mapping errors"); + } +} + +/* + * Free all queues' sysctl trees attached to the port's tree. + */ +void +mana_sysctl_free_queues(struct mana_port_context *apc) +{ + sysctl_ctx_free(&apc->que_sysctl_ctx); +} + +static int +mana_sysctl_cleanup_thread_cpu(SYSCTL_HANDLER_ARGS) +{ + struct mana_port_context *apc = arg1; + bool bind_cpu = false; + uint8_t val; + int err; + + val = 0; + err = sysctl_wire_old_buffer(req, sizeof(val)); + if (err == 0) { + val = apc->bind_cleanup_thread_cpu; + err = sysctl_handle_8(oidp, &val, 0, req); + } + + if (err != 0 || req->newptr == NULL) + return (err); + + if (val != 0) + bind_cpu = true; + + if (bind_cpu != apc->bind_cleanup_thread_cpu) { + apc->bind_cleanup_thread_cpu = bind_cpu; + err = mana_restart(apc); + } + + return (err); +} |
