Ingo Molnar a263898f62 CPU hotplug: fix cpu_is_offline() on !CONFIG_HOTPLUG_CPU
make randconfig bootup testing found that the cpufreq code
crashes on bootup, if the powernow-k8 driver is enabled and
if maxcpus=1 passed on the boot line to a !CONFIG_HOTPLUG_CPU
kernel.

First lockdep found out that there's an inconsistent unlock
sequence:

 =====================================
 [ BUG: bad unlock balance detected! ]
 -------------------------------------
 swapper/1 is trying to release lock (&per_cpu(cpu_policy_rwsem, cpu)) at:
 [<ffffffff806ffd8e>] unlock_policy_rwsem_write+0x3c/0x42
 but there are no more locks to release!

Call Trace:
 [<ffffffff806ffd8e>] unlock_policy_rwsem_write+0x3c/0x42
 [<ffffffff80251c29>] print_unlock_inbalance_bug+0x104/0x12c
 [<ffffffff80252f3a>] mark_held_locks+0x56/0x94
 [<ffffffff806ffd8e>] unlock_policy_rwsem_write+0x3c/0x42
 [<ffffffff807008b6>] cpufreq_add_dev+0x2a8/0x5c4
 ...

then shortly afterwards the cpufreq code crashed on an assert:

 ------------[ cut here ]------------
 kernel BUG at drivers/cpufreq/cpufreq.c:1068!
 invalid opcode: 0000 [1] SMP
 [...]
 Call Trace:
  [<ffffffff805145d6>] sysdev_driver_unregister+0x5b/0x91
  [<ffffffff806ff520>] cpufreq_register_driver+0x15d/0x1a2
  [<ffffffff80cc0596>] powernowk8_init+0x86/0x94
 [...]
 ---[ end trace 1e9219be2b4431de ]---

the bug was caused by maxcpus=1 bootup, which brought up the
secondary core as !cpu_online() but !cpu_is_offline() either,
which on on !CONFIG_HOTPLUG_CPU is always 0 (include/linux/cpu.h):

  /* CPUs don't go offline once they're online w/o CONFIG_HOTPLUG_CPU */
  static inline int cpu_is_offline(int cpu) { return 0; }

but the cpufreq code uses cpu_online() and cpu_is_offline() in
a mixed way - the low-level drivers use cpu_online(), while
the cpufreq core uses cpu_is_offline(). This opened up the
possibility to add the non-initialized sysdev device of the
secondary core:

 cpufreq-core: trying to register driver powernow-k8
 cpufreq-core: adding CPU 0
 powernow-k8: BIOS error - no PSB or ACPI _PSS objects
 cpufreq-core: initialization failed
 cpufreq-core: adding CPU 1
 cpufreq-core: initialization failed

which then blew up. The fix is to make cpu_is_offline() always
the negation of cpu_online(). With that fix applied the kernel
boots up fine without crashing:

 Calling initcall 0xffffffff80cc0510: powernowk8_init+0x0/0x94()
 powernow-k8: Found 1 AMD Athlon(tm) 64 X2 Dual Core Processor 3800+ processors (1 cpu cores) (version 2.20.00)
 powernow-k8: BIOS error - no PSB or ACPI _PSS objects
 initcall 0xffffffff80cc0510: powernowk8_init+0x0/0x94() returned -19.
 initcall 0xffffffff80cc0510 ran for 19 msecs: powernowk8_init+0x0/0x94()
 Calling initcall 0xffffffff80cc328f: init_lapic_nmi_sysfs+0x0/0x39()

We could fix this by making CPU enumeration aware of max_cpus, but that
would be more fragile IMO, and the cpu_online(cpu) != cpu_is_offline(cpu)
possibility was quite confusing and a continuous source of bugs too.

Most distributions have kernels with CPU hotplug enabled, so this bug
remained hidden for a long time.

Bug forensics:

The broken cpu_is_offline() API variant was introduced via:

 commit a59d2e4e6977e7b94e003c96a41f07e96cddc340
 Author: Rusty Russell <rusty@rustcorp.com.au>
 Date:   Mon Mar 8 06:06:03 2004 -0800

     [PATCH] minor cleanups for hotplug CPUs

( this predates linux-2.6.git, this commit is available from Thomas's
  historic git tree. )

Then 1.5 years later the cpufreq code made use of it:

 commit c32b6b8e524d2c337767d312814484d9289550cf
 Author: Ashok Raj <ashok.raj@intel.com>
 Date:   Sun Oct 30 14:59:54 2005 -0800

     [PATCH] create and destroy cpufreq sysfs entries based on cpu notifiers

 +       if (cpu_is_offline(cpu))
 +               return 0;

which is a correct use of the subtly broken new API. v2.6.15 then
shipped with this bug included.

then it took two more years for random-kernel qa to hit it.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2008-01-06 12:39:42 -08:00
..
2006-09-26 17:40:24 -04:00
2007-10-14 20:17:39 -07:00
2007-10-17 08:43:03 -07:00
2007-12-26 19:36:35 -08:00
2007-10-15 17:56:36 -07:00
2006-12-04 02:00:22 -05:00
2007-09-11 04:22:16 -07:00
2007-10-18 14:37:20 -07:00
2007-10-10 16:51:59 -07:00
2007-12-17 20:33:12 -05:00
2006-12-02 21:22:55 -08:00
2006-12-02 21:22:55 -08:00
2007-10-21 02:37:45 -04:00
2007-02-20 17:10:15 -08:00
2007-10-17 08:42:45 -07:00
2007-10-17 08:43:07 -07:00
2007-10-18 14:37:29 -07:00
2007-10-19 11:53:42 -07:00
2007-10-19 11:53:42 -07:00
2006-12-08 08:28:39 -08:00
2006-12-07 08:39:20 -08:00
2007-07-31 10:43:05 -05:00
2007-10-16 09:42:58 -07:00
2007-01-30 08:26:45 -08:00
2007-10-20 03:10:57 +02:00
2007-10-19 11:53:36 -07:00
2007-10-19 11:53:36 -07:00
2007-07-10 17:18:59 -07:00
2007-10-16 09:43:13 -07:00
2007-10-17 08:42:52 -07:00
2007-11-19 21:43:22 -05:00
2007-07-17 10:23:04 -07:00
2007-05-10 18:24:13 +02:00
2007-10-19 23:07:36 +02:00
2007-10-16 09:43:09 -07:00
2007-10-21 02:37:45 -04:00
2007-10-19 11:53:36 -07:00
2007-12-20 17:32:12 +00:00
2007-05-08 11:15:26 -07:00
2007-07-09 08:22:54 +01:00
2007-07-09 08:23:17 +01:00
2007-10-20 02:00:58 +01:00
2007-10-18 14:37:21 -07:00
2007-02-09 17:39:36 -05:00
2007-02-11 11:18:07 -08:00
2007-07-19 10:04:54 -07:00
2007-10-22 08:13:19 -07:00
2007-10-22 08:13:20 -07:00
2007-10-17 08:42:51 -07:00
2007-06-01 08:18:29 -07:00
2007-10-29 07:41:32 -07:00
2007-10-22 08:13:21 -07:00
2007-10-17 08:43:02 -07:00
2007-05-09 08:57:56 +02:00
2007-10-17 08:42:48 -07:00
2007-10-17 08:43:01 -07:00
2007-07-18 18:29:37 -04:00
2007-11-29 09:24:54 -08:00
2006-10-02 07:57:12 -07:00
2007-07-10 00:35:17 -04:00
2007-07-09 18:51:58 +02:00
2007-04-28 11:01:07 -04:00
2007-10-19 11:53:42 -07:00
2007-07-19 10:04:41 -07:00
2007-03-16 00:59:29 -04:00
2006-12-10 21:21:29 +01:00
2007-11-15 19:24:02 +01:00
2007-10-16 11:21:00 +02:00
2007-10-22 00:56:52 -04:00
2007-07-16 09:05:34 -07:00
2007-10-10 16:51:59 -07:00
2007-10-17 08:42:52 -07:00
2007-07-14 18:55:06 -07:00
2007-10-10 16:52:04 -07:00
2007-04-25 22:24:41 -07:00
2007-04-25 22:29:10 -07:00
2006-09-28 18:02:29 -07:00
2007-12-05 05:37:32 -08:00
2007-07-16 09:05:50 -07:00
2006-10-10 15:37:22 -07:00
2007-10-16 09:43:01 -07:00
2006-12-02 21:21:21 -08:00
2006-12-07 08:39:47 -08:00
2007-10-18 14:37:32 -07:00
2006-10-04 00:31:09 -07:00
2006-11-30 05:24:39 +01:00
2007-07-11 15:03:53 +01:00
2007-04-25 22:25:52 -07:00
2007-10-16 09:42:49 -07:00
2007-11-05 15:12:32 -08:00
2007-10-17 08:42:52 -07:00
2007-12-26 19:36:35 -08:00
2007-11-29 09:24:52 -08:00
2007-10-17 08:43:01 -07:00
2007-10-19 11:53:49 -07:00
2007-07-18 08:47:40 -07:00
2007-10-12 14:51:12 -07:00
2007-10-16 09:43:10 -07:00
2007-05-09 12:30:53 -07:00
2007-10-13 10:18:29 +02:00
2007-12-07 09:06:53 +00:00
2007-10-25 15:02:50 +10:00
2007-10-25 15:02:50 +10:00
2007-12-17 20:43:28 -05:00
2007-07-17 10:23:03 -07:00
2007-07-17 10:23:13 -07:00
2007-07-24 12:24:59 -07:00
2007-07-16 09:05:34 -07:00
2007-07-18 08:47:45 -07:00
2007-10-19 11:53:55 -07:00
2007-05-09 12:30:49 -07:00
2007-10-10 16:54:03 -07:00
2007-05-03 10:52:22 +03:00
2007-10-23 15:49:54 +10:00
2007-10-19 11:53:54 -07:00
2006-11-30 04:40:22 +01:00
2007-07-16 09:05:42 -07:00
2007-10-19 11:53:44 -07:00
2007-01-23 00:34:54 -05:00
2007-07-16 09:05:51 -07:00
2007-11-07 04:15:12 -08:00
2007-05-09 12:30:54 -07:00
2007-10-09 17:15:11 -04:00
2007-10-17 08:42:58 -07:00
2006-08-27 11:01:32 -07:00
2007-10-19 11:53:34 -07:00
2007-05-04 17:59:07 -07:00
2007-10-19 11:53:41 -07:00
2007-10-16 09:43:02 -07:00
2007-05-08 11:15:05 -07:00
2007-05-05 14:15:32 -07:00
2007-12-12 20:01:00 +01:00
2007-10-17 08:42:44 -07:00
2007-10-19 11:53:41 -07:00
2007-10-19 11:53:41 -07:00
2007-04-17 16:36:26 -07:00
2007-07-26 11:35:21 -07:00
2006-10-03 23:01:26 +02:00
2007-07-16 09:05:50 -07:00
2007-10-19 11:53:41 -07:00
2007-12-05 09:21:20 -08:00
2007-10-17 08:42:45 -07:00
2007-10-17 08:42:56 -07:00
2007-10-16 09:42:53 -07:00
2007-07-18 08:47:40 -07:00
2007-10-22 08:13:20 -07:00
2007-07-21 18:37:10 -07:00
2007-05-17 05:23:06 -07:00
2007-11-29 09:24:54 -08:00
2007-11-27 09:30:39 +01:00
2007-07-16 09:05:50 -07:00
2007-10-16 09:43:17 -07:00
2007-10-19 11:53:44 -07:00
2007-11-29 09:24:53 -08:00
2007-10-19 11:53:44 -07:00
2007-07-22 11:03:37 -07:00
2007-10-17 08:43:01 -07:00
2008-01-02 13:04:48 -08:00
2008-01-02 13:04:48 -08:00
2008-01-02 13:04:48 -08:00
2007-02-20 17:10:14 -08:00
2007-05-21 21:47:27 -07:00
2007-11-09 22:39:38 +01:00
2007-07-16 09:05:46 -07:00
2007-07-19 10:04:49 -07:00
2007-07-16 09:05:40 -07:00
2007-05-08 11:15:18 -07:00
2006-10-01 00:39:18 -07:00
2007-05-09 12:30:57 -07:00
2007-02-20 17:10:13 -08:00
2007-05-11 08:29:34 -07:00
2007-10-12 14:51:12 -07:00
2007-10-15 12:59:43 -07:00
2006-11-30 05:32:19 +01:00
2007-10-17 08:42:53 -07:00
2007-05-11 08:29:36 -07:00
2007-11-26 20:42:19 +01:00
2006-12-02 21:21:08 -08:00
2006-09-28 17:53:59 -07:00
2007-05-11 08:29:35 -07:00
2007-05-11 08:29:35 -07:00
2007-10-29 07:41:33 -07:00
2007-07-18 15:57:15 -07:00
2006-12-15 08:47:51 -08:00
2007-12-17 10:47:15 -08:00
2007-09-19 11:24:18 -07:00
2006-10-01 00:39:19 -07:00
2007-12-26 19:36:35 -08:00
2007-10-23 13:47:31 -05:00
2007-10-23 15:49:54 +10:00
2007-10-23 15:49:54 +10:00
2007-10-23 15:49:55 +10:00
2007-10-23 15:49:54 +10:00
2007-10-23 15:49:54 +10:00
2007-07-17 10:22:59 -07:00
2007-10-17 08:42:56 -07:00
2007-10-19 11:53:34 -07:00
2007-07-09 18:52:01 +02:00
2007-10-17 08:43:02 -07:00
2007-02-11 11:18:05 -08:00
2007-05-04 12:55:39 -07:00