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

scheduler/gscheduler: decide freq on highest util of SMT siblings



The CPU frequency governor can only take effect if all SMT siblings
agree on the same frequency. Assume there are two SMT siblings,
one is 80% busy, the other is 20% busy, we want to make the decision
on frequency for both cores based on the 80% busy. This ensures the
work on that 80% core is not impacted by the other core trying to set
20%.

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


Reviewed-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarTomasz Zawadzki <tomasz.zawadzki@intel.com>
parent cdeecfb8
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -123,7 +123,7 @@ DEPDIRS-sock_uring := log sock util thread trace
DEPDIRS-scheduler_dynamic := event log thread util json
ifeq (y,$(DPDK_POWER))
DEPDIRS-scheduler_dpdk_governor := event json log util
DEPDIRS-scheduler_gscheduler := event log
DEPDIRS-scheduler_gscheduler := event log util
endif

# module/bdev
+22 −0
Original line number Diff line number Diff line
@@ -38,6 +38,21 @@ calculate_busy_pct(struct spdk_scheduler_core_info *core)
	return core->current_busy_tsc * 100 / total_tsc;
}

struct check_sibling_ctx {
	struct spdk_scheduler_core_info *cores;
	uint32_t busy_pct;
};

static void
check_sibling(void *_ctx, uint32_t i)
{
	struct check_sibling_ctx *ctx = _ctx;
	struct spdk_scheduler_core_info *core = &ctx->cores[i];
	uint32_t busy_pct = calculate_busy_pct(core);

	ctx->busy_pct = spdk_max(ctx->busy_pct, busy_pct);
}

static void
balance(struct spdk_scheduler_core_info *cores, uint32_t core_count)
{
@@ -53,6 +68,7 @@ balance(struct spdk_scheduler_core_info *cores, uint32_t core_count)

	/* Gather active/idle statistics */
	SPDK_ENV_FOREACH_CORE(i) {
		struct spdk_cpuset smt_siblings = {};
		core = &cores[i];

		rc = governor->get_core_capabilities(core->lcore, &capabilities);
@@ -62,6 +78,12 @@ balance(struct spdk_scheduler_core_info *cores, uint32_t core_count)
		}

		busy_pct = calculate_busy_pct(core);
		if (spdk_env_core_get_smt_cpuset(&smt_siblings, i)) {
			struct check_sibling_ctx ctx = {.cores = cores, .busy_pct = busy_pct};

			spdk_cpuset_for_each_cpu(&smt_siblings, check_sibling, &ctx);
			busy_pct = ctx.busy_pct;
		}

		if (busy_pct < g_min_threshold) {
			rc = governor->set_core_freq_min(core->lcore);