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 } 262