diff --git a/CHANGELOG.md b/CHANGELOG.md index ec7581b3e..43c166dde 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,12 @@ A new flag `ACCEL_FLAG_PERSISTENT` was added to indicate the target memory is PM Added `bdev_nvme_add_error_injection` and `bdev_nvme_remove_error_injection` RPCs to add and remove NVMe error injections. +### event + +Added `msg_mempool_size` parameter to `spdk_reactors_init` and `spdk_thread_lib_init_ext`. +The size of `g_spdk_msg_mempool` can now be controlled through the same-named +user option of `spdk_app_opts` structure. + ### nvmf Removed deprecated max_qpairs_per_ctrlr parameter from nvmf_create_transport RPC. Use diff --git a/examples/nvmf/nvmf/nvmf.c b/examples/nvmf/nvmf/nvmf.c index ebd88cb32..d39259272 100644 --- a/examples/nvmf/nvmf/nvmf.c +++ b/examples/nvmf/nvmf/nvmf.c @@ -334,7 +334,7 @@ nvmf_init_threads(void) * framework. The size of the extra memory allocated is the second parameter. */ spdk_thread_lib_init_ext(nvmf_reactor_thread_op, nvmf_reactor_thread_op_supported, - sizeof(struct nvmf_lw_thread)); + sizeof(struct nvmf_lw_thread), SPDK_DEFAULT_MSG_MEMPOOL_SIZE); /* Spawn one system thread per CPU core. The system thread is called a reactor. * SPDK will spawn lightweight threads that must be mapped to reactors in diff --git a/include/spdk/event.h b/include/spdk/event.h index c98ce6a2f..444dea778 100644 --- a/include/spdk/event.h +++ b/include/spdk/event.h @@ -147,6 +147,13 @@ struct spdk_app_opts { * Default is `false`. */ bool disable_signal_handlers; + + /** + * The allocated size for the message pool used by the threading library. + * + * Default is `SPDK_DEFAULT_MSG_MEMPOOL_SIZE`. + */ + size_t msg_mempool_size; }; /** diff --git a/include/spdk/thread.h b/include/spdk/thread.h index e82b35484..c260fcc7a 100644 --- a/include/spdk/thread.h +++ b/include/spdk/thread.h @@ -213,6 +213,9 @@ typedef void (*spdk_channel_for_each_cpl)(struct spdk_io_channel_iter *i, int st #define SPDK_IO_CHANNEL_STRUCT_SIZE 96 +/* Power of 2 minus 1 is optimal for memory consumption */ +#define SPDK_DEFAULT_MSG_MEMPOOL_SIZE (262144 - 1) + /** * Initialize the threading library. Must be called once prior to allocating any threads. * @@ -236,12 +239,13 @@ int spdk_thread_lib_init(spdk_new_thread_fn new_thread_fn, size_t ctx_sz); * \param thread_op_supported_fn Called to check whether the SPDK thread operation is supported. * \param ctx_sz For each thread allocated, for use by the thread scheduler. A pointer * to this region may be obtained by calling spdk_thread_get_ctx(). + * \param msg_mempool_size Size of the allocated spdk_msg_mempool. * * \return 0 on success. Negated errno on failure. */ int spdk_thread_lib_init_ext(spdk_thread_op_fn thread_op_fn, spdk_thread_op_supported_fn thread_op_supported_fn, - size_t ctx_sz); + size_t ctx_sz, size_t msg_mempool_size); /** * Release all resources associated with this library. diff --git a/include/spdk_internal/event.h b/include/spdk_internal/event.h index 1df224421..77c781e70 100644 --- a/include/spdk_internal/event.h +++ b/include/spdk_internal/event.h @@ -116,7 +116,7 @@ struct spdk_reactor { int resched_fd; } __attribute__((aligned(SPDK_CACHE_LINE_SIZE))); -int spdk_reactors_init(void); +int spdk_reactors_init(size_t msg_mempool_size); void spdk_reactors_fini(void); void spdk_reactors_start(void); diff --git a/lib/event/app.c b/lib/event/app.c index b626b1c69..c70d2d7cf 100644 --- a/lib/event/app.c +++ b/lib/event/app.c @@ -225,6 +225,7 @@ spdk_app_opts_init(struct spdk_app_opts *opts, size_t opts_size) SET_FIELD(num_entries, SPDK_APP_DEFAULT_NUM_TRACE_ENTRIES); SET_FIELD(delay_subsystem_init, false); SET_FIELD(disable_signal_handlers, false); + SET_FIELD(msg_mempool_size, SPDK_DEFAULT_MSG_MEMPOOL_SIZE); #undef SET_FIELD } @@ -520,10 +521,11 @@ app_copy_opts(struct spdk_app_opts *opts, struct spdk_app_opts *opts_user, size_ SET_FIELD(log); SET_FIELD(base_virtaddr); SET_FIELD(disable_signal_handlers); + SET_FIELD(msg_mempool_size); /* You should not remove this statement, but need to update the assert statement * if you add a new field, and also add a corresponding SET_FIELD statement */ - SPDK_STATIC_ASSERT(sizeof(struct spdk_app_opts) == 192, "Incorrect size"); + SPDK_STATIC_ASSERT(sizeof(struct spdk_app_opts) == 200, "Incorrect size"); #undef SET_FIELD } @@ -600,7 +602,7 @@ spdk_app_start(struct spdk_app_opts *opts_user, spdk_msg_fn start_fn, spdk_log_open(opts->log); SPDK_NOTICELOG("Total cores available: %d\n", spdk_env_get_core_count()); - if ((rc = spdk_reactors_init()) != 0) { + if ((rc = spdk_reactors_init(opts->msg_mempool_size)) != 0) { SPDK_ERRLOG("Reactor Initialization failed: rc = %d\n", rc); return 1; } diff --git a/lib/event/reactor.c b/lib/event/reactor.c index 0e1b1e9a9..b3c8dea03 100644 --- a/lib/event/reactor.c +++ b/lib/event/reactor.c @@ -233,7 +233,7 @@ static int reactor_thread_op(struct spdk_thread *thread, enum spdk_thread_op op) static bool reactor_thread_op_supported(enum spdk_thread_op op); int -spdk_reactors_init(void) +spdk_reactors_init(size_t msg_mempool_size) { struct spdk_reactor *reactor; int rc; @@ -274,7 +274,7 @@ spdk_reactors_init(void) memset(g_reactors, 0, (g_reactor_count) * sizeof(struct spdk_reactor)); spdk_thread_lib_init_ext(reactor_thread_op, reactor_thread_op_supported, - sizeof(struct spdk_lw_thread)); + sizeof(struct spdk_lw_thread), msg_mempool_size); SPDK_ENV_FOREACH_CORE(i) { reactor_construct(&g_reactors[i], i); diff --git a/lib/thread/thread.c b/lib/thread/thread.c index 841c8be52..f339591d8 100644 --- a/lib/thread/thread.c +++ b/lib/thread/thread.c @@ -266,19 +266,21 @@ _get_thread(void) } static int -_thread_lib_init(size_t ctx_sz) +_thread_lib_init(size_t ctx_sz, size_t msg_mempool_sz) { char mempool_name[SPDK_MAX_MEMZONE_NAME_LEN]; g_ctx_sz = ctx_sz; snprintf(mempool_name, sizeof(mempool_name), "msgpool_%d", getpid()); - g_spdk_msg_mempool = spdk_mempool_create(mempool_name, - 262144 - 1, /* Power of 2 minus 1 is optimal for memory consumption */ + g_spdk_msg_mempool = spdk_mempool_create(mempool_name, msg_mempool_sz, sizeof(struct spdk_msg), 0, /* No cache. We do our own. */ SPDK_ENV_SOCKET_ID_ANY); + SPDK_DEBUGLOG(thread, "spdk_msg_mempool was created with size: %zu\n", + msg_mempool_sz); + if (!g_spdk_msg_mempool) { SPDK_ERRLOG("spdk_msg_mempool creation failed\n"); return -1; @@ -299,13 +301,13 @@ spdk_thread_lib_init(spdk_new_thread_fn new_thread_fn, size_t ctx_sz) g_new_thread_fn = new_thread_fn; } - return _thread_lib_init(ctx_sz); + return _thread_lib_init(ctx_sz, SPDK_DEFAULT_MSG_MEMPOOL_SIZE); } int spdk_thread_lib_init_ext(spdk_thread_op_fn thread_op_fn, spdk_thread_op_supported_fn thread_op_supported_fn, - size_t ctx_sz) + size_t ctx_sz, size_t msg_mempool_sz) { assert(g_new_thread_fn == NULL); assert(g_thread_op_fn == NULL); @@ -323,7 +325,7 @@ spdk_thread_lib_init_ext(spdk_thread_op_fn thread_op_fn, g_thread_op_supported_fn = thread_op_supported_fn; } - return _thread_lib_init(ctx_sz); + return _thread_lib_init(ctx_sz, msg_mempool_sz); } void diff --git a/test/unit/lib/event/app.c/app_ut.c b/test/unit/lib/event/app.c/app_ut.c index d6485fdfa..df5ffcde1 100644 --- a/test/unit/lib/event/app.c/app_ut.c +++ b/test/unit/lib/event/app.c/app_ut.c @@ -56,7 +56,7 @@ DEFINE_STUB_V(spdk_subsystem_init_from_json_config, (const char *json_config_fil spdk_subsystem_init_fn cb_fn, void *cb_arg, bool stop_on_error)); DEFINE_STUB_V(spdk_reactors_start, (void)); DEFINE_STUB_V(spdk_reactors_stop, (void *arg1)); -DEFINE_STUB(spdk_reactors_init, int, (void), 0); +DEFINE_STUB(spdk_reactors_init, int, (size_t msg_mempool_size), 0); DEFINE_STUB_V(spdk_reactors_fini, (void)); DEFINE_STUB_V(_spdk_scheduler_set_period, (uint64_t period)); bool g_scheduling_in_progress; diff --git a/test/unit/lib/event/reactor.c/reactor_ut.c b/test/unit/lib/event/reactor.c/reactor_ut.c index 4089212aa..8ead75e0f 100644 --- a/test/unit/lib/event/reactor.c/reactor_ut.c +++ b/test/unit/lib/event/reactor.c/reactor_ut.c @@ -83,7 +83,7 @@ test_init_reactors(void) allocate_cores(3); - CU_ASSERT(spdk_reactors_init() == 0); + CU_ASSERT(spdk_reactors_init(SPDK_DEFAULT_MSG_MEMPOOL_SIZE) == 0); CU_ASSERT(g_reactor_state == SPDK_REACTOR_STATE_INITIALIZED); for (core = 0; core < 3; core++) { @@ -118,7 +118,7 @@ test_event_call(void) allocate_cores(1); - CU_ASSERT(spdk_reactors_init() == 0); + CU_ASSERT(spdk_reactors_init(SPDK_DEFAULT_MSG_MEMPOOL_SIZE) == 0); evt = spdk_event_allocate(0, ut_event_fn, &test1, &test2); CU_ASSERT(evt != NULL); @@ -155,7 +155,7 @@ test_schedule_thread(void) allocate_cores(5); - CU_ASSERT(spdk_reactors_init() == 0); + CU_ASSERT(spdk_reactors_init(SPDK_DEFAULT_MSG_MEMPOOL_SIZE) == 0); spdk_cpuset_set_cpu(&cpuset, 3, true); g_next_core = 4; @@ -207,7 +207,7 @@ test_reschedule_thread(void) allocate_cores(3); - CU_ASSERT(spdk_reactors_init() == 0); + CU_ASSERT(spdk_reactors_init(SPDK_DEFAULT_MSG_MEMPOOL_SIZE) == 0); spdk_cpuset_set_cpu(&g_reactor_core_mask, 0, true); spdk_cpuset_set_cpu(&g_reactor_core_mask, 1, true); @@ -309,7 +309,7 @@ test_for_each_reactor(void) allocate_cores(5); - CU_ASSERT(spdk_reactors_init() == 0); + CU_ASSERT(spdk_reactors_init(SPDK_DEFAULT_MSG_MEMPOOL_SIZE) == 0); spdk_for_each_reactor(for_each_reactor_cb, &count, &done, for_each_reactor_done); @@ -404,7 +404,7 @@ test_reactor_stats(void) allocate_cores(1); - CU_ASSERT(spdk_reactors_init() == 0); + CU_ASSERT(spdk_reactors_init(SPDK_DEFAULT_MSG_MEMPOOL_SIZE) == 0); spdk_cpuset_set_cpu(&cpuset, 0, true); @@ -577,7 +577,7 @@ test_scheduler(void) allocate_cores(3); - CU_ASSERT(spdk_reactors_init() == 0); + CU_ASSERT(spdk_reactors_init(SPDK_DEFAULT_MSG_MEMPOOL_SIZE) == 0); spdk_scheduler_set("dynamic"); @@ -816,7 +816,7 @@ test_governor(void) allocate_cores(2); - CU_ASSERT(spdk_reactors_init() == 0); + CU_ASSERT(spdk_reactors_init(SPDK_DEFAULT_MSG_MEMPOOL_SIZE) == 0); spdk_scheduler_set("dynamic"); spdk_governor_set("dpdk_governor"); diff --git a/test/unit/lib/thread/thread.c/thread_ut.c b/test/unit/lib/thread/thread.c/thread_ut.c index 59728c9fa..7bb69e4ae 100644 --- a/test/unit/lib/thread/thread.c/thread_ut.c +++ b/test/unit/lib/thread/thread.c/thread_ut.c @@ -109,7 +109,8 @@ thread_alloc(void) spdk_thread_lib_fini(); /* Scheduling callback exists with extended thread library initialization. */ - spdk_thread_lib_init_ext(_thread_op, _thread_op_supported, 0); + spdk_thread_lib_init_ext(_thread_op, _thread_op_supported, 0, + SPDK_DEFAULT_MSG_MEMPOOL_SIZE); /* Scheduling succeeds */ g_sched_rc = 0;