Root/mm/failslab.c

1#include <linux/fault-inject.h>
2#include <linux/slab.h>
3
4static struct {
5    struct fault_attr attr;
6    u32 ignore_gfp_wait;
7    int cache_filter;
8#ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
9    struct dentry *ignore_gfp_wait_file;
10    struct dentry *cache_filter_file;
11#endif
12} failslab = {
13    .attr = FAULT_ATTR_INITIALIZER,
14    .ignore_gfp_wait = 1,
15    .cache_filter = 0,
16};
17
18bool should_failslab(size_t size, gfp_t gfpflags, unsigned long cache_flags)
19{
20    if (gfpflags & __GFP_NOFAIL)
21        return false;
22
23        if (failslab.ignore_gfp_wait && (gfpflags & __GFP_WAIT))
24        return false;
25
26    if (failslab.cache_filter && !(cache_flags & SLAB_FAILSLAB))
27        return false;
28
29    return should_fail(&failslab.attr, size);
30}
31
32static int __init setup_failslab(char *str)
33{
34    return setup_fault_attr(&failslab.attr, str);
35}
36__setup("failslab=", setup_failslab);
37
38#ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
39static int __init failslab_debugfs_init(void)
40{
41    mode_t mode = S_IFREG | S_IRUSR | S_IWUSR;
42    struct dentry *dir;
43    int err;
44
45    err = init_fault_attr_dentries(&failslab.attr, "failslab");
46    if (err)
47        return err;
48    dir = failslab.attr.dentries.dir;
49
50    failslab.ignore_gfp_wait_file =
51        debugfs_create_bool("ignore-gfp-wait", mode, dir,
52                      &failslab.ignore_gfp_wait);
53
54    failslab.cache_filter_file =
55        debugfs_create_bool("cache-filter", mode, dir,
56                      &failslab.cache_filter);
57
58    if (!failslab.ignore_gfp_wait_file ||
59        !failslab.cache_filter_file) {
60        err = -ENOMEM;
61        debugfs_remove(failslab.cache_filter_file);
62        debugfs_remove(failslab.ignore_gfp_wait_file);
63        cleanup_fault_attr_dentries(&failslab.attr);
64    }
65
66    return err;
67}
68
69late_initcall(failslab_debugfs_init);
70
71#endif /* CONFIG_FAULT_INJECTION_DEBUG_FS */
72

Archive Download this file



interactive