mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
xen/sysctl: Nest cpufreq scaling options
Add a union and struct so that most of the scaling variables of struct xen_get_cpufreq_para are within in a binary-compatible layout. This allows cppc_para to live in the larger union and use uint32_ts - struct xen_cppc_para will be 10 uint32_t's. The new scaling struct is 3 * uint32_t + 16 bytes CPUFREQ_NAME_LEN + 4 * uint32_t for xen_ondemand = 11 uint32_t. That means the old size is retained, int32_t turbo_enabled doesn't move and it's binary compatible. The out-of-context memcpy() in xc_get_cpufreq_para() now handles the copying of the fields removed there. Signed-off-by: Jason Andryuk <jandryuk@gmail.com> Reviewed-by: Jan Beulich <jbeulich@suse.com> Reviewed-by: Anthony PERARD <anthony.perard@citrix.com>
This commit is contained in:
1 parent
01a833e1fa
commit
2381dfab08
5 files changed
+92
-49
No files matched your search
+13
-9
@@ -1926,16 +1926,20 @@ struct xc_get_cpufreq_para {
|
||||
uint32_t cpuinfo_cur_freq;
|
||||
uint32_t cpuinfo_max_freq;
|
||||
uint32_t cpuinfo_min_freq;
|
||||
uint32_t scaling_cur_freq;
|
||||
|
||||
char scaling_governor[CPUFREQ_NAME_LEN];
|
||||
uint32_t scaling_max_freq;
|
||||
uint32_t scaling_min_freq;
|
||||
|
||||
/* for specific governor */
|
||||
union {
|
||||
xc_userspace_t userspace;
|
||||
xc_ondemand_t ondemand;
|
||||
struct {
|
||||
uint32_t scaling_cur_freq;
|
||||
|
||||
char scaling_governor[CPUFREQ_NAME_LEN];
|
||||
uint32_t scaling_max_freq;
|
||||
uint32_t scaling_min_freq;
|
||||
|
||||
/* for specific governor */
|
||||
union {
|
||||
xc_userspace_t userspace;
|
||||
xc_ondemand_t ondemand;
|
||||
} u;
|
||||
} s;
|
||||
} u;
|
||||
|
||||
int32_t turbo_enabled;
|
||||
|
||||
+40
-6
@@ -245,6 +245,45 @@ int xc_get_cpufreq_para(xc_interface *xch, int cpuid,
|
||||
sys_para->freq_num = user_para->freq_num;
|
||||
sys_para->gov_num = user_para->gov_num;
|
||||
|
||||
/* Sanity check struct layout */
|
||||
BUILD_BUG_ON(sizeof(*user_para) != sizeof(*sys_para));
|
||||
BUILD_BUG_ON(offsetof(typeof(*user_para), cpu_num) !=
|
||||
offsetof(typeof(*sys_para), cpu_num));
|
||||
BUILD_BUG_ON(offsetof(typeof(*user_para), freq_num) !=
|
||||
offsetof(typeof(*sys_para), freq_num));
|
||||
BUILD_BUG_ON(offsetof(typeof(*user_para), gov_num) !=
|
||||
offsetof(typeof(*sys_para), gov_num));
|
||||
BUILD_BUG_ON(offsetof(typeof(*user_para), affected_cpus) !=
|
||||
offsetof(typeof(*sys_para), affected_cpus));
|
||||
BUILD_BUG_ON(offsetof(typeof(*user_para), scaling_available_frequencies) !=
|
||||
offsetof(typeof(*sys_para), scaling_available_frequencies));
|
||||
BUILD_BUG_ON(offsetof(typeof(*user_para), scaling_available_governors) !=
|
||||
offsetof(typeof(*sys_para), scaling_available_governors));
|
||||
BUILD_BUG_ON(offsetof(typeof(*user_para), scaling_driver) !=
|
||||
offsetof(typeof(*sys_para), scaling_driver));
|
||||
BUILD_BUG_ON(offsetof(typeof(*user_para), cpuinfo_cur_freq) !=
|
||||
offsetof(typeof(*sys_para), cpuinfo_cur_freq));
|
||||
BUILD_BUG_ON(offsetof(typeof(*user_para), cpuinfo_max_freq) !=
|
||||
offsetof(typeof(*sys_para), cpuinfo_max_freq));
|
||||
BUILD_BUG_ON(offsetof(typeof(*user_para), cpuinfo_min_freq) !=
|
||||
offsetof(typeof(*sys_para), cpuinfo_min_freq));
|
||||
BUILD_BUG_ON(offsetof(typeof(*user_para), u.s.scaling_cur_freq) !=
|
||||
offsetof(typeof(*sys_para), u.s.scaling_cur_freq));
|
||||
BUILD_BUG_ON(offsetof(typeof(*user_para), u.s.scaling_governor) !=
|
||||
offsetof(typeof(*sys_para), u.s.scaling_governor));
|
||||
BUILD_BUG_ON(offsetof(typeof(*user_para), u.s.scaling_max_freq) !=
|
||||
offsetof(typeof(*sys_para), u.s.scaling_max_freq));
|
||||
BUILD_BUG_ON(offsetof(typeof(*user_para), u.s.scaling_min_freq) !=
|
||||
offsetof(typeof(*sys_para), u.s.scaling_min_freq));
|
||||
BUILD_BUG_ON(offsetof(typeof(*user_para), u.s.u.userspace) !=
|
||||
offsetof(typeof(*sys_para), u.s.u.userspace));
|
||||
BUILD_BUG_ON(offsetof(typeof(*user_para), u.s.u.ondemand) !=
|
||||
offsetof(typeof(*sys_para), u.s.u.ondemand));
|
||||
BUILD_BUG_ON(offsetof(typeof(*user_para), u.cppc_para) !=
|
||||
offsetof(typeof(*sys_para), u.cppc_para));
|
||||
BUILD_BUG_ON(offsetof(typeof(*user_para), turbo_enabled) !=
|
||||
offsetof(typeof(*sys_para), turbo_enabled));
|
||||
|
||||
ret = xc_sysctl(xch, &sysctl);
|
||||
if ( ret )
|
||||
{
|
||||
@@ -265,17 +304,12 @@ int xc_get_cpufreq_para(xc_interface *xch, int cpuid,
|
||||
user_para->cpuinfo_cur_freq = sys_para->cpuinfo_cur_freq;
|
||||
user_para->cpuinfo_max_freq = sys_para->cpuinfo_max_freq;
|
||||
user_para->cpuinfo_min_freq = sys_para->cpuinfo_min_freq;
|
||||
user_para->scaling_cur_freq = sys_para->scaling_cur_freq;
|
||||
user_para->scaling_max_freq = sys_para->scaling_max_freq;
|
||||
user_para->scaling_min_freq = sys_para->scaling_min_freq;
|
||||
user_para->turbo_enabled = sys_para->turbo_enabled;
|
||||
|
||||
memcpy(user_para->scaling_driver,
|
||||
sys_para->scaling_driver, CPUFREQ_NAME_LEN);
|
||||
memcpy(user_para->scaling_governor,
|
||||
sys_para->scaling_governor, CPUFREQ_NAME_LEN);
|
||||
|
||||
/* copy to user_para no matter what cpufreq governor */
|
||||
/* copy to user_para no matter what cpufreq driver/governor */
|
||||
BUILD_BUG_ON(sizeof(((struct xc_get_cpufreq_para *)0)->u) !=
|
||||
sizeof(((struct xen_get_cpufreq_para *)0)->u));
|
||||
|
||||
|
||||
+12
-12
@@ -730,39 +730,39 @@ static void print_cpufreq_para(int cpuid, struct xc_get_cpufreq_para *p_cpufreq)
|
||||
printf("scaling_avail_gov : %s\n",
|
||||
p_cpufreq->scaling_available_governors);
|
||||
|
||||
printf("current_governor : %s\n", p_cpufreq->scaling_governor);
|
||||
if ( !strncmp(p_cpufreq->scaling_governor,
|
||||
printf("current_governor : %s\n", p_cpufreq->u.s.scaling_governor);
|
||||
if ( !strncmp(p_cpufreq->u.s.scaling_governor,
|
||||
"userspace", CPUFREQ_NAME_LEN) )
|
||||
{
|
||||
printf(" userspace specific :\n");
|
||||
printf(" scaling_setspeed : %u\n",
|
||||
p_cpufreq->u.userspace.scaling_setspeed);
|
||||
p_cpufreq->u.s.u.userspace.scaling_setspeed);
|
||||
}
|
||||
else if ( !strncmp(p_cpufreq->scaling_governor,
|
||||
else if ( !strncmp(p_cpufreq->u.s.scaling_governor,
|
||||
"ondemand", CPUFREQ_NAME_LEN) )
|
||||
{
|
||||
printf(" ondemand specific :\n");
|
||||
printf(" sampling_rate : max [%u] min [%u] cur [%u]\n",
|
||||
p_cpufreq->u.ondemand.sampling_rate_max,
|
||||
p_cpufreq->u.ondemand.sampling_rate_min,
|
||||
p_cpufreq->u.ondemand.sampling_rate);
|
||||
p_cpufreq->u.s.u.ondemand.sampling_rate_max,
|
||||
p_cpufreq->u.s.u.ondemand.sampling_rate_min,
|
||||
p_cpufreq->u.s.u.ondemand.sampling_rate);
|
||||
printf(" up_threshold : %u\n",
|
||||
p_cpufreq->u.ondemand.up_threshold);
|
||||
p_cpufreq->u.s.u.ondemand.up_threshold);
|
||||
}
|
||||
|
||||
printf("scaling_avail_freq :");
|
||||
for ( i = 0; i < p_cpufreq->freq_num; i++ )
|
||||
if ( p_cpufreq->scaling_available_frequencies[i] ==
|
||||
p_cpufreq->scaling_cur_freq )
|
||||
p_cpufreq->u.s.scaling_cur_freq )
|
||||
printf(" *%d", p_cpufreq->scaling_available_frequencies[i]);
|
||||
else
|
||||
printf(" %d", p_cpufreq->scaling_available_frequencies[i]);
|
||||
printf("\n");
|
||||
|
||||
printf("scaling frequency : max [%u] min [%u] cur [%u]\n",
|
||||
p_cpufreq->scaling_max_freq,
|
||||
p_cpufreq->scaling_min_freq,
|
||||
p_cpufreq->scaling_cur_freq);
|
||||
p_cpufreq->u.s.scaling_max_freq,
|
||||
p_cpufreq->u.s.scaling_min_freq,
|
||||
p_cpufreq->u.s.scaling_cur_freq);
|
||||
|
||||
printf("turbo mode : %s\n",
|
||||
p_cpufreq->turbo_enabled ? "enabled" : "disabled or n/a");
|
||||
|
||||
+14
-13
@@ -258,37 +258,38 @@ static int get_cpufreq_para(struct xen_sysctl_pm_op *op)
|
||||
cpufreq_driver.get ? cpufreq_driver.get(op->cpuid) : policy->cur;
|
||||
op->u.get_para.cpuinfo_max_freq = policy->cpuinfo.max_freq;
|
||||
op->u.get_para.cpuinfo_min_freq = policy->cpuinfo.min_freq;
|
||||
op->u.get_para.scaling_cur_freq = policy->cur;
|
||||
op->u.get_para.scaling_max_freq = policy->max;
|
||||
op->u.get_para.scaling_min_freq = policy->min;
|
||||
|
||||
op->u.get_para.u.s.scaling_cur_freq = policy->cur;
|
||||
op->u.get_para.u.s.scaling_max_freq = policy->max;
|
||||
op->u.get_para.u.s.scaling_min_freq = policy->min;
|
||||
|
||||
if ( cpufreq_driver.name[0] )
|
||||
strlcpy(op->u.get_para.scaling_driver,
|
||||
strlcpy(op->u.get_para.scaling_driver,
|
||||
cpufreq_driver.name, CPUFREQ_NAME_LEN);
|
||||
else
|
||||
strlcpy(op->u.get_para.scaling_driver, "Unknown", CPUFREQ_NAME_LEN);
|
||||
|
||||
if ( policy->governor->name[0] )
|
||||
strlcpy(op->u.get_para.scaling_governor,
|
||||
strlcpy(op->u.get_para.u.s.scaling_governor,
|
||||
policy->governor->name, CPUFREQ_NAME_LEN);
|
||||
else
|
||||
strlcpy(op->u.get_para.scaling_governor, "Unknown", CPUFREQ_NAME_LEN);
|
||||
strlcpy(op->u.get_para.u.s.scaling_governor, "Unknown", CPUFREQ_NAME_LEN);
|
||||
|
||||
/* governor specific para */
|
||||
if ( !strncasecmp(op->u.get_para.scaling_governor,
|
||||
if ( !strncasecmp(op->u.get_para.u.s.scaling_governor,
|
||||
"userspace", CPUFREQ_NAME_LEN) )
|
||||
{
|
||||
op->u.get_para.u.userspace.scaling_setspeed = policy->cur;
|
||||
op->u.get_para.u.s.u.userspace.scaling_setspeed = policy->cur;
|
||||
}
|
||||
|
||||
if ( !strncasecmp(op->u.get_para.scaling_governor,
|
||||
if ( !strncasecmp(op->u.get_para.u.s.scaling_governor,
|
||||
"ondemand", CPUFREQ_NAME_LEN) )
|
||||
{
|
||||
ret = get_cpufreq_ondemand_para(
|
||||
&op->u.get_para.u.ondemand.sampling_rate_max,
|
||||
&op->u.get_para.u.ondemand.sampling_rate_min,
|
||||
&op->u.get_para.u.ondemand.sampling_rate,
|
||||
&op->u.get_para.u.ondemand.up_threshold);
|
||||
&op->u.get_para.u.s.u.ondemand.sampling_rate_max,
|
||||
&op->u.get_para.u.s.u.ondemand.sampling_rate_min,
|
||||
&op->u.get_para.u.s.u.ondemand.sampling_rate,
|
||||
&op->u.get_para.u.s.u.ondemand.up_threshold);
|
||||
}
|
||||
op->u.get_para.turbo_enabled = cpufreq_get_turbo_status(op->cpuid);
|
||||
|
||||
|
||||
@@ -317,16 +317,20 @@ struct xen_get_cpufreq_para {
|
||||
uint32_t cpuinfo_cur_freq;
|
||||
uint32_t cpuinfo_max_freq;
|
||||
uint32_t cpuinfo_min_freq;
|
||||
uint32_t scaling_cur_freq;
|
||||
|
||||
char scaling_governor[CPUFREQ_NAME_LEN];
|
||||
uint32_t scaling_max_freq;
|
||||
uint32_t scaling_min_freq;
|
||||
|
||||
/* for specific governor */
|
||||
union {
|
||||
struct xen_userspace userspace;
|
||||
struct xen_ondemand ondemand;
|
||||
struct {
|
||||
uint32_t scaling_cur_freq;
|
||||
|
||||
char scaling_governor[CPUFREQ_NAME_LEN];
|
||||
uint32_t scaling_max_freq;
|
||||
uint32_t scaling_min_freq;
|
||||
|
||||
/* for specific governor */
|
||||
union {
|
||||
struct xen_userspace userspace;
|
||||
struct xen_ondemand ondemand;
|
||||
} u;
|
||||
} s;
|
||||
} u;
|
||||
|
||||
int32_t turbo_enabled;
|
||||
|
||||