Line data Source code
1 : /* SPDX-License-Identifier: BSD-3-Clause 2 : * Copyright (C) 2020 Intel Corporation. 3 : * All rights reserved. 4 : */ 5 : 6 : #include "spdk/stdinc.h" 7 : #include "spdk/log.h" 8 : #include "spdk/env.h" 9 : #include "spdk/event.h" 10 : #include "spdk/scheduler.h" 11 : 12 : #include "spdk_internal/event.h" 13 : 14 : #include <rte_power.h> 15 : 16 : static uint32_t 17 0 : _get_core_curr_freq(uint32_t lcore_id) 18 0 : { 19 0 : const uint32_t MAX_CORE_FREQ_NUM = 64; 20 0 : uint32_t freqs[MAX_CORE_FREQ_NUM]; 21 : uint32_t freq_index; 22 : int rc; 23 : 24 0 : rc = rte_power_freqs(lcore_id, freqs, MAX_CORE_FREQ_NUM); 25 0 : if (!rc) { 26 0 : SPDK_ERRLOG("Unable to get current core frequency array for core %d\n.", lcore_id); 27 : 28 0 : return 0; 29 : } 30 0 : freq_index = rte_power_get_freq(lcore_id); 31 0 : if (freq_index >= MAX_CORE_FREQ_NUM) { 32 0 : SPDK_ERRLOG("Unable to get current core frequency for core %d\n.", lcore_id); 33 : 34 0 : return 0; 35 : } 36 : 37 0 : return freqs[freq_index]; 38 : } 39 : 40 : static int 41 0 : _core_freq_up(uint32_t lcore_id) 42 : { 43 0 : return rte_power_freq_up(lcore_id); 44 : } 45 : 46 : static int 47 0 : _core_freq_down(uint32_t lcore_id) 48 : { 49 0 : return rte_power_freq_down(lcore_id); 50 : } 51 : 52 : static int 53 0 : _set_core_freq_max(uint32_t lcore_id) 54 : { 55 0 : return rte_power_freq_max(lcore_id); 56 : } 57 : 58 : static int 59 0 : _set_core_freq_min(uint32_t lcore_id) 60 : { 61 0 : return rte_power_freq_min(lcore_id); 62 : } 63 : 64 : static int 65 0 : _get_core_capabilities(uint32_t lcore_id, struct spdk_governor_capabilities *capabilities) 66 : { 67 0 : struct rte_power_core_capabilities caps; 68 : int rc; 69 : 70 0 : rc = rte_power_get_capabilities(lcore_id, &caps); 71 0 : if (rc != 0) { 72 0 : return rc; 73 : } 74 : 75 0 : capabilities->priority = caps.priority == 0 ? false : true; 76 : 77 0 : return 0; 78 : } 79 : 80 : static int 81 0 : _init_core(uint32_t lcore_id) 82 : { 83 0 : struct rte_power_core_capabilities caps; 84 : int rc; 85 : 86 0 : rc = rte_power_init(lcore_id); 87 0 : if (rc != 0) { 88 0 : SPDK_ERRLOG("Failed to initialize on core%d\n", lcore_id); 89 0 : return rc; 90 : } 91 : 92 0 : rc = rte_power_get_capabilities(lcore_id, &caps); 93 0 : if (rc != 0) { 94 0 : SPDK_ERRLOG("Failed retrieve capabilities of core%d\n", lcore_id); 95 0 : return rc; 96 : } 97 : 98 0 : if (caps.turbo) { 99 0 : rc = rte_power_freq_enable_turbo(lcore_id); 100 0 : if (rc != 0) { 101 0 : SPDK_ERRLOG("Failed to set turbo on core%d\n", lcore_id); 102 0 : return rc; 103 : } 104 : } 105 : 106 0 : return rc; 107 : } 108 : 109 : static int 110 0 : _init(void) 111 : { 112 : uint32_t i, j; 113 0 : int rc = 0; 114 : 115 0 : SPDK_ENV_FOREACH_CORE(i) { 116 0 : rc = _init_core(i); 117 0 : if (rc != 0) { 118 0 : SPDK_ERRLOG("Failed to initialize on core%d\n", i); 119 0 : break; 120 : } 121 : } 122 : 123 0 : if (rc == 0) { 124 0 : return rc; 125 : } 126 : 127 : /* When initialization of a core failed, deinitialize prior cores. */ 128 0 : SPDK_ENV_FOREACH_CORE(j) { 129 0 : if (j >= i) { 130 0 : break; 131 : } 132 0 : if (rte_power_exit(j) != 0) { 133 0 : SPDK_ERRLOG("Failed to deinitialize on core%d\n", j); 134 : } 135 : } 136 0 : return rc; 137 : } 138 : 139 : static void 140 0 : _deinit(void) 141 : { 142 : uint32_t i; 143 : 144 0 : SPDK_ENV_FOREACH_CORE(i) { 145 0 : if (rte_power_exit(i) != 0) { 146 0 : SPDK_ERRLOG("Failed to deinitialize on core%d\n", i); 147 : } 148 : } 149 0 : } 150 : 151 : static struct spdk_governor dpdk_governor = { 152 : .name = "dpdk_governor", 153 : .get_core_curr_freq = _get_core_curr_freq, 154 : .core_freq_up = _core_freq_up, 155 : .core_freq_down = _core_freq_down, 156 : .set_core_freq_max = _set_core_freq_max, 157 : .set_core_freq_min = _set_core_freq_min, 158 : .get_core_capabilities = _get_core_capabilities, 159 : .init = _init, 160 : .deinit = _deinit, 161 : }; 162 : 163 0 : SPDK_GOVERNOR_REGISTER(dpdk_governor);