Skip to content

Commit b4b21ca

Browse files
committed
Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/davej/cpufreq
* 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/davej/cpufreq: [CPUFREQ] Powernow-k8: support family 0xf with 2 low p-states [CPUFREQ] fix (utter) cpufreq_add_dev mess [CPUFREQ] Cleanup locking in conservative governor [CPUFREQ] Cleanup locking in ondemand governor [CPUFREQ] Mark policy_rwsem as going static in cpufreq.c wont be exported [CPUFREQ] Eliminate the recent lockdep warnings in cpufreq
2 parents 728b690 + a2e1b4c commit b4b21ca

File tree

6 files changed

+115
-123
lines changed

6 files changed

+115
-123
lines changed

Documentation/feature-removal-schedule.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,3 +458,13 @@ Why: Remove the old legacy 32bit machine check code. This has been
458458
but the old version has been kept around for easier testing. Note this
459459
doesn't impact the old P5 and WinChip machine check handlers.
460460
Who: Andi Kleen <andi@firstfloor.org>
461+
462+
----------------------------
463+
464+
What: lock_policy_rwsem_* and unlock_policy_rwsem_* will not be
465+
exported interface anymore.
466+
When: 2.6.33
467+
Why: cpu_policy_rwsem has a new cleaner definition making it local to
468+
cpufreq core and contained inside cpufreq.c. Other dependent
469+
drivers should not use it in order to safely avoid lockdep issues.
470+
Who: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>

arch/x86/kernel/cpu/cpufreq/powernow-k8.c

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ static int transition_pstate(struct powernow_k8_data *data, u32 pstate)
299299
static int transition_fid_vid(struct powernow_k8_data *data,
300300
u32 reqfid, u32 reqvid)
301301
{
302-
if (core_voltage_pre_transition(data, reqvid))
302+
if (core_voltage_pre_transition(data, reqvid, reqfid))
303303
return 1;
304304

305305
if (core_frequency_transition(data, reqfid))
@@ -327,17 +327,20 @@ static int transition_fid_vid(struct powernow_k8_data *data,
327327

328328
/* Phase 1 - core voltage transition ... setup voltage */
329329
static int core_voltage_pre_transition(struct powernow_k8_data *data,
330-
u32 reqvid)
330+
u32 reqvid, u32 reqfid)
331331
{
332332
u32 rvosteps = data->rvo;
333333
u32 savefid = data->currfid;
334-
u32 maxvid, lo;
334+
u32 maxvid, lo, rvomult = 1;
335335

336336
dprintk("ph1 (cpu%d): start, currfid 0x%x, currvid 0x%x, "
337337
"reqvid 0x%x, rvo 0x%x\n",
338338
smp_processor_id(),
339339
data->currfid, data->currvid, reqvid, data->rvo);
340340

341+
if ((savefid < LO_FID_TABLE_TOP) && (reqfid < LO_FID_TABLE_TOP))
342+
rvomult = 2;
343+
rvosteps *= rvomult;
341344
rdmsr(MSR_FIDVID_STATUS, lo, maxvid);
342345
maxvid = 0x1f & (maxvid >> 16);
343346
dprintk("ph1 maxvid=0x%x\n", maxvid);
@@ -351,7 +354,8 @@ static int core_voltage_pre_transition(struct powernow_k8_data *data,
351354
return 1;
352355
}
353356

354-
while ((rvosteps > 0) && ((data->rvo + data->currvid) > reqvid)) {
357+
while ((rvosteps > 0) &&
358+
((rvomult * data->rvo + data->currvid) > reqvid)) {
355359
if (data->currvid == maxvid) {
356360
rvosteps = 0;
357361
} else {
@@ -384,13 +388,6 @@ static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid)
384388
u32 vcoreqfid, vcocurrfid, vcofiddiff;
385389
u32 fid_interval, savevid = data->currvid;
386390

387-
if ((reqfid < HI_FID_TABLE_BOTTOM) &&
388-
(data->currfid < HI_FID_TABLE_BOTTOM)) {
389-
printk(KERN_ERR PFX "ph2: illegal lo-lo transition "
390-
"0x%x 0x%x\n", reqfid, data->currfid);
391-
return 1;
392-
}
393-
394391
if (data->currfid == reqfid) {
395392
printk(KERN_ERR PFX "ph2 null fid transition 0x%x\n",
396393
data->currfid);
@@ -407,6 +404,9 @@ static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid)
407404
vcofiddiff = vcocurrfid > vcoreqfid ? vcocurrfid - vcoreqfid
408405
: vcoreqfid - vcocurrfid;
409406

407+
if ((reqfid <= LO_FID_TABLE_TOP) && (data->currfid <= LO_FID_TABLE_TOP))
408+
vcofiddiff = 0;
409+
410410
while (vcofiddiff > 2) {
411411
(data->currfid & 1) ? (fid_interval = 1) : (fid_interval = 2);
412412

@@ -1081,14 +1081,6 @@ static int transition_frequency_fidvid(struct powernow_k8_data *data,
10811081
return 0;
10821082
}
10831083

1084-
if ((fid < HI_FID_TABLE_BOTTOM) &&
1085-
(data->currfid < HI_FID_TABLE_BOTTOM)) {
1086-
printk(KERN_ERR PFX
1087-
"ignoring illegal change in lo freq table-%x to 0x%x\n",
1088-
data->currfid, fid);
1089-
return 1;
1090-
}
1091-
10921084
dprintk("cpu %d, changing to fid 0x%x, vid 0x%x\n",
10931085
smp_processor_id(), fid, vid);
10941086
freqs.old = find_khz_freq_from_fid(data->currfid);

arch/x86/kernel/cpu/cpufreq/powernow-k8.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,8 @@ struct pst_s {
215215

216216
#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "powernow-k8", msg)
217217

218-
static int core_voltage_pre_transition(struct powernow_k8_data *data, u32 reqvid);
218+
static int core_voltage_pre_transition(struct powernow_k8_data *data,
219+
u32 reqvid, u32 regfid);
219220
static int core_voltage_post_transition(struct powernow_k8_data *data, u32 reqvid);
220221
static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid);
221222

drivers/cpufreq/cpufreq.c

Lines changed: 42 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,10 @@ static struct kobj_type ktype_cpufreq = {
761761
* cpufreq_add_dev - add a CPU device
762762
*
763763
* Adds the cpufreq interface for a CPU device.
764+
*
765+
* The Oracle says: try running cpufreq registration/unregistration concurrently
766+
* with with cpu hotplugging and all hell will break loose. Tried to clean this
767+
* mess up, but more thorough testing is needed. - Mathieu
764768
*/
765769
static int cpufreq_add_dev(struct sys_device *sys_dev)
766770
{
@@ -804,23 +808,21 @@ static int cpufreq_add_dev(struct sys_device *sys_dev)
804808
goto nomem_out;
805809
}
806810
if (!alloc_cpumask_var(&policy->cpus, GFP_KERNEL)) {
807-
kfree(policy);
808811
ret = -ENOMEM;
809-
goto nomem_out;
812+
goto err_free_policy;
810813
}
811814
if (!zalloc_cpumask_var(&policy->related_cpus, GFP_KERNEL)) {
812-
free_cpumask_var(policy->cpus);
813-
kfree(policy);
814815
ret = -ENOMEM;
815-
goto nomem_out;
816+
goto err_free_cpumask;
816817
}
817818

818819
policy->cpu = cpu;
819820
cpumask_copy(policy->cpus, cpumask_of(cpu));
820821

821822
/* Initially set CPU itself as the policy_cpu */
822823
per_cpu(policy_cpu, cpu) = cpu;
823-
lock_policy_rwsem_write(cpu);
824+
ret = (lock_policy_rwsem_write(cpu) < 0);
825+
WARN_ON(ret);
824826

825827
init_completion(&policy->kobj_unregister);
826828
INIT_WORK(&policy->update, handle_update);
@@ -833,7 +835,7 @@ static int cpufreq_add_dev(struct sys_device *sys_dev)
833835
ret = cpufreq_driver->init(policy);
834836
if (ret) {
835837
dprintk("initialization failed\n");
836-
goto err_out;
838+
goto err_unlock_policy;
837839
}
838840
policy->user_policy.min = policy->min;
839841
policy->user_policy.max = policy->max;
@@ -858,15 +860,21 @@ static int cpufreq_add_dev(struct sys_device *sys_dev)
858860
/* Check for existing affected CPUs.
859861
* They may not be aware of it due to CPU Hotplug.
860862
*/
861-
managed_policy = cpufreq_cpu_get(j); /* FIXME: Where is this released? What about error paths? */
863+
managed_policy = cpufreq_cpu_get(j);
862864
if (unlikely(managed_policy)) {
863865

864866
/* Set proper policy_cpu */
865867
unlock_policy_rwsem_write(cpu);
866868
per_cpu(policy_cpu, cpu) = managed_policy->cpu;
867869

868-
if (lock_policy_rwsem_write(cpu) < 0)
869-
goto err_out_driver_exit;
870+
if (lock_policy_rwsem_write(cpu) < 0) {
871+
/* Should not go through policy unlock path */
872+
if (cpufreq_driver->exit)
873+
cpufreq_driver->exit(policy);
874+
ret = -EBUSY;
875+
cpufreq_cpu_put(managed_policy);
876+
goto err_free_cpumask;
877+
}
870878

871879
spin_lock_irqsave(&cpufreq_driver_lock, flags);
872880
cpumask_copy(managed_policy->cpus, policy->cpus);
@@ -877,12 +885,14 @@ static int cpufreq_add_dev(struct sys_device *sys_dev)
877885
ret = sysfs_create_link(&sys_dev->kobj,
878886
&managed_policy->kobj,
879887
"cpufreq");
880-
if (ret)
881-
goto err_out_driver_exit;
882-
883-
cpufreq_debug_enable_ratelimit();
884-
ret = 0;
885-
goto err_out_driver_exit; /* call driver->exit() */
888+
if (!ret)
889+
cpufreq_cpu_put(managed_policy);
890+
/*
891+
* Success. We only needed to be added to the mask.
892+
* Call driver->exit() because only the cpu parent of
893+
* the kobj needed to call init().
894+
*/
895+
goto out_driver_exit; /* call driver->exit() */
886896
}
887897
}
888898
#endif
@@ -892,25 +902,25 @@ static int cpufreq_add_dev(struct sys_device *sys_dev)
892902
ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq, &sys_dev->kobj,
893903
"cpufreq");
894904
if (ret)
895-
goto err_out_driver_exit;
905+
goto out_driver_exit;
896906

897907
/* set up files for this cpu device */
898908
drv_attr = cpufreq_driver->attr;
899909
while ((drv_attr) && (*drv_attr)) {
900910
ret = sysfs_create_file(&policy->kobj, &((*drv_attr)->attr));
901911
if (ret)
902-
goto err_out_driver_exit;
912+
goto err_out_kobj_put;
903913
drv_attr++;
904914
}
905915
if (cpufreq_driver->get) {
906916
ret = sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr);
907917
if (ret)
908-
goto err_out_driver_exit;
918+
goto err_out_kobj_put;
909919
}
910920
if (cpufreq_driver->target) {
911921
ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr);
912922
if (ret)
913-
goto err_out_driver_exit;
923+
goto err_out_kobj_put;
914924
}
915925

916926
spin_lock_irqsave(&cpufreq_driver_lock, flags);
@@ -928,12 +938,14 @@ static int cpufreq_add_dev(struct sys_device *sys_dev)
928938
continue;
929939

930940
dprintk("CPU %u already managed, adding link\n", j);
931-
cpufreq_cpu_get(cpu);
941+
managed_policy = cpufreq_cpu_get(cpu);
932942
cpu_sys_dev = get_cpu_sysdev(j);
933943
ret = sysfs_create_link(&cpu_sys_dev->kobj, &policy->kobj,
934944
"cpufreq");
935-
if (ret)
945+
if (ret) {
946+
cpufreq_cpu_put(managed_policy);
936947
goto err_out_unregister;
948+
}
937949
}
938950

939951
policy->governor = NULL; /* to assure that the starting sequence is
@@ -965,17 +977,20 @@ static int cpufreq_add_dev(struct sys_device *sys_dev)
965977
per_cpu(cpufreq_cpu_data, j) = NULL;
966978
spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
967979

980+
err_out_kobj_put:
968981
kobject_put(&policy->kobj);
969982
wait_for_completion(&policy->kobj_unregister);
970983

971-
err_out_driver_exit:
984+
out_driver_exit:
972985
if (cpufreq_driver->exit)
973986
cpufreq_driver->exit(policy);
974987

975-
err_out:
988+
err_unlock_policy:
976989
unlock_policy_rwsem_write(cpu);
990+
err_free_cpumask:
991+
free_cpumask_var(policy->cpus);
992+
err_free_policy:
977993
kfree(policy);
978-
979994
nomem_out:
980995
module_put(cpufreq_driver->owner);
981996
module_out:
@@ -1070,8 +1085,6 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev)
10701085
spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
10711086
#endif
10721087

1073-
unlock_policy_rwsem_write(cpu);
1074-
10751088
if (cpufreq_driver->target)
10761089
__cpufreq_governor(data, CPUFREQ_GOV_STOP);
10771090

@@ -1088,6 +1101,8 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev)
10881101
if (cpufreq_driver->exit)
10891102
cpufreq_driver->exit(data);
10901103

1104+
unlock_policy_rwsem_write(cpu);
1105+
10911106
free_cpumask_var(data->related_cpus);
10921107
free_cpumask_var(data->cpus);
10931108
kfree(data);

0 commit comments

Comments
 (0)