0001
0002 #include <linux/fault-inject.h>
0003 #include <linux/slab.h>
0004 #include <linux/mm.h>
0005 #include "slab.h"
0006
0007 static struct {
0008 struct fault_attr attr;
0009 bool ignore_gfp_reclaim;
0010 bool cache_filter;
0011 } failslab = {
0012 .attr = FAULT_ATTR_INITIALIZER,
0013 .ignore_gfp_reclaim = true,
0014 .cache_filter = false,
0015 };
0016
0017 bool __should_failslab(struct kmem_cache *s, gfp_t gfpflags)
0018 {
0019
0020 if (unlikely(s == kmem_cache))
0021 return false;
0022
0023 if (gfpflags & __GFP_NOFAIL)
0024 return false;
0025
0026 if (failslab.ignore_gfp_reclaim &&
0027 (gfpflags & __GFP_DIRECT_RECLAIM))
0028 return false;
0029
0030 if (failslab.cache_filter && !(s->flags & SLAB_FAILSLAB))
0031 return false;
0032
0033 if (gfpflags & __GFP_NOWARN)
0034 failslab.attr.no_warn = true;
0035
0036 return should_fail(&failslab.attr, s->object_size);
0037 }
0038
0039 static int __init setup_failslab(char *str)
0040 {
0041 return setup_fault_attr(&failslab.attr, str);
0042 }
0043 __setup("failslab=", setup_failslab);
0044
0045 #ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
0046 static int __init failslab_debugfs_init(void)
0047 {
0048 struct dentry *dir;
0049 umode_t mode = S_IFREG | 0600;
0050
0051 dir = fault_create_debugfs_attr("failslab", NULL, &failslab.attr);
0052 if (IS_ERR(dir))
0053 return PTR_ERR(dir);
0054
0055 debugfs_create_bool("ignore-gfp-wait", mode, dir,
0056 &failslab.ignore_gfp_reclaim);
0057 debugfs_create_bool("cache-filter", mode, dir,
0058 &failslab.cache_filter);
0059
0060 return 0;
0061 }
0062
0063 late_initcall(failslab_debugfs_init);
0064
0065 #endif