io_channel: allow user to provide a thread name

This moves the thread name setting code into the generic SPDK thread
setup code, so now all spdk_threads can be named, not just ones created
by the event framework.

Change-Id: I6c824cf4bcf12fe64a8e2fc7cdc2d6c949021e40
Signed-off-by: Daniel Verkamp <daniel.verkamp@intel.com>
Reviewed-on: https://review.gerrithub.io/375220
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
Daniel Verkamp 2017-08-22 13:06:57 -07:00 committed by Jim Harris
parent 02f088bb95
commit 47182bd7c9
10 changed files with 87 additions and 51 deletions

View File

@ -50,6 +50,13 @@ makes it explicit that the default is being used.
spdk_bs_io_readv_blob() and spdk_bs_io_writev_blob() were added to enable spdk_bs_io_readv_blob() and spdk_bs_io_writev_blob() were added to enable
scattered payloads. scattered payloads.
### Event Framework
The ability to set a thread name, previously only used by the reactor code, is
now part of the `spdk_thread_allocate()` API. Users may specify a thread name
which will show up in tools like `gdb`.
## v17.07: Build system improvements, userspace vhost-blk target, and GPT bdev ## v17.07: Build system improvements, userspace vhost-blk target, and GPT bdev
### Build System ### Build System

View File

@ -196,7 +196,7 @@ spdk_fio_init_thread(struct thread_data *td)
return -1; return -1;
} }
fio_thread->thread = spdk_allocate_thread(spdk_fio_send_msg, fio_thread); fio_thread->thread = spdk_allocate_thread(spdk_fio_send_msg, fio_thread, "fio_thread");
if (!fio_thread->thread) { if (!fio_thread->thread) {
spdk_ring_free(fio_thread->ring); spdk_ring_free(fio_thread->ring);
free(fio_thread); free(fio_thread);

View File

@ -66,8 +66,12 @@ typedef void (*spdk_channel_for_each_cpl)(void *io_device, void *ctx);
* called on the same thread that spdk_allocate_thread * called on the same thread that spdk_allocate_thread
* was called from. * was called from.
* @param thread_ctx Context that will be passed to fn. * @param thread_ctx Context that will be passed to fn.
* @param name Human-readable name for the thread; can be retrieved with spdk_thread_get_name().
* The string is copied, so the pointed-to data only needs to be valid during the
* spdk_allocate_thread() call. May be NULL to specify no name.
*/ */
struct spdk_thread *spdk_allocate_thread(spdk_thread_pass_msg fn, void *thread_ctx); struct spdk_thread *spdk_allocate_thread(spdk_thread_pass_msg fn, void *thread_ctx,
const char *name);
/** /**
* \brief Releases any resources related to the calling thread for I/O channel allocation. * \brief Releases any resources related to the calling thread for I/O channel allocation.
@ -85,6 +89,11 @@ void spdk_free_thread(void);
*/ */
struct spdk_thread *spdk_get_thread(void); struct spdk_thread *spdk_get_thread(void);
/**
* \brief Get a thread's name.
*/
const char *spdk_thread_get_name(const struct spdk_thread *thread);
/** /**
* \brief Send a message to the given thread. The message * \brief Send a message to the given thread. The message
* may be sent asynchronously - i.e. spdk_thread_send_msg * may be sent asynchronously - i.e. spdk_thread_send_msg

View File

@ -36,14 +36,6 @@
#include "spdk_internal/event.h" #include "spdk_internal/event.h"
#include "spdk_internal/log.h" #include "spdk_internal/log.h"
#ifdef __linux__
#include <sys/prctl.h>
#endif
#ifdef __FreeBSD__
#include <pthread_np.h>
#endif
#include "spdk/log.h" #include "spdk/log.h"
#include "spdk/io_channel.h" #include "spdk/io_channel.h"
#include "spdk/env.h" #include "spdk/env.h"
@ -207,27 +199,6 @@ _spdk_event_queue_run_batch(struct spdk_reactor *reactor)
return count; return count;
} }
/**
*
* \brief Set current reactor thread name to "reactor <cpu #>".
*
* This makes the reactor threads distinguishable in top and gdb.
*/
static void set_reactor_thread_name(uint32_t lcore)
{
char thread_name[16];
snprintf(thread_name, sizeof(thread_name), "reactor_%u", lcore);
#if defined(__linux__)
prctl(PR_SET_NAME, thread_name, 0, 0, 0);
#elif defined(__FreeBSD__)
pthread_set_name_np(pthread_self(), thread_name);
#else
#error missing platform support for thread name
#endif
}
static void static void
spdk_poller_insert_timer(struct spdk_reactor *reactor, struct spdk_poller *poller, uint64_t now) spdk_poller_insert_timer(struct spdk_reactor *reactor, struct spdk_poller *poller, uint64_t now)
{ {
@ -335,9 +306,10 @@ _spdk_reactor_run(void *arg)
uint64_t spin_cycles, sleep_cycles; uint64_t spin_cycles, sleep_cycles;
uint32_t sleep_us; uint32_t sleep_us;
uint32_t timer_poll_count; uint32_t timer_poll_count;
char thread_name[32];
spdk_allocate_thread(_spdk_reactor_send_msg, &reactor->lcore); snprintf(thread_name, sizeof(thread_name), "reactor_%u", reactor->lcore);
set_reactor_thread_name(reactor->lcore); spdk_allocate_thread(_spdk_reactor_send_msg, &reactor->lcore, thread_name);
SPDK_NOTICELOG("Reactor started on core %u on socket %u\n", reactor->lcore, SPDK_NOTICELOG("Reactor started on core %u on socket %u\n", reactor->lcore,
reactor->socket_id); reactor->socket_id);

View File

@ -440,7 +440,7 @@ _spdk_send_msg(spdk_thread_fn fn, void *ctx, void *thread_ctx)
void SpdkInitializeThread(void) void SpdkInitializeThread(void)
{ {
if (g_fs != NULL) { if (g_fs != NULL) {
spdk_allocate_thread(_spdk_send_msg, NULL); spdk_allocate_thread(_spdk_send_msg, NULL, "spdk_rocksdb");
g_sync_args.channel = spdk_fs_alloc_io_channel_sync(g_fs); g_sync_args.channel = spdk_fs_alloc_io_channel_sync(g_fs);
} }
} }
@ -481,7 +481,6 @@ spdk_rocksdb_run(void *arg1, void *arg2)
{ {
struct spdk_bdev *bdev; struct spdk_bdev *bdev;
pthread_setname_np(pthread_self(), "spdk");
bdev = spdk_bdev_get_by_name(g_bdev_name.c_str()); bdev = spdk_bdev_get_by_name(g_bdev_name.c_str());
if (bdev == NULL) { if (bdev == NULL) {

View File

@ -36,6 +36,14 @@
#include "spdk/io_channel.h" #include "spdk/io_channel.h"
#include "spdk/log.h" #include "spdk/log.h"
#ifdef __linux__
#include <sys/prctl.h>
#endif
#ifdef __FreeBSD__
#include <pthread_np.h>
#endif
static pthread_mutex_t g_devlist_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t g_devlist_mutex = PTHREAD_MUTEX_INITIALIZER;
struct io_device { struct io_device {
@ -72,6 +80,7 @@ struct spdk_thread {
void *thread_ctx; void *thread_ctx;
TAILQ_HEAD(, spdk_io_channel) io_channels; TAILQ_HEAD(, spdk_io_channel) io_channels;
TAILQ_ENTRY(spdk_thread) tailq; TAILQ_ENTRY(spdk_thread) tailq;
char *name;
}; };
static TAILQ_HEAD(, spdk_thread) g_threads = TAILQ_HEAD_INITIALIZER(g_threads); static TAILQ_HEAD(, spdk_thread) g_threads = TAILQ_HEAD_INITIALIZER(g_threads);
@ -94,8 +103,20 @@ _get_thread(void)
return NULL; return NULL;
} }
static void
_set_thread_name(const char *thread_name)
{
#if defined(__linux__)
prctl(PR_SET_NAME, thread_name, 0, 0, 0);
#elif defined(__FreeBSD__)
pthread_set_name_np(pthread_self(), thread_name);
#else
#error missing platform support for thread name
#endif
}
struct spdk_thread * struct spdk_thread *
spdk_allocate_thread(spdk_thread_pass_msg fn, void *thread_ctx) spdk_allocate_thread(spdk_thread_pass_msg fn, void *thread_ctx, const char *name)
{ {
struct spdk_thread *thread; struct spdk_thread *thread;
@ -120,6 +141,10 @@ spdk_allocate_thread(spdk_thread_pass_msg fn, void *thread_ctx)
thread->thread_ctx = thread_ctx; thread->thread_ctx = thread_ctx;
TAILQ_INIT(&thread->io_channels); TAILQ_INIT(&thread->io_channels);
TAILQ_INSERT_TAIL(&g_threads, thread, tailq); TAILQ_INSERT_TAIL(&g_threads, thread, tailq);
if (name) {
_set_thread_name(name);
thread->name = strdup(name);
}
pthread_mutex_unlock(&g_devlist_mutex); pthread_mutex_unlock(&g_devlist_mutex);
@ -141,6 +166,7 @@ spdk_free_thread(void)
} }
TAILQ_REMOVE(&g_threads, thread, tailq); TAILQ_REMOVE(&g_threads, thread, tailq);
free(thread->name);
free(thread); free(thread);
pthread_mutex_unlock(&g_devlist_mutex); pthread_mutex_unlock(&g_devlist_mutex);
@ -163,6 +189,12 @@ spdk_get_thread(void)
return thread; return thread;
} }
const char *
spdk_thread_get_name(const struct spdk_thread *thread)
{
return thread->name;
}
void void
spdk_thread_send_msg(const struct spdk_thread *thread, spdk_thread_fn fn, void *ctx) spdk_thread_send_msg(const struct spdk_thread *thread, spdk_thread_fn fn, void *ctx)
{ {

View File

@ -73,7 +73,7 @@ fs_init(void)
struct spdk_bs_dev *dev; struct spdk_bs_dev *dev;
dev = init_dev(); dev = init_dev();
spdk_allocate_thread(_fs_send_msg, NULL); spdk_allocate_thread(_fs_send_msg, NULL, "thread0");
spdk_fs_init(dev, NULL, fs_op_with_handle_complete, NULL); spdk_fs_init(dev, NULL, fs_op_with_handle_complete, NULL);
CU_ASSERT(g_fs != NULL); CU_ASSERT(g_fs != NULL);
@ -117,7 +117,7 @@ fs_open(void)
dev = init_dev(); dev = init_dev();
memset(name, 'a', sizeof(name) - 1); memset(name, 'a', sizeof(name) - 1);
spdk_allocate_thread(_fs_send_msg, NULL); spdk_allocate_thread(_fs_send_msg, NULL, "thread0");
spdk_fs_init(dev, NULL, fs_op_with_handle_complete, NULL); spdk_fs_init(dev, NULL, fs_op_with_handle_complete, NULL);
CU_ASSERT(g_fs != NULL); CU_ASSERT(g_fs != NULL);
@ -186,7 +186,7 @@ fs_create(void)
dev = init_dev(); dev = init_dev();
memset(name, 'a', sizeof(name) - 1); memset(name, 'a', sizeof(name) - 1);
spdk_allocate_thread(_fs_send_msg, NULL); spdk_allocate_thread(_fs_send_msg, NULL, "thread0");
spdk_fs_init(dev, NULL, fs_op_with_handle_complete, NULL); spdk_fs_init(dev, NULL, fs_op_with_handle_complete, NULL);
SPDK_CU_ASSERT_FATAL(g_fs != NULL); SPDK_CU_ASSERT_FATAL(g_fs != NULL);
@ -225,7 +225,7 @@ fs_truncate(void)
struct spdk_bs_dev *dev; struct spdk_bs_dev *dev;
dev = init_dev(); dev = init_dev();
spdk_allocate_thread(_fs_send_msg, NULL); spdk_allocate_thread(_fs_send_msg, NULL, "thread0");
spdk_fs_init(dev, NULL, fs_op_with_handle_complete, NULL); spdk_fs_init(dev, NULL, fs_op_with_handle_complete, NULL);
SPDK_CU_ASSERT_FATAL(g_fs != NULL); SPDK_CU_ASSERT_FATAL(g_fs != NULL);
@ -278,7 +278,7 @@ fs_rename(void)
struct spdk_bs_dev *dev; struct spdk_bs_dev *dev;
dev = init_dev(); dev = init_dev();
spdk_allocate_thread(_fs_send_msg, NULL); spdk_allocate_thread(_fs_send_msg, NULL, "thread0");
spdk_fs_init(dev, NULL, fs_op_with_handle_complete, NULL); spdk_fs_init(dev, NULL, fs_op_with_handle_complete, NULL);
SPDK_CU_ASSERT_FATAL(g_fs != NULL); SPDK_CU_ASSERT_FATAL(g_fs != NULL);
@ -431,7 +431,7 @@ channel_ops(void)
struct spdk_io_channel *channel; struct spdk_io_channel *channel;
dev = init_dev(); dev = init_dev();
spdk_allocate_thread(_fs_send_msg, NULL); spdk_allocate_thread(_fs_send_msg, NULL, "thread0");
spdk_fs_init(dev, NULL, fs_op_with_handle_complete, NULL); spdk_fs_init(dev, NULL, fs_op_with_handle_complete, NULL);
SPDK_CU_ASSERT_FATAL(g_fs != NULL); SPDK_CU_ASSERT_FATAL(g_fs != NULL);
@ -459,7 +459,7 @@ channel_ops_sync(void)
struct spdk_io_channel *channel; struct spdk_io_channel *channel;
dev = init_dev(); dev = init_dev();
spdk_allocate_thread(_fs_send_msg, NULL); spdk_allocate_thread(_fs_send_msg, NULL, "thread0");
spdk_fs_init(dev, NULL, fs_op_with_handle_complete, NULL); spdk_fs_init(dev, NULL, fs_op_with_handle_complete, NULL);
SPDK_CU_ASSERT_FATAL(g_fs != NULL); SPDK_CU_ASSERT_FATAL(g_fs != NULL);

View File

@ -158,7 +158,7 @@ cache_write(void)
ut_send_request(_fs_init, NULL); ut_send_request(_fs_init, NULL);
spdk_allocate_thread(_fs_send_msg, NULL); spdk_allocate_thread(_fs_send_msg, NULL, "thread0");
channel = spdk_fs_alloc_io_channel_sync(g_fs); channel = spdk_fs_alloc_io_channel_sync(g_fs);
rc = spdk_fs_open_file(g_fs, channel, "testfile", SPDK_BLOBFS_OPEN_CREATE, &g_file); rc = spdk_fs_open_file(g_fs, channel, "testfile", SPDK_BLOBFS_OPEN_CREATE, &g_file);
@ -196,7 +196,7 @@ cache_write_null_buffer(void)
ut_send_request(_fs_init, NULL); ut_send_request(_fs_init, NULL);
spdk_allocate_thread(_fs_send_msg, NULL); spdk_allocate_thread(_fs_send_msg, NULL, "thread0");
channel = spdk_fs_alloc_io_channel_sync(g_fs); channel = spdk_fs_alloc_io_channel_sync(g_fs);
rc = spdk_fs_open_file(g_fs, channel, "testfile", SPDK_BLOBFS_OPEN_CREATE, &g_file); rc = spdk_fs_open_file(g_fs, channel, "testfile", SPDK_BLOBFS_OPEN_CREATE, &g_file);
@ -227,7 +227,7 @@ fs_create_sync(void)
ut_send_request(_fs_init, NULL); ut_send_request(_fs_init, NULL);
spdk_allocate_thread(_fs_send_msg, NULL); spdk_allocate_thread(_fs_send_msg, NULL, "thread0");
channel = spdk_fs_alloc_io_channel_sync(g_fs); channel = spdk_fs_alloc_io_channel_sync(g_fs);
CU_ASSERT(channel != NULL); CU_ASSERT(channel != NULL);
@ -256,7 +256,7 @@ cache_append_no_cache(void)
ut_send_request(_fs_init, NULL); ut_send_request(_fs_init, NULL);
spdk_allocate_thread(_fs_send_msg, NULL); spdk_allocate_thread(_fs_send_msg, NULL, "thread0");
channel = spdk_fs_alloc_io_channel_sync(g_fs); channel = spdk_fs_alloc_io_channel_sync(g_fs);
rc = spdk_fs_open_file(g_fs, channel, "testfile", SPDK_BLOBFS_OPEN_CREATE, &g_file); rc = spdk_fs_open_file(g_fs, channel, "testfile", SPDK_BLOBFS_OPEN_CREATE, &g_file);
@ -298,7 +298,7 @@ spdk_thread(void *arg)
{ {
struct ut_request *req; struct ut_request *req;
spdk_allocate_thread(_fs_send_msg, NULL); spdk_allocate_thread(_fs_send_msg, NULL, "thread0");
while (1) { while (1) {
pthread_mutex_lock(&g_mutex); pthread_mutex_lock(&g_mutex);

View File

@ -1218,7 +1218,7 @@ int main(int argc, char **argv)
} }
g_dev_buffer = calloc(1, DEV_BUFFER_SIZE); g_dev_buffer = calloc(1, DEV_BUFFER_SIZE);
spdk_allocate_thread(_bs_send_msg, NULL); spdk_allocate_thread(_bs_send_msg, NULL, "thread0");
CU_basic_set_mode(CU_BRM_VERBOSE); CU_basic_set_mode(CU_BRM_VERBOSE);
CU_basic_run_tests(); CU_basic_run_tests();
num_failures = CU_get_number_of_failures(); num_failures = CU_get_number_of_failures();

View File

@ -46,7 +46,24 @@ _send_msg(spdk_thread_fn fn, void *ctx, void *thread_ctx)
static void static void
thread_alloc(void) thread_alloc(void)
{ {
spdk_allocate_thread(_send_msg, NULL); struct spdk_thread *thread;
const char *name;
/* Create thread with no name */
spdk_allocate_thread(_send_msg, NULL, NULL);
thread = spdk_get_thread();
SPDK_CU_ASSERT_FATAL(thread != NULL);
name = spdk_thread_get_name(thread);
CU_ASSERT(name == NULL);
spdk_free_thread();
/* Create thread named "test_thread" */
spdk_allocate_thread(_send_msg, NULL, "test_thread");
thread = spdk_get_thread();
SPDK_CU_ASSERT_FATAL(thread != NULL);
name = spdk_thread_get_name(thread);
SPDK_CU_ASSERT_FATAL(name != NULL);
CU_ASSERT(strcmp(name, "test_thread") == 0);
spdk_free_thread(); spdk_free_thread();
} }
@ -106,7 +123,7 @@ channel(void)
struct spdk_io_channel *ch1, *ch2; struct spdk_io_channel *ch1, *ch2;
void *ctx; void *ctx;
spdk_allocate_thread(_send_msg, NULL); spdk_allocate_thread(_send_msg, NULL, "thread0");
spdk_io_device_register(&device1, create_cb_1, destroy_cb_1, sizeof(ctx1)); spdk_io_device_register(&device1, create_cb_1, destroy_cb_1, sizeof(ctx1));
spdk_io_device_register(&device2, create_cb_2, destroy_cb_2, sizeof(ctx2)); spdk_io_device_register(&device2, create_cb_2, destroy_cb_2, sizeof(ctx2));
spdk_io_device_register(&device3, create_cb_null, NULL, 0); spdk_io_device_register(&device3, create_cb_null, NULL, 0);