blob: 0e2c9a1e958a490cdbbaae732f379c5ee3b26d87
1 | #include <linux/kernel.h> |
2 | #include <linux/module.h> |
3 | #include <linux/cpu.h> |
4 | |
5 | #include "notifier-error-inject.h" |
6 | |
7 | static int priority; |
8 | module_param(priority, int, 0); |
9 | MODULE_PARM_DESC(priority, "specify cpu notifier priority"); |
10 | |
11 | #define UP_PREPARE 0 |
12 | #define UP_PREPARE_FROZEN 0 |
13 | #define DOWN_PREPARE 0 |
14 | #define DOWN_PREPARE_FROZEN 0 |
15 | |
16 | static struct notifier_err_inject cpu_notifier_err_inject = { |
17 | .actions = { |
18 | { NOTIFIER_ERR_INJECT_ACTION(UP_PREPARE) }, |
19 | { NOTIFIER_ERR_INJECT_ACTION(UP_PREPARE_FROZEN) }, |
20 | { NOTIFIER_ERR_INJECT_ACTION(DOWN_PREPARE) }, |
21 | { NOTIFIER_ERR_INJECT_ACTION(DOWN_PREPARE_FROZEN) }, |
22 | {} |
23 | } |
24 | }; |
25 | |
26 | static int notf_err_handle(struct notifier_err_inject_action *action) |
27 | { |
28 | int ret; |
29 | |
30 | ret = action->error; |
31 | if (ret) |
32 | pr_info("Injecting error (%d) to %s\n", ret, action->name); |
33 | return ret; |
34 | } |
35 | |
36 | static int notf_err_inj_up_prepare(unsigned int cpu) |
37 | { |
38 | if (!cpuhp_tasks_frozen) |
39 | return notf_err_handle(&cpu_notifier_err_inject.actions[0]); |
40 | else |
41 | return notf_err_handle(&cpu_notifier_err_inject.actions[1]); |
42 | } |
43 | |
44 | static int notf_err_inj_dead(unsigned int cpu) |
45 | { |
46 | if (!cpuhp_tasks_frozen) |
47 | return notf_err_handle(&cpu_notifier_err_inject.actions[2]); |
48 | else |
49 | return notf_err_handle(&cpu_notifier_err_inject.actions[3]); |
50 | } |
51 | |
52 | static struct dentry *dir; |
53 | |
54 | static int err_inject_init(void) |
55 | { |
56 | int err; |
57 | |
58 | dir = notifier_err_inject_init("cpu", notifier_err_inject_dir, |
59 | &cpu_notifier_err_inject, priority); |
60 | if (IS_ERR(dir)) |
61 | return PTR_ERR(dir); |
62 | |
63 | err = cpuhp_setup_state_nocalls(CPUHP_NOTF_ERR_INJ_PREPARE, |
64 | "cpu-err-notif:prepare", |
65 | notf_err_inj_up_prepare, |
66 | notf_err_inj_dead); |
67 | if (err) |
68 | debugfs_remove_recursive(dir); |
69 | |
70 | return err; |
71 | } |
72 | |
73 | static void err_inject_exit(void) |
74 | { |
75 | cpuhp_remove_state_nocalls(CPUHP_NOTF_ERR_INJ_PREPARE); |
76 | debugfs_remove_recursive(dir); |
77 | } |
78 | |
79 | module_init(err_inject_init); |
80 | module_exit(err_inject_exit); |
81 | |
82 | MODULE_DESCRIPTION("CPU notifier error injection module"); |
83 | MODULE_LICENSE("GPL"); |
84 | MODULE_AUTHOR("Akinobu Mita <akinobu.mita@gmail.com>"); |
85 |