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: Seth Howell <seth.howell@intel.com>
Reviewed-on: https://review.gerrithub.io/c/439415
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
Seth Howell 2019-01-07 11:07:59 -07:00 committed by Ben Walker
parent ea17d2ebb9
commit e816c8fda8
3 changed files with 48 additions and 21 deletions

View File

@ -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;
};
/**

View File

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

View File

@ -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 = {