From: Vasiliy Ulyanov Date: Mon, 5 May 2014 11:42:35 +0000 (+0400) Subject: [FIX] non boot cpus shutting down on uniprocessor devices X-Git-Tag: Tizen_SDK_2.3~71 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F60%2F20360%2F1;p=kernel%2Fswap-modules.git [FIX] non boot cpus shutting down on uniprocessor devices Change-Id: I7a4c5ca32d5e8b6f15aacf6f6d0875979faeee36 Signed-off-by: Vasiliy Ulyanov --- diff --git a/parser/Kbuild b/parser/Kbuild index 7ef0288..13a49fa 100644 --- a/parser/Kbuild +++ b/parser/Kbuild @@ -12,4 +12,5 @@ swap_message_parser-y := swap_msg_parser.o \ msg_buf.o \ msg_cmd.o \ features.o \ - us_inst.o + us_inst.o \ + cpu_ctrl.o diff --git a/parser/cpu_ctrl.c b/parser/cpu_ctrl.c new file mode 100644 index 0000000..38425fa --- /dev/null +++ b/parser/cpu_ctrl.c @@ -0,0 +1,82 @@ +#include +#include +#include + +#ifdef CONFIG_SMP +static void (*swap_cpu_maps_update_begin)(void); +static void (*swap_cpu_maps_update_done)(void); +static int (*swap_cpu_down)(unsigned int, int); +static int (*swap_cpu_up)(unsigned int, int); + +int swap_disable_nonboot_cpus_lock(struct cpumask *mask) +{ + int boot_cpu, cpu; + int ret = 0; + + swap_cpu_maps_update_begin(); + cpumask_clear(mask); + + boot_cpu = cpumask_first(cpu_online_mask); + + for_each_online_cpu(cpu) { + if (cpu == boot_cpu) + continue; + ret = swap_cpu_down(cpu, 0); + if (ret == 0) + cpumask_set_cpu(cpu, mask); + printk("===> SWAP CPU[%d] down(%d)\n", cpu, ret); + } + + WARN_ON(num_online_cpus() > 1); + return ret; +} + +int swap_enable_nonboot_cpus_unlock(struct cpumask *mask) +{ + int cpu, ret = 0; + + if (cpumask_empty(mask)) + goto out; + + for_each_cpu(cpu, mask) { + ret = swap_cpu_up(cpu, 0); + printk("===> SWAP CPU[%d] up(%d)\n", cpu, ret); + } + + swap_cpu_maps_update_done(); + +out: + return ret; +} + +int init_cpu_deps(void) +{ + const char *sym = "cpu_maps_update_begin"; + + swap_cpu_maps_update_begin = (void *)swap_ksyms(sym); + if (!swap_cpu_maps_update_begin) + goto not_found; + + sym = "cpu_maps_update_done"; + swap_cpu_maps_update_done = (void *)swap_ksyms(sym); + if (!swap_cpu_maps_update_done) + goto not_found; + + sym = "_cpu_up"; + swap_cpu_up = (void *)swap_ksyms(sym); + if (!swap_cpu_up) + goto not_found; + + sym = "_cpu_down"; + swap_cpu_down = (void *)swap_ksyms(sym); + if (!swap_cpu_down) + goto not_found; + + return 0; + +not_found: + printk("ERROR: symbol %s(...) not found\n", sym); + return -ESRCH; +} + +#endif /* CONFIG_SMP */ diff --git a/parser/cpu_ctrl.h b/parser/cpu_ctrl.h new file mode 100644 index 0000000..17ff199 --- /dev/null +++ b/parser/cpu_ctrl.h @@ -0,0 +1,31 @@ +#ifndef _CPU_CTRL_H_ +#define _CPU_CTRL_H_ + +struct cpumask; + +#ifdef CONFIG_SMP +int swap_disable_nonboot_cpus_lock(struct cpumask *mask); +int swap_enable_nonboot_cpus_unlock(struct cpumask *mask); + +int init_cpu_deps(void); + +#else /* CONFIG_SMP */ + +static inline int swap_disable_nonboot_cpus_lock(struct cpumask *mask) +{ + return 0; +} + +static inline int swap_enable_nonboot_cpus_unlock(struct cpumask *mask) +{ + return 0; +} + +static inline int init_cpu_deps(void) +{ + return 0; +} + +#endif /* CONFIG_SMP */ + +#endif /* _CPU_CTRL_H_ */ diff --git a/parser/swap_msg_parser.c b/parser/swap_msg_parser.c index aac3455..5c32fc1 100644 --- a/parser/swap_msg_parser.c +++ b/parser/swap_msg_parser.c @@ -26,16 +26,15 @@ #include #include #include -#include #include #include "parser_defs.h" #include "msg_buf.h" #include "msg_cmd.h" +#include "cpu_ctrl.h" #include #include -#include enum MSG_ID { MSG_KEEP_ALIVE = 0x0001, @@ -51,82 +50,6 @@ struct basic_msg_fmt { u32 len; } __attribute__((packed)); -static void (*swap_cpu_maps_update_begin)(void); -static void (*swap_cpu_maps_update_done)(void); -static int (*swap_cpu_down)(unsigned int, int); -static int (*swap_cpu_up)(unsigned int, int); - -static int init_cpu_deps(void) -{ - const char *sym = "cpu_maps_update_begin"; - - swap_cpu_maps_update_begin = (void *)swap_ksyms(sym); - if (!swap_cpu_maps_update_begin) - goto not_found; - - sym = "cpu_maps_update_done"; - swap_cpu_maps_update_done = (void *)swap_ksyms(sym); - if (!swap_cpu_maps_update_done) - goto not_found; - - sym = "_cpu_up"; - swap_cpu_up = (void *)swap_ksyms(sym); - if (!swap_cpu_up) - goto not_found; - - sym = "_cpu_down"; - swap_cpu_down = (void *)swap_ksyms(sym); - if (!swap_cpu_down) - goto not_found; - - return 0; - -not_found: - printk("ERROR: symbol %s(...) not found\n", sym); - return -ESRCH; -} - -static int swap_disable_nonboot_cpus_lock(struct cpumask *mask) -{ - int boot_cpu, cpu; - int ret = 0; - - swap_cpu_maps_update_begin(); - cpumask_clear(mask); - - boot_cpu = cpumask_first(cpu_online_mask); - - for_each_online_cpu(cpu) { - if (cpu == boot_cpu) - continue; - ret = swap_cpu_down(cpu, 0); - if (ret == 0) - cpumask_set_cpu(cpu, mask); - printk("===> SWAP CPU[%d] down(%d)\n", cpu, ret); - } - - WARN_ON(num_online_cpus() > 1); - return ret; -} - -static int swap_enable_nonboot_cpus_unlock(struct cpumask *mask) -{ - int cpu, ret = 0; - - if (cpumask_empty(mask)) - goto out; - - for_each_cpu(cpu, mask) { - ret = swap_cpu_up(cpu, 0); - printk("===> SWAP CPU[%d] up(%d)\n", cpu, ret); - } - - swap_cpu_maps_update_done(); - -out: - return ret; -} - static int msg_handler(void __user *msg) { int ret;