1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
2773ff60eSAkinobu Mita #include <linux/fault-inject.h>
34c13dd3bSDmitry Monakhov #include <linux/slab.h>
4fab9963aSJesper Dangaard Brouer #include <linux/mm.h>
5fab9963aSJesper Dangaard Brouer #include "slab.h"
6773ff60eSAkinobu Mita
7773ff60eSAkinobu Mita static struct {
8773ff60eSAkinobu Mita struct fault_attr attr;
971baba4bSMel Gorman bool ignore_gfp_reclaim;
10621a5f7aSViresh Kumar bool cache_filter;
11773ff60eSAkinobu Mita } failslab = {
12773ff60eSAkinobu Mita .attr = FAULT_ATTR_INITIALIZER,
1371baba4bSMel Gorman .ignore_gfp_reclaim = true,
14621a5f7aSViresh Kumar .cache_filter = false,
15773ff60eSAkinobu Mita };
16773ff60eSAkinobu Mita
__should_failslab(struct kmem_cache * s,gfp_t gfpflags)174f6923fbSHoward McLauchlan bool __should_failslab(struct kmem_cache *s, gfp_t gfpflags)
18773ff60eSAkinobu Mita {
19*ea4452deSQi Zheng int flags = 0;
20*ea4452deSQi Zheng
21fab9963aSJesper Dangaard Brouer /* No fault-injection for bootstrap cache */
22fab9963aSJesper Dangaard Brouer if (unlikely(s == kmem_cache))
23fab9963aSJesper Dangaard Brouer return false;
24fab9963aSJesper Dangaard Brouer
25773ff60eSAkinobu Mita if (gfpflags & __GFP_NOFAIL)
26773ff60eSAkinobu Mita return false;
27773ff60eSAkinobu Mita
28a9659476SNicolas Boichat if (failslab.ignore_gfp_reclaim &&
29a9659476SNicolas Boichat (gfpflags & __GFP_DIRECT_RECLAIM))
30773ff60eSAkinobu Mita return false;
31773ff60eSAkinobu Mita
32fab9963aSJesper Dangaard Brouer if (failslab.cache_filter && !(s->flags & SLAB_FAILSLAB))
334c13dd3bSDmitry Monakhov return false;
344c13dd3bSDmitry Monakhov
35*ea4452deSQi Zheng /*
36*ea4452deSQi Zheng * In some cases, it expects to specify __GFP_NOWARN
37*ea4452deSQi Zheng * to avoid printing any information(not just a warning),
38*ea4452deSQi Zheng * thus avoiding deadlocks. See commit 6b9dbedbe349 for
39*ea4452deSQi Zheng * details.
40*ea4452deSQi Zheng */
413f913fc5SQi Zheng if (gfpflags & __GFP_NOWARN)
42*ea4452deSQi Zheng flags |= FAULT_NOWARN;
433f913fc5SQi Zheng
44*ea4452deSQi Zheng return should_fail_ex(&failslab.attr, s->object_size, flags);
45773ff60eSAkinobu Mita }
46773ff60eSAkinobu Mita
setup_failslab(char * str)47773ff60eSAkinobu Mita static int __init setup_failslab(char *str)
48773ff60eSAkinobu Mita {
49773ff60eSAkinobu Mita return setup_fault_attr(&failslab.attr, str);
50773ff60eSAkinobu Mita }
51773ff60eSAkinobu Mita __setup("failslab=", setup_failslab);
52773ff60eSAkinobu Mita
53773ff60eSAkinobu Mita #ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
failslab_debugfs_init(void)54773ff60eSAkinobu Mita static int __init failslab_debugfs_init(void)
55773ff60eSAkinobu Mita {
56dd48c085SAkinobu Mita struct dentry *dir;
570825a6f9SJoe Perches umode_t mode = S_IFREG | 0600;
58773ff60eSAkinobu Mita
59dd48c085SAkinobu Mita dir = fault_create_debugfs_attr("failslab", NULL, &failslab.attr);
60dd48c085SAkinobu Mita if (IS_ERR(dir))
61dd48c085SAkinobu Mita return PTR_ERR(dir);
62773ff60eSAkinobu Mita
63d9f7979cSGreg Kroah-Hartman debugfs_create_bool("ignore-gfp-wait", mode, dir,
64d9f7979cSGreg Kroah-Hartman &failslab.ignore_gfp_reclaim);
65d9f7979cSGreg Kroah-Hartman debugfs_create_bool("cache-filter", mode, dir,
66d9f7979cSGreg Kroah-Hartman &failslab.cache_filter);
67773ff60eSAkinobu Mita
68810f09b8SAkinobu Mita return 0;
69773ff60eSAkinobu Mita }
70773ff60eSAkinobu Mita
71773ff60eSAkinobu Mita late_initcall(failslab_debugfs_init);
72773ff60eSAkinobu Mita
73773ff60eSAkinobu Mita #endif /* CONFIG_FAULT_INJECTION_DEBUG_FS */
74