Commit e816c8fd authored by Seth Howell's avatar Seth Howell Committed by Ben Walker
Browse files

nvmf: add a buffer_cache to transport opts



This patch series is geared at solving github issue 555.
Ultimately the goal of this series is to add a per-poll-group buffer
cache to prevent starvation.

Change-Id: I8ddaa47487665c2f9adce2109eb71b8fa71a7927
Signed-off-by: default avatarSeth Howell <seth.howell@intel.com>
Reviewed-on: https://review.gerrithub.io/c/439415


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
parent ea17d2eb
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -71,6 +71,7 @@ struct spdk_nvmf_transport_opts {
	uint32_t io_unit_size;
	uint32_t max_aq_depth;
	uint32_t num_shared_buffers;
	uint32_t buf_cache_size;
};

/**
+13 −0
Original line number Diff line number Diff line
@@ -1578,6 +1578,7 @@ spdk_nvmf_rdma_request_process(struct spdk_nvmf_rdma_transport *rtransport,
#define SPDK_NVMF_RDMA_DEFAULT_MAX_IO_SIZE 131072
#define SPDK_NVMF_RDMA_MIN_IO_BUFFER_SIZE 4096
#define SPDK_NVMF_RDMA_DEFAULT_NUM_SHARED_BUFFERS 512
#define SPDK_NVMF_RDMA_DEFAULT_BUFFER_CACHE_SIZE 32
#define SPDK_NVMF_RDMA_DEFAULT_IO_BUFFER_SIZE (SPDK_NVMF_RDMA_DEFAULT_MAX_IO_SIZE / SPDK_NVMF_MAX_SGL_ENTRIES)

static void
@@ -1591,6 +1592,7 @@ spdk_nvmf_rdma_opts_init(struct spdk_nvmf_transport_opts *opts)
					SPDK_NVMF_RDMA_MIN_IO_BUFFER_SIZE);
	opts->max_aq_depth =		SPDK_NVMF_RDMA_DEFAULT_AQ_DEPTH;
	opts->num_shared_buffers =	SPDK_NVMF_RDMA_DEFAULT_NUM_SHARED_BUFFERS;
	opts->buf_cache_size =		SPDK_NVMF_RDMA_DEFAULT_BUFFER_CACHE_SIZE;
}

static int spdk_nvmf_rdma_destroy(struct spdk_nvmf_transport *transport);
@@ -1605,6 +1607,7 @@ spdk_nvmf_rdma_create(struct spdk_nvmf_transport_opts *opts)
	uint32_t			i;
	int				flag;
	uint32_t			sge_count;
	uint32_t			min_shared_buffers;

	const struct spdk_mem_map_ops nvmf_rdma_map_ops = {
		.notify_cb = spdk_nvmf_rdma_mem_notify,
@@ -1658,6 +1661,16 @@ spdk_nvmf_rdma_create(struct spdk_nvmf_transport_opts *opts)
		return NULL;
	}

	min_shared_buffers = spdk_thread_get_count() * opts->buf_cache_size;
	if (min_shared_buffers > opts->num_shared_buffers) {
		SPDK_ERRLOG("There are not enough buffers to satisfy"
			    "per-poll group caches for each thread. (%" PRIu32 ")"
			    "supplied. (%" PRIu32 ") required\n", opts->num_shared_buffers, min_shared_buffers);
		SPDK_ERRLOG("Please specify a larger number of shared buffers\n");
		spdk_nvmf_rdma_destroy(&rtransport->transport);
		return NULL;
	}

	sge_count = opts->max_io_size / opts->io_unit_size;
	if (sge_count > NVMF_DEFAULT_TX_SGE) {
		SPDK_ERRLOG("Unsupported IO Unit size specified, %d bytes\n", opts->io_unit_size);
+34 −21
Original line number Diff line number Diff line
@@ -527,11 +527,33 @@ spdk_nvmf_tcp_qpair_destroy(struct nvme_tcp_qpair *tqpair)
	SPDK_DEBUGLOG(SPDK_LOG_NVMF_TCP, "Leave\n");
}

static int
spdk_nvmf_tcp_destroy(struct spdk_nvmf_transport *transport)
{
	struct spdk_nvmf_tcp_transport	*ttransport;

	assert(transport != NULL);
	ttransport = SPDK_CONTAINEROF(transport, struct spdk_nvmf_tcp_transport, transport);

	if (spdk_mempool_count(ttransport->data_buf_pool) != (transport->opts.num_shared_buffers)) {
		SPDK_ERRLOG("transport buffer pool count is %zu but should be %u\n",
			    spdk_mempool_count(ttransport->data_buf_pool),
			    transport->opts.num_shared_buffers);
	}

	spdk_mempool_free(ttransport->data_buf_pool);
	spdk_io_device_unregister(ttransport, NULL);
	pthread_mutex_destroy(&ttransport->lock);
	free(ttransport);
	return 0;
}

static struct spdk_nvmf_transport *
spdk_nvmf_tcp_create(struct spdk_nvmf_transport_opts *opts)
{
	struct spdk_nvmf_tcp_transport *ttransport;
	uint32_t sge_count;
	uint32_t min_shared_buffers;

	ttransport = calloc(1, sizeof(*ttransport));
	if (!ttransport) {
@@ -581,6 +603,16 @@ spdk_nvmf_tcp_create(struct spdk_nvmf_transport_opts *opts)
		return NULL;
	}

	min_shared_buffers = spdk_thread_get_count() * opts->buf_cache_size;
	if (min_shared_buffers > opts->num_shared_buffers) {
		SPDK_ERRLOG("There are not enough buffers to satisfy"
			    "per-poll group caches for each thread. (%" PRIu32 ")"
			    "supplied. (%" PRIu32 ") required\n", opts->num_shared_buffers, min_shared_buffers);
		SPDK_ERRLOG("Please specify a larger number of shared buffers\n");
		spdk_nvmf_tcp_destroy(&ttransport->transport);
		return NULL;
	}

	pthread_mutex_init(&ttransport->lock, NULL);

	spdk_io_device_register(ttransport, spdk_nvmf_tcp_mgmt_channel_create,
@@ -590,27 +622,6 @@ spdk_nvmf_tcp_create(struct spdk_nvmf_transport_opts *opts)
	return &ttransport->transport;
}

static int
spdk_nvmf_tcp_destroy(struct spdk_nvmf_transport *transport)
{
	struct spdk_nvmf_tcp_transport	*ttransport;

	assert(transport != NULL);
	ttransport = SPDK_CONTAINEROF(transport, struct spdk_nvmf_tcp_transport, transport);

	if (spdk_mempool_count(ttransport->data_buf_pool) != (transport->opts.num_shared_buffers)) {
		SPDK_ERRLOG("transport buffer pool count is %zu but should be %u\n",
			    spdk_mempool_count(ttransport->data_buf_pool),
			    transport->opts.num_shared_buffers);
	}

	spdk_mempool_free(ttransport->data_buf_pool);
	spdk_io_device_unregister(ttransport, NULL);
	pthread_mutex_destroy(&ttransport->lock);
	free(ttransport);
	return 0;
}

static int
_spdk_nvmf_tcp_trsvcid_to_int(const char *trsvcid)
{
@@ -2855,6 +2866,7 @@ spdk_nvmf_tcp_qpair_set_sq_size(struct spdk_nvmf_qpair *qpair)
#define SPDK_NVMF_TCP_DEFAULT_MAX_IO_SIZE 131072
#define SPDK_NVMF_TCP_DEFAULT_IO_UNIT_SIZE 131072
#define SPDK_NVMF_TCP_DEFAULT_NUM_SHARED_BUFFERS 512
#define SPDK_NVMF_TCP_DEFAULT_BUFFER_CACHE_SIZE 32

static void
spdk_nvmf_tcp_opts_init(struct spdk_nvmf_transport_opts *opts)
@@ -2866,6 +2878,7 @@ spdk_nvmf_tcp_opts_init(struct spdk_nvmf_transport_opts *opts)
	opts->io_unit_size =		SPDK_NVMF_TCP_DEFAULT_IO_UNIT_SIZE;
	opts->max_aq_depth =		SPDK_NVMF_TCP_DEFAULT_AQ_DEPTH;
	opts->num_shared_buffers =	SPDK_NVMF_TCP_DEFAULT_NUM_SHARED_BUFFERS;
	opts->buf_cache_size =		SPDK_NVMF_TCP_DEFAULT_BUFFER_CACHE_SIZE;
}

const struct spdk_nvmf_transport_ops spdk_nvmf_transport_tcp = {