Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/davej/cpufreq

* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/davej/cpufreq:
  [CPUFREQ] Fix NULL ptr regression in powernow-k8
  [CPUFREQ] Create a blacklist for processors that should not load the acpi-cpufreq module.
  [CPUFREQ] Powernow-k8: Enable more than 2 low P-states
  [CPUFREQ] remove rwsem lock from CPUFREQ_GOV_STOP call (second call site)
  [CPUFREQ] ondemand - Use global sysfs dir for tuning settings
  [CPUFREQ] Introduce global, not per core: /sys/devices/system/cpu/cpufreq
  [CPUFREQ] Bail out of cpufreq_add_dev if the link for a managed CPU got created
  [CPUFREQ] Factor out policy setting from cpufreq_add_dev
  [CPUFREQ] Factor out interface creation from cpufreq_add_dev
  [CPUFREQ] Factor out symlink creation from cpufreq_add_dev
  [CPUFREQ] cleanup up -ENOMEM handling in cpufreq_add_dev
  [CPUFREQ] Reduce scope of cpu_sys_dev in cpufreq_add_dev
  [CPUFREQ] update Doc for cpuinfo_cur_freq and scaling_cur_freq
This commit is contained in:
Linus Torvalds
2009-09-18 09:16:57 -07:00
melakukan 714af06938
6 mengubah file dengan 350 tambahan dan 178 penghapusan

Melihat File

@@ -61,6 +61,8 @@ static DEFINE_SPINLOCK(cpufreq_driver_lock);
* are concerned with are online after they get the lock.
* - Governor routines that can be called in cpufreq hotplug path should not
* take this sem as top level hotplug notifier handler takes this.
* - Lock should not be held across
* __cpufreq_governor(data, CPUFREQ_GOV_STOP);
*/
static DEFINE_PER_CPU(int, policy_cpu);
static DEFINE_PER_CPU(struct rw_semaphore, cpu_policy_rwsem);
@@ -686,6 +688,9 @@ static struct attribute *default_attrs[] = {
NULL
};
struct kobject *cpufreq_global_kobject;
EXPORT_SYMBOL(cpufreq_global_kobject);
#define to_policy(k) container_of(k, struct cpufreq_policy, kobj)
#define to_attr(a) container_of(a, struct freq_attr, attr)
@@ -756,92 +761,20 @@ static struct kobj_type ktype_cpufreq = {
.release = cpufreq_sysfs_release,
};
/**
* cpufreq_add_dev - add a CPU device
*
* Adds the cpufreq interface for a CPU device.
*
* The Oracle says: try running cpufreq registration/unregistration concurrently
* with with cpu hotplugging and all hell will break loose. Tried to clean this
* mess up, but more thorough testing is needed. - Mathieu
/*
* Returns:
* Negative: Failure
* 0: Success
* Positive: When we have a managed CPU and the sysfs got symlinked
*/
static int cpufreq_add_dev(struct sys_device *sys_dev)
int cpufreq_add_dev_policy(unsigned int cpu, struct cpufreq_policy *policy,
struct sys_device *sys_dev)
{
unsigned int cpu = sys_dev->id;
int ret = 0;
struct cpufreq_policy new_policy;
struct cpufreq_policy *policy;
struct freq_attr **drv_attr;
struct sys_device *cpu_sys_dev;
#ifdef CONFIG_SMP
unsigned long flags;
unsigned int j;
if (cpu_is_offline(cpu))
return 0;
cpufreq_debug_disable_ratelimit();
dprintk("adding CPU %u\n", cpu);
#ifdef CONFIG_SMP
/* check whether a different CPU already registered this
* CPU because it is in the same boat. */
policy = cpufreq_cpu_get(cpu);
if (unlikely(policy)) {
cpufreq_cpu_put(policy);
cpufreq_debug_enable_ratelimit();
return 0;
}
#endif
if (!try_module_get(cpufreq_driver->owner)) {
ret = -EINVAL;
goto module_out;
}
policy = kzalloc(sizeof(struct cpufreq_policy), GFP_KERNEL);
if (!policy) {
ret = -ENOMEM;
goto nomem_out;
}
if (!alloc_cpumask_var(&policy->cpus, GFP_KERNEL)) {
ret = -ENOMEM;
goto err_free_policy;
}
if (!zalloc_cpumask_var(&policy->related_cpus, GFP_KERNEL)) {
ret = -ENOMEM;
goto err_free_cpumask;
}
policy->cpu = cpu;
cpumask_copy(policy->cpus, cpumask_of(cpu));
/* Initially set CPU itself as the policy_cpu */
per_cpu(policy_cpu, cpu) = cpu;
ret = (lock_policy_rwsem_write(cpu) < 0);
WARN_ON(ret);
init_completion(&policy->kobj_unregister);
INIT_WORK(&policy->update, handle_update);
/* Set governor before ->init, so that driver could check it */
policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
/* call driver. From then on the cpufreq must be able
* to accept all calls to ->verify and ->setpolicy for this CPU
*/
ret = cpufreq_driver->init(policy);
if (ret) {
dprintk("initialization failed\n");
goto err_unlock_policy;
}
policy->user_policy.min = policy->min;
policy->user_policy.max = policy->max;
blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
CPUFREQ_START, policy);
#ifdef CONFIG_SMP
#ifdef CONFIG_HOTPLUG_CPU
if (per_cpu(cpufreq_cpu_governor, cpu)) {
policy->governor = per_cpu(cpufreq_cpu_governor, cpu);
@@ -872,9 +805,8 @@ static int cpufreq_add_dev(struct sys_device *sys_dev)
/* Should not go through policy unlock path */
if (cpufreq_driver->exit)
cpufreq_driver->exit(policy);
ret = -EBUSY;
cpufreq_cpu_put(managed_policy);
goto err_free_cpumask;
return -EBUSY;
}
spin_lock_irqsave(&cpufreq_driver_lock, flags);
@@ -893,17 +825,62 @@ static int cpufreq_add_dev(struct sys_device *sys_dev)
* Call driver->exit() because only the cpu parent of
* the kobj needed to call init().
*/
goto out_driver_exit; /* call driver->exit() */
if (cpufreq_driver->exit)
cpufreq_driver->exit(policy);
if (!ret)
return 1;
else
return ret;
}
}
#endif
memcpy(&new_policy, policy, sizeof(struct cpufreq_policy));
return ret;
}
/* symlink affected CPUs */
int cpufreq_add_dev_symlink(unsigned int cpu, struct cpufreq_policy *policy)
{
unsigned int j;
int ret = 0;
for_each_cpu(j, policy->cpus) {
struct cpufreq_policy *managed_policy;
struct sys_device *cpu_sys_dev;
if (j == cpu)
continue;
if (!cpu_online(j))
continue;
dprintk("CPU %u already managed, adding link\n", j);
managed_policy = cpufreq_cpu_get(cpu);
cpu_sys_dev = get_cpu_sysdev(j);
ret = sysfs_create_link(&cpu_sys_dev->kobj, &policy->kobj,
"cpufreq");
if (ret) {
cpufreq_cpu_put(managed_policy);
return ret;
}
}
return ret;
}
int cpufreq_add_dev_interface(unsigned int cpu, struct cpufreq_policy *policy,
struct sys_device *sys_dev)
{
struct cpufreq_policy new_policy;
struct freq_attr **drv_attr;
unsigned long flags;
int ret = 0;
unsigned int j;
/* prepare interface data */
ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq, &sys_dev->kobj,
"cpufreq");
ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq,
&sys_dev->kobj, "cpufreq");
if (ret)
goto out_driver_exit;
return ret;
/* set up files for this cpu device */
drv_attr = cpufreq_driver->attr;
@@ -926,35 +903,20 @@ static int cpufreq_add_dev(struct sys_device *sys_dev)
spin_lock_irqsave(&cpufreq_driver_lock, flags);
for_each_cpu(j, policy->cpus) {
if (!cpu_online(j))
continue;
if (!cpu_online(j))
continue;
per_cpu(cpufreq_cpu_data, j) = policy;
per_cpu(policy_cpu, j) = policy->cpu;
}
spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
/* symlink affected CPUs */
for_each_cpu(j, policy->cpus) {
struct cpufreq_policy *managed_policy;
ret = cpufreq_add_dev_symlink(cpu, policy);
if (ret)
goto err_out_kobj_put;
if (j == cpu)
continue;
if (!cpu_online(j))
continue;
dprintk("CPU %u already managed, adding link\n", j);
managed_policy = cpufreq_cpu_get(cpu);
cpu_sys_dev = get_cpu_sysdev(j);
ret = sysfs_create_link(&cpu_sys_dev->kobj, &policy->kobj,
"cpufreq");
if (ret) {
cpufreq_cpu_put(managed_policy);
goto err_out_unregister;
}
}
policy->governor = NULL; /* to assure that the starting sequence is
* run in cpufreq_set_policy */
memcpy(&new_policy, policy, sizeof(struct cpufreq_policy));
/* assure that the starting sequence is run in __cpufreq_set_policy */
policy->governor = NULL;
/* set default policy */
ret = __cpufreq_set_policy(policy, &new_policy);
@@ -963,8 +925,107 @@ static int cpufreq_add_dev(struct sys_device *sys_dev)
if (ret) {
dprintk("setting policy failed\n");
goto err_out_unregister;
if (cpufreq_driver->exit)
cpufreq_driver->exit(policy);
}
return ret;
err_out_kobj_put:
kobject_put(&policy->kobj);
wait_for_completion(&policy->kobj_unregister);
return ret;
}
/**
* cpufreq_add_dev - add a CPU device
*
* Adds the cpufreq interface for a CPU device.
*
* The Oracle says: try running cpufreq registration/unregistration concurrently
* with with cpu hotplugging and all hell will break loose. Tried to clean this
* mess up, but more thorough testing is needed. - Mathieu
*/
static int cpufreq_add_dev(struct sys_device *sys_dev)
{
unsigned int cpu = sys_dev->id;
int ret = 0;
struct cpufreq_policy *policy;
unsigned long flags;
unsigned int j;
if (cpu_is_offline(cpu))
return 0;
cpufreq_debug_disable_ratelimit();
dprintk("adding CPU %u\n", cpu);
#ifdef CONFIG_SMP
/* check whether a different CPU already registered this
* CPU because it is in the same boat. */
policy = cpufreq_cpu_get(cpu);
if (unlikely(policy)) {
cpufreq_cpu_put(policy);
cpufreq_debug_enable_ratelimit();
return 0;
}
#endif
if (!try_module_get(cpufreq_driver->owner)) {
ret = -EINVAL;
goto module_out;
}
ret = -ENOMEM;
policy = kzalloc(sizeof(struct cpufreq_policy), GFP_KERNEL);
if (!policy)
goto nomem_out;
if (!alloc_cpumask_var(&policy->cpus, GFP_KERNEL))
goto err_free_policy;
if (!zalloc_cpumask_var(&policy->related_cpus, GFP_KERNEL))
goto err_free_cpumask;
policy->cpu = cpu;
cpumask_copy(policy->cpus, cpumask_of(cpu));
/* Initially set CPU itself as the policy_cpu */
per_cpu(policy_cpu, cpu) = cpu;
ret = (lock_policy_rwsem_write(cpu) < 0);
WARN_ON(ret);
init_completion(&policy->kobj_unregister);
INIT_WORK(&policy->update, handle_update);
/* Set governor before ->init, so that driver could check it */
policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
/* call driver. From then on the cpufreq must be able
* to accept all calls to ->verify and ->setpolicy for this CPU
*/
ret = cpufreq_driver->init(policy);
if (ret) {
dprintk("initialization failed\n");
goto err_unlock_policy;
}
policy->user_policy.min = policy->min;
policy->user_policy.max = policy->max;
blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
CPUFREQ_START, policy);
ret = cpufreq_add_dev_policy(cpu, policy, sys_dev);
if (ret) {
if (ret > 0)
/* This is a managed cpu, symlink created,
exit with 0 */
ret = 0;
goto err_unlock_policy;
}
ret = cpufreq_add_dev_interface(cpu, policy, sys_dev);
if (ret)
goto err_out_unregister;
unlock_policy_rwsem_write(cpu);
@@ -982,14 +1043,9 @@ err_out_unregister:
per_cpu(cpufreq_cpu_data, j) = NULL;
spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
err_out_kobj_put:
kobject_put(&policy->kobj);
wait_for_completion(&policy->kobj_unregister);
out_driver_exit:
if (cpufreq_driver->exit)
cpufreq_driver->exit(policy);
err_unlock_policy:
unlock_policy_rwsem_write(cpu);
err_free_cpumask:
@@ -1653,8 +1709,17 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data,
dprintk("governor switch\n");
/* end old governor */
if (data->governor)
if (data->governor) {
/*
* Need to release the rwsem around governor
* stop due to lock dependency between
* cancel_delayed_work_sync and the read lock
* taken in the delayed work handler.
*/
unlock_policy_rwsem_write(data->cpu);
__cpufreq_governor(data, CPUFREQ_GOV_STOP);
lock_policy_rwsem_write(data->cpu);
}
/* start new governor */
data->governor = policy->governor;
@@ -1884,7 +1949,11 @@ static int __init cpufreq_core_init(void)
per_cpu(policy_cpu, cpu) = -1;
init_rwsem(&per_cpu(cpu_policy_rwsem, cpu));
}
cpufreq_global_kobject = kobject_create_and_add("cpufreq",
&cpu_sysdev_class.kset.kobj);
BUG_ON(!cpufreq_global_kobject);
return 0;
}
core_initcall(cpufreq_core_init);

Melihat File

@@ -55,6 +55,18 @@ static unsigned int min_sampling_rate;
#define TRANSITION_LATENCY_LIMIT (10 * 1000 * 1000)
static void do_dbs_timer(struct work_struct *work);
static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
unsigned int event);
#ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND
static
#endif
struct cpufreq_governor cpufreq_gov_ondemand = {
.name = "ondemand",
.governor = cpufreq_governor_dbs,
.max_transition_latency = TRANSITION_LATENCY_LIMIT,
.owner = THIS_MODULE,
};
/* Sampling types */
enum {DBS_NORMAL_SAMPLE, DBS_SUB_SAMPLE};
@@ -207,20 +219,23 @@ static void ondemand_powersave_bias_init(void)
}
/************************** sysfs interface ************************/
static ssize_t show_sampling_rate_max(struct cpufreq_policy *policy, char *buf)
static ssize_t show_sampling_rate_max(struct kobject *kobj,
struct attribute *attr, char *buf)
{
printk_once(KERN_INFO "CPUFREQ: ondemand sampling_rate_max "
"sysfs file is deprecated - used by: %s\n", current->comm);
return sprintf(buf, "%u\n", -1U);
}
static ssize_t show_sampling_rate_min(struct cpufreq_policy *policy, char *buf)
static ssize_t show_sampling_rate_min(struct kobject *kobj,
struct attribute *attr, char *buf)
{
return sprintf(buf, "%u\n", min_sampling_rate);
}
#define define_one_ro(_name) \
static struct freq_attr _name = \
static struct global_attr _name = \
__ATTR(_name, 0444, show_##_name, NULL)
define_one_ro(sampling_rate_max);
@@ -229,7 +244,7 @@ define_one_ro(sampling_rate_min);
/* cpufreq_ondemand Governor Tunables */
#define show_one(file_name, object) \
static ssize_t show_##file_name \
(struct cpufreq_policy *unused, char *buf) \
(struct kobject *kobj, struct attribute *attr, char *buf) \
{ \
return sprintf(buf, "%u\n", dbs_tuners_ins.object); \
}
@@ -238,8 +253,38 @@ show_one(up_threshold, up_threshold);
show_one(ignore_nice_load, ignore_nice);
show_one(powersave_bias, powersave_bias);
static ssize_t store_sampling_rate(struct cpufreq_policy *unused,
const char *buf, size_t count)
/*** delete after deprecation time ***/
#define DEPRECATION_MSG(file_name) \
printk_once(KERN_INFO "CPUFREQ: Per core ondemand sysfs " \
"interface is deprecated - " #file_name "\n");
#define show_one_old(file_name) \
static ssize_t show_##file_name##_old \
(struct cpufreq_policy *unused, char *buf) \
{ \
printk_once(KERN_INFO "CPUFREQ: Per core ondemand sysfs " \
"interface is deprecated - " #file_name "\n"); \
return show_##file_name(NULL, NULL, buf); \
}
show_one_old(sampling_rate);
show_one_old(up_threshold);
show_one_old(ignore_nice_load);
show_one_old(powersave_bias);
show_one_old(sampling_rate_min);
show_one_old(sampling_rate_max);
#define define_one_ro_old(object, _name) \
static struct freq_attr object = \
__ATTR(_name, 0444, show_##_name##_old, NULL)
define_one_ro_old(sampling_rate_min_old, sampling_rate_min);
define_one_ro_old(sampling_rate_max_old, sampling_rate_max);
/*** delete after deprecation time ***/
static ssize_t store_sampling_rate(struct kobject *a, struct attribute *b,
const char *buf, size_t count)
{
unsigned int input;
int ret;
@@ -254,8 +299,8 @@ static ssize_t store_sampling_rate(struct cpufreq_policy *unused,
return count;
}
static ssize_t store_up_threshold(struct cpufreq_policy *unused,
const char *buf, size_t count)
static ssize_t store_up_threshold(struct kobject *a, struct attribute *b,
const char *buf, size_t count)
{
unsigned int input;
int ret;
@@ -273,8 +318,8 @@ static ssize_t store_up_threshold(struct cpufreq_policy *unused,
return count;
}
static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy,
const char *buf, size_t count)
static ssize_t store_ignore_nice_load(struct kobject *a, struct attribute *b,
const char *buf, size_t count)
{
unsigned int input;
int ret;
@@ -310,8 +355,8 @@ static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy,
return count;
}
static ssize_t store_powersave_bias(struct cpufreq_policy *unused,
const char *buf, size_t count)
static ssize_t store_powersave_bias(struct kobject *a, struct attribute *b,
const char *buf, size_t count)
{
unsigned int input;
int ret;
@@ -332,7 +377,7 @@ static ssize_t store_powersave_bias(struct cpufreq_policy *unused,
}
#define define_one_rw(_name) \
static struct freq_attr _name = \
static struct global_attr _name = \
__ATTR(_name, 0644, show_##_name, store_##_name)
define_one_rw(sampling_rate);
@@ -355,6 +400,47 @@ static struct attribute_group dbs_attr_group = {
.name = "ondemand",
};
/*** delete after deprecation time ***/
#define write_one_old(file_name) \
static ssize_t store_##file_name##_old \
(struct cpufreq_policy *unused, const char *buf, size_t count) \
{ \
printk_once(KERN_INFO "CPUFREQ: Per core ondemand sysfs " \
"interface is deprecated - " #file_name "\n"); \
return store_##file_name(NULL, NULL, buf, count); \
}
write_one_old(sampling_rate);
write_one_old(up_threshold);
write_one_old(ignore_nice_load);
write_one_old(powersave_bias);
#define define_one_rw_old(object, _name) \
static struct freq_attr object = \
__ATTR(_name, 0644, show_##_name##_old, store_##_name##_old)
define_one_rw_old(sampling_rate_old, sampling_rate);
define_one_rw_old(up_threshold_old, up_threshold);
define_one_rw_old(ignore_nice_load_old, ignore_nice_load);
define_one_rw_old(powersave_bias_old, powersave_bias);
static struct attribute *dbs_attributes_old[] = {
&sampling_rate_max_old.attr,
&sampling_rate_min_old.attr,
&sampling_rate_old.attr,
&up_threshold_old.attr,
&ignore_nice_load_old.attr,
&powersave_bias_old.attr,
NULL
};
static struct attribute_group dbs_attr_group_old = {
.attrs = dbs_attributes_old,
.name = "ondemand",
};
/*** delete after deprecation time ***/
/************************** sysfs end ************************/
static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
@@ -545,7 +631,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
mutex_lock(&dbs_mutex);
rc = sysfs_create_group(&policy->kobj, &dbs_attr_group);
rc = sysfs_create_group(&policy->kobj, &dbs_attr_group_old);
if (rc) {
mutex_unlock(&dbs_mutex);
return rc;
@@ -566,13 +652,20 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
}
this_dbs_info->cpu = cpu;
ondemand_powersave_bias_init_cpu(cpu);
mutex_init(&this_dbs_info->timer_mutex);
/*
* Start the timerschedule work, when this governor
* is used for first time
*/
if (dbs_enable == 1) {
unsigned int latency;
rc = sysfs_create_group(cpufreq_global_kobject,
&dbs_attr_group);
if (rc) {
mutex_unlock(&dbs_mutex);
return rc;
}
/* policy latency is in nS. Convert it to uS first */
latency = policy->cpuinfo.transition_latency / 1000;
if (latency == 0)
@@ -586,6 +679,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
}
mutex_unlock(&dbs_mutex);
mutex_init(&this_dbs_info->timer_mutex);
dbs_timer_init(this_dbs_info);
break;
@@ -593,10 +687,13 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
dbs_timer_exit(this_dbs_info);
mutex_lock(&dbs_mutex);
sysfs_remove_group(&policy->kobj, &dbs_attr_group);
sysfs_remove_group(&policy->kobj, &dbs_attr_group_old);
mutex_destroy(&this_dbs_info->timer_mutex);
dbs_enable--;
mutex_unlock(&dbs_mutex);
if (!dbs_enable)
sysfs_remove_group(cpufreq_global_kobject,
&dbs_attr_group);
break;
@@ -614,16 +711,6 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
return 0;
}
#ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND
static
#endif
struct cpufreq_governor cpufreq_gov_ondemand = {
.name = "ondemand",
.governor = cpufreq_governor_dbs,
.max_transition_latency = TRANSITION_LATENCY_LIMIT,
.owner = THIS_MODULE,
};
static int __init cpufreq_gov_dbs_init(void)
{
int err;