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
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
### Build System

View File

@ -196,7 +196,7 @@ spdk_fio_init_thread(struct thread_data *td)
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) {
spdk_ring_free(fio_thread->ring);
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
* was called from.
* @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.
@ -85,6 +89,11 @@ void spdk_free_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
* may be sent asynchronously - i.e. spdk_thread_send_msg

View File

@ -36,14 +36,6 @@
#include "spdk_internal/event.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/io_channel.h"
#include "spdk/env.h"
@ -207,27 +199,6 @@ _spdk_event_queue_run_batch(struct spdk_reactor *reactor)
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
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;
uint32_t sleep_us;
uint32_t timer_poll_count;
char thread_name[32];
spdk_allocate_thread(_spdk_reactor_send_msg, &reactor->lcore);
set_reactor_thread_name(reactor->lcore);
snprintf(thread_name, sizeof(thread_name), "reactor_%u", 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,
reactor->socket_id);

View File

@ -440,7 +440,7 @@ _spdk_send_msg(spdk_thread_fn fn, void *ctx, void *thread_ctx)
void SpdkInitializeThread(void)
{
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);
}
}
@ -481,7 +481,6 @@ spdk_rocksdb_run(void *arg1, void *arg2)
{
struct spdk_bdev *bdev;
pthread_setname_np(pthread_self(), "spdk");
bdev = spdk_bdev_get_by_name(g_bdev_name.c_str());
if (bdev == NULL) {

View File

@ -36,6 +36,14 @@
#include "spdk/io_channel.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;
struct io_device {
@ -72,6 +80,7 @@ struct spdk_thread {
void *thread_ctx;
TAILQ_HEAD(, spdk_io_channel) io_channels;
TAILQ_ENTRY(spdk_thread) tailq;
char *name;
};
static TAILQ_HEAD(, spdk_thread) g_threads = TAILQ_HEAD_INITIALIZER(g_threads);
@ -94,8 +103,20 @@ _get_thread(void)
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 *
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;
@ -120,6 +141,10 @@ spdk_allocate_thread(spdk_thread_pass_msg fn, void *thread_ctx)
thread->thread_ctx = thread_ctx;
TAILQ_INIT(&thread->io_channels);
TAILQ_INSERT_TAIL(&g_threads, thread, tailq);
if (name) {
_set_thread_name(name);
thread->name = strdup(name);
}
pthread_mutex_unlock(&g_devlist_mutex);
@ -141,6 +166,7 @@ spdk_free_thread(void)
}
TAILQ_REMOVE(&g_threads, thread, tailq);
free(thread->name);
free(thread);
pthread_mutex_unlock(&g_devlist_mutex);
@ -163,6 +189,12 @@ spdk_get_thread(void)
return thread;
}
const char *
spdk_thread_get_name(const struct spdk_thread *thread)
{
return thread->name;
}
void
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;
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);
CU_ASSERT(g_fs != NULL);
@ -117,7 +117,7 @@ fs_open(void)
dev = init_dev();
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);
CU_ASSERT(g_fs != NULL);
@ -186,7 +186,7 @@ fs_create(void)
dev = init_dev();
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_CU_ASSERT_FATAL(g_fs != NULL);
@ -225,7 +225,7 @@ fs_truncate(void)
struct spdk_bs_dev *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_CU_ASSERT_FATAL(g_fs != NULL);
@ -278,7 +278,7 @@ fs_rename(void)
struct spdk_bs_dev *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_CU_ASSERT_FATAL(g_fs != NULL);
@ -431,7 +431,7 @@ channel_ops(void)
struct spdk_io_channel *channel;
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_CU_ASSERT_FATAL(g_fs != NULL);
@ -459,7 +459,7 @@ channel_ops_sync(void)
struct spdk_io_channel *channel;
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_CU_ASSERT_FATAL(g_fs != NULL);

View File

@ -158,7 +158,7 @@ cache_write(void)
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);
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);
spdk_allocate_thread(_fs_send_msg, NULL);
spdk_allocate_thread(_fs_send_msg, NULL, "thread0");
channel = spdk_fs_alloc_io_channel_sync(g_fs);
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);
spdk_allocate_thread(_fs_send_msg, NULL);
spdk_allocate_thread(_fs_send_msg, NULL, "thread0");
channel = spdk_fs_alloc_io_channel_sync(g_fs);
CU_ASSERT(channel != NULL);
@ -256,7 +256,7 @@ cache_append_no_cache(void)
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);
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;
spdk_allocate_thread(_fs_send_msg, NULL);
spdk_allocate_thread(_fs_send_msg, NULL, "thread0");
while (1) {
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);
spdk_allocate_thread(_bs_send_msg, NULL);
spdk_allocate_thread(_bs_send_msg, NULL, "thread0");
CU_basic_set_mode(CU_BRM_VERBOSE);
CU_basic_run_tests();
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
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();
}
@ -106,7 +123,7 @@ channel(void)
struct spdk_io_channel *ch1, *ch2;
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(&device2, create_cb_2, destroy_cb_2, sizeof(ctx2));
spdk_io_device_register(&device3, create_cb_null, NULL, 0);