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 <daniel.verkamp@intel.com>
This commit is contained in:
Daniel Verkamp 2016-07-26 13:03:14 -07:00
parent 5d8c94536a
commit 7dfc5e922d
3 changed files with 38 additions and 6 deletions

View File

@ -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,
};

View File

@ -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);

View File

@ -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;