On an pre-F12 based Fedora system, echo 0 > /sys/devices/system/cpu/cpu4/online service cpuspeed stop service cpupseed start echo 1 > /sys/devices/system/cpu/cpu4/online results in BUG: unable to handle kernel NULL pointer dereference at (null) IP: [<(null)>] (null) PGD 409cab067 PUD 409c84067 PMD 0 Oops: 0010 [#1] SMP last sysfs file: /sys/devices/system/cpu/cpu6/online CPU 5 Modules linked in: cpufreq_ondemand nfs fscache ipt_MASQUERADE iptable_nat nf_nat bridge stp llc nfsd lockd nfs_acl auth_rpcgss exportfs sunrpc xt_physdev ip6t_REJECT nf_conntrack_ipv6 ip6table_filter ip6_tables ipv6 acpi_cpufreq freq_table dm_multipath i5k_amb hwmon ata_generic qla2xxx pata_acpi iTCO_wdt scsi_transport_fc bnx2 iTCO_vendor_support scsi_tgt i5000_edac ses ata_piix enclosure edac_core dcdbas pcspkr serio_raw joydev dm_snapshot dm_zero dm_mirror dm_region_hash dm_log dm_mod shpchp megaraid_sas radeon ttm drm_kms_helper drm i2c_algo_bit i2c_core [last unloaded: cpufreq_ondemand] Pid: 5508, comm: bash Not tainted 2.6.32-rc5 #1 PowerEdge 1950 RIP: 0010:[<0000000000000000>] [<(null)>] (null) RSP: 0018:ffff88042c463a80 EFLAGS: 00010296 RAX: ffffffffa021c4a0 RBX: ffff88042ab39da8 RCX: 0000000000000006 RDX: ffffffff816afbb7 RSI: 0000000000000001 RDI: ffff88042ab39da8 RBP: ffff88042c463ab8 R08: 0000000000000001 R09: 00000000e531e4a0 R10: ffffffff81e9cb60 R11: ffff88042c463a48 R12: 0000000000000001 R13: 00000000ffffffea R14: 0000000000000000 R15: 00000000001daaa0 FS: 00007f3b46040700(0000) GS:ffff880043400000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000000 CR3: 0000000409ca8000 CR4: 00000000000006e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 Process bash (pid: 5508, threadinfo ffff88042c462000, task ffff88042227d940) Stack: ffffffff813e2508 00000000002dc6c0 00000000e531e4a0 ffff88042c463ab8 <0> ffff88042ab39da8 ffff88042c463b18 0000000000000000 ffff88042c463af8 <0> ffffffff813e35b8 ffff88042c463af8 00000000e531e4a0 ffff88042ab39da8 Call Trace: [<ffffffff813e2508>] ? __cpufreq_governor+0x93/0xe7 [<ffffffff813e35b8>] __cpufreq_set_policy+0x1bb/0x24d [<ffffffff813e37d2>] cpufreq_add_dev_interface+0x188/0x212 [<ffffffff813e3cd7>] ? handle_update+0x0/0x57 [<ffffffff813e442d>] cpufreq_add_dev+0x269/0x370 [<ffffffff814c85a5>] cpufreq_cpu_callback+0x7b/0x9f [<ffffffff814d0e3a>] notifier_call_chain+0x72/0xba [<ffffffff81084b18>] raw_notifier_call_chain+0x22/0x38 [<ffffffff814c69bb>] _cpu_up+0xef/0x152 [<ffffffff814c6a88>] cpu_up+0x6a/0x8b [<ffffffff814b7ac1>] store_online+0x5b/0x96 [<ffffffff8133229d>] sysdev_store+0x2e/0x44 [<ffffffff81197471>] sysfs_write_file+0x105/0x155 [<ffffffff811322ee>] vfs_write+0xb8/0x129 [<ffffffff81132447>] sys_write+0x54/0x8c [<ffffffff81011e02>] system_call_fastpath+0x16/0x1b Code: Bad RIP value. RIP [<(null)>] (null) RSP <ffff88042c463a80> CR2: 0000000000000000 ---[ end trace b2117a324130d450 ]--- This happens because the per_cpu element cpufreq_cpu_governor becomes stale after the cpuspeed service is stopped and the governor is unregistered. 1. When a governor is unregistered, go through the cpufreq_cpu_governor values and NULL out those corresponding to the governor. 2. After a cpu is brought up, the CPUFREQ_DEFAULT_GOVERNOR is automatically selected by the kernel. However, it is possible that the governor being used by the cpu's siblings is not the default governor. In the hotplug case, the other siblings should be queried in order to determine what they are using as a governor, and then that governor should be used for the current cpu. Signed-off-by: Prarit Bhargava <prarit@xxxxxxxxxx> diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 2968ed6..4ac4237 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -769,13 +769,16 @@ static struct kobj_type ktype_cpufreq = { static int cpufreq_add_dev(struct sys_device *sys_dev) { unsigned int cpu = sys_dev->id; - int ret = 0; + int ret = 0, found = 0; struct cpufreq_policy new_policy; struct cpufreq_policy *policy; struct freq_attr **drv_attr; struct sys_device *cpu_sys_dev; unsigned long flags; unsigned int j; +#ifdef CONFIG_HOTPLUG_CPU + int sibling; +#endif if (cpu_is_offline(cpu)) return 0; @@ -825,7 +828,19 @@ static int cpufreq_add_dev(struct sys_device *sys_dev) INIT_WORK(&policy->update, handle_update); /* Set governor before ->init, so that driver could check it */ - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; +#ifdef CONFIG_HOTPLUG_CPU + for_each_online_cpu(sibling) { + struct cpufreq_policy *cp = per_cpu(cpufreq_cpu_data, sibling); + if (cp && cp->governor && + (cpumask_test_cpu(cpu, cp->related_cpus))) { + policy->governor = cp->governor; + found = 1; + break; + } + } +#endif + if (!found) + 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 */ @@ -1550,9 +1565,22 @@ EXPORT_SYMBOL_GPL(cpufreq_register_governor); void cpufreq_unregister_governor(struct cpufreq_governor *governor) { + int cpu; + struct cpufreq_governor * cg; + if (!governor) return; +#if CONFIG_HOTPLUG_CPU + for_each_present_cpu(cpu) { + if (cpu_online(cpu)) + continue; + cg = per_cpu(cpufreq_cpu_governor, cpu); + if (cg && !strcmp(cg->name, governor->name)) + per_cpu(cpufreq_cpu_governor, cpu) = NULL; + } +#endif + mutex_lock(&cpufreq_governor_mutex); list_del(&governor->governor_list); mutex_unlock(&cpufreq_governor_mutex); -- To unsubscribe from this list: send the line "unsubscribe cpufreq" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html