Commit 515733ca authored by Shuhei Matsumoto's avatar Shuhei Matsumoto Committed by Tomasz Zawadzki
Browse files

lib/thread: Add unique ID for each created SPDK thread



Add an unique ID for each created SPDK thread. Use a single 64 bits
variable, g_thread_id, and guard its update by the global mutex
g_devlist_mutex. For our safety, further thread creation is not
allowed if g_thread_id rolls over, and request user to restart SPDK
application.

Besides, as a minor update, move the debug log down and add ID to it
in spdk_thread_create(), and ID is added to thread_get_stats RPC and
framework_get_reactors RPC.

The thread ID will be used to set the cpumask of the running thread
to the specified value in the subsequent patches.

Signed-off-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Change-Id: Ic09f11d4c7175c3b89acba6a42e76063acd0d1a0
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/498


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarDarek Stojaczyk <dariusz.stojaczyk@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
parent 04f6e24a
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -520,6 +520,7 @@ Example response:
        "lw_threads": [
          {
            "name": "app_thread",
            "id", 1,
            "cpumask": "1"
          }
        ]
@@ -563,6 +564,7 @@ Example response:
    "threads": [
      {
        "name": "app_thread",
        "id": 1,
	"cpumask": "1",
        "busy": 139223208,
        "idle": 8641080608
+9 −0
Original line number Diff line number Diff line
@@ -363,6 +363,15 @@ struct spdk_thread *spdk_get_thread(void);
 */
const char *spdk_thread_get_name(const struct spdk_thread *thread);

/**
 * Get a thread's ID.
 *
 * \param thread Thread to query.
 *
 * \return the ID of the thread..
 */
uint64_t spdk_thread_get_id(const struct spdk_thread *thread);

struct spdk_thread_stats {
	uint64_t busy_tsc;
	uint64_t idle_tsc;
+22 −2
Original line number Diff line number Diff line
@@ -51,6 +51,11 @@ static pthread_mutex_t g_devlist_mutex = PTHREAD_MUTEX_INITIALIZER;

static spdk_new_thread_fn g_new_thread_fn = NULL;
static size_t g_ctx_sz = 0;
/* Monotonic increasing ID is set to each created thread beginning at 1. Once the
 * ID exceeds UINT64_MAX, further thread creation is not allowed and restarting
 * SPDK application is required.
 */
static uint64_t g_thread_id = 1;

struct io_device {
	void				*io_device;
@@ -118,6 +123,7 @@ struct spdk_thread {
	TAILQ_HEAD(, spdk_io_channel)	io_channels;
	TAILQ_ENTRY(spdk_thread)	tailq;
	char				name[SPDK_MAX_THREAD_NAME_LEN + 1];
	uint64_t			id;

	bool				exit;

@@ -321,13 +327,21 @@ spdk_thread_create(const char *name, struct spdk_cpuset *cpumask)
		snprintf(thread->name, sizeof(thread->name), "%p", thread);
	}

	SPDK_DEBUGLOG(SPDK_LOG_THREAD, "Allocating new thread %s\n", thread->name);

	pthread_mutex_lock(&g_devlist_mutex);
	if (g_thread_id == 0) {
		SPDK_ERRLOG("Thread ID rolled over. Further thread creation is not allowed.\n");
		pthread_mutex_unlock(&g_devlist_mutex);
		_free_thread(thread);
		return NULL;
	}
	thread->id = g_thread_id++;
	TAILQ_INSERT_TAIL(&g_threads, thread, tailq);
	g_thread_count++;
	pthread_mutex_unlock(&g_devlist_mutex);

	SPDK_DEBUGLOG(SPDK_LOG_THREAD, "Allocating new thread (%" PRIu64 ", %s)\n",
		      thread->id, thread->name);

	if (g_new_thread_fn) {
		rc = g_new_thread_fn(thread);
		if (rc != 0) {
@@ -715,6 +729,12 @@ spdk_thread_get_name(const struct spdk_thread *thread)
	return thread->name;
}

uint64_t
spdk_thread_get_id(const struct spdk_thread *thread)
{
	return thread->id;
}

int
spdk_thread_get_stats(struct spdk_thread_stats *stats)
{
+2 −0
Original line number Diff line number Diff line
@@ -180,6 +180,7 @@ rpc_thread_get_stats(void *arg)
	if (0 == spdk_thread_get_stats(&stats)) {
		spdk_json_write_object_begin(ctx->w);
		spdk_json_write_named_string(ctx->w, "name", spdk_thread_get_name(thread));
		spdk_json_write_named_uint64(ctx->w, "id", spdk_thread_get_id(thread));
		spdk_json_write_named_string(ctx->w, "cpumask",
					     spdk_cpuset_fmt(spdk_thread_get_cpumask(thread)));
		spdk_json_write_named_uint64(ctx->w, "busy", stats.busy_tsc);
@@ -251,6 +252,7 @@ rpc_framework_get_reactors(void *arg1, void *arg2)

		spdk_json_write_object_begin(ctx->w);
		spdk_json_write_named_string(ctx->w, "name", spdk_thread_get_name(thread));
		spdk_json_write_named_uint64(ctx->w, "id", spdk_thread_get_id(thread));
		spdk_json_write_named_string(ctx->w, "cpumask",
					     spdk_cpuset_fmt(spdk_thread_get_cpumask(thread)));
		spdk_json_write_object_end(ctx->w);
+4 −4
Original line number Diff line number Diff line
@@ -61,12 +61,12 @@ struct ut_thread *g_ut_threads;

#define INVALID_THREAD 0x1000

static uint64_t g_thread_id = INVALID_THREAD;
static uint64_t g_ut_thread_id = INVALID_THREAD;

static void
set_thread(uintptr_t thread_id)
{
	g_thread_id = thread_id;
	g_ut_thread_id = thread_id;
	if (thread_id == INVALID_THREAD) {
		spdk_set_thread(NULL);
	} else {
@@ -138,7 +138,7 @@ poll_thread_times(uintptr_t thread_id, uint32_t max_polls)
	assert(thread_id != (uintptr_t)INVALID_THREAD);
	assert(thread_id < g_ut_num_threads);

	original_thread_id = g_thread_id;
	original_thread_id = g_ut_thread_id;
	set_thread(INVALID_THREAD);

	while (polls_executed < max_polls) {
@@ -163,7 +163,7 @@ poll_thread(uintptr_t thread_id)
	assert(thread_id != (uintptr_t)INVALID_THREAD);
	assert(thread_id < g_ut_num_threads);

	original_thread_id = g_thread_id;
	original_thread_id = g_ut_thread_id;
	set_thread(INVALID_THREAD);

	while (spdk_thread_poll(thread->thread, 0, 0) > 0) {