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