aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/fault-inject.h17
-rw-r--r--lib/fault-inject.c21
2 files changed, 28 insertions, 10 deletions
diff --git a/include/linux/fault-inject.h b/include/linux/fault-inject.h
index c6f996f2abb6..798fad9e420d 100644
--- a/include/linux/fault-inject.h
+++ b/include/linux/fault-inject.h
@@ -5,6 +5,7 @@
5 5
6#include <linux/types.h> 6#include <linux/types.h>
7#include <linux/debugfs.h> 7#include <linux/debugfs.h>
8#include <linux/ratelimit.h>
8#include <linux/atomic.h> 9#include <linux/atomic.h>
9 10
10/* 11/*
@@ -25,14 +26,18 @@ struct fault_attr {
25 unsigned long reject_end; 26 unsigned long reject_end;
26 27
27 unsigned long count; 28 unsigned long count;
29 struct ratelimit_state ratelimit_state;
30 struct dentry *dname;
28}; 31};
29 32
30#define FAULT_ATTR_INITIALIZER { \ 33#define FAULT_ATTR_INITIALIZER { \
31 .interval = 1, \ 34 .interval = 1, \
32 .times = ATOMIC_INIT(1), \ 35 .times = ATOMIC_INIT(1), \
33 .require_end = ULONG_MAX, \ 36 .require_end = ULONG_MAX, \
34 .stacktrace_depth = 32, \ 37 .stacktrace_depth = 32, \
35 .verbose = 2, \ 38 .ratelimit_state = RATELIMIT_STATE_INIT_DISABLED, \
39 .verbose = 2, \
40 .dname = NULL, \
36 } 41 }
37 42
38#define DECLARE_FAULT_ATTR(name) struct fault_attr name = FAULT_ATTR_INITIALIZER 43#define DECLARE_FAULT_ATTR(name) struct fault_attr name = FAULT_ATTR_INITIALIZER
diff --git a/lib/fault-inject.c b/lib/fault-inject.c
index d7d501ea856d..f1cdeb024d17 100644
--- a/lib/fault-inject.c
+++ b/lib/fault-inject.c
@@ -40,10 +40,16 @@ EXPORT_SYMBOL_GPL(setup_fault_attr);
40 40
41static void fail_dump(struct fault_attr *attr) 41static void fail_dump(struct fault_attr *attr)
42{ 42{
43 if (attr->verbose > 0) 43 if (attr->verbose > 0 && __ratelimit(&attr->ratelimit_state)) {
44 printk(KERN_NOTICE "FAULT_INJECTION: forcing a failure\n"); 44 printk(KERN_NOTICE "FAULT_INJECTION: forcing a failure.\n"
45 if (attr->verbose > 1) 45 "name %pd, interval %lu, probability %lu, "
46 dump_stack(); 46 "space %d, times %d\n", attr->dname,
47 attr->probability, attr->interval,
48 atomic_read(&attr->space),
49 atomic_read(&attr->times));
50 if (attr->verbose > 1)
51 dump_stack();
52 }
47} 53}
48 54
49#define atomic_dec_not_zero(v) atomic_add_unless((v), -1, 0) 55#define atomic_dec_not_zero(v) atomic_add_unless((v), -1, 0)
@@ -202,6 +208,12 @@ struct dentry *fault_create_debugfs_attr(const char *name,
202 goto fail; 208 goto fail;
203 if (!debugfs_create_ul("verbose", mode, dir, &attr->verbose)) 209 if (!debugfs_create_ul("verbose", mode, dir, &attr->verbose))
204 goto fail; 210 goto fail;
211 if (!debugfs_create_u32("verbose_ratelimit_interval_ms", mode, dir,
212 &attr->ratelimit_state.interval))
213 goto fail;
214 if (!debugfs_create_u32("verbose_ratelimit_burst", mode, dir,
215 &attr->ratelimit_state.burst))
216 goto fail;
205 if (!debugfs_create_bool("task-filter", mode, dir, &attr->task_filter)) 217 if (!debugfs_create_bool("task-filter", mode, dir, &attr->task_filter))
206 goto fail; 218 goto fail;
207 219
@@ -222,6 +234,7 @@ struct dentry *fault_create_debugfs_attr(const char *name,
222 234
223#endif /* CONFIG_FAULT_INJECTION_STACKTRACE_FILTER */ 235#endif /* CONFIG_FAULT_INJECTION_STACKTRACE_FILTER */
224 236
237 attr->dname = dget(dir);
225 return dir; 238 return dir;
226fail: 239fail:
227 debugfs_remove_recursive(dir); 240 debugfs_remove_recursive(dir);