xref: /spdk/module/scheduler/gscheduler/gscheduler.c (revision 8a6101458532c70e17ff48c2d48391f284a0fdd5)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (C) 2021 Intel Corporation.
3  *   All rights reserved.
4  */
5 
6 #include "spdk/stdinc.h"
7 #include "spdk/likely.h"
8 
9 #include "spdk_internal/event.h"
10 #include "spdk/thread.h"
11 
12 #include "spdk/log.h"
13 #include "spdk/env.h"
14 #include "spdk/scheduler.h"
15 
16 static uint32_t g_max_threshold = 99;
17 static uint32_t g_adjust_threshold = 50;
18 static uint32_t g_min_threshold = 1;
19 
20 static int
21 init(void)
22 {
23 	return spdk_governor_set("dpdk_governor");
24 }
25 
26 static void
27 deinit(void)
28 {
29 	spdk_governor_set(NULL);
30 }
31 
32 static void
33 balance(struct spdk_scheduler_core_info *cores, uint32_t core_count)
34 {
35 	struct spdk_governor *governor;
36 	struct spdk_scheduler_core_info *core;
37 	struct spdk_governor_capabilities capabilities;
38 	uint64_t total_tsc;
39 	uint32_t busy_pct;
40 	uint32_t i;
41 	int rc;
42 
43 	governor = spdk_governor_get();
44 	assert(governor != NULL);
45 
46 	/* Gather active/idle statistics */
47 	SPDK_ENV_FOREACH_CORE(i) {
48 		core = &cores[i];
49 
50 		rc = governor->get_core_capabilities(core->lcore, &capabilities);
51 		if (rc < 0) {
52 			SPDK_ERRLOG("failed to get capabilities for core: %u\n", core->lcore);
53 			return;
54 		}
55 
56 		total_tsc = core->current_busy_tsc + core->current_idle_tsc;
57 		busy_pct = core->current_busy_tsc * 100 / total_tsc;
58 
59 		if (busy_pct < g_min_threshold) {
60 			rc = governor->set_core_freq_min(core->lcore);
61 			if (rc < 0) {
62 				SPDK_ERRLOG("setting to minimal frequency for core %u failed\n", core->lcore);
63 			}
64 		} else if (busy_pct < g_adjust_threshold) {
65 			rc = governor->core_freq_down(core->lcore);
66 			if (rc < 0) {
67 				SPDK_ERRLOG("lowering frequency for core %u failed\n", core->lcore);
68 			}
69 		} else if (busy_pct >= g_max_threshold) {
70 			rc = governor->set_core_freq_max(core->lcore);
71 			if (rc < 0) {
72 				SPDK_ERRLOG("setting to maximal frequency for core %u failed\n", core->lcore);
73 			}
74 		} else {
75 			rc = governor->core_freq_up(core->lcore);
76 			if (rc < 0) {
77 				SPDK_ERRLOG("increasing frequency for core %u failed\n", core->lcore);
78 			}
79 		}
80 	}
81 }
82 
83 static struct spdk_scheduler gscheduler = {
84 	.name = "gscheduler",
85 	.init = init,
86 	.deinit = deinit,
87 	.balance = balance,
88 };
89 
90 SPDK_SCHEDULER_REGISTER(gscheduler);
91