aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/mana/mana_sysctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/mana/mana_sysctl.c')
-rw-r--r--sys/dev/mana/mana_sysctl.c219
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);
+}