.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | #include <linux/kernel.h> |
---|
2 | 3 | #include <linux/init.h> |
---|
3 | 4 | #include <linux/random.h> |
---|
.. | .. |
---|
65 | 66 | |
---|
66 | 67 | static bool fail_stacktrace(struct fault_attr *attr) |
---|
67 | 68 | { |
---|
68 | | - struct stack_trace trace; |
---|
69 | 69 | int depth = attr->stacktrace_depth; |
---|
70 | 70 | unsigned long entries[MAX_STACK_TRACE_DEPTH]; |
---|
71 | | - int n; |
---|
| 71 | + int n, nr_entries; |
---|
72 | 72 | bool found = (attr->require_start == 0 && attr->require_end == ULONG_MAX); |
---|
73 | 73 | |
---|
74 | 74 | if (depth == 0) |
---|
75 | 75 | return found; |
---|
76 | 76 | |
---|
77 | | - trace.nr_entries = 0; |
---|
78 | | - trace.entries = entries; |
---|
79 | | - trace.max_entries = depth; |
---|
80 | | - trace.skip = 1; |
---|
81 | | - |
---|
82 | | - save_stack_trace(&trace); |
---|
83 | | - for (n = 0; n < trace.nr_entries; n++) { |
---|
| 77 | + nr_entries = stack_trace_save(entries, depth, 1); |
---|
| 78 | + for (n = 0; n < nr_entries; n++) { |
---|
84 | 79 | if (attr->reject_start <= entries[n] && |
---|
85 | 80 | entries[n] < attr->reject_end) |
---|
86 | 81 | return false; |
---|
.. | .. |
---|
111 | 106 | unsigned int fail_nth = READ_ONCE(current->fail_nth); |
---|
112 | 107 | |
---|
113 | 108 | if (fail_nth) { |
---|
114 | | - if (!WRITE_ONCE(current->fail_nth, fail_nth - 1)) |
---|
| 109 | + fail_nth--; |
---|
| 110 | + WRITE_ONCE(current->fail_nth, fail_nth); |
---|
| 111 | + if (!fail_nth) |
---|
115 | 112 | goto fail; |
---|
116 | 113 | |
---|
117 | 114 | return false; |
---|
.. | .. |
---|
171 | 168 | |
---|
172 | 169 | DEFINE_SIMPLE_ATTRIBUTE(fops_ul, debugfs_ul_get, debugfs_ul_set, "%llu\n"); |
---|
173 | 170 | |
---|
174 | | -static struct dentry *debugfs_create_ul(const char *name, umode_t mode, |
---|
175 | | - struct dentry *parent, unsigned long *value) |
---|
| 171 | +static void debugfs_create_ul(const char *name, umode_t mode, |
---|
| 172 | + struct dentry *parent, unsigned long *value) |
---|
176 | 173 | { |
---|
177 | | - return debugfs_create_file(name, mode, parent, value, &fops_ul); |
---|
| 174 | + debugfs_create_file(name, mode, parent, value, &fops_ul); |
---|
178 | 175 | } |
---|
179 | 176 | |
---|
180 | 177 | #ifdef CONFIG_FAULT_INJECTION_STACKTRACE_FILTER |
---|
.. | .. |
---|
190 | 187 | DEFINE_SIMPLE_ATTRIBUTE(fops_stacktrace_depth, debugfs_ul_get, |
---|
191 | 188 | debugfs_stacktrace_depth_set, "%llu\n"); |
---|
192 | 189 | |
---|
193 | | -static struct dentry *debugfs_create_stacktrace_depth( |
---|
194 | | - const char *name, umode_t mode, |
---|
195 | | - struct dentry *parent, unsigned long *value) |
---|
| 190 | +static void debugfs_create_stacktrace_depth(const char *name, umode_t mode, |
---|
| 191 | + struct dentry *parent, |
---|
| 192 | + unsigned long *value) |
---|
196 | 193 | { |
---|
197 | | - return debugfs_create_file(name, mode, parent, value, |
---|
198 | | - &fops_stacktrace_depth); |
---|
| 194 | + debugfs_create_file(name, mode, parent, value, &fops_stacktrace_depth); |
---|
199 | 195 | } |
---|
200 | 196 | |
---|
201 | 197 | #endif /* CONFIG_FAULT_INJECTION_STACKTRACE_FILTER */ |
---|
.. | .. |
---|
207 | 203 | struct dentry *dir; |
---|
208 | 204 | |
---|
209 | 205 | dir = debugfs_create_dir(name, parent); |
---|
210 | | - if (!dir) |
---|
211 | | - return ERR_PTR(-ENOMEM); |
---|
| 206 | + if (IS_ERR(dir)) |
---|
| 207 | + return dir; |
---|
212 | 208 | |
---|
213 | | - if (!debugfs_create_ul("probability", mode, dir, &attr->probability)) |
---|
214 | | - goto fail; |
---|
215 | | - if (!debugfs_create_ul("interval", mode, dir, &attr->interval)) |
---|
216 | | - goto fail; |
---|
217 | | - if (!debugfs_create_atomic_t("times", mode, dir, &attr->times)) |
---|
218 | | - goto fail; |
---|
219 | | - if (!debugfs_create_atomic_t("space", mode, dir, &attr->space)) |
---|
220 | | - goto fail; |
---|
221 | | - if (!debugfs_create_ul("verbose", mode, dir, &attr->verbose)) |
---|
222 | | - goto fail; |
---|
223 | | - if (!debugfs_create_u32("verbose_ratelimit_interval_ms", mode, dir, |
---|
224 | | - &attr->ratelimit_state.interval)) |
---|
225 | | - goto fail; |
---|
226 | | - if (!debugfs_create_u32("verbose_ratelimit_burst", mode, dir, |
---|
227 | | - &attr->ratelimit_state.burst)) |
---|
228 | | - goto fail; |
---|
229 | | - if (!debugfs_create_bool("task-filter", mode, dir, &attr->task_filter)) |
---|
230 | | - goto fail; |
---|
| 209 | + debugfs_create_ul("probability", mode, dir, &attr->probability); |
---|
| 210 | + debugfs_create_ul("interval", mode, dir, &attr->interval); |
---|
| 211 | + debugfs_create_atomic_t("times", mode, dir, &attr->times); |
---|
| 212 | + debugfs_create_atomic_t("space", mode, dir, &attr->space); |
---|
| 213 | + debugfs_create_ul("verbose", mode, dir, &attr->verbose); |
---|
| 214 | + debugfs_create_u32("verbose_ratelimit_interval_ms", mode, dir, |
---|
| 215 | + &attr->ratelimit_state.interval); |
---|
| 216 | + debugfs_create_u32("verbose_ratelimit_burst", mode, dir, |
---|
| 217 | + &attr->ratelimit_state.burst); |
---|
| 218 | + debugfs_create_bool("task-filter", mode, dir, &attr->task_filter); |
---|
231 | 219 | |
---|
232 | 220 | #ifdef CONFIG_FAULT_INJECTION_STACKTRACE_FILTER |
---|
233 | | - |
---|
234 | | - if (!debugfs_create_stacktrace_depth("stacktrace-depth", mode, dir, |
---|
235 | | - &attr->stacktrace_depth)) |
---|
236 | | - goto fail; |
---|
237 | | - if (!debugfs_create_ul("require-start", mode, dir, |
---|
238 | | - &attr->require_start)) |
---|
239 | | - goto fail; |
---|
240 | | - if (!debugfs_create_ul("require-end", mode, dir, &attr->require_end)) |
---|
241 | | - goto fail; |
---|
242 | | - if (!debugfs_create_ul("reject-start", mode, dir, &attr->reject_start)) |
---|
243 | | - goto fail; |
---|
244 | | - if (!debugfs_create_ul("reject-end", mode, dir, &attr->reject_end)) |
---|
245 | | - goto fail; |
---|
246 | | - |
---|
| 221 | + debugfs_create_stacktrace_depth("stacktrace-depth", mode, dir, |
---|
| 222 | + &attr->stacktrace_depth); |
---|
| 223 | + debugfs_create_ul("require-start", mode, dir, &attr->require_start); |
---|
| 224 | + debugfs_create_ul("require-end", mode, dir, &attr->require_end); |
---|
| 225 | + debugfs_create_ul("reject-start", mode, dir, &attr->reject_start); |
---|
| 226 | + debugfs_create_ul("reject-end", mode, dir, &attr->reject_end); |
---|
247 | 227 | #endif /* CONFIG_FAULT_INJECTION_STACKTRACE_FILTER */ |
---|
248 | 228 | |
---|
249 | 229 | attr->dname = dget(dir); |
---|
250 | 230 | return dir; |
---|
251 | | -fail: |
---|
252 | | - debugfs_remove_recursive(dir); |
---|
253 | | - |
---|
254 | | - return ERR_PTR(-ENOMEM); |
---|
255 | 231 | } |
---|
256 | 232 | EXPORT_SYMBOL_GPL(fault_create_debugfs_attr); |
---|
257 | 233 | |
---|