1 #include <linux/kernel.h>
3 #include <linux/random.h>
4 #include <linux/sched.h>
5 #include <linux/stat.h>
6 #include <linux/types.h>
8 #include <linux/export.h>
19 unsigned long probability;
25 if (
sscanf(str,
"%lu,%lu,%d,%d",
26 &interval, &probability, &space, ×) < 4) {
28 "FAULT_INJECTION: failed to parse arguments\n");
32 attr->probability = probability;
41 static void fail_dump(
struct fault_attr *
attr)
43 if (attr->verbose > 0)
45 if (attr->verbose > 1)
49 #define atomic_dec_not_zero(v) atomic_add_unless((v), -1, 0)
51 static bool fail_task(
struct fault_attr *attr,
struct task_struct *
task)
56 #define MAX_STACK_TRACE_DEPTH 32
58 #ifdef CONFIG_FAULT_INJECTION_STACKTRACE_FILTER
60 static bool fail_stacktrace(
struct fault_attr *attr)
62 struct stack_trace trace;
63 int depth = attr->stacktrace_depth;
66 bool found = (attr->require_start == 0 && attr->require_end ==
ULONG_MAX);
73 trace.max_entries =
depth;
77 for (n = 0; n < trace.nr_entries; n++) {
78 if (attr->reject_start <= entries[n] &&
79 entries[n] < attr->reject_end)
81 if (attr->require_start <= entries[n] &&
82 entries[n] < attr->require_end)
90 static inline bool fail_stacktrace(
struct fault_attr *attr)
105 if (attr->probability == 0)
108 if (attr->task_filter && !fail_task(attr,
current))
119 if (attr->interval > 1) {
121 if (attr->count % attr->interval)
125 if (attr->probability <=
random32() % 100)
128 if (!fail_stacktrace(attr))
140 #ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
142 static int debugfs_ul_set(
void *
data,
u64 val)
144 *(
unsigned long *)data = val;
148 static int debugfs_ul_get(
void *
data,
u64 *
val)
150 *val = *(
unsigned long *)data;
162 #ifdef CONFIG_FAULT_INJECTION_STACKTRACE_FILTER
164 static int debugfs_stacktrace_depth_set(
void *
data,
u64 val)
166 *(
unsigned long *)data =
173 debugfs_stacktrace_depth_set,
"%llu\n");
175 static struct dentry *debugfs_create_stacktrace_depth(
180 &fops_stacktrace_depth);
185 static int debugfs_atomic_t_set(
void *data,
u64 val)
191 static int debugfs_atomic_t_get(
void *data,
u64 *val)
198 debugfs_atomic_t_set,
"%lld\n");
206 struct dentry *fault_create_debugfs_attr(
const char *
name,
207 struct dentry *parent,
struct fault_attr *attr)
216 if (!debugfs_create_ul(
"probability", mode, dir, &attr->probability))
218 if (!debugfs_create_ul(
"interval", mode, dir, &attr->interval))
220 if (!debugfs_create_atomic_t(
"times", mode, dir, &attr->times))
222 if (!debugfs_create_atomic_t(
"space", mode, dir, &attr->space))
224 if (!debugfs_create_ul(
"verbose", mode, dir, &attr->verbose))
229 #ifdef CONFIG_FAULT_INJECTION_STACKTRACE_FILTER
231 if (!debugfs_create_stacktrace_depth(
"stacktrace-depth", mode, dir,
232 &attr->stacktrace_depth))
234 if (!debugfs_create_ul(
"require-start", mode, dir,
235 &attr->require_start))
237 if (!debugfs_create_ul(
"require-end", mode, dir, &attr->require_end))
239 if (!debugfs_create_ul(
"reject-start", mode, dir, &attr->reject_start))
241 if (!debugfs_create_ul(
"reject-end", mode, dir, &attr->reject_end))