From 7dfc5e922d7c69fd5efdc1ecbbcd6af1245f5462 Mon Sep 17 00:00:00 2001 From: Daniel Verkamp Date: Tue, 26 Jul 2016 13:03:14 -0700 Subject: [PATCH] nvmf: only poll admin queue once every 10 ms This should enhance performance, since the hardware admin queue poll function takes a mutex and should not be in the performance path. Change-Id: I7e4acde0337aaf7079811612cba5348acf0a467d Signed-off-by: Daniel Verkamp --- lib/nvmf/direct.c | 12 +++++++++--- lib/nvmf/subsystem.c | 22 +++++++++++++++++++++- lib/nvmf/subsystem.h | 10 ++++++++-- 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/lib/nvmf/direct.c b/lib/nvmf/direct.c index 46e5f67eb..53fe5b54d 100644 --- a/lib/nvmf/direct.c +++ b/lib/nvmf/direct.c @@ -49,10 +49,15 @@ nvmf_direct_ctrlr_get_data(struct nvmf_session *session) } static void -nvmf_direct_ctrlr_poll_for_completions(struct nvmf_session *session) +nvmf_direct_ctrlr_poll_for_io_completions(struct nvmf_session *session) +{ + spdk_nvme_qpair_process_completions(session->subsys->ctrlr.dev.direct.io_qpair, 0); +} + +static void +nvmf_direct_ctrlr_poll_for_admin_completions(struct nvmf_session *session) { spdk_nvme_ctrlr_process_admin_completions(session->subsys->ctrlr.dev.direct.ctrlr); - spdk_nvme_qpair_process_completions(session->subsys->ctrlr.dev.direct.io_qpair, 0); } static void @@ -251,5 +256,6 @@ const struct spdk_nvmf_ctrlr_ops spdk_nvmf_direct_ctrlr_ops = { .ctrlr_get_data = nvmf_direct_ctrlr_get_data, .process_admin_cmd = nvmf_direct_ctrlr_process_admin_cmd, .process_io_cmd = nvmf_direct_ctrlr_process_io_cmd, - .poll_for_completions = nvmf_direct_ctrlr_poll_for_completions, + .poll_for_io_completions = nvmf_direct_ctrlr_poll_for_io_completions, + .poll_for_admin_completions = nvmf_direct_ctrlr_poll_for_admin_completions, }; diff --git a/lib/nvmf/subsystem.c b/lib/nvmf/subsystem.c index 486d66625..3c8e1a8ea 100644 --- a/lib/nvmf/subsystem.c +++ b/lib/nvmf/subsystem.c @@ -42,6 +42,8 @@ #include "spdk/trace.h" #include "spdk/nvmf_spec.h" +#define ADMIN_POLL_MICROSECONDS 10000 /* 10 milliseconds */ + static TAILQ_HEAD(, spdk_nvmf_subsystem) g_subsystems = TAILQ_HEAD_INITIALIZER(g_subsystems); struct spdk_nvmf_subsystem * @@ -85,13 +87,29 @@ spdk_nvmf_subsystem_poller(void *arg) /* For NVMe subsystems, check the backing physical device for completions. */ if (subsystem->subtype == SPDK_NVMF_SUBTYPE_NVME) { - session->subsys->ctrlr.ops->poll_for_completions(session); + session->subsys->ctrlr.ops->poll_for_io_completions(session); } /* For each connection in the session, check for RDMA completions */ spdk_nvmf_session_poll(session); } +static void +spdk_nvmf_subsystem_admin_poll(void *arg) +{ + struct spdk_nvmf_subsystem *subsystem = arg; + struct nvmf_session *session = subsystem->session; + + if (!session) { + /* No active connections, so just return */ + return; + } + + if (subsystem->subtype == SPDK_NVMF_SUBTYPE_NVME) { + session->subsys->ctrlr.ops->poll_for_admin_completions(session); + } +} + struct spdk_nvmf_subsystem * nvmf_create_subsystem(int num, const char *name, enum spdk_nvmf_subtype subtype, @@ -114,6 +132,8 @@ nvmf_create_subsystem(int num, const char *name, subsystem->lcore = lcore; spdk_poller_register(&subsystem->poller, spdk_nvmf_subsystem_poller, subsystem, lcore, NULL, 0); + spdk_poller_register(&subsystem->admin_poller, spdk_nvmf_subsystem_admin_poll, subsystem, + lcore, NULL, ADMIN_POLL_MICROSECONDS); TAILQ_INSERT_HEAD(&g_subsystems, subsystem, entries); diff --git a/lib/nvmf/subsystem.h b/lib/nvmf/subsystem.h index f8e373e3e..b6b9dfe79 100644 --- a/lib/nvmf/subsystem.h +++ b/lib/nvmf/subsystem.h @@ -88,9 +88,14 @@ struct spdk_nvmf_ctrlr_ops { int (*process_io_cmd)(struct spdk_nvmf_request *req); /** - * Poll for completions. + * Poll for I/O completions. */ - void (*poll_for_completions)(struct nvmf_session *session); + void (*poll_for_io_completions)(struct nvmf_session *session); + + /** + * Poll for admin completions. + */ + void (*poll_for_admin_completions)(struct nvmf_session *session); }; struct spdk_nvmf_controller { @@ -127,6 +132,7 @@ struct spdk_nvmf_subsystem { struct spdk_nvmf_controller ctrlr; struct spdk_poller *poller; + struct spdk_poller *admin_poller; TAILQ_HEAD(, spdk_nvmf_listen_addr) listen_addrs; uint32_t num_listen_addrs;