diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/extable.c | 2 | ||||
| -rw-r--r-- | kernel/module.c | 12 | ||||
| -rw-r--r-- | kernel/rcupdate.c | 19 |
3 files changed, 26 insertions, 7 deletions
diff --git a/kernel/extable.c b/kernel/extable.c index 7501b531ceed..7fe262855317 100644 --- a/kernel/extable.c +++ b/kernel/extable.c | |||
| @@ -40,7 +40,7 @@ const struct exception_table_entry *search_exception_tables(unsigned long addr) | |||
| 40 | return e; | 40 | return e; |
| 41 | } | 41 | } |
| 42 | 42 | ||
| 43 | static int core_kernel_text(unsigned long addr) | 43 | int core_kernel_text(unsigned long addr) |
| 44 | { | 44 | { |
| 45 | if (addr >= (unsigned long)_stext && | 45 | if (addr >= (unsigned long)_stext && |
| 46 | addr <= (unsigned long)_etext) | 46 | addr <= (unsigned long)_etext) |
diff --git a/kernel/module.c b/kernel/module.c index d24deb0dbbc9..bbe04862e1b0 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
| @@ -705,14 +705,14 @@ EXPORT_SYMBOL(__symbol_put); | |||
| 705 | 705 | ||
| 706 | void symbol_put_addr(void *addr) | 706 | void symbol_put_addr(void *addr) |
| 707 | { | 707 | { |
| 708 | unsigned long flags; | 708 | struct module *modaddr; |
| 709 | 709 | ||
| 710 | spin_lock_irqsave(&modlist_lock, flags); | 710 | if (core_kernel_text((unsigned long)addr)) |
| 711 | if (!kernel_text_address((unsigned long)addr)) | 711 | return; |
| 712 | BUG(); | ||
| 713 | 712 | ||
| 714 | module_put(module_text_address((unsigned long)addr)); | 713 | if (!(modaddr = module_text_address((unsigned long)addr))) |
| 715 | spin_unlock_irqrestore(&modlist_lock, flags); | 714 | BUG(); |
| 715 | module_put(modaddr); | ||
| 716 | } | 716 | } |
| 717 | EXPORT_SYMBOL_GPL(symbol_put_addr); | 717 | EXPORT_SYMBOL_GPL(symbol_put_addr); |
| 718 | 718 | ||
diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c index 6d32ff26f948..2058f88c7bbb 100644 --- a/kernel/rcupdate.c +++ b/kernel/rcupdate.c | |||
| @@ -479,12 +479,31 @@ static int __rcu_pending(struct rcu_ctrlblk *rcp, struct rcu_data *rdp) | |||
| 479 | return 0; | 479 | return 0; |
| 480 | } | 480 | } |
| 481 | 481 | ||
| 482 | /* | ||
| 483 | * Check to see if there is any immediate RCU-related work to be done | ||
| 484 | * by the current CPU, returning 1 if so. This function is part of the | ||
| 485 | * RCU implementation; it is -not- an exported member of the RCU API. | ||
| 486 | */ | ||
| 482 | int rcu_pending(int cpu) | 487 | int rcu_pending(int cpu) |
| 483 | { | 488 | { |
| 484 | return __rcu_pending(&rcu_ctrlblk, &per_cpu(rcu_data, cpu)) || | 489 | return __rcu_pending(&rcu_ctrlblk, &per_cpu(rcu_data, cpu)) || |
| 485 | __rcu_pending(&rcu_bh_ctrlblk, &per_cpu(rcu_bh_data, cpu)); | 490 | __rcu_pending(&rcu_bh_ctrlblk, &per_cpu(rcu_bh_data, cpu)); |
| 486 | } | 491 | } |
| 487 | 492 | ||
| 493 | /* | ||
| 494 | * Check to see if any future RCU-related work will need to be done | ||
| 495 | * by the current CPU, even if none need be done immediately, returning | ||
| 496 | * 1 if so. This function is part of the RCU implementation; it is -not- | ||
| 497 | * an exported member of the RCU API. | ||
| 498 | */ | ||
| 499 | int rcu_needs_cpu(int cpu) | ||
| 500 | { | ||
| 501 | struct rcu_data *rdp = &per_cpu(rcu_data, cpu); | ||
| 502 | struct rcu_data *rdp_bh = &per_cpu(rcu_bh_data, cpu); | ||
| 503 | |||
| 504 | return (!!rdp->curlist || !!rdp_bh->curlist || rcu_pending(cpu)); | ||
| 505 | } | ||
| 506 | |||
| 488 | void rcu_check_callbacks(int cpu, int user) | 507 | void rcu_check_callbacks(int cpu, int user) |
| 489 | { | 508 | { |
| 490 | if (user || | 509 | if (user || |
