Commit a75a557b authored by Jim Harris's avatar Jim Harris Committed by Tomasz Zawadzki
Browse files

scheduler/dynamic: adjust frequency when core goes to sleep or wakes



When all spdk_threads have been moved to the scheduling core because
they are all idle, we will try to reduce frequency on the scheduling
core if it is still idle. But the frequency changes don't take effect
if it has an SMT sibling which is still set to max frequency.

So when we have moved the last thread off of a core, set its frequency
to min. And conversely, when we move the first thread onto a core,
set its frequency to max.

Signed-off-by: default avatarJim Harris <jim.harris@samsung.com>
Change-Id: I034194d553aa678d387b1b5448631ba4ffcbb3d3
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/23649


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarTomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
parent 8a610145
Loading
Loading
Loading
Loading
+34 −0
Original line number Diff line number Diff line
@@ -66,6 +66,38 @@ _foreach_thread(struct spdk_scheduler_core_info *cores_info, _foreach_fn fn)
	}
}

static void
prepare_to_sleep(uint32_t core)
{
	struct spdk_governor *governor = spdk_governor_get();
	int rc;

	if (governor == NULL) {
		return;
	}

	rc = governor->set_core_freq_min(core);
	if (rc < 0) {
		SPDK_ERRLOG("could not set_core_freq_min(%d)\n", core);
	}
}

static void
prepare_to_wake(uint32_t core)
{
	struct spdk_governor *governor = spdk_governor_get();
	int rc;

	if (governor == NULL) {
		return;
	}

	rc = governor->set_core_freq_max(core);
	if (rc < 0) {
		SPDK_ERRLOG("could not set_core_freq_max(%d)\n", core);
	}
}

static void
_move_thread(struct spdk_scheduler_thread_info *thread_info, uint32_t dst_core)
{
@@ -316,12 +348,14 @@ balance(struct spdk_scheduler_core_info *cores_info, uint32_t cores_count)
		/* We can switch mode only if reactor already does not have any threads */
		if (g_cores[i].thread_count == 0 && TAILQ_EMPTY(&reactor->threads)) {
			core->interrupt_mode = true;
			prepare_to_sleep(i);
		} else if (g_cores[i].thread_count != 0) {
			core->interrupt_mode = false;
			if (i != g_main_lcore) {
				/* If a thread is present on non g_main_lcore,
				 * it has to be busy. */
				busy_threads_present = true;
				prepare_to_wake(i);
			}
		}
	}