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