aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorAkinobu Mita <akinobu.mita@gmail.com>2006-12-08 05:39:45 -0500
committerLinus Torvalds <torvalds@woody.osdl.org>2006-12-08 11:29:02 -0500
commit933e312e73f8fc39652bd4d216a5393cc3a014b9 (patch)
treea2aacc2a098c3c95fe5a94fef1a2cc9751bee79b /mm
parent8a8b6502fb669c3a0638a08955442814cedc86b1 (diff)
[PATCH] fault-injection capability for alloc_pages()
This patch provides fault-injection capability for alloc_pages() Boot option: fail_page_alloc=<interval>,<probability>,<space>,<times> <interval> -- specifies the interval of failures. <probability> -- specifies how often it should fail in percent. <space> -- specifies the size of free space where memory can be allocated safely in pages. <times> -- specifies how many times failures may happen at most. Debugfs: /debug/fail_page_alloc/interval /debug/fail_page_alloc/probability /debug/fail_page_alloc/specifies /debug/fail_page_alloc/times /debug/fail_page_alloc/ignore-gfp-highmem /debug/fail_page_alloc/ignore-gfp-wait Example: fail_page_alloc=10,100,0,-1 The page allocation (alloc_pages(), ...) fails once per 10 times. Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'mm')
-rw-r--r--mm/page_alloc.c87
1 files changed, 87 insertions, 0 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 18f0e044c43d..0cc8b4376e91 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -40,6 +40,7 @@
40#include <linux/sort.h> 40#include <linux/sort.h>
41#include <linux/pfn.h> 41#include <linux/pfn.h>
42#include <linux/backing-dev.h> 42#include <linux/backing-dev.h>
43#include <linux/fault-inject.h>
43 44
44#include <asm/tlbflush.h> 45#include <asm/tlbflush.h>
45#include <asm/div64.h> 46#include <asm/div64.h>
@@ -892,6 +893,89 @@ failed:
892#define ALLOC_HIGH 0x20 /* __GFP_HIGH set */ 893#define ALLOC_HIGH 0x20 /* __GFP_HIGH set */
893#define ALLOC_CPUSET 0x40 /* check for correct cpuset */ 894#define ALLOC_CPUSET 0x40 /* check for correct cpuset */
894 895
896#ifdef CONFIG_FAIL_PAGE_ALLOC
897
898static struct fail_page_alloc_attr {
899 struct fault_attr attr;
900
901 u32 ignore_gfp_highmem;
902 u32 ignore_gfp_wait;
903
904#ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
905
906 struct dentry *ignore_gfp_highmem_file;
907 struct dentry *ignore_gfp_wait_file;
908
909#endif /* CONFIG_FAULT_INJECTION_DEBUG_FS */
910
911} fail_page_alloc = {
912 .attr = FAULT_ATTR_INITIALIZER,
913};
914
915static int __init setup_fail_page_alloc(char *str)
916{
917 return setup_fault_attr(&fail_page_alloc.attr, str);
918}
919__setup("fail_page_alloc=", setup_fail_page_alloc);
920
921static int should_fail_alloc_page(gfp_t gfp_mask, unsigned int order)
922{
923 if (gfp_mask & __GFP_NOFAIL)
924 return 0;
925 if (fail_page_alloc.ignore_gfp_highmem && (gfp_mask & __GFP_HIGHMEM))
926 return 0;
927 if (fail_page_alloc.ignore_gfp_wait && (gfp_mask & __GFP_WAIT))
928 return 0;
929
930 return should_fail(&fail_page_alloc.attr, 1 << order);
931}
932
933#ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
934
935static int __init fail_page_alloc_debugfs(void)
936{
937 mode_t mode = S_IFREG | S_IRUSR | S_IWUSR;
938 struct dentry *dir;
939 int err;
940
941 err = init_fault_attr_dentries(&fail_page_alloc.attr,
942 "fail_page_alloc");
943 if (err)
944 return err;
945 dir = fail_page_alloc.attr.dentries.dir;
946
947 fail_page_alloc.ignore_gfp_wait_file =
948 debugfs_create_bool("ignore-gfp-wait", mode, dir,
949 &fail_page_alloc.ignore_gfp_wait);
950
951 fail_page_alloc.ignore_gfp_highmem_file =
952 debugfs_create_bool("ignore-gfp-highmem", mode, dir,
953 &fail_page_alloc.ignore_gfp_highmem);
954
955 if (!fail_page_alloc.ignore_gfp_wait_file ||
956 !fail_page_alloc.ignore_gfp_highmem_file) {
957 err = -ENOMEM;
958 debugfs_remove(fail_page_alloc.ignore_gfp_wait_file);
959 debugfs_remove(fail_page_alloc.ignore_gfp_highmem_file);
960 cleanup_fault_attr_dentries(&fail_page_alloc.attr);
961 }
962
963 return err;
964}
965
966late_initcall(fail_page_alloc_debugfs);
967
968#endif /* CONFIG_FAULT_INJECTION_DEBUG_FS */
969
970#else /* CONFIG_FAIL_PAGE_ALLOC */
971
972static inline int should_fail_alloc_page(gfp_t gfp_mask, unsigned int order)
973{
974 return 0;
975}
976
977#endif /* CONFIG_FAIL_PAGE_ALLOC */
978
895/* 979/*
896 * Return 1 if free pages are above 'mark'. This takes into account the order 980 * Return 1 if free pages are above 'mark'. This takes into account the order
897 * of the allocation. 981 * of the allocation.
@@ -1136,6 +1220,9 @@ __alloc_pages(gfp_t gfp_mask, unsigned int order,
1136 1220
1137 might_sleep_if(wait); 1221 might_sleep_if(wait);
1138 1222
1223 if (should_fail_alloc_page(gfp_mask, order))
1224 return NULL;
1225
1139restart: 1226restart:
1140 z = zonelist->zones; /* the list of zones suitable for gfp_mask */ 1227 z = zonelist->zones; /* the list of zones suitable for gfp_mask */
1141 1228