aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/Kconfig.debug16
-rw-r--r--lib/cpu-notifier-error-inject.c63
2 files changed, 39 insertions, 40 deletions
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index bdee91d50a5b..20341480bb54 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -1097,10 +1097,22 @@ config NOTIFIER_ERROR_INJECTION
1097 1097
1098config CPU_NOTIFIER_ERROR_INJECT 1098config CPU_NOTIFIER_ERROR_INJECT
1099 tristate "CPU notifier error injection module" 1099 tristate "CPU notifier error injection module"
1100 depends on HOTPLUG_CPU && DEBUG_KERNEL 1100 depends on HOTPLUG_CPU && NOTIFIER_ERROR_INJECTION
1101 help 1101 help
1102 This option provides a kernel module that can be used to test 1102 This option provides a kernel module that can be used to test
1103 the error handling of the cpu notifiers 1103 the error handling of the cpu notifiers by injecting artifical
1104 errors to CPU notifier chain callbacks. It is controlled through
1105 debugfs interface under /sys/kernel/debug/notifier-error-inject/cpu
1106
1107 If the notifier call chain should be failed with some events
1108 notified, write the error code to "actions/<notifier event>/error".
1109
1110 Example: Inject CPU offline error (-1 == -EPERM)
1111
1112 # cd /sys/kernel/debug/notifier-error-inject/cpu
1113 # echo -1 > actions/CPU_DOWN_PREPARE/error
1114 # echo 0 > /sys/devices/system/cpu/cpu1/online
1115 bash: echo: write error: Operation not permitted
1104 1116
1105 To compile this code as a module, choose M here: the module will 1117 To compile this code as a module, choose M here: the module will
1106 be called cpu-notifier-error-inject. 1118 be called cpu-notifier-error-inject.
diff --git a/lib/cpu-notifier-error-inject.c b/lib/cpu-notifier-error-inject.c
index 4dc20321b0d5..707ca24f7b18 100644
--- a/lib/cpu-notifier-error-inject.c
+++ b/lib/cpu-notifier-error-inject.c
@@ -1,58 +1,45 @@
1#include <linux/kernel.h> 1#include <linux/kernel.h>
2#include <linux/cpu.h>
3#include <linux/module.h> 2#include <linux/module.h>
4#include <linux/notifier.h> 3#include <linux/cpu.h>
5 4
6static int priority; 5#include "notifier-error-inject.h"
7static int cpu_up_prepare_error;
8static int cpu_down_prepare_error;
9 6
7static int priority;
10module_param(priority, int, 0); 8module_param(priority, int, 0);
11MODULE_PARM_DESC(priority, "specify cpu notifier priority"); 9MODULE_PARM_DESC(priority, "specify cpu notifier priority");
12 10
13module_param(cpu_up_prepare_error, int, 0644); 11static struct notifier_err_inject cpu_notifier_err_inject = {
14MODULE_PARM_DESC(cpu_up_prepare_error, 12 .actions = {
15 "specify error code to inject CPU_UP_PREPARE action"); 13 { NOTIFIER_ERR_INJECT_ACTION(CPU_UP_PREPARE) },
16 14 { NOTIFIER_ERR_INJECT_ACTION(CPU_UP_PREPARE_FROZEN) },
17module_param(cpu_down_prepare_error, int, 0644); 15 { NOTIFIER_ERR_INJECT_ACTION(CPU_DOWN_PREPARE) },
18MODULE_PARM_DESC(cpu_down_prepare_error, 16 { NOTIFIER_ERR_INJECT_ACTION(CPU_DOWN_PREPARE_FROZEN) },
19 "specify error code to inject CPU_DOWN_PREPARE action"); 17 {}
20
21static int err_inject_cpu_callback(struct notifier_block *nfb,
22 unsigned long action, void *hcpu)
23{
24 int err = 0;
25
26 switch (action) {
27 case CPU_UP_PREPARE:
28 case CPU_UP_PREPARE_FROZEN:
29 err = cpu_up_prepare_error;
30 break;
31 case CPU_DOWN_PREPARE:
32 case CPU_DOWN_PREPARE_FROZEN:
33 err = cpu_down_prepare_error;
34 break;
35 } 18 }
36 if (err)
37 printk(KERN_INFO "Injecting error (%d) at cpu notifier\n", err);
38
39 return notifier_from_errno(err);
40}
41
42static struct notifier_block err_inject_cpu_notifier = {
43 .notifier_call = err_inject_cpu_callback,
44}; 19};
45 20
21static struct dentry *dir;
22
46static int err_inject_init(void) 23static int err_inject_init(void)
47{ 24{
48 err_inject_cpu_notifier.priority = priority; 25 int err;
26
27 dir = notifier_err_inject_init("cpu", notifier_err_inject_dir,
28 &cpu_notifier_err_inject, priority);
29 if (IS_ERR(dir))
30 return PTR_ERR(dir);
31
32 err = register_hotcpu_notifier(&cpu_notifier_err_inject.nb);
33 if (err)
34 debugfs_remove_recursive(dir);
49 35
50 return register_hotcpu_notifier(&err_inject_cpu_notifier); 36 return err;
51} 37}
52 38
53static void err_inject_exit(void) 39static void err_inject_exit(void)
54{ 40{
55 unregister_hotcpu_notifier(&err_inject_cpu_notifier); 41 unregister_hotcpu_notifier(&cpu_notifier_err_inject.nb);
42 debugfs_remove_recursive(dir);
56} 43}
57 44
58module_init(err_inject_init); 45module_init(err_inject_init);