| #include <linux/kernel.h> | |
| #include <linux/cpu.h> | |
| #include <linux/module.h> | |
| #include <linux/notifier.h> | |
| static int priority; | |
| static int cpu_up_prepare_error; | |
| static int cpu_down_prepare_error; | |
| module_param(priority, int, 0); | |
| MODULE_PARM_DESC(priority, "specify cpu notifier priority"); | |
| module_param(cpu_up_prepare_error, int, 0644); | |
| MODULE_PARM_DESC(cpu_up_prepare_error, | |
| "specify error code to inject CPU_UP_PREPARE action"); | |
| module_param(cpu_down_prepare_error, int, 0644); | |
| MODULE_PARM_DESC(cpu_down_prepare_error, | |
| "specify error code to inject CPU_DOWN_PREPARE action"); | |
| static int err_inject_cpu_callback(struct notifier_block *nfb, | |
| unsigned long action, void *hcpu) | |
| { | |
| int err = 0; | |
| switch (action) { | |
| case CPU_UP_PREPARE: | |
| case CPU_UP_PREPARE_FROZEN: | |
| err = cpu_up_prepare_error; | |
| break; | |
| case CPU_DOWN_PREPARE: | |
| case CPU_DOWN_PREPARE_FROZEN: | |
| err = cpu_down_prepare_error; | |
| break; | |
| } | |
| if (err) | |
| printk(KERN_INFO "Injecting error (%d) at cpu notifier\n", err); | |
| return notifier_from_errno(err); | |
| } | |
| static struct notifier_block err_inject_cpu_notifier = { | |
| .notifier_call = err_inject_cpu_callback, | |
| }; | |
| static int err_inject_init(void) | |
| { | |
| err_inject_cpu_notifier.priority = priority; | |
| return register_hotcpu_notifier(&err_inject_cpu_notifier); | |
| } | |
| static void err_inject_exit(void) | |
| { | |
| unregister_hotcpu_notifier(&err_inject_cpu_notifier); | |
| } | |
| module_init(err_inject_init); | |
| module_exit(err_inject_exit); | |
| MODULE_DESCRIPTION("CPU notifier error injection module"); | |
| MODULE_LICENSE("GPL"); | |
| MODULE_AUTHOR("Akinobu Mita <akinobu.mita@gmail.com>"); |