Commit 62491a67 authored by Maciej Szwed's avatar Maciej Szwed Committed by Jim Harris
Browse files

scheduler_dynamic: refactor out moving thread between cores



Refactor all thread moves and core stats updates to single function.

At this time in series only tsc of main core was modified and
only idle tsc of main core was used. Main core would be either
the destination core or the source core. In both cases, the idle
time for main core had to be updated.

This patch generalizes this logic to always move the execution
time from source core to destination core.
As a byproduct cores besides main core have the stats updated,
which will be useful later in the series. Once core load will
be the deciding factor for choosing a core.

Signed-off-by: default avatarMaciej Szwed <maciej.szwed@intel.com>
Signed-off-by: default avatarTomasz Zawadzki <tomasz.zawadzki@intel.com>
Change-Id: I57564e8b2632f919869d74e8f10b01fb3dda3be9
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/6658


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarPaul Luse <paul.e.luse@intel.com>
Reviewed-by: default avatarKrzysztof Karas <krzysztof.karas@intel.com>
parent b0d3f29a
Loading
Loading
Loading
Loading
+27 −26
Original line number Diff line number Diff line
@@ -86,6 +86,30 @@ _get_thread_load(struct spdk_lw_thread *lw_thread)
	return busy  * 100 / (busy + idle);
}

static void
_move_thread(struct spdk_lw_thread *lw_thread, uint32_t dst_core)
{
	struct core_stats *dst = &g_cores[dst_core];
	struct core_stats *src = &g_cores[lw_thread->lcore];
	uint64_t busy_tsc = lw_thread->current_stats.busy_tsc;

	if (src == dst) {
		/* Don't modify stats if thread is already on that core. */
		return;
	}

	dst->busy += spdk_min(UINT64_MAX - dst->busy, busy_tsc);
	dst->idle -= spdk_min(dst->idle, busy_tsc);
	dst->thread_count++;

	src->busy -= spdk_min(src->busy, busy_tsc);
	src->idle += spdk_min(UINT64_MAX - src->busy, busy_tsc);
	assert(src->thread_count > 0);
	src->thread_count--;

	lw_thread->lcore = dst_core;
}

static int
init(struct spdk_governor *governor)
{
@@ -182,28 +206,13 @@ balance(struct spdk_scheduler_core_info *cores_info, int cores_count,
					}

					if (spdk_cpuset_get_cpu(cpumask, target_lcore)) {
						lw_thread->lcore = target_lcore;
						g_cores[target_lcore].thread_count++;
						assert(g_cores[i].thread_count > 0);
						g_cores[i].thread_count--;

						if (target_lcore != g_main_lcore) {
							main_core->idle += spdk_min(UINT64_MAX - main_core->idle, thread_busy);
							main_core->busy -= spdk_min(main_core->busy, thread_busy);
						}

						_move_thread(lw_thread, target_lcore);
						break;
					}
				}
			} else if (i != g_main_lcore && load < SCHEDULER_LOAD_LIMIT) {
				/* This thread is idle but not on the main core, so we need to move it to the main core */
				lw_thread->lcore = g_main_lcore;
				assert(g_cores[i].thread_count > 0);
				g_cores[i].thread_count--;

				main_core->thread_count++;
				main_core->busy += spdk_min(UINT64_MAX - main_core->busy, thread_busy);
				main_core->idle -= spdk_min(main_core->idle, thread_busy);
				_move_thread(lw_thread, g_main_lcore);
			} else {
				/* Move busy thread only if cpumask does not match current core (except main core) */
				if (i != g_main_lcore) {
@@ -212,15 +221,7 @@ balance(struct spdk_scheduler_core_info *cores_info, int cores_count,
							target_lcore = _get_next_target_core();

							if (spdk_cpuset_get_cpu(cpumask, target_lcore)) {
								lw_thread->lcore = target_lcore;
								g_cores[target_lcore].thread_count++;
								assert(g_cores[i].thread_count > 0);
								g_cores[i].thread_count--;

								if (target_lcore == g_main_lcore) {
									main_core->busy += spdk_min(UINT64_MAX - main_core->busy, thread_busy);
									main_core->idle -= spdk_min(main_core->idle, thread_busy);
								}
								_move_thread(lw_thread, target_lcore);
								break;
							}
						}