| .. | .. |
|---|
| 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 | |
|---|