diff options
| author | Pekka Paalanen <pq@iki.fi> | 2008-05-12 15:21:01 -0400 |
|---|---|---|
| committer | Thomas Gleixner <tglx@linutronix.de> | 2008-05-23 15:56:52 -0400 |
| commit | 2f1dafe50cc4e58a239fd81bd47f87f32042a1ee (patch) | |
| tree | 2a5a5653c37ac4846889404bad4142a1a1edbeaa | |
| parent | 107bad8bef5ab2c3a3bff7648c18c9dc3abdc13b (diff) | |
x86: fix SMP alternatives: use mutex instead of spinlock, text_poke is sleepable
text_poke is sleepable.
The original fix by Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>.
Signed-off-by: Pekka Paalanen <pq@iki.fi>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
| -rw-r--r-- | arch/x86/kernel/alternative.c | 18 |
1 files changed, 9 insertions, 9 deletions
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index de240ba2e288..2763cb37b553 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | #include <linux/module.h> | 1 | #include <linux/module.h> |
| 2 | #include <linux/sched.h> | 2 | #include <linux/sched.h> |
| 3 | #include <linux/spinlock.h> | 3 | #include <linux/mutex.h> |
| 4 | #include <linux/list.h> | 4 | #include <linux/list.h> |
| 5 | #include <linux/kprobes.h> | 5 | #include <linux/kprobes.h> |
| 6 | #include <linux/mm.h> | 6 | #include <linux/mm.h> |
| @@ -279,7 +279,7 @@ struct smp_alt_module { | |||
| 279 | struct list_head next; | 279 | struct list_head next; |
| 280 | }; | 280 | }; |
| 281 | static LIST_HEAD(smp_alt_modules); | 281 | static LIST_HEAD(smp_alt_modules); |
| 282 | static DEFINE_SPINLOCK(smp_alt); | 282 | static DEFINE_MUTEX(smp_alt); |
| 283 | static int smp_mode = 1; /* protected by smp_alt */ | 283 | static int smp_mode = 1; /* protected by smp_alt */ |
| 284 | 284 | ||
| 285 | void alternatives_smp_module_add(struct module *mod, char *name, | 285 | void alternatives_smp_module_add(struct module *mod, char *name, |
| @@ -312,12 +312,12 @@ void alternatives_smp_module_add(struct module *mod, char *name, | |||
| 312 | __func__, smp->locks, smp->locks_end, | 312 | __func__, smp->locks, smp->locks_end, |
| 313 | smp->text, smp->text_end, smp->name); | 313 | smp->text, smp->text_end, smp->name); |
| 314 | 314 | ||
| 315 | spin_lock(&smp_alt); | 315 | mutex_lock(&smp_alt); |
| 316 | list_add_tail(&smp->next, &smp_alt_modules); | 316 | list_add_tail(&smp->next, &smp_alt_modules); |
| 317 | if (boot_cpu_has(X86_FEATURE_UP)) | 317 | if (boot_cpu_has(X86_FEATURE_UP)) |
| 318 | alternatives_smp_unlock(smp->locks, smp->locks_end, | 318 | alternatives_smp_unlock(smp->locks, smp->locks_end, |
| 319 | smp->text, smp->text_end); | 319 | smp->text, smp->text_end); |
| 320 | spin_unlock(&smp_alt); | 320 | mutex_unlock(&smp_alt); |
| 321 | } | 321 | } |
| 322 | 322 | ||
| 323 | void alternatives_smp_module_del(struct module *mod) | 323 | void alternatives_smp_module_del(struct module *mod) |
| @@ -327,17 +327,17 @@ void alternatives_smp_module_del(struct module *mod) | |||
| 327 | if (smp_alt_once || noreplace_smp) | 327 | if (smp_alt_once || noreplace_smp) |
| 328 | return; | 328 | return; |
| 329 | 329 | ||
| 330 | spin_lock(&smp_alt); | 330 | mutex_lock(&smp_alt); |
| 331 | list_for_each_entry(item, &smp_alt_modules, next) { | 331 | list_for_each_entry(item, &smp_alt_modules, next) { |
| 332 | if (mod != item->mod) | 332 | if (mod != item->mod) |
| 333 | continue; | 333 | continue; |
| 334 | list_del(&item->next); | 334 | list_del(&item->next); |
| 335 | spin_unlock(&smp_alt); | 335 | mutex_unlock(&smp_alt); |
| 336 | DPRINTK("%s: %s\n", __func__, item->name); | 336 | DPRINTK("%s: %s\n", __func__, item->name); |
| 337 | kfree(item); | 337 | kfree(item); |
| 338 | return; | 338 | return; |
| 339 | } | 339 | } |
| 340 | spin_unlock(&smp_alt); | 340 | mutex_unlock(&smp_alt); |
| 341 | } | 341 | } |
| 342 | 342 | ||
| 343 | void alternatives_smp_switch(int smp) | 343 | void alternatives_smp_switch(int smp) |
| @@ -359,7 +359,7 @@ void alternatives_smp_switch(int smp) | |||
| 359 | return; | 359 | return; |
| 360 | BUG_ON(!smp && (num_online_cpus() > 1)); | 360 | BUG_ON(!smp && (num_online_cpus() > 1)); |
| 361 | 361 | ||
| 362 | spin_lock(&smp_alt); | 362 | mutex_lock(&smp_alt); |
| 363 | 363 | ||
| 364 | /* | 364 | /* |
| 365 | * Avoid unnecessary switches because it forces JIT based VMs to | 365 | * Avoid unnecessary switches because it forces JIT based VMs to |
| @@ -383,7 +383,7 @@ void alternatives_smp_switch(int smp) | |||
| 383 | mod->text, mod->text_end); | 383 | mod->text, mod->text_end); |
| 384 | } | 384 | } |
| 385 | smp_mode = smp; | 385 | smp_mode = smp; |
| 386 | spin_unlock(&smp_alt); | 386 | mutex_unlock(&smp_alt); |
| 387 | } | 387 | } |
| 388 | 388 | ||
| 389 | #endif | 389 | #endif |
