| #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>"); |