xref: /freebsd/sys/dev/mana/mana_sysctl.c (revision d0b2dbfa0ecf2bbc9709efc5e20baf8e4b44bbbf)
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