# HG changeset patch # User Jan Beulich # Date 1318580154 -7200 # Node ID de316831471a8e0f11f615e7bf336dee2ba811e7 # Parent a65693f9fb1250ff4819774a70284693705db9e7 cpufreq: error path fixes This fixes an actual bug (failure to exit from a function after an allocation failure), an inconsistency (not removing the cpufreq_dom list member upon failure), and a latent bug (not clearing the current governor upon governor initialization failure when there was no old one; latent because the only current code path leading to this situation frees the policy upon failure and hence the governor not getting cleared is benign). Signed-off-by: Jan Beulich Acked-by: Keir Fraser --- a/xen/drivers/cpufreq/cpufreq.c +++ b/xen/drivers/cpufreq/cpufreq.c @@ -195,8 +195,10 @@ int cpufreq_add_cpu(unsigned int cpu) if (!domexist || hw_all) { policy = xmalloc(struct cpufreq_policy); - if (!policy) + if (!policy) { ret = -ENOMEM; + goto err0; + } memset(policy, 0, sizeof(struct cpufreq_policy)); policy->cpu = cpu; @@ -206,7 +208,7 @@ int cpufreq_add_cpu(unsigned int cpu) if (ret) { xfree(policy); per_cpu(cpufreq_cpu_policy, cpu) = NULL; - return ret; + goto err0; } if (cpufreq_verbose) printk("CPU %u initialization completed\n", cpu); @@ -263,7 +265,7 @@ err1: cpufreq_driver->exit(policy); xfree(policy); } - +err0: if (cpus_empty(cpufreq_dom->map)) { list_del(&cpufreq_dom->node); xfree(cpufreq_dom); --- a/xen/drivers/cpufreq/utility.c +++ b/xen/drivers/cpufreq/utility.c @@ -462,8 +462,8 @@ int __cpufreq_set_policy(struct cpufreq_ data->governor->name); /* new governor failed, so re-start old one */ + data->governor = old_gov; if (old_gov) { - data->governor = old_gov; __cpufreq_governor(data, CPUFREQ_GOV_START); printk(KERN_WARNING "Still stay at %s governor\n", data->governor->name);