diff options
author | James Morris <jmorris@namei.org> | 2008-11-13 19:29:12 -0500 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2008-11-13 19:29:12 -0500 |
commit | 2b828925652340277a889cbc11b2d0637f7cdaf7 (patch) | |
tree | 32fcb3d3e466fc419fad2d3717956a5b5ad3d35a /kernel/workqueue.c | |
parent | 3a3b7ce9336952ea7b9564d976d068a238976c9d (diff) | |
parent | 58e20d8d344b0ee083febb18c2b021d2427e56ca (diff) |
Merge branch 'master' into next
Conflicts:
security/keys/internal.h
security/keys/process_keys.c
security/keys/request_key.c
Fixed conflicts above by using the non 'tsk' versions.
Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'kernel/workqueue.c')
-rw-r--r-- | kernel/workqueue.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index f12ab5c4dec4..4952322cba45 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; |