svn commit: r352630 - head/sys/dev/nvme
Alexander Motin
mav at FreeBSD.org
Mon Sep 23 17:53:49 UTC 2019
Author: mav
Date: Mon Sep 23 17:53:47 2019
New Revision: 352630
URL: https://svnweb.freebsd.org/changeset/base/352630
Log:
Make nvme(4) driver some more NUMA aware.
- For each queue pair precalculate CPU and domain it is bound to.
If queue pairs are not per-CPU, then use the domain of the device.
- Allocate most of queue pair memory from the domain it is bound to.
- Bind callouts to the same CPUs as queue pair to avoid migrations.
- Do not assign queue pairs to each SMT thread. It just wasted
resources and increased lock congestions.
- Remove fixed multiplier of CPUs per queue pair, spread them even.
This allows to use more queue pairs in some hardware configurations.
- If queue pair serves multiple CPUs, bind different NVMe devices to
different CPUs.
MFC after: 1 month
Sponsored by: iXsystems, Inc.
Modified:
head/sys/dev/nvme/nvme_ahci.c
head/sys/dev/nvme/nvme_ctrlr.c
head/sys/dev/nvme/nvme_ctrlr_cmd.c
head/sys/dev/nvme/nvme_pci.c
head/sys/dev/nvme/nvme_private.h
head/sys/dev/nvme/nvme_qpair.c
head/sys/dev/nvme/nvme_sysctl.c
Modified: head/sys/dev/nvme/nvme_ahci.c
==============================================================================
--- head/sys/dev/nvme/nvme_ahci.c Mon Sep 23 17:05:46 2019 (r352629)
+++ head/sys/dev/nvme/nvme_ahci.c Mon Sep 23 17:53:47 2019 (r352630)
@@ -96,7 +96,6 @@ nvme_ahci_attach(device_t dev)
ctrlr->msix_enabled = 0;
ctrlr->num_io_queues = 1;
- ctrlr->num_cpus_per_ioq = mp_ncpus;
if (bus_setup_intr(dev, ctrlr->res,
INTR_TYPE_MISC | INTR_MPSAFE, NULL, nvme_ctrlr_intx_handler,
ctrlr, &ctrlr->tag) != 0) {
Modified: head/sys/dev/nvme/nvme_ctrlr.c
==============================================================================
--- head/sys/dev/nvme/nvme_ctrlr.c Mon Sep 23 17:05:46 2019 (r352629)
+++ head/sys/dev/nvme/nvme_ctrlr.c Mon Sep 23 17:53:47 2019 (r352630)
@@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
#include <sys/smp.h>
#include <sys/uio.h>
#include <sys/endian.h>
+#include <vm/vm.h>
#include "nvme_private.h"
@@ -57,6 +58,9 @@ nvme_ctrlr_construct_admin_qpair(struct nvme_controlle
int error;
qpair = &ctrlr->adminq;
+ qpair->id = 0;
+ qpair->cpu = CPU_FFS(&cpuset_domain[ctrlr->domain]) - 1;
+ qpair->domain = ctrlr->domain;
num_entries = NVME_ADMIN_ENTRIES;
TUNABLE_INT_FETCH("hw.nvme.admin_entries", &num_entries);
@@ -75,22 +79,21 @@ nvme_ctrlr_construct_admin_qpair(struct nvme_controlle
* The admin queue's max xfer size is treated differently than the
* max I/O xfer size. 16KB is sufficient here - maybe even less?
*/
- error = nvme_qpair_construct(qpair,
- 0, /* qpair ID */
- 0, /* vector */
- num_entries,
- NVME_ADMIN_TRACKERS,
- ctrlr);
+ error = nvme_qpair_construct(qpair, num_entries, NVME_ADMIN_TRACKERS,
+ ctrlr);
return (error);
}
+#define QP(ctrlr, c) ((c) * (ctrlr)->num_io_queues / mp_ncpus)
+
static int
nvme_ctrlr_construct_io_qpairs(struct nvme_controller *ctrlr)
{
struct nvme_qpair *qpair;
uint32_t cap_lo;
uint16_t mqes;
- int i, error, num_entries, num_trackers, max_entries;
+ int c, error, i, n;
+ int num_entries, num_trackers, max_entries;
/*
* NVMe spec sets a hard limit of 64K max entries, but devices may
@@ -130,32 +133,35 @@ nvme_ctrlr_construct_io_qpairs(struct nvme_controller
*/
ctrlr->max_hw_pend_io = num_trackers * ctrlr->num_io_queues * 3 / 4;
- /*
- * This was calculated previously when setting up interrupts, but
- * a controller could theoretically support fewer I/O queues than
- * MSI-X vectors. So calculate again here just to be safe.
- */
- ctrlr->num_cpus_per_ioq = howmany(mp_ncpus, ctrlr->num_io_queues);
-
ctrlr->ioq = malloc(ctrlr->num_io_queues * sizeof(struct nvme_qpair),
M_NVME, M_ZERO | M_WAITOK);
- for (i = 0; i < ctrlr->num_io_queues; i++) {
+ for (i = c = n = 0; i < ctrlr->num_io_queues; i++, c += n) {
qpair = &ctrlr->ioq[i];
/*
* Admin queue has ID=0. IO queues start at ID=1 -
* hence the 'i+1' here.
- *
+ */
+ qpair->id = i + 1;
+ if (ctrlr->num_io_queues > 1) {
+ /* Find number of CPUs served by this queue. */
+ for (n = 1; QP(ctrlr, c + n) == i; n++)
+ ;
+ /* Shuffle multiple NVMe devices between CPUs. */
+ qpair->cpu = c + (device_get_unit(ctrlr->dev)+n/2) % n;
+ qpair->domain = pcpu_find(qpair->cpu)->pc_domain;
+ } else {
+ qpair->cpu = CPU_FFS(&cpuset_domain[ctrlr->domain]) - 1;
+ qpair->domain = ctrlr->domain;
+ }
+
+ /*
* For I/O queues, use the controller-wide max_xfer_size
* calculated in nvme_attach().
*/
- error = nvme_qpair_construct(qpair,
- i+1, /* qpair ID */
- ctrlr->msix_enabled ? i+1 : 0, /* vector */
- num_entries,
- num_trackers,
- ctrlr);
+ error = nvme_qpair_construct(qpair, num_entries, num_trackers,
+ ctrlr);
if (error)
return (error);
@@ -164,8 +170,7 @@ nvme_ctrlr_construct_io_qpairs(struct nvme_controller
* interrupt thread for this controller.
*/
if (ctrlr->num_io_queues > 1)
- bus_bind_intr(ctrlr->dev, qpair->res,
- i * ctrlr->num_cpus_per_ioq);
+ bus_bind_intr(ctrlr->dev, qpair->res, qpair->cpu);
}
return (0);
@@ -458,6 +463,8 @@ nvme_ctrlr_set_num_qpairs(struct nvme_controller *ctrl
*/
ctrlr->num_io_queues = min(ctrlr->num_io_queues, sq_allocated);
ctrlr->num_io_queues = min(ctrlr->num_io_queues, cq_allocated);
+ if (ctrlr->num_io_queues > vm_ndomains)
+ ctrlr->num_io_queues -= ctrlr->num_io_queues % vm_ndomains;
return (0);
}
@@ -473,7 +480,7 @@ nvme_ctrlr_create_qpairs(struct nvme_controller *ctrlr
qpair = &ctrlr->ioq[i];
status.done = 0;
- nvme_ctrlr_cmd_create_io_cq(ctrlr, qpair, qpair->vector,
+ nvme_ctrlr_cmd_create_io_cq(ctrlr, qpair,
nvme_completion_poll_cb, &status);
nvme_completion_poll(&status);
if (nvme_completion_is_error(&status.cpl)) {
@@ -1132,6 +1139,8 @@ nvme_ctrlr_construct(struct nvme_controller *ctrlr, de
ctrlr->dev = dev;
mtx_init(&ctrlr->lock, "nvme ctrlr lock", NULL, MTX_DEF);
+ if (bus_get_domain(dev, &ctrlr->domain) != 0)
+ ctrlr->domain = 0;
cap_hi = nvme_mmio_read_4(ctrlr, cap_hi);
ctrlr->dstrd = NVME_CAP_HI_DSTRD(cap_hi) + 2;
@@ -1296,7 +1305,7 @@ nvme_ctrlr_submit_io_request(struct nvme_controller *c
{
struct nvme_qpair *qpair;
- qpair = &ctrlr->ioq[curcpu / ctrlr->num_cpus_per_ioq];
+ qpair = &ctrlr->ioq[QP(ctrlr, curcpu)];
nvme_qpair_submit_request(qpair, req);
}
Modified: head/sys/dev/nvme/nvme_ctrlr_cmd.c
==============================================================================
--- head/sys/dev/nvme/nvme_ctrlr_cmd.c Mon Sep 23 17:05:46 2019 (r352629)
+++ head/sys/dev/nvme/nvme_ctrlr_cmd.c Mon Sep 23 17:53:47 2019 (r352630)
@@ -76,8 +76,7 @@ nvme_ctrlr_cmd_identify_namespace(struct nvme_controll
void
nvme_ctrlr_cmd_create_io_cq(struct nvme_controller *ctrlr,
- struct nvme_qpair *io_que, uint16_t vector, nvme_cb_fn_t cb_fn,
- void *cb_arg)
+ struct nvme_qpair *io_que, nvme_cb_fn_t cb_fn, void *cb_arg)
{
struct nvme_request *req;
struct nvme_command *cmd;
@@ -93,7 +92,7 @@ nvme_ctrlr_cmd_create_io_cq(struct nvme_controller *ct
*/
cmd->cdw10 = htole32(((io_que->num_entries-1) << 16) | io_que->id);
/* 0x3 = interrupts enabled | physically contiguous */
- cmd->cdw11 = htole32((vector << 16) | 0x3);
+ cmd->cdw11 = htole32((io_que->vector << 16) | 0x3);
cmd->prp1 = htole64(io_que->cpl_bus_addr);
nvme_ctrlr_submit_admin_request(ctrlr, req);
Modified: head/sys/dev/nvme/nvme_pci.c
==============================================================================
--- head/sys/dev/nvme/nvme_pci.c Mon Sep 23 17:05:46 2019 (r352629)
+++ head/sys/dev/nvme/nvme_pci.c Mon Sep 23 17:53:47 2019 (r352630)
@@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
#include <sys/conf.h>
#include <sys/proc.h>
#include <sys/smp.h>
+#include <vm/vm.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
@@ -233,7 +234,6 @@ nvme_ctrlr_configure_intx(struct nvme_controller *ctrl
ctrlr->msix_enabled = 0;
ctrlr->num_io_queues = 1;
- ctrlr->num_cpus_per_ioq = mp_ncpus;
ctrlr->rid = 0;
ctrlr->res = bus_alloc_resource_any(ctrlr->dev, SYS_RES_IRQ,
&ctrlr->rid, RF_SHAREABLE | RF_ACTIVE);
@@ -259,82 +259,61 @@ static void
nvme_ctrlr_setup_interrupts(struct nvme_controller *ctrlr)
{
device_t dev;
- int per_cpu_io_queues;
+ int force_intx, num_io_queues, per_cpu_io_queues;
int min_cpus_per_ioq;
int num_vectors_requested, num_vectors_allocated;
- int num_vectors_available;
dev = ctrlr->dev;
- min_cpus_per_ioq = 1;
- TUNABLE_INT_FETCH("hw.nvme.min_cpus_per_ioq", &min_cpus_per_ioq);
- if (min_cpus_per_ioq < 1) {
- min_cpus_per_ioq = 1;
- } else if (min_cpus_per_ioq > mp_ncpus) {
- min_cpus_per_ioq = mp_ncpus;
+ force_intx = 0;
+ TUNABLE_INT_FETCH("hw.nvme.force_intx", &force_intx);
+ if (force_intx || pci_msix_count(dev) < 2) {
+ nvme_ctrlr_configure_intx(ctrlr);
+ return;
}
+ num_io_queues = mp_ncpus;
+ TUNABLE_INT_FETCH("hw.nvme.num_io_queues", &num_io_queues);
+ if (num_io_queues < 1 || num_io_queues > mp_ncpus)
+ num_io_queues = mp_ncpus;
+
per_cpu_io_queues = 1;
TUNABLE_INT_FETCH("hw.nvme.per_cpu_io_queues", &per_cpu_io_queues);
+ if (per_cpu_io_queues == 0)
+ num_io_queues = 1;
- if (per_cpu_io_queues == 0) {
- min_cpus_per_ioq = mp_ncpus;
+ min_cpus_per_ioq = smp_threads_per_core;
+ TUNABLE_INT_FETCH("hw.nvme.min_cpus_per_ioq", &min_cpus_per_ioq);
+ if (min_cpus_per_ioq > 1) {
+ num_io_queues = min(num_io_queues,
+ max(1, mp_ncpus / min_cpus_per_ioq));
}
- ctrlr->force_intx = 0;
- TUNABLE_INT_FETCH("hw.nvme.force_intx", &ctrlr->force_intx);
+ num_io_queues = min(num_io_queues, pci_msix_count(dev) - 1);
- /*
- * FreeBSD currently cannot allocate more than about 190 vectors at
- * boot, meaning that systems with high core count and many devices
- * requesting per-CPU interrupt vectors will not get their full
- * allotment. So first, try to allocate as many as we may need to
- * understand what is available, then immediately release them.
- * Then figure out how many of those we will actually use, based on
- * assigning an equal number of cores to each I/O queue.
- */
-
+again:
+ if (num_io_queues > vm_ndomains)
+ num_io_queues -= num_io_queues % vm_ndomains;
/* One vector for per core I/O queue, plus one vector for admin queue. */
- num_vectors_available = min(pci_msix_count(dev), mp_ncpus + 1);
- if (pci_alloc_msix(dev, &num_vectors_available) != 0) {
- num_vectors_available = 0;
- }
- pci_release_msi(dev);
-
- if (ctrlr->force_intx || num_vectors_available < 2) {
- nvme_ctrlr_configure_intx(ctrlr);
- return;
- }
-
- /*
- * Do not use all vectors for I/O queues - one must be saved for the
- * admin queue.
- */
- ctrlr->num_cpus_per_ioq = max(min_cpus_per_ioq,
- howmany(mp_ncpus, num_vectors_available - 1));
-
- ctrlr->num_io_queues = howmany(mp_ncpus, ctrlr->num_cpus_per_ioq);
- num_vectors_requested = ctrlr->num_io_queues + 1;
+ num_vectors_requested = num_io_queues + 1;
num_vectors_allocated = num_vectors_requested;
-
- /*
- * Now just allocate the number of vectors we need. This should
- * succeed, since we previously called pci_alloc_msix()
- * successfully returning at least this many vectors, but just to
- * be safe, if something goes wrong just revert to INTx.
- */
if (pci_alloc_msix(dev, &num_vectors_allocated) != 0) {
nvme_ctrlr_configure_intx(ctrlr);
return;
}
-
- if (num_vectors_allocated < num_vectors_requested) {
+ if (num_vectors_allocated < 2) {
pci_release_msi(dev);
nvme_ctrlr_configure_intx(ctrlr);
return;
}
+ if (num_vectors_allocated != num_vectors_requested) {
+ pci_release_msi(dev);
+ num_io_queues = num_vectors_allocated - 1;
+ goto again;
+ }
ctrlr->msix_enabled = 1;
+ ctrlr->num_io_queues = num_io_queues;
}
static int
Modified: head/sys/dev/nvme/nvme_private.h
==============================================================================
--- head/sys/dev/nvme/nvme_private.h Mon Sep 23 17:05:46 2019 (r352629)
+++ head/sys/dev/nvme/nvme_private.h Mon Sep 23 17:53:47 2019 (r352630)
@@ -175,7 +175,8 @@ struct nvme_qpair {
struct nvme_controller *ctrlr;
uint32_t id;
- uint32_t phase;
+ int domain;
+ int cpu;
uint16_t vector;
int rid;
@@ -187,6 +188,7 @@ struct nvme_qpair {
uint32_t sq_tdbl_off;
uint32_t cq_hdbl_off;
+ uint32_t phase;
uint32_t sq_head;
uint32_t sq_tail;
uint32_t cq_head;
@@ -238,7 +240,7 @@ struct nvme_controller {
device_t dev;
struct mtx lock;
-
+ int domain;
uint32_t ready_timeout_in_ms;
uint32_t quirks;
#define QUIRK_DELAY_B4_CHK_RDY 1 /* Can't touch MMIO on disable */
@@ -258,11 +260,9 @@ struct nvme_controller {
struct resource *bar4_resource;
uint32_t msix_enabled;
- uint32_t force_intx;
uint32_t enable_aborts;
uint32_t num_io_queues;
- uint32_t num_cpus_per_ioq;
uint32_t max_hw_pend_io;
/* Fields for tracking progress during controller initialization. */
@@ -377,7 +377,7 @@ void nvme_ctrlr_cmd_get_firmware_page(struct nvme_cont
nvme_cb_fn_t cb_fn,
void *cb_arg);
void nvme_ctrlr_cmd_create_io_cq(struct nvme_controller *ctrlr,
- struct nvme_qpair *io_que, uint16_t vector,
+ struct nvme_qpair *io_que,
nvme_cb_fn_t cb_fn, void *cb_arg);
void nvme_ctrlr_cmd_create_io_sq(struct nvme_controller *ctrlr,
struct nvme_qpair *io_que,
@@ -413,9 +413,8 @@ void nvme_ctrlr_submit_io_request(struct nvme_controll
void nvme_ctrlr_post_failed_request(struct nvme_controller *ctrlr,
struct nvme_request *req);
-int nvme_qpair_construct(struct nvme_qpair *qpair, uint32_t id,
- uint16_t vector, uint32_t num_entries,
- uint32_t num_trackers,
+int nvme_qpair_construct(struct nvme_qpair *qpair,
+ uint32_t num_entries, uint32_t num_trackers,
struct nvme_controller *ctrlr);
void nvme_qpair_submit_tracker(struct nvme_qpair *qpair,
struct nvme_tracker *tr);
Modified: head/sys/dev/nvme/nvme_qpair.c
==============================================================================
--- head/sys/dev/nvme/nvme_qpair.c Mon Sep 23 17:05:46 2019 (r352629)
+++ head/sys/dev/nvme/nvme_qpair.c Mon Sep 23 17:53:47 2019 (r352630)
@@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/conf.h>
+#include <sys/domainset.h>
#include <sys/proc.h>
#include <dev/pci/pcivar.h>
@@ -637,8 +638,8 @@ nvme_qpair_msix_handler(void *arg)
}
int
-nvme_qpair_construct(struct nvme_qpair *qpair, uint32_t id,
- uint16_t vector, uint32_t num_entries, uint32_t num_trackers,
+nvme_qpair_construct(struct nvme_qpair *qpair,
+ uint32_t num_entries, uint32_t num_trackers,
struct nvme_controller *ctrlr)
{
struct nvme_tracker *tr;
@@ -647,8 +648,7 @@ nvme_qpair_construct(struct nvme_qpair *qpair, uint32_
uint8_t *queuemem, *prpmem, *prp_list;
int i, err;
- qpair->id = id;
- qpair->vector = vector;
+ qpair->vector = ctrlr->msix_enabled ? qpair->id : 0;
qpair->num_entries = num_entries;
qpair->num_trackers = num_trackers;
qpair->ctrlr = ctrlr;
@@ -659,19 +659,19 @@ nvme_qpair_construct(struct nvme_qpair *qpair, uint32_
* MSI-X vector resource IDs start at 1, so we add one to
* the queue's vector to get the corresponding rid to use.
*/
- qpair->rid = vector + 1;
+ qpair->rid = qpair->vector + 1;
qpair->res = bus_alloc_resource_any(ctrlr->dev, SYS_RES_IRQ,
&qpair->rid, RF_ACTIVE);
bus_setup_intr(ctrlr->dev, qpair->res,
INTR_TYPE_MISC | INTR_MPSAFE, NULL,
nvme_qpair_msix_handler, qpair, &qpair->tag);
- if (id == 0) {
+ if (qpair->id == 0) {
bus_describe_intr(ctrlr->dev, qpair->res, qpair->tag,
"admin");
} else {
bus_describe_intr(ctrlr->dev, qpair->res, qpair->tag,
- "io%d", id - 1);
+ "io%d", qpair->id - 1);
}
}
@@ -707,6 +707,7 @@ nvme_qpair_construct(struct nvme_qpair *qpair, uint32_
nvme_printf(ctrlr, "tag create failed %d\n", err);
goto out;
}
+ bus_dma_tag_set_domain(qpair->dma_tag, qpair->domain);
if (bus_dmamem_alloc(qpair->dma_tag, (void **)&queuemem,
BUS_DMA_NOWAIT, &qpair->queuemem_map)) {
@@ -737,9 +738,9 @@ nvme_qpair_construct(struct nvme_qpair *qpair, uint32_
* it to various small values.
*/
qpair->sq_tdbl_off = nvme_mmio_offsetof(doorbell[0]) +
- (id << (ctrlr->dstrd + 1));
+ (qpair->id << (ctrlr->dstrd + 1));
qpair->cq_hdbl_off = nvme_mmio_offsetof(doorbell[0]) +
- (id << (ctrlr->dstrd + 1)) + (1 << ctrlr->dstrd);
+ (qpair->id << (ctrlr->dstrd + 1)) + (1 << ctrlr->dstrd);
TAILQ_INIT(&qpair->free_tr);
TAILQ_INIT(&qpair->outstanding_tr);
@@ -765,7 +766,8 @@ nvme_qpair_construct(struct nvme_qpair *qpair, uint32_
(uint8_t *)roundup2((uintptr_t)prp_list, PAGE_SIZE);
}
- tr = malloc(sizeof(*tr), M_NVME, M_ZERO | M_WAITOK);
+ tr = malloc_domainset(sizeof(*tr), M_NVME,
+ DOMAINSET_PREF(qpair->domain), M_ZERO | M_WAITOK);
bus_dmamap_create(qpair->dma_tag_payload, 0,
&tr->payload_dma_map);
callout_init(&tr->timer, 1);
@@ -783,8 +785,9 @@ nvme_qpair_construct(struct nvme_qpair *qpair, uint32_
goto out;
}
- qpair->act_tr = malloc(sizeof(struct nvme_tracker *) *
- qpair->num_entries, M_NVME, M_ZERO | M_WAITOK);
+ qpair->act_tr = malloc_domainset(sizeof(struct nvme_tracker *) *
+ qpair->num_entries, M_NVME, DOMAINSET_PREF(qpair->domain),
+ M_ZERO | M_WAITOK);
return (0);
out:
@@ -814,14 +817,14 @@ nvme_qpair_destroy(struct nvme_qpair *qpair)
}
if (qpair->act_tr)
- free(qpair->act_tr, M_NVME);
+ free_domain(qpair->act_tr, M_NVME);
while (!TAILQ_EMPTY(&qpair->free_tr)) {
tr = TAILQ_FIRST(&qpair->free_tr);
TAILQ_REMOVE(&qpair->free_tr, tr, tailq);
bus_dmamap_destroy(qpair->dma_tag_payload,
tr->payload_dma_map);
- free(tr, M_NVME);
+ free_domain(tr, M_NVME);
}
if (qpair->dma_tag)
@@ -938,8 +941,8 @@ nvme_qpair_submit_tracker(struct nvme_qpair *qpair, st
ctrlr = qpair->ctrlr;
if (req->timeout)
- callout_reset_curcpu(&tr->timer, ctrlr->timeout_period * hz,
- nvme_timeout, tr);
+ callout_reset_on(&tr->timer, ctrlr->timeout_period * hz,
+ nvme_timeout, tr, qpair->cpu);
/* Copy the command from the tracker to the submission queue. */
memcpy(&qpair->cmd[qpair->sq_tail], &req->cmd, sizeof(req->cmd));
Modified: head/sys/dev/nvme/nvme_sysctl.c
==============================================================================
--- head/sys/dev/nvme/nvme_sysctl.c Mon Sep 23 17:05:46 2019 (r352629)
+++ head/sys/dev/nvme/nvme_sysctl.c Mon Sep 23 17:53:47 2019 (r352630)
@@ -306,9 +306,9 @@ nvme_sysctl_initialize_ctrlr(struct nvme_controller *c
ctrlr_tree = device_get_sysctl_tree(ctrlr->dev);
ctrlr_list = SYSCTL_CHILDREN(ctrlr_tree);
- SYSCTL_ADD_UINT(ctrlr_ctx, ctrlr_list, OID_AUTO, "num_cpus_per_ioq",
- CTLFLAG_RD, &ctrlr->num_cpus_per_ioq, 0,
- "Number of CPUs assigned per I/O queue pair");
+ SYSCTL_ADD_UINT(ctrlr_ctx, ctrlr_list, OID_AUTO, "num_io_queues",
+ CTLFLAG_RD, &ctrlr->num_io_queues, 0,
+ "Number of I/O queue pairs");
SYSCTL_ADD_PROC(ctrlr_ctx, ctrlr_list, OID_AUTO,
"int_coal_time", CTLTYPE_UINT | CTLFLAG_RW, ctrlr, 0,
More information about the svn-src-head
mailing list