1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (c) 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 int 17 init(void) 18 { 19 return spdk_governor_set("dpdk_governor"); 20 } 21 22 static void 23 deinit(void) 24 { 25 spdk_governor_set(NULL); 26 } 27 28 static void 29 balance(struct spdk_scheduler_core_info *cores, uint32_t core_count) 30 { 31 struct spdk_governor *governor; 32 struct spdk_scheduler_core_info *core; 33 struct spdk_governor_capabilities capabilities; 34 uint32_t i; 35 int rc; 36 37 governor = spdk_governor_get(); 38 assert(governor != NULL); 39 40 /* Gather active/idle statistics */ 41 SPDK_ENV_FOREACH_CORE(i) { 42 core = &cores[i]; 43 44 rc = governor->get_core_capabilities(core->lcore, &capabilities); 45 if (rc < 0) { 46 SPDK_ERRLOG("failed to get capabilities for core: %u\n", core->lcore); 47 return; 48 } 49 50 if (core->current_busy_tsc < (core->current_idle_tsc / 1000)) { 51 rc = governor->set_core_freq_min(core->lcore); 52 if (rc < 0) { 53 SPDK_ERRLOG("setting to minimal frequency for core %u failed\n", core->lcore); 54 } 55 } else if (core->current_idle_tsc > core->current_busy_tsc) { 56 rc = governor->core_freq_down(core->lcore); 57 if (rc < 0) { 58 SPDK_ERRLOG("lowering frequency for core %u failed\n", core->lcore); 59 } 60 } else if (core->current_idle_tsc < (core->current_busy_tsc / 1000)) { 61 rc = governor->set_core_freq_max(core->lcore); 62 if (rc < 0) { 63 SPDK_ERRLOG("setting to maximal frequency for core %u failed\n", core->lcore); 64 } 65 } else { 66 rc = governor->core_freq_up(core->lcore); 67 if (rc < 0) { 68 SPDK_ERRLOG("increasing frequency for core %u failed\n", core->lcore); 69 } 70 } 71 } 72 } 73 74 static struct spdk_scheduler gscheduler = { 75 .name = "gscheduler", 76 .init = init, 77 .deinit = deinit, 78 .balance = balance, 79 }; 80 81 SPDK_SCHEDULER_REGISTER(gscheduler); 82