2 * SPDX-License-Identifier: BSD-3-Clause
4 * Copyright (c) 2023 Google LLC
6 * Redistribution and use in source and binary forms, with or without modification,
7 * are permitted provided that the following conditions are met:
9 * 1. Redistributions of source code must retain the above copyright notice, this
10 * list of conditions and the following disclaimer.
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.
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.
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.
34 gve_setup_rxq_sysctl(struct sysctl_ctx_list *ctx,
35 struct sysctl_oid_list *child, struct gve_rx_ring *rxq)
37 struct sysctl_oid *node;
38 struct sysctl_oid_list *list;
39 struct gve_rxq_stats *stats;
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);
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");
85 gve_setup_txq_sysctl(struct sysctl_ctx_list *ctx,
86 struct sysctl_oid_list *child, struct gve_tx_ring *txq)
88 struct sysctl_oid *node;
89 struct sysctl_oid_list *tx_list;
90 struct gve_txq_stats *stats;
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);
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");
130 gve_setup_queue_stat_sysctl(struct sysctl_ctx_list *ctx, struct sysctl_oid_list *child,
131 struct gve_priv *priv)
135 for (i = 0; i < priv->rx_cfg.num_queues; i++) {
136 gve_setup_rxq_sysctl(ctx, child, &priv->rx[i]);
138 for (i = 0; i < priv->tx_cfg.num_queues; i++) {
139 gve_setup_txq_sysctl(ctx, child, &priv->tx[i]);
144 gve_setup_adminq_stat_sysctl(struct sysctl_ctx_list *ctx,
145 struct sysctl_oid_list *child, struct gve_priv *priv)
147 struct sysctl_oid *admin_node;
148 struct sysctl_oid_list *admin_list;
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);
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");
203 gve_setup_main_stat_sysctl(struct sysctl_ctx_list *ctx,
204 struct sysctl_oid_list *child, struct gve_priv *priv)
206 struct sysctl_oid *main_node;
207 struct sysctl_oid_list *main_list;
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);
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");
222 void gve_setup_sysctl(struct gve_priv *priv)
225 struct sysctl_ctx_list *ctx;
226 struct sysctl_oid *tree;
227 struct sysctl_oid_list *child;
230 ctx = device_get_sysctl_ctx(dev);
231 tree = device_get_sysctl_tree(dev);
232 child = SYSCTL_CHILDREN(tree);
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);
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)
244 struct gve_rxq_stats *rxqstats;
245 struct gve_txq_stats *txqstats;
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);
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);