]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/gve/gve_sysctl.c
Merge llvm-project release/18.x llvmorg-18.1.5-0-g617a15a9eac9
[FreeBSD/FreeBSD.git] / sys / dev / gve / gve_sysctl.c
1 /*-
2  * SPDX-License-Identifier: BSD-3-Clause
3  *
4  * Copyright (c) 2023 Google LLC
5  *
6  * Redistribution and use in source and binary forms, with or without modification,
7  * are permitted provided that the following conditions are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright notice, this
10  *    list of conditions and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright notice,
13  *    this list of conditions and the following disclaimer in the documentation
14  *    and/or other materials provided with the distribution.
15  *
16  * 3. Neither the name of the copyright holder nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software without
18  *    specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
24  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
27  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 #include "gve.h"
32
33 static void
34 gve_setup_rxq_sysctl(struct sysctl_ctx_list *ctx,
35     struct sysctl_oid_list *child, struct gve_rx_ring *rxq)
36 {
37         struct sysctl_oid *node;
38         struct sysctl_oid_list *list;
39         struct gve_rxq_stats *stats;
40         char namebuf[16];
41
42         snprintf(namebuf, sizeof(namebuf), "rxq%d", rxq->com.id);
43         node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, namebuf,
44             CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "Receive Queue");
45         list = SYSCTL_CHILDREN(node);
46
47         stats = &rxq->stats;
48
49         SYSCTL_ADD_COUNTER_U64(ctx, list, OID_AUTO,
50             "rx_bytes", CTLFLAG_RD,
51             &stats->rbytes, "Bytes received");
52         SYSCTL_ADD_COUNTER_U64(ctx, list, OID_AUTO,
53             "rx_packets", CTLFLAG_RD,
54             &stats->rpackets, "Packets received");
55         SYSCTL_ADD_COUNTER_U64(ctx, list, OID_AUTO, "rx_copybreak_cnt",
56             CTLFLAG_RD, &stats->rx_copybreak_cnt,
57             "Total frags with mbufs allocated for copybreak");
58         SYSCTL_ADD_COUNTER_U64(ctx, list, OID_AUTO, "rx_frag_flip_cnt",
59             CTLFLAG_RD, &stats->rx_frag_flip_cnt,
60             "Total frags that allocated mbuf with page flip");
61         SYSCTL_ADD_COUNTER_U64(ctx, list, OID_AUTO, "rx_frag_copy_cnt",
62             CTLFLAG_RD, &stats->rx_frag_copy_cnt,
63             "Total frags with mbuf that copied payload into mbuf");
64         SYSCTL_ADD_COUNTER_U64(ctx, list, OID_AUTO, "rx_dropped_pkt",
65             CTLFLAG_RD, &stats->rx_dropped_pkt,
66             "Total rx packets dropped");
67         SYSCTL_ADD_COUNTER_U64(ctx, list, OID_AUTO,
68             "rx_dropped_pkt_desc_err", CTLFLAG_RD,
69             &stats->rx_dropped_pkt_desc_err,
70             "Packets dropped due to descriptor error");
71         SYSCTL_ADD_COUNTER_U64(ctx, list, OID_AUTO,
72             "rx_dropped_pkt_mbuf_alloc_fail", CTLFLAG_RD,
73             &stats->rx_dropped_pkt_mbuf_alloc_fail,
74             "Packets dropped due to failed mbuf allocation");
75         SYSCTL_ADD_U32(ctx, list, OID_AUTO,
76             "rx_completed_desc", CTLFLAG_RD,
77             &rxq->cnt, 0, "Number of descriptors completed");
78         SYSCTL_ADD_U32(ctx, list, OID_AUTO,
79             "num_desc_posted", CTLFLAG_RD,
80             &rxq->fill_cnt, rxq->fill_cnt,
81             "Toal number of descriptors posted");
82 }
83
84 static void
85 gve_setup_txq_sysctl(struct sysctl_ctx_list *ctx,
86     struct sysctl_oid_list *child, struct gve_tx_ring *txq)
87 {
88         struct sysctl_oid *node;
89         struct sysctl_oid_list *tx_list;
90         struct gve_txq_stats *stats;
91         char namebuf[16];
92
93         snprintf(namebuf, sizeof(namebuf), "txq%d", txq->com.id);
94         node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, namebuf,
95             CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "Transmit Queue");
96         tx_list = SYSCTL_CHILDREN(node);
97
98         stats = &txq->stats;
99
100         SYSCTL_ADD_U32(ctx, tx_list, OID_AUTO,
101             "tx_posted_desc", CTLFLAG_RD,
102             &txq->req, 0, "Number of descriptors posted by NIC");
103         SYSCTL_ADD_U32(ctx, tx_list, OID_AUTO,
104             "tx_completed_desc", CTLFLAG_RD,
105             &txq->done, 0, "Number of descriptors completed");
106         SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO,
107             "tx_packets", CTLFLAG_RD,
108             &stats->tpackets, "Packets transmitted");
109         SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO,
110             "tx_tso_packets", CTLFLAG_RD,
111             &stats->tso_packet_cnt, "TSO Packets transmitted");
112         SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO,
113             "tx_bytes", CTLFLAG_RD,
114             &stats->tbytes, "Bytes transmitted");
115         SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO,
116             "tx_dropped_pkt_nospace_device", CTLFLAG_RD,
117             &stats->tx_dropped_pkt_nospace_device,
118             "Packets dropped due to no space in device");
119         SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO,
120             "tx_dropped_pkt_nospace_bufring", CTLFLAG_RD,
121             &stats->tx_dropped_pkt_nospace_bufring,
122             "Packets dropped due to no space in br ring");
123         SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO,
124             "tx_dropped_pkt_vlan", CTLFLAG_RD,
125             &stats->tx_dropped_pkt_vlan,
126             "Dropped VLAN packets");
127 }
128
129 static void
130 gve_setup_queue_stat_sysctl(struct sysctl_ctx_list *ctx, struct sysctl_oid_list *child,
131     struct gve_priv *priv)
132 {
133         int i;
134
135         for (i = 0; i < priv->rx_cfg.num_queues; i++) {
136                 gve_setup_rxq_sysctl(ctx, child, &priv->rx[i]);
137         }
138         for (i = 0; i < priv->tx_cfg.num_queues; i++) {
139                 gve_setup_txq_sysctl(ctx, child, &priv->tx[i]);
140         }
141 }
142
143 static void
144 gve_setup_adminq_stat_sysctl(struct sysctl_ctx_list *ctx,
145     struct sysctl_oid_list *child, struct gve_priv *priv)
146 {
147         struct sysctl_oid *admin_node;
148         struct sysctl_oid_list *admin_list;
149
150         /* Admin queue stats */
151         admin_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "adminq_stats",
152             CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "Admin Queue statistics");
153         admin_list = SYSCTL_CHILDREN(admin_node);
154
155         SYSCTL_ADD_U32(ctx, admin_list, OID_AUTO, "adminq_prod_cnt", CTLFLAG_RD,
156             &priv->adminq_prod_cnt, 0, "Adminq Commands issued");
157         SYSCTL_ADD_U32(ctx, admin_list, OID_AUTO, "adminq_cmd_fail", CTLFLAG_RD,
158             &priv->adminq_cmd_fail, 0, "Aqminq Failed commands");
159         SYSCTL_ADD_U32(ctx, admin_list, OID_AUTO, "adminq_timeouts", CTLFLAG_RD,
160             &priv->adminq_timeouts, 0, "Adminq Timedout commands");
161         SYSCTL_ADD_U32(ctx, admin_list, OID_AUTO, "adminq_describe_device_cnt",
162             CTLFLAG_RD, &priv->adminq_describe_device_cnt, 0,
163             "adminq_describe_device_cnt");
164         SYSCTL_ADD_U32(ctx, admin_list, OID_AUTO,
165             "adminq_cfg_device_resources_cnt", CTLFLAG_RD,
166             &priv->adminq_cfg_device_resources_cnt, 0,
167             "adminq_cfg_device_resources_cnt");
168         SYSCTL_ADD_U32(ctx, admin_list, OID_AUTO,
169             "adminq_register_page_list_cnt", CTLFLAG_RD,
170             &priv->adminq_register_page_list_cnt, 0,
171             "adminq_register_page_list_cnt");
172         SYSCTL_ADD_U32(ctx, admin_list, OID_AUTO,
173             "adminq_unregister_page_list_cnt", CTLFLAG_RD,
174             &priv->adminq_unregister_page_list_cnt, 0,
175             "adminq_unregister_page_list_cnt");
176         SYSCTL_ADD_U32(ctx, admin_list, OID_AUTO, "adminq_create_tx_queue_cnt",
177             CTLFLAG_RD, &priv->adminq_create_tx_queue_cnt, 0,
178             "adminq_create_tx_queue_cnt");
179         SYSCTL_ADD_U32(ctx, admin_list, OID_AUTO, "adminq_create_rx_queue_cnt",
180             CTLFLAG_RD, &priv->adminq_create_rx_queue_cnt, 0,
181             "adminq_create_rx_queue_cnt");
182         SYSCTL_ADD_U32(ctx, admin_list, OID_AUTO, "adminq_destroy_tx_queue_cnt",
183             CTLFLAG_RD, &priv->adminq_destroy_tx_queue_cnt, 0,
184             "adminq_destroy_tx_queue_cnt");
185         SYSCTL_ADD_U32(ctx, admin_list, OID_AUTO, "adminq_destroy_rx_queue_cnt",
186             CTLFLAG_RD, &priv->adminq_destroy_rx_queue_cnt, 0,
187             "adminq_destroy_rx_queue_cnt");
188         SYSCTL_ADD_U32(ctx, admin_list, OID_AUTO,
189             "adminq_dcfg_device_resources_cnt", CTLFLAG_RD,
190             &priv->adminq_dcfg_device_resources_cnt, 0,
191             "adminq_dcfg_device_resources_cnt");
192         SYSCTL_ADD_U32(ctx, admin_list, OID_AUTO,
193             "adminq_set_driver_parameter_cnt", CTLFLAG_RD,
194             &priv->adminq_set_driver_parameter_cnt, 0,
195             "adminq_set_driver_parameter_cnt");
196         SYSCTL_ADD_U32(ctx, admin_list, OID_AUTO,
197             "adminq_verify_driver_compatibility_cnt", CTLFLAG_RD,
198             &priv->adminq_verify_driver_compatibility_cnt, 0,
199             "adminq_verify_driver_compatibility_cnt");
200 }
201
202 static void
203 gve_setup_main_stat_sysctl(struct sysctl_ctx_list *ctx,
204     struct sysctl_oid_list *child, struct gve_priv *priv)
205 {
206         struct sysctl_oid *main_node;
207         struct sysctl_oid_list *main_list;
208
209         /* Main stats */
210         main_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "main_stats",
211             CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "Main statistics");
212         main_list = SYSCTL_CHILDREN(main_node);
213
214         SYSCTL_ADD_U32(ctx, main_list, OID_AUTO, "interface_up_cnt", CTLFLAG_RD,
215             &priv->interface_up_cnt, 0, "Times interface was set to up");
216         SYSCTL_ADD_U32(ctx, main_list, OID_AUTO, "interface_down_cnt", CTLFLAG_RD,
217             &priv->interface_down_cnt, 0, "Times interface was set to down");
218         SYSCTL_ADD_U32(ctx, main_list, OID_AUTO, "reset_cnt", CTLFLAG_RD,
219             &priv->reset_cnt, 0, "Times reset");
220 }
221
222 void gve_setup_sysctl(struct gve_priv *priv)
223 {
224         device_t dev;
225         struct sysctl_ctx_list *ctx;
226         struct sysctl_oid *tree;
227         struct sysctl_oid_list *child;
228
229         dev = priv->dev;
230         ctx = device_get_sysctl_ctx(dev);
231         tree = device_get_sysctl_tree(dev);
232         child = SYSCTL_CHILDREN(tree);
233
234         gve_setup_queue_stat_sysctl(ctx, child, priv);
235         gve_setup_adminq_stat_sysctl(ctx, child, priv);
236         gve_setup_main_stat_sysctl(ctx, child, priv);
237 }
238
239 void
240 gve_accum_stats(struct gve_priv *priv, uint64_t *rpackets,
241     uint64_t *rbytes, uint64_t *rx_dropped_pkt, uint64_t *tpackets,
242     uint64_t *tbytes, uint64_t *tx_dropped_pkt)
243 {
244         struct gve_rxq_stats *rxqstats;
245         struct gve_txq_stats *txqstats;
246         int i;
247
248         for (i = 0; i < priv->rx_cfg.num_queues; i++) {
249                 rxqstats = &priv->rx[i].stats;
250                 *rpackets += counter_u64_fetch(rxqstats->rpackets);
251                 *rbytes += counter_u64_fetch(rxqstats->rbytes);
252                 *rx_dropped_pkt += counter_u64_fetch(rxqstats->rx_dropped_pkt);
253         }
254
255         for (i = 0; i < priv->tx_cfg.num_queues; i++) {
256                 txqstats = &priv->tx[i].stats;
257                 *tpackets += counter_u64_fetch(txqstats->tpackets);
258                 *tbytes += counter_u64_fetch(txqstats->tbytes);
259                 *tx_dropped_pkt += counter_u64_fetch(txqstats->tx_dropped_pkt);
260         }
261 }