Commit 7dfc5e92 authored by Daniel Verkamp's avatar Daniel Verkamp
Browse files

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: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
parent 5d8c9453
Loading
Loading
Loading
Loading
+9 −3
Original line number Diff line number Diff line
@@ -49,12 +49,17 @@ 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_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
nvmf_direct_ctrlr_poll_for_admin_completions(struct nvmf_session *session)
{
	spdk_nvme_ctrlr_process_admin_completions(session->subsys->ctrlr.dev.direct.ctrlr);
}

static void
nvmf_direct_ctrlr_complete_cmd(void *ctx, const struct spdk_nvme_cpl *cmp)
{
@@ -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,
};
+21 −1
Original line number Diff line number Diff line
@@ -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);

+8 −2
Original line number Diff line number Diff line
@@ -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;