diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/cpu.c | 3 | ||||
| -rw-r--r-- | kernel/sched.c | 7 | ||||
| -rw-r--r-- | kernel/workqueue.c | 45 |
3 files changed, 53 insertions, 2 deletions
diff --git a/kernel/cpu.c b/kernel/cpu.c index 86d49045daed..5a732c5ef08b 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c | |||
| @@ -499,3 +499,6 @@ const unsigned long cpu_bit_bitmap[BITS_PER_LONG+1][BITS_TO_LONGS(NR_CPUS)] = { | |||
| 499 | #endif | 499 | #endif |
| 500 | }; | 500 | }; |
| 501 | EXPORT_SYMBOL_GPL(cpu_bit_bitmap); | 501 | EXPORT_SYMBOL_GPL(cpu_bit_bitmap); |
| 502 | |||
| 503 | const DECLARE_BITMAP(cpu_all_bits, NR_CPUS) = CPU_BITS_ALL; | ||
| 504 | EXPORT_SYMBOL(cpu_all_bits); | ||
diff --git a/kernel/sched.c b/kernel/sched.c index 82cc839c9210..57c933ffbee1 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
| @@ -6877,15 +6877,17 @@ cpu_attach_domain(struct sched_domain *sd, struct root_domain *rd, int cpu) | |||
| 6877 | struct sched_domain *tmp; | 6877 | struct sched_domain *tmp; |
| 6878 | 6878 | ||
| 6879 | /* Remove the sched domains which do not contribute to scheduling. */ | 6879 | /* Remove the sched domains which do not contribute to scheduling. */ |
| 6880 | for (tmp = sd; tmp; tmp = tmp->parent) { | 6880 | for (tmp = sd; tmp; ) { |
| 6881 | struct sched_domain *parent = tmp->parent; | 6881 | struct sched_domain *parent = tmp->parent; |
| 6882 | if (!parent) | 6882 | if (!parent) |
| 6883 | break; | 6883 | break; |
| 6884 | |||
| 6884 | if (sd_parent_degenerate(tmp, parent)) { | 6885 | if (sd_parent_degenerate(tmp, parent)) { |
| 6885 | tmp->parent = parent->parent; | 6886 | tmp->parent = parent->parent; |
| 6886 | if (parent->parent) | 6887 | if (parent->parent) |
| 6887 | parent->parent->child = tmp; | 6888 | parent->parent->child = tmp; |
| 6888 | } | 6889 | } else |
| 6890 | tmp = tmp->parent; | ||
| 6889 | } | 6891 | } |
| 6890 | 6892 | ||
| 6891 | if (sd && sd_degenerate(sd)) { | 6893 | if (sd && sd_degenerate(sd)) { |
| @@ -7674,6 +7676,7 @@ static int __build_sched_domains(const cpumask_t *cpu_map, | |||
| 7674 | error: | 7676 | error: |
| 7675 | free_sched_groups(cpu_map, tmpmask); | 7677 | free_sched_groups(cpu_map, tmpmask); |
| 7676 | SCHED_CPUMASK_FREE((void *)allmasks); | 7678 | SCHED_CPUMASK_FREE((void *)allmasks); |
| 7679 | kfree(rd); | ||
| 7677 | return -ENOMEM; | 7680 | return -ENOMEM; |
| 7678 | #endif | 7681 | #endif |
| 7679 | } | 7682 | } |
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index f928f2a87b9b..d4dc69ddebd7 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c | |||
| @@ -970,6 +970,51 @@ undo: | |||
| 970 | return ret; | 970 | return ret; |
| 971 | } | 971 | } |
| 972 | 972 | ||
| 973 | #ifdef CONFIG_SMP | ||
| 974 | struct work_for_cpu { | ||
| 975 | struct work_struct work; | ||
| 976 | long (*fn)(void *); | ||
| 977 | void *arg; | ||
| 978 | long ret; | ||
| 979 | }; | ||
| 980 | |||
| 981 | static void do_work_for_cpu(struct work_struct *w) | ||
| 982 | { | ||
| 983 | struct work_for_cpu *wfc = container_of(w, struct work_for_cpu, work); | ||
| 984 | |||
| 985 | wfc->ret = wfc->fn(wfc->arg); | ||
| 986 | } | ||
| 987 | |||
| 988 | /** | ||
| 989 | * work_on_cpu - run a function in user context on a particular cpu | ||
| 990 | * @cpu: the cpu to run on | ||
| 991 | * @fn: the function to run | ||
| 992 | * @arg: the function arg | ||
| 993 | * | ||
| 994 | * This will return -EINVAL in the cpu is not online, or the return value | ||
| 995 | * of @fn otherwise. | ||
| 996 | */ | ||
| 997 | long work_on_cpu(unsigned int cpu, long (*fn)(void *), void *arg) | ||
| 998 | { | ||
| 999 | struct work_for_cpu wfc; | ||
| 1000 | |||
| 1001 | INIT_WORK(&wfc.work, do_work_for_cpu); | ||
| 1002 | wfc.fn = fn; | ||
| 1003 | wfc.arg = arg; | ||
| 1004 | get_online_cpus(); | ||
| 1005 | if (unlikely(!cpu_online(cpu))) | ||
| 1006 | wfc.ret = -EINVAL; | ||
| 1007 | else { | ||
| 1008 | schedule_work_on(cpu, &wfc.work); | ||
| 1009 | flush_work(&wfc.work); | ||
| 1010 | } | ||
| 1011 | put_online_cpus(); | ||
| 1012 | |||
| 1013 | return wfc.ret; | ||
| 1014 | } | ||
| 1015 | EXPORT_SYMBOL_GPL(work_on_cpu); | ||
| 1016 | #endif /* CONFIG_SMP */ | ||
| 1017 | |||
| 973 | void __init init_workqueues(void) | 1018 | void __init init_workqueues(void) |
| 974 | { | 1019 | { |
| 975 | cpu_populated_map = cpu_online_map; | 1020 | cpu_populated_map = cpu_online_map; |
