aboutsummaryrefslogtreecommitdiffstats
path: root/lib/librte_power/rte_power.c
blob: cc05b0faf0d29e6284be227cb79516682269df9f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/* SPDX-License-Identifier: BSD-3-Clause
 * Copyright(c) 2010-2014 Intel Corporation
 */

#include <rte_spinlock.h>

#include "rte_power.h"
#include "power_acpi_cpufreq.h"
#include "power_kvm_vm.h"
#include "power_common.h"

enum power_management_env global_default_env = PM_ENV_NOT_SET;

static rte_spinlock_t global_env_cfg_lock = RTE_SPINLOCK_INITIALIZER;

/* function pointers */
rte_power_freqs_t rte_power_freqs  = NULL;
rte_power_get_freq_t rte_power_get_freq = NULL;
rte_power_set_freq_t rte_power_set_freq = NULL;
rte_power_freq_change_t rte_power_freq_up = NULL;
rte_power_freq_change_t rte_power_freq_down = NULL;
rte_power_freq_change_t rte_power_freq_max = NULL;
rte_power_freq_change_t rte_power_freq_min = NULL;
rte_power_freq_change_t rte_power_turbo_status;
rte_power_freq_change_t rte_power_freq_enable_turbo;
rte_power_freq_change_t rte_power_freq_disable_turbo;
rte_power_get_capabilities_t rte_power_get_capabilities;

int
rte_power_set_env(enum power_management_env env)
{
	rte_spinlock_lock(&global_env_cfg_lock);

	if (global_default_env != PM_ENV_NOT_SET) {
		rte_spinlock_unlock(&global_env_cfg_lock);
		return 0;
	}

	int ret = 0;

	if (env == PM_ENV_ACPI_CPUFREQ) {
		rte_power_freqs = power_acpi_cpufreq_freqs;
		rte_power_get_freq = power_acpi_cpufreq_get_freq;
		rte_power_set_freq = power_acpi_cpufreq_set_freq;
		rte_power_freq_up = power_acpi_cpufreq_freq_up;
		rte_power_freq_down = power_acpi_cpufreq_freq_down;
		rte_power_freq_min = power_acpi_cpufreq_freq_min;
		rte_power_freq_max = power_acpi_cpufreq_freq_max;
		rte_power_turbo_status = power_acpi_turbo_status;
		rte_power_freq_enable_turbo = power_acpi_enable_turbo;
		rte_power_freq_disable_turbo = power_acpi_disable_turbo;
		rte_power_get_capabilities = power_acpi_get_capabilities;
	} else if (env == PM_ENV_KVM_VM) {
		rte_power_freqs = power_kvm_vm_freqs;
		rte_power_get_freq = power_kvm_vm_get_freq;
		rte_power_set_freq = power_kvm_vm_set_freq;
		rte_power_freq_up = power_kvm_vm_freq_up;
		rte_power_freq_down = power_kvm_vm_freq_down;
		rte_power_freq_min = power_kvm_vm_freq_min;
		rte_power_freq_max = power_kvm_vm_freq_max;
		rte_power_turbo_status = power_kvm_vm_turbo_status;
		rte_power_freq_enable_turbo = power_kvm_vm_enable_turbo;
		rte_power_freq_disable_turbo = power_kvm_vm_disable_turbo;
		rte_power_get_capabilities = power_kvm_vm_get_capabilities;
	} else {
		RTE_LOG(ERR, POWER, "Invalid Power Management Environment(%d) set\n",
				env);
		ret = -1;
	}

	if (ret == 0)
		global_default_env = env;
	else
		global_default_env = PM_ENV_NOT_SET;

	rte_spinlock_unlock(&global_env_cfg_lock);
	return ret;

}

void
rte_power_unset_env(void)
{
	rte_spinlock_lock(&global_env_cfg_lock);
	global_default_env = PM_ENV_NOT_SET;
	rte_spinlock_unlock(&global_env_cfg_lock);
}

enum power_management_env
rte_power_get_env(void) {
	return global_default_env;
}

int
rte_power_init(unsigned int lcore_id)
{
	int ret = -1;

	if (global_default_env == PM_ENV_ACPI_CPUFREQ) {
		return power_acpi_cpufreq_init(lcore_id);
	}
	if (global_default_env == PM_ENV_KVM_VM) {
		return power_kvm_vm_init(lcore_id);
	}
	/* Auto detect Environment */
	RTE_LOG(INFO, POWER, "Attempting to initialise ACPI cpufreq power "
			"management...\n");
	ret = power_acpi_cpufreq_init(lcore_id);
	if (ret == 0) {
		rte_power_set_env(PM_ENV_ACPI_CPUFREQ);
		goto out;
	}

	RTE_LOG(INFO, POWER, "Attempting to initialise VM power management...\n");
	ret = power_kvm_vm_init(lcore_id);
	if (ret == 0) {
		rte_power_set_env(PM_ENV_KVM_VM);
		goto out;
	}
	RTE_LOG(ERR, POWER, "Unable to set Power Management Environment for lcore "
			"%u\n", lcore_id);
out:
	return ret;
}

int
rte_power_exit(unsigned int lcore_id)
{
	if (global_default_env == PM_ENV_ACPI_CPUFREQ)
		return power_acpi_cpufreq_exit(lcore_id);
	if (global_default_env == PM_ENV_KVM_VM)
		return power_kvm_vm_exit(lcore_id);

	RTE_LOG(ERR, POWER, "Environment has not been set, unable to exit "
				"gracefully\n");
	return -1;

}