diff options
author | Jim Harris <jimharris@FreeBSD.org> | 2012-10-10 23:35:16 +0000 |
---|---|---|
committer | Jim Harris <jimharris@FreeBSD.org> | 2012-10-10 23:35:16 +0000 |
commit | 6568ebfcbb8587bd6962e0f52d8ef01efc89c6b2 (patch) | |
tree | 62b67a90fd070b1a48c592b6ee5dc97c8be3489d /sys/dev/nvme | |
parent | 8bed48f25d3df5aa13654651ee5bc4284f10d310 (diff) | |
download | src-6568ebfcbb8587bd6962e0f52d8ef01efc89c6b2.tar.gz src-6568ebfcbb8587bd6962e0f52d8ef01efc89c6b2.zip |
Count number of times each queue pair's interrupt handler is invoked.
Also add sysctls to query and reset each queue pair's stats, including
the new count added here.
Sponsored by: Intel
Notes
Notes:
svn path=/head/; revision=241434
Diffstat (limited to 'sys/dev/nvme')
-rw-r--r-- | sys/dev/nvme/nvme_private.h | 1 | ||||
-rw-r--r-- | sys/dev/nvme/nvme_qpair.c | 3 | ||||
-rw-r--r-- | sys/dev/nvme/nvme_sysctl.c | 91 |
3 files changed, 95 insertions, 0 deletions
diff --git a/sys/dev/nvme/nvme_private.h b/sys/dev/nvme/nvme_private.h index ae7faf92a146..df182f719564 100644 --- a/sys/dev/nvme/nvme_private.h +++ b/sys/dev/nvme/nvme_private.h @@ -134,6 +134,7 @@ struct nvme_qpair { uint32_t cq_head; int64_t num_cmds; + int64_t num_intr_handler_calls; struct nvme_command *cmd; struct nvme_completion *cpl; diff --git a/sys/dev/nvme/nvme_qpair.c b/sys/dev/nvme/nvme_qpair.c index a49a7027d2fe..5ad1ea8aae33 100644 --- a/sys/dev/nvme/nvme_qpair.c +++ b/sys/dev/nvme/nvme_qpair.c @@ -125,6 +125,8 @@ nvme_qpair_process_completions(struct nvme_qpair *qpair) struct nvme_completion *cpl; boolean_t retry, error; + qpair->num_intr_handler_calls++; + while (1) { cpl = &qpair->cpl[qpair->cq_head]; @@ -238,6 +240,7 @@ nvme_qpair_construct(struct nvme_qpair *qpair, uint32_t id, NULL, NULL, &qpair->dma_tag); qpair->num_cmds = 0; + qpair->num_intr_handler_calls = 0; qpair->num_tr = 0; qpair->num_prp_list = 0; qpair->sq_head = qpair->sq_tail = qpair->cq_head = 0; diff --git a/sys/dev/nvme/nvme_sysctl.c b/sys/dev/nvme/nvme_sysctl.c index b8fa209060ff..ecf8b6e0a684 100644 --- a/sys/dev/nvme/nvme_sysctl.c +++ b/sys/dev/nvme/nvme_sysctl.c @@ -33,6 +33,16 @@ __FBSDID("$FreeBSD$"); #include "nvme_private.h" +/* + * CTLTYPE_S64 and sysctl_handle_64 were added in r217616. Define these + * explicitly here for older kernels that don't include the r217616 + * changeset. + */ +#ifndef CTLTYPE_S64 +#define CTLTYPE_S64 CTLTYPE_QUAD +#define sysctl_handle_64 sysctl_handle_quad +#endif + static void nvme_dump_queue(struct nvme_qpair *qpair) { @@ -114,6 +124,66 @@ nvme_sysctl_int_coal_threshold(SYSCTL_HANDLER_ARGS) } static void +nvme_qpair_reset_stats(struct nvme_qpair *qpair) +{ + + qpair->num_cmds = 0; + qpair->num_intr_handler_calls = 0; +} + +static int +nvme_sysctl_num_cmds(SYSCTL_HANDLER_ARGS) +{ + struct nvme_controller *ctrlr = arg1; + int64_t num_cmds = 0; + int i; + + num_cmds = ctrlr->adminq.num_cmds; + + for (i = 0; i < ctrlr->num_io_queues; i++) + num_cmds += ctrlr->ioq[i].num_cmds; + + return (sysctl_handle_64(oidp, &num_cmds, 0, req)); +} + +static int +nvme_sysctl_num_intr_handler_calls(SYSCTL_HANDLER_ARGS) +{ + struct nvme_controller *ctrlr = arg1; + int64_t num_intr_handler_calls = 0; + int i; + + num_intr_handler_calls = ctrlr->adminq.num_intr_handler_calls; + + for (i = 0; i < ctrlr->num_io_queues; i++) + num_intr_handler_calls += ctrlr->ioq[i].num_intr_handler_calls; + + return (sysctl_handle_64(oidp, &num_intr_handler_calls, 0, req)); +} + +static int +nvme_sysctl_reset_stats(SYSCTL_HANDLER_ARGS) +{ + struct nvme_controller *ctrlr = arg1; + uint32_t i, val = 0; + + int error = sysctl_handle_int(oidp, &val, 0, req); + + if (error) + return (error); + + if (val != 0) { + nvme_qpair_reset_stats(&ctrlr->adminq); + + for (i = 0; i < ctrlr->num_io_queues; i++) + nvme_qpair_reset_stats(&ctrlr->ioq[i]); + } + + return (0); +} + + +static void nvme_sysctl_initialize_queue(struct nvme_qpair *qpair, struct sysctl_ctx_list *ctrlr_ctx, struct sysctl_oid *que_tree) { @@ -140,6 +210,11 @@ nvme_sysctl_initialize_queue(struct nvme_qpair *qpair, SYSCTL_ADD_QUAD(ctrlr_ctx, que_list, OID_AUTO, "num_cmds", CTLFLAG_RD, &qpair->num_cmds, "Number of commands submitted"); + SYSCTL_ADD_QUAD(ctrlr_ctx, que_list, OID_AUTO, "num_intr_handler_calls", + CTLFLAG_RD, &qpair->num_intr_handler_calls, + "Number of times interrupt handler was invoked (will typically be " + "less than number of actual interrupts generated due to " + "coalescing)"); SYSCTL_ADD_PROC(ctrlr_ctx, que_list, OID_AUTO, "dump_debug", CTLTYPE_UINT | CTLFLAG_RW, qpair, 0, @@ -170,6 +245,22 @@ nvme_sysctl_initialize_ctrlr(struct nvme_controller *ctrlr) "int_coal_threshold", CTLTYPE_UINT | CTLFLAG_RW, ctrlr, 0, nvme_sysctl_int_coal_threshold, "IU", "Interrupt coalescing threshold"); + + SYSCTL_ADD_PROC(ctrlr_ctx, ctrlr_list, OID_AUTO, + "num_cmds", CTLTYPE_S64 | CTLFLAG_RD, + ctrlr, 0, nvme_sysctl_num_cmds, "IU", + "Number of commands submitted"); + + SYSCTL_ADD_PROC(ctrlr_ctx, ctrlr_list, OID_AUTO, + "num_intr_handler_calls", CTLTYPE_S64 | CTLFLAG_RD, + ctrlr, 0, nvme_sysctl_num_intr_handler_calls, "IU", + "Number of times interrupt handler was invoked (will " + "typically be less than number of actual interrupts " + "generated due to coalescing)"); + + SYSCTL_ADD_PROC(ctrlr_ctx, ctrlr_list, OID_AUTO, + "reset_stats", CTLTYPE_UINT | CTLFLAG_RW, ctrlr, 0, + nvme_sysctl_reset_stats, "IU", "Reset statistics to zero"); } que_tree = SYSCTL_ADD_NODE(ctrlr_ctx, ctrlr_list, OID_AUTO, "adminq", |