xref: /f-stack/dpdk/lib/librte_power/rte_power.c (revision 2d9fd380)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2014 Intel Corporation
3  */
4 
5 #include <rte_errno.h>
6 #include <rte_spinlock.h>
7 
8 #include "rte_power.h"
9 #include "power_acpi_cpufreq.h"
10 #include "power_kvm_vm.h"
11 #include "power_pstate_cpufreq.h"
12 #include "power_common.h"
13 
14 enum power_management_env global_default_env = PM_ENV_NOT_SET;
15 
16 static rte_spinlock_t global_env_cfg_lock = RTE_SPINLOCK_INITIALIZER;
17 
18 /* function pointers */
19 rte_power_freqs_t rte_power_freqs  = NULL;
20 rte_power_get_freq_t rte_power_get_freq = NULL;
21 rte_power_set_freq_t rte_power_set_freq = NULL;
22 rte_power_freq_change_t rte_power_freq_up = NULL;
23 rte_power_freq_change_t rte_power_freq_down = NULL;
24 rte_power_freq_change_t rte_power_freq_max = NULL;
25 rte_power_freq_change_t rte_power_freq_min = NULL;
26 rte_power_freq_change_t rte_power_turbo_status;
27 rte_power_freq_change_t rte_power_freq_enable_turbo;
28 rte_power_freq_change_t rte_power_freq_disable_turbo;
29 rte_power_get_capabilities_t rte_power_get_capabilities;
30 
31 static void
reset_power_function_ptrs(void)32 reset_power_function_ptrs(void)
33 {
34 	rte_power_freqs  = NULL;
35 	rte_power_get_freq = NULL;
36 	rte_power_set_freq = NULL;
37 	rte_power_freq_up = NULL;
38 	rte_power_freq_down = NULL;
39 	rte_power_freq_max = NULL;
40 	rte_power_freq_min = NULL;
41 	rte_power_turbo_status = NULL;
42 	rte_power_freq_enable_turbo = NULL;
43 	rte_power_freq_disable_turbo = NULL;
44 	rte_power_get_capabilities = NULL;
45 }
46 
47 int
rte_power_check_env_supported(enum power_management_env env)48 rte_power_check_env_supported(enum power_management_env env)
49 {
50 	switch (env) {
51 	case PM_ENV_ACPI_CPUFREQ:
52 		return power_acpi_cpufreq_check_supported();
53 	case PM_ENV_PSTATE_CPUFREQ:
54 		return power_pstate_cpufreq_check_supported();
55 	case PM_ENV_KVM_VM:
56 		return power_kvm_vm_check_supported();
57 	default:
58 		rte_errno = EINVAL;
59 		return -1;
60 	}
61 }
62 
63 int
rte_power_set_env(enum power_management_env env)64 rte_power_set_env(enum power_management_env env)
65 {
66 	rte_spinlock_lock(&global_env_cfg_lock);
67 
68 	if (global_default_env != PM_ENV_NOT_SET) {
69 		RTE_LOG(ERR, POWER, "Power Management Environment already set.\n");
70 		rte_spinlock_unlock(&global_env_cfg_lock);
71 		return -1;
72 	}
73 
74 	int ret = 0;
75 
76 	if (env == PM_ENV_ACPI_CPUFREQ) {
77 		rte_power_freqs = power_acpi_cpufreq_freqs;
78 		rte_power_get_freq = power_acpi_cpufreq_get_freq;
79 		rte_power_set_freq = power_acpi_cpufreq_set_freq;
80 		rte_power_freq_up = power_acpi_cpufreq_freq_up;
81 		rte_power_freq_down = power_acpi_cpufreq_freq_down;
82 		rte_power_freq_min = power_acpi_cpufreq_freq_min;
83 		rte_power_freq_max = power_acpi_cpufreq_freq_max;
84 		rte_power_turbo_status = power_acpi_turbo_status;
85 		rte_power_freq_enable_turbo = power_acpi_enable_turbo;
86 		rte_power_freq_disable_turbo = power_acpi_disable_turbo;
87 		rte_power_get_capabilities = power_acpi_get_capabilities;
88 	} else if (env == PM_ENV_KVM_VM) {
89 		rte_power_freqs = power_kvm_vm_freqs;
90 		rte_power_get_freq = power_kvm_vm_get_freq;
91 		rte_power_set_freq = power_kvm_vm_set_freq;
92 		rte_power_freq_up = power_kvm_vm_freq_up;
93 		rte_power_freq_down = power_kvm_vm_freq_down;
94 		rte_power_freq_min = power_kvm_vm_freq_min;
95 		rte_power_freq_max = power_kvm_vm_freq_max;
96 		rte_power_turbo_status = power_kvm_vm_turbo_status;
97 		rte_power_freq_enable_turbo = power_kvm_vm_enable_turbo;
98 		rte_power_freq_disable_turbo = power_kvm_vm_disable_turbo;
99 		rte_power_get_capabilities = power_kvm_vm_get_capabilities;
100 	} else if (env == PM_ENV_PSTATE_CPUFREQ) {
101 		rte_power_freqs = power_pstate_cpufreq_freqs;
102 		rte_power_get_freq = power_pstate_cpufreq_get_freq;
103 		rte_power_set_freq = power_pstate_cpufreq_set_freq;
104 		rte_power_freq_up = power_pstate_cpufreq_freq_up;
105 		rte_power_freq_down = power_pstate_cpufreq_freq_down;
106 		rte_power_freq_min = power_pstate_cpufreq_freq_min;
107 		rte_power_freq_max = power_pstate_cpufreq_freq_max;
108 		rte_power_turbo_status = power_pstate_turbo_status;
109 		rte_power_freq_enable_turbo = power_pstate_enable_turbo;
110 		rte_power_freq_disable_turbo = power_pstate_disable_turbo;
111 		rte_power_get_capabilities = power_pstate_get_capabilities;
112 
113 	} else {
114 		RTE_LOG(ERR, POWER, "Invalid Power Management Environment(%d) set\n",
115 				env);
116 		ret = -1;
117 	}
118 
119 	if (ret == 0)
120 		global_default_env = env;
121 	else {
122 		global_default_env = PM_ENV_NOT_SET;
123 		reset_power_function_ptrs();
124 	}
125 
126 	rte_spinlock_unlock(&global_env_cfg_lock);
127 	return ret;
128 }
129 
130 void
rte_power_unset_env(void)131 rte_power_unset_env(void)
132 {
133 	rte_spinlock_lock(&global_env_cfg_lock);
134 	global_default_env = PM_ENV_NOT_SET;
135 	reset_power_function_ptrs();
136 	rte_spinlock_unlock(&global_env_cfg_lock);
137 }
138 
139 enum power_management_env
rte_power_get_env(void)140 rte_power_get_env(void) {
141 	return global_default_env;
142 }
143 
144 int
rte_power_init(unsigned int lcore_id)145 rte_power_init(unsigned int lcore_id)
146 {
147 	int ret = -1;
148 
149 	switch (global_default_env) {
150 	case PM_ENV_ACPI_CPUFREQ:
151 		return power_acpi_cpufreq_init(lcore_id);
152 	case PM_ENV_KVM_VM:
153 		return power_kvm_vm_init(lcore_id);
154 	case PM_ENV_PSTATE_CPUFREQ:
155 		return power_pstate_cpufreq_init(lcore_id);
156 	default:
157 		RTE_LOG(INFO, POWER, "Env isn't set yet!\n");
158 	}
159 
160 	/* Auto detect Environment */
161 	RTE_LOG(INFO, POWER, "Attempting to initialise ACPI cpufreq power management...\n");
162 	ret = power_acpi_cpufreq_init(lcore_id);
163 	if (ret == 0) {
164 		rte_power_set_env(PM_ENV_ACPI_CPUFREQ);
165 		goto out;
166 	}
167 
168 	RTE_LOG(INFO, POWER, "Attempting to initialise PSTAT power management...\n");
169 	ret = power_pstate_cpufreq_init(lcore_id);
170 	if (ret == 0) {
171 		rte_power_set_env(PM_ENV_PSTATE_CPUFREQ);
172 		goto out;
173 	}
174 
175 	RTE_LOG(INFO, POWER, "Attempting to initialise VM power management...\n");
176 	ret = power_kvm_vm_init(lcore_id);
177 	if (ret == 0) {
178 		rte_power_set_env(PM_ENV_KVM_VM);
179 		goto out;
180 	}
181 	RTE_LOG(ERR, POWER, "Unable to set Power Management Environment for lcore "
182 			"%u\n", lcore_id);
183 out:
184 	return ret;
185 }
186 
187 int
rte_power_exit(unsigned int lcore_id)188 rte_power_exit(unsigned int lcore_id)
189 {
190 	switch (global_default_env) {
191 	case PM_ENV_ACPI_CPUFREQ:
192 		return power_acpi_cpufreq_exit(lcore_id);
193 	case PM_ENV_KVM_VM:
194 		return power_kvm_vm_exit(lcore_id);
195 	case PM_ENV_PSTATE_CPUFREQ:
196 		return power_pstate_cpufreq_exit(lcore_id);
197 	default:
198 		RTE_LOG(ERR, POWER, "Environment has not been set, unable to exit gracefully\n");
199 
200 	}
201 	return -1;
202 
203 }
204