xref: /linux/mm/fail_page_alloc.c (revision cdd5b5a9761fd66d17586e4f4ba6588c70e640ea)
1*0866e82eSKefeng Wang // SPDX-License-Identifier: GPL-2.0
2*0866e82eSKefeng Wang #include <linux/fault-inject.h>
3*0866e82eSKefeng Wang #include <linux/mm.h>
4*0866e82eSKefeng Wang 
5*0866e82eSKefeng Wang static struct {
6*0866e82eSKefeng Wang 	struct fault_attr attr;
7*0866e82eSKefeng Wang 
8*0866e82eSKefeng Wang 	bool ignore_gfp_highmem;
9*0866e82eSKefeng Wang 	bool ignore_gfp_reclaim;
10*0866e82eSKefeng Wang 	u32 min_order;
11*0866e82eSKefeng Wang } fail_page_alloc = {
12*0866e82eSKefeng Wang 	.attr = FAULT_ATTR_INITIALIZER,
13*0866e82eSKefeng Wang 	.ignore_gfp_reclaim = true,
14*0866e82eSKefeng Wang 	.ignore_gfp_highmem = true,
15*0866e82eSKefeng Wang 	.min_order = 1,
16*0866e82eSKefeng Wang };
17*0866e82eSKefeng Wang 
setup_fail_page_alloc(char * str)18*0866e82eSKefeng Wang static int __init setup_fail_page_alloc(char *str)
19*0866e82eSKefeng Wang {
20*0866e82eSKefeng Wang 	return setup_fault_attr(&fail_page_alloc.attr, str);
21*0866e82eSKefeng Wang }
22*0866e82eSKefeng Wang __setup("fail_page_alloc=", setup_fail_page_alloc);
23*0866e82eSKefeng Wang 
__should_fail_alloc_page(gfp_t gfp_mask,unsigned int order)24*0866e82eSKefeng Wang bool __should_fail_alloc_page(gfp_t gfp_mask, unsigned int order)
25*0866e82eSKefeng Wang {
26*0866e82eSKefeng Wang 	int flags = 0;
27*0866e82eSKefeng Wang 
28*0866e82eSKefeng Wang 	if (order < fail_page_alloc.min_order)
29*0866e82eSKefeng Wang 		return false;
30*0866e82eSKefeng Wang 	if (gfp_mask & __GFP_NOFAIL)
31*0866e82eSKefeng Wang 		return false;
32*0866e82eSKefeng Wang 	if (fail_page_alloc.ignore_gfp_highmem && (gfp_mask & __GFP_HIGHMEM))
33*0866e82eSKefeng Wang 		return false;
34*0866e82eSKefeng Wang 	if (fail_page_alloc.ignore_gfp_reclaim &&
35*0866e82eSKefeng Wang 			(gfp_mask & __GFP_DIRECT_RECLAIM))
36*0866e82eSKefeng Wang 		return false;
37*0866e82eSKefeng Wang 
38*0866e82eSKefeng Wang 	/* See comment in __should_failslab() */
39*0866e82eSKefeng Wang 	if (gfp_mask & __GFP_NOWARN)
40*0866e82eSKefeng Wang 		flags |= FAULT_NOWARN;
41*0866e82eSKefeng Wang 
42*0866e82eSKefeng Wang 	return should_fail_ex(&fail_page_alloc.attr, 1 << order, flags);
43*0866e82eSKefeng Wang }
44*0866e82eSKefeng Wang 
45*0866e82eSKefeng Wang #ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
46*0866e82eSKefeng Wang 
fail_page_alloc_debugfs(void)47*0866e82eSKefeng Wang static int __init fail_page_alloc_debugfs(void)
48*0866e82eSKefeng Wang {
49*0866e82eSKefeng Wang 	umode_t mode = S_IFREG | 0600;
50*0866e82eSKefeng Wang 	struct dentry *dir;
51*0866e82eSKefeng Wang 
52*0866e82eSKefeng Wang 	dir = fault_create_debugfs_attr("fail_page_alloc", NULL,
53*0866e82eSKefeng Wang 					&fail_page_alloc.attr);
54*0866e82eSKefeng Wang 
55*0866e82eSKefeng Wang 	debugfs_create_bool("ignore-gfp-wait", mode, dir,
56*0866e82eSKefeng Wang 			    &fail_page_alloc.ignore_gfp_reclaim);
57*0866e82eSKefeng Wang 	debugfs_create_bool("ignore-gfp-highmem", mode, dir,
58*0866e82eSKefeng Wang 			    &fail_page_alloc.ignore_gfp_highmem);
59*0866e82eSKefeng Wang 	debugfs_create_u32("min-order", mode, dir, &fail_page_alloc.min_order);
60*0866e82eSKefeng Wang 
61*0866e82eSKefeng Wang 	return 0;
62*0866e82eSKefeng Wang }
63*0866e82eSKefeng Wang 
64*0866e82eSKefeng Wang late_initcall(fail_page_alloc_debugfs);
65*0866e82eSKefeng Wang 
66*0866e82eSKefeng Wang #endif /* CONFIG_FAULT_INJECTION_DEBUG_FS */
67