1 // SPDX-License-Identifier: GPL-2.0 2 #include <linux/fault-inject.h> 3 #include <linux/error-injection.h> 4 #include <linux/slab.h> 5 #include <linux/mm.h> 6 #include "slab.h" 7 8 static struct { 9 struct fault_attr attr; 10 bool ignore_gfp_reclaim; 11 bool cache_filter; 12 } failslab = { 13 .attr = FAULT_ATTR_INITIALIZER, 14 .ignore_gfp_reclaim = true, 15 .cache_filter = false, 16 }; 17 18 int should_failslab(struct kmem_cache *s, gfp_t gfpflags) 19 { 20 int flags = 0; 21 22 /* No fault-injection for bootstrap cache */ 23 if (unlikely(s == kmem_cache)) 24 return 0; 25 26 if (gfpflags & __GFP_NOFAIL) 27 return 0; 28 29 if (failslab.ignore_gfp_reclaim && 30 (gfpflags & __GFP_DIRECT_RECLAIM)) 31 return 0; 32 33 if (failslab.cache_filter && !(s->flags & SLAB_FAILSLAB)) 34 return 0; 35 36 /* 37 * In some cases, it expects to specify __GFP_NOWARN 38 * to avoid printing any information(not just a warning), 39 * thus avoiding deadlocks. See commit 6b9dbedbe349 for 40 * details. 41 */ 42 if (gfpflags & __GFP_NOWARN) 43 flags |= FAULT_NOWARN; 44 45 return should_fail_ex(&failslab.attr, s->object_size, flags) ? -ENOMEM : 0; 46 } 47 ALLOW_ERROR_INJECTION(should_failslab, ERRNO); 48 49 static int __init setup_failslab(char *str) 50 { 51 return setup_fault_attr(&failslab.attr, str); 52 } 53 __setup("failslab=", setup_failslab); 54 55 #ifdef CONFIG_FAULT_INJECTION_DEBUG_FS 56 static int __init failslab_debugfs_init(void) 57 { 58 struct dentry *dir; 59 umode_t mode = S_IFREG | 0600; 60 61 dir = fault_create_debugfs_attr("failslab", NULL, &failslab.attr); 62 if (IS_ERR(dir)) 63 return PTR_ERR(dir); 64 65 debugfs_create_bool("ignore-gfp-wait", mode, dir, 66 &failslab.ignore_gfp_reclaim); 67 debugfs_create_bool("cache-filter", mode, dir, 68 &failslab.cache_filter); 69 70 return 0; 71 } 72 73 late_initcall(failslab_debugfs_init); 74 75 #endif /* CONFIG_FAULT_INJECTION_DEBUG_FS */ 76