1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2015-2020 Amazon.com, Inc. or its affiliates. 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 __FBSDID("$FreeBSD$"); 32 33 #include "ena_sysctl.h" 34 35 static void ena_sysctl_add_wd(struct ena_adapter *); 36 static void ena_sysctl_add_stats(struct ena_adapter *); 37 static void ena_sysctl_add_eni_metrics(struct ena_adapter *); 38 static void ena_sysctl_add_tuneables(struct ena_adapter *); 39 static int ena_sysctl_buf_ring_size(SYSCTL_HANDLER_ARGS); 40 static int ena_sysctl_rx_queue_size(SYSCTL_HANDLER_ARGS); 41 static int ena_sysctl_io_queues_nb(SYSCTL_HANDLER_ARGS); 42 static int ena_sysctl_eni_metrics_interval(SYSCTL_HANDLER_ARGS); 43 44 /* Limit max ENI sample rate to be an hour. */ 45 #define ENI_METRICS_MAX_SAMPLE_INTERVAL 3600 46 47 static SYSCTL_NODE(_hw, OID_AUTO, ena, CTLFLAG_RD | CTLFLAG_MPSAFE, 0, 48 "ENA driver parameters"); 49 50 /* 51 * Logging level for changing verbosity of the output 52 */ 53 int ena_log_level = ENA_ALERT | ENA_WARNING; 54 SYSCTL_INT(_hw_ena, OID_AUTO, log_level, CTLFLAG_RWTUN, 55 &ena_log_level, 0, "Logging level indicating verbosity of the logs"); 56 57 SYSCTL_CONST_STRING(_hw_ena, OID_AUTO, driver_version, CTLFLAG_RD, 58 DRV_MODULE_VERSION, "ENA driver version"); 59 60 /* 61 * Use 9k mbufs for the Rx buffers. Default to 0 (use page size mbufs instead). 62 * Using 9k mbufs in low memory conditions might cause allocation to take a lot 63 * of time and lead to the OS instability as it needs to look for the contiguous 64 * pages. 65 * However, page size mbufs has a bit smaller throughput than 9k mbufs, so if 66 * the network performance is the priority, the 9k mbufs can be used. 67 */ 68 int ena_enable_9k_mbufs = 0; 69 SYSCTL_INT(_hw_ena, OID_AUTO, enable_9k_mbufs, CTLFLAG_RDTUN, 70 &ena_enable_9k_mbufs, 0, "Use 9 kB mbufs for Rx descriptors"); 71 72 void 73 ena_sysctl_add_nodes(struct ena_adapter *adapter) 74 { 75 ena_sysctl_add_wd(adapter); 76 ena_sysctl_add_stats(adapter); 77 ena_sysctl_add_eni_metrics(adapter); 78 ena_sysctl_add_tuneables(adapter); 79 } 80 81 static void 82 ena_sysctl_add_wd(struct ena_adapter *adapter) 83 { 84 device_t dev; 85 86 struct sysctl_ctx_list *ctx; 87 struct sysctl_oid *tree; 88 struct sysctl_oid_list *child; 89 90 dev = adapter->pdev; 91 92 ctx = device_get_sysctl_ctx(dev); 93 tree = device_get_sysctl_tree(dev); 94 child = SYSCTL_CHILDREN(tree); 95 96 /* Sysctl calls for Watchdog service */ 97 SYSCTL_ADD_INT(ctx, child, OID_AUTO, "wd_active", 98 CTLFLAG_RWTUN, &adapter->wd_active, 0, 99 "Watchdog is active"); 100 101 SYSCTL_ADD_QUAD(ctx, child, OID_AUTO, "keep_alive_timeout", 102 CTLFLAG_RWTUN, &adapter->keep_alive_timeout, 103 "Timeout for Keep Alive messages"); 104 105 SYSCTL_ADD_QUAD(ctx, child, OID_AUTO, "missing_tx_timeout", 106 CTLFLAG_RWTUN, &adapter->missing_tx_timeout, 107 "Timeout for TX completion"); 108 109 SYSCTL_ADD_U32(ctx, child, OID_AUTO, "missing_tx_max_queues", 110 CTLFLAG_RWTUN, &adapter->missing_tx_max_queues, 0, 111 "Number of TX queues to check per run"); 112 113 SYSCTL_ADD_U32(ctx, child, OID_AUTO, "missing_tx_threshold", 114 CTLFLAG_RWTUN, &adapter->missing_tx_threshold, 0, 115 "Max number of timeouted packets"); 116 } 117 118 static void 119 ena_sysctl_add_stats(struct ena_adapter *adapter) 120 { 121 device_t dev; 122 123 struct ena_ring *tx_ring; 124 struct ena_ring *rx_ring; 125 126 struct ena_hw_stats *hw_stats; 127 struct ena_stats_dev *dev_stats; 128 struct ena_stats_tx *tx_stats; 129 struct ena_stats_rx *rx_stats; 130 struct ena_com_stats_admin *admin_stats; 131 132 struct sysctl_ctx_list *ctx; 133 struct sysctl_oid *tree; 134 struct sysctl_oid_list *child; 135 136 struct sysctl_oid *queue_node, *tx_node, *rx_node, *hw_node; 137 struct sysctl_oid *admin_node; 138 struct sysctl_oid_list *queue_list, *tx_list, *rx_list, *hw_list; 139 struct sysctl_oid_list *admin_list; 140 141 #define QUEUE_NAME_LEN 32 142 char namebuf[QUEUE_NAME_LEN]; 143 int i; 144 145 dev = adapter->pdev; 146 147 ctx = device_get_sysctl_ctx(dev); 148 tree = device_get_sysctl_tree(dev); 149 child = SYSCTL_CHILDREN(tree); 150 151 tx_ring = adapter->tx_ring; 152 rx_ring = adapter->rx_ring; 153 154 hw_stats = &adapter->hw_stats; 155 dev_stats = &adapter->dev_stats; 156 admin_stats = &adapter->ena_dev->admin_queue.stats; 157 158 SYSCTL_ADD_COUNTER_U64(ctx, child, OID_AUTO, "wd_expired", 159 CTLFLAG_RD, &dev_stats->wd_expired, 160 "Watchdog expiry count"); 161 SYSCTL_ADD_COUNTER_U64(ctx, child, OID_AUTO, "interface_up", 162 CTLFLAG_RD, &dev_stats->interface_up, 163 "Network interface up count"); 164 SYSCTL_ADD_COUNTER_U64(ctx, child, OID_AUTO, "interface_down", 165 CTLFLAG_RD, &dev_stats->interface_down, 166 "Network interface down count"); 167 SYSCTL_ADD_COUNTER_U64(ctx, child, OID_AUTO, "admin_q_pause", 168 CTLFLAG_RD, &dev_stats->admin_q_pause, 169 "Admin queue pauses"); 170 171 for (i = 0; i < adapter->num_io_queues; ++i, ++tx_ring, ++rx_ring) { 172 snprintf(namebuf, QUEUE_NAME_LEN, "queue%d", i); 173 174 queue_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, 175 namebuf, CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "Queue Name"); 176 queue_list = SYSCTL_CHILDREN(queue_node); 177 178 /* TX specific stats */ 179 tx_node = SYSCTL_ADD_NODE(ctx, queue_list, OID_AUTO, 180 "tx_ring", CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "TX ring"); 181 tx_list = SYSCTL_CHILDREN(tx_node); 182 183 tx_stats = &tx_ring->tx_stats; 184 185 SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO, 186 "count", CTLFLAG_RD, 187 &tx_stats->cnt, "Packets sent"); 188 SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO, 189 "bytes", CTLFLAG_RD, 190 &tx_stats->bytes, "Bytes sent"); 191 SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO, 192 "prepare_ctx_err", CTLFLAG_RD, 193 &tx_stats->prepare_ctx_err, 194 "TX buffer preparation failures"); 195 SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO, 196 "dma_mapping_err", CTLFLAG_RD, 197 &tx_stats->dma_mapping_err, "DMA mapping failures"); 198 SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO, 199 "doorbells", CTLFLAG_RD, 200 &tx_stats->doorbells, "Queue doorbells"); 201 SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO, 202 "missing_tx_comp", CTLFLAG_RD, 203 &tx_stats->missing_tx_comp, "TX completions missed"); 204 SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO, 205 "bad_req_id", CTLFLAG_RD, 206 &tx_stats->bad_req_id, "Bad request id count"); 207 SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO, 208 "mbuf_collapses", CTLFLAG_RD, 209 &tx_stats->collapse, 210 "Mbuf collapse count"); 211 SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO, 212 "mbuf_collapse_err", CTLFLAG_RD, 213 &tx_stats->collapse_err, 214 "Mbuf collapse failures"); 215 SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO, 216 "queue_wakeups", CTLFLAG_RD, 217 &tx_stats->queue_wakeup, "Queue wakeups"); 218 SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO, 219 "queue_stops", CTLFLAG_RD, 220 &tx_stats->queue_stop, "Queue stops"); 221 SYSCTL_ADD_COUNTER_U64(ctx, tx_list, OID_AUTO, 222 "llq_buffer_copy", CTLFLAG_RD, 223 &tx_stats->llq_buffer_copy, 224 "Header copies for llq transaction"); 225 226 /* RX specific stats */ 227 rx_node = SYSCTL_ADD_NODE(ctx, queue_list, OID_AUTO, 228 "rx_ring", CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "RX ring"); 229 rx_list = SYSCTL_CHILDREN(rx_node); 230 231 rx_stats = &rx_ring->rx_stats; 232 233 SYSCTL_ADD_COUNTER_U64(ctx, rx_list, OID_AUTO, 234 "count", CTLFLAG_RD, 235 &rx_stats->cnt, "Packets received"); 236 SYSCTL_ADD_COUNTER_U64(ctx, rx_list, OID_AUTO, 237 "bytes", CTLFLAG_RD, 238 &rx_stats->bytes, "Bytes received"); 239 SYSCTL_ADD_COUNTER_U64(ctx, rx_list, OID_AUTO, 240 "refil_partial", CTLFLAG_RD, 241 &rx_stats->refil_partial, "Partial refilled mbufs"); 242 SYSCTL_ADD_COUNTER_U64(ctx, rx_list, OID_AUTO, 243 "bad_csum", CTLFLAG_RD, 244 &rx_stats->bad_csum, "Bad RX checksum"); 245 SYSCTL_ADD_COUNTER_U64(ctx, rx_list, OID_AUTO, 246 "mbuf_alloc_fail", CTLFLAG_RD, 247 &rx_stats->mbuf_alloc_fail, "Failed mbuf allocs"); 248 SYSCTL_ADD_COUNTER_U64(ctx, rx_list, OID_AUTO, 249 "mjum_alloc_fail", CTLFLAG_RD, 250 &rx_stats->mjum_alloc_fail, "Failed jumbo mbuf allocs"); 251 SYSCTL_ADD_COUNTER_U64(ctx, rx_list, OID_AUTO, 252 "dma_mapping_err", CTLFLAG_RD, 253 &rx_stats->dma_mapping_err, "DMA mapping errors"); 254 SYSCTL_ADD_COUNTER_U64(ctx, rx_list, OID_AUTO, 255 "bad_desc_num", CTLFLAG_RD, 256 &rx_stats->bad_desc_num, "Bad descriptor count"); 257 SYSCTL_ADD_COUNTER_U64(ctx, rx_list, OID_AUTO, 258 "bad_req_id", CTLFLAG_RD, 259 &rx_stats->bad_req_id, "Bad request id count"); 260 SYSCTL_ADD_COUNTER_U64(ctx, rx_list, OID_AUTO, 261 "empty_rx_ring", CTLFLAG_RD, 262 &rx_stats->empty_rx_ring, "RX descriptors depletion count"); 263 } 264 265 /* Stats read from device */ 266 hw_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "hw_stats", 267 CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "Statistics from hardware"); 268 hw_list = SYSCTL_CHILDREN(hw_node); 269 270 SYSCTL_ADD_COUNTER_U64(ctx, hw_list, OID_AUTO, "rx_packets", CTLFLAG_RD, 271 &hw_stats->rx_packets, "Packets received"); 272 SYSCTL_ADD_COUNTER_U64(ctx, hw_list, OID_AUTO, "tx_packets", CTLFLAG_RD, 273 &hw_stats->tx_packets, "Packets transmitted"); 274 SYSCTL_ADD_COUNTER_U64(ctx, hw_list, OID_AUTO, "rx_bytes", CTLFLAG_RD, 275 &hw_stats->rx_bytes, "Bytes received"); 276 SYSCTL_ADD_COUNTER_U64(ctx, hw_list, OID_AUTO, "tx_bytes", CTLFLAG_RD, 277 &hw_stats->tx_bytes, "Bytes transmitted"); 278 SYSCTL_ADD_COUNTER_U64(ctx, hw_list, OID_AUTO, "rx_drops", CTLFLAG_RD, 279 &hw_stats->rx_drops, "Receive packet drops"); 280 SYSCTL_ADD_COUNTER_U64(ctx, hw_list, OID_AUTO, "tx_drops", CTLFLAG_RD, 281 &hw_stats->tx_drops, "Transmit packet drops"); 282 283 /* ENA Admin queue stats */ 284 admin_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "admin_stats", 285 CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "ENA Admin Queue statistics"); 286 admin_list = SYSCTL_CHILDREN(admin_node); 287 288 SYSCTL_ADD_U64(ctx, admin_list, OID_AUTO, "aborted_cmd", CTLFLAG_RD, 289 &admin_stats->aborted_cmd, 0, "Aborted commands"); 290 SYSCTL_ADD_U64(ctx, admin_list, OID_AUTO, "sumbitted_cmd", CTLFLAG_RD, 291 &admin_stats->submitted_cmd, 0, "Submitted commands"); 292 SYSCTL_ADD_U64(ctx, admin_list, OID_AUTO, "completed_cmd", CTLFLAG_RD, 293 &admin_stats->completed_cmd, 0, "Completed commands"); 294 SYSCTL_ADD_U64(ctx, admin_list, OID_AUTO, "out_of_space", CTLFLAG_RD, 295 &admin_stats->out_of_space, 0, "Queue out of space"); 296 SYSCTL_ADD_U64(ctx, admin_list, OID_AUTO, "no_completion", CTLFLAG_RD, 297 &admin_stats->no_completion, 0, "Commands not completed"); 298 } 299 300 static void 301 ena_sysctl_add_eni_metrics(struct ena_adapter *adapter) 302 { 303 device_t dev; 304 struct ena_admin_eni_stats *eni_metrics; 305 306 struct sysctl_ctx_list *ctx; 307 struct sysctl_oid *tree; 308 struct sysctl_oid_list *child; 309 310 struct sysctl_oid *eni_node; 311 struct sysctl_oid_list *eni_list; 312 313 dev = adapter->pdev; 314 315 ctx = device_get_sysctl_ctx(dev); 316 tree = device_get_sysctl_tree(dev); 317 child = SYSCTL_CHILDREN(tree); 318 319 eni_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "eni_metrics", 320 CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "ENA's ENI metrics"); 321 eni_list = SYSCTL_CHILDREN(eni_node); 322 323 eni_metrics = &adapter->eni_metrics; 324 325 SYSCTL_ADD_U64(ctx, eni_list, OID_AUTO, "bw_in_allowance_exceeded", 326 CTLFLAG_RD, &eni_metrics->bw_in_allowance_exceeded, 0, 327 "Inbound BW allowance exceeded"); 328 SYSCTL_ADD_U64(ctx, eni_list, OID_AUTO, "bw_out_allowance_exceeded", 329 CTLFLAG_RD, &eni_metrics->bw_out_allowance_exceeded, 0, 330 "Outbound BW allowance exceeded"); 331 SYSCTL_ADD_U64(ctx, eni_list, OID_AUTO, "pps_allowance_exceeded", 332 CTLFLAG_RD, &eni_metrics->pps_allowance_exceeded, 0, 333 "PPS allowance exceeded"); 334 SYSCTL_ADD_U64(ctx, eni_list, OID_AUTO, "conntrack_allowance_exceeded", 335 CTLFLAG_RD, &eni_metrics->conntrack_allowance_exceeded, 0, 336 "Connection tracking allowance exceeded"); 337 SYSCTL_ADD_U64(ctx, eni_list, OID_AUTO, "linklocal_allowance_exceeded", 338 CTLFLAG_RD, &eni_metrics->linklocal_allowance_exceeded, 0, 339 "Linklocal packet rate allowance exceeded"); 340 341 /* 342 * Tuneable, which determines how often ENI metrics will be read. 343 * 0 means it's turned off. Maximum allowed value is limited by: 344 * ENI_METRICS_MAX_SAMPLE_INTERVAL. 345 */ 346 SYSCTL_ADD_PROC(ctx, eni_list, OID_AUTO, "sample_interval", 347 CTLTYPE_U16 | CTLFLAG_RW | CTLFLAG_MPSAFE, adapter, 0, 348 ena_sysctl_eni_metrics_interval, "SU", 349 "Interval in seconds for updating ENI emetrics. 0 turns off the update."); 350 } 351 352 static void 353 ena_sysctl_add_tuneables(struct ena_adapter *adapter) 354 { 355 device_t dev; 356 357 struct sysctl_ctx_list *ctx; 358 struct sysctl_oid *tree; 359 struct sysctl_oid_list *child; 360 361 dev = adapter->pdev; 362 363 ctx = device_get_sysctl_ctx(dev); 364 tree = device_get_sysctl_tree(dev); 365 child = SYSCTL_CHILDREN(tree); 366 367 /* Tuneable number of buffers in the buf-ring (drbr) */ 368 SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "buf_ring_size", 369 CTLTYPE_U32 | CTLFLAG_RW | CTLFLAG_MPSAFE, adapter, 0, 370 ena_sysctl_buf_ring_size, "I", 371 "Size of the Tx buffer ring (drbr)."); 372 373 /* Tuneable number of the Rx ring size */ 374 SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "rx_queue_size", 375 CTLTYPE_U32 | CTLFLAG_RW | CTLFLAG_MPSAFE, adapter, 0, 376 ena_sysctl_rx_queue_size, "I", 377 "Size of the Rx ring. The size should be a power of 2."); 378 379 /* Tuneable number of IO queues */ 380 SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "io_queues_nb", 381 CTLTYPE_U32 | CTLFLAG_RW | CTLFLAG_MPSAFE, adapter, 0, 382 ena_sysctl_io_queues_nb, "I", "Number of IO queues."); 383 } 384 385 386 static int 387 ena_sysctl_buf_ring_size(SYSCTL_HANDLER_ARGS) 388 { 389 struct ena_adapter *adapter = arg1; 390 uint32_t val; 391 int error; 392 393 val = 0; 394 error = sysctl_wire_old_buffer(req, sizeof(val)); 395 if (error == 0) { 396 val = adapter->buf_ring_size; 397 error = sysctl_handle_32(oidp, &val, 0, req); 398 } 399 if (error != 0 || req->newptr == NULL) 400 return (error); 401 402 if (!powerof2(val) || val == 0) { 403 device_printf(adapter->pdev, 404 "Requested new Tx buffer ring size (%u) is not a power of 2\n", 405 val); 406 return (EINVAL); 407 } 408 409 if (val != adapter->buf_ring_size) { 410 device_printf(adapter->pdev, 411 "Requested new Tx buffer ring size: %d. Old size: %d\n", 412 val, adapter->buf_ring_size); 413 414 error = ena_update_buf_ring_size(adapter, val); 415 } else { 416 device_printf(adapter->pdev, 417 "New Tx buffer ring size is the same as already used: %u\n", 418 adapter->buf_ring_size); 419 } 420 421 return (error); 422 } 423 424 static int 425 ena_sysctl_rx_queue_size(SYSCTL_HANDLER_ARGS) 426 { 427 struct ena_adapter *adapter = arg1; 428 uint32_t val; 429 int error; 430 431 val = 0; 432 error = sysctl_wire_old_buffer(req, sizeof(val)); 433 if (error == 0) { 434 val = adapter->requested_rx_ring_size; 435 error = sysctl_handle_32(oidp, &val, 0, req); 436 } 437 if (error != 0 || req->newptr == NULL) 438 return (error); 439 440 if (val < ENA_MIN_RING_SIZE || val > adapter->max_rx_ring_size) { 441 device_printf(adapter->pdev, 442 "Requested new Rx queue size (%u) is out of range: [%u, %u]\n", 443 val, ENA_MIN_RING_SIZE, adapter->max_rx_ring_size); 444 return (EINVAL); 445 } 446 447 /* Check if the parameter is power of 2 */ 448 if (!powerof2(val)) { 449 device_printf(adapter->pdev, 450 "Requested new Rx queue size (%u) is not a power of 2\n", 451 val); 452 return (EINVAL); 453 } 454 455 if (val != adapter->requested_rx_ring_size) { 456 device_printf(adapter->pdev, 457 "Requested new Rx queue size: %u. Old size: %u\n", 458 val, adapter->requested_rx_ring_size); 459 460 error = ena_update_queue_size(adapter, 461 adapter->requested_tx_ring_size, val); 462 } else { 463 device_printf(adapter->pdev, 464 "New Rx queue size is the same as already used: %u\n", 465 adapter->requested_rx_ring_size); 466 } 467 468 return (error); 469 } 470 471 /* 472 * Change number of effectively used IO queues adapter->num_io_queues 473 */ 474 static int 475 ena_sysctl_io_queues_nb(SYSCTL_HANDLER_ARGS) 476 { 477 struct ena_adapter *adapter = arg1; 478 uint32_t tmp = 0; 479 int error; 480 481 error = sysctl_wire_old_buffer(req, sizeof(tmp)); 482 if (error == 0) { 483 tmp = adapter->num_io_queues; 484 error = sysctl_handle_int(oidp, &tmp, 0, req); 485 } 486 if (error != 0 || req->newptr == NULL) 487 return (error); 488 489 if (tmp == 0) { 490 device_printf(adapter->pdev, 491 "Requested number of IO queues is zero\n"); 492 return (EINVAL); 493 } 494 495 /* 496 * The adapter::max_num_io_queues is the HW capability. The system 497 * resources availability may potentially be a tighter limit. Therefore 498 * the relation `adapter::max_num_io_queues >= adapter::msix_vecs` 499 * always holds true, while the `adapter::msix_vecs` is variable across 500 * device reset (`ena_destroy_device()` + `ena_restore_device()`). 501 */ 502 if (tmp > (adapter->msix_vecs - ENA_ADMIN_MSIX_VEC)) { 503 device_printf(adapter->pdev, 504 "Requested number of IO queues is higher than maximum " 505 "allowed (%u)\n", adapter->msix_vecs - ENA_ADMIN_MSIX_VEC); 506 return (EINVAL); 507 } 508 if (tmp == adapter->num_io_queues) { 509 device_printf(adapter->pdev, 510 "Requested number of IO queues is equal to current value " 511 "(%u)\n", adapter->num_io_queues); 512 } else { 513 device_printf(adapter->pdev, 514 "Requested new number of IO queues: %u, current value: " 515 "%u\n", tmp, adapter->num_io_queues); 516 517 error = ena_update_io_queue_nb(adapter, tmp); 518 } 519 520 return (error); 521 } 522 523 static int 524 ena_sysctl_eni_metrics_interval(SYSCTL_HANDLER_ARGS) 525 { 526 struct ena_adapter *adapter = arg1; 527 uint16_t interval; 528 int error; 529 530 error = sysctl_wire_old_buffer(req, sizeof(interval)); 531 if (error == 0) { 532 interval = adapter->eni_metrics_sample_interval; 533 error = sysctl_handle_16(oidp, &interval, 0, req); 534 } 535 if (error != 0 || req->newptr == NULL) 536 return (error); 537 538 if (interval > ENI_METRICS_MAX_SAMPLE_INTERVAL) { 539 device_printf(adapter->pdev, 540 "ENI metrics update interval is out of range - maximum allowed value: %d seconds\n", 541 ENI_METRICS_MAX_SAMPLE_INTERVAL); 542 return (EINVAL); 543 } 544 545 if (interval == 0) { 546 device_printf(adapter->pdev, 547 "ENI metrics update is now turned off\n"); 548 bzero(&adapter->eni_metrics, sizeof(adapter->eni_metrics)); 549 } else { 550 device_printf(adapter->pdev, 551 "ENI metrics update interval is set to: %"PRIu16" seconds\n", 552 interval); 553 } 554 555 adapter->eni_metrics_sample_interval = interval; 556 557 return (0); 558 } 559