Commit 3c506efd7e0f615bd9603ce8c06bc4a896952599

Authored by Pekka Enberg

Merge branch 'topic/failslab' into for-linus

Conflicts:

	mm/slub.c

Signed-off-by: Pekka Enberg <penberg@cs.helsinki.fi>

Showing 6 changed files Side-by-side Diff

include/linux/fault-inject.h
... ... @@ -81,5 +81,14 @@
81 81  
82 82 #endif /* CONFIG_FAULT_INJECTION */
83 83  
  84 +#ifdef CONFIG_FAILSLAB
  85 +extern bool should_failslab(size_t size, gfp_t gfpflags);
  86 +#else
  87 +static inline bool should_failslab(size_t size, gfp_t gfpflags)
  88 +{
  89 + return false;
  90 +}
  91 +#endif /* CONFIG_FAILSLAB */
  92 +
84 93 #endif /* _LINUX_FAULT_INJECT_H */
... ... @@ -699,6 +699,7 @@
699 699 config FAILSLAB
700 700 bool "Fault-injection capability for kmalloc"
701 701 depends on FAULT_INJECTION
  702 + depends on SLAB || SLUB
702 703 help
703 704 Provide fault-injection capability for kmalloc.
704 705  
... ... @@ -28,6 +28,7 @@
28 28 obj-$(CONFIG_MMU_NOTIFIER) += mmu_notifier.o
29 29 obj-$(CONFIG_SLAB) += slab.o
30 30 obj-$(CONFIG_SLUB) += slub.o
  31 +obj-$(CONFIG_FAILSLAB) += failslab.o
31 32 obj-$(CONFIG_MEMORY_HOTPLUG) += memory_hotplug.o
32 33 obj-$(CONFIG_FS_XIP) += filemap_xip.o
33 34 obj-$(CONFIG_MIGRATION) += migrate.o
  1 +#include <linux/fault-inject.h>
  2 +
  3 +static struct {
  4 + struct fault_attr attr;
  5 + u32 ignore_gfp_wait;
  6 +#ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
  7 + struct dentry *ignore_gfp_wait_file;
  8 +#endif
  9 +} failslab = {
  10 + .attr = FAULT_ATTR_INITIALIZER,
  11 + .ignore_gfp_wait = 1,
  12 +};
  13 +
  14 +bool should_failslab(size_t size, gfp_t gfpflags)
  15 +{
  16 + if (gfpflags & __GFP_NOFAIL)
  17 + return false;
  18 +
  19 + if (failslab.ignore_gfp_wait && (gfpflags & __GFP_WAIT))
  20 + return false;
  21 +
  22 + return should_fail(&failslab.attr, size);
  23 +}
  24 +
  25 +static int __init setup_failslab(char *str)
  26 +{
  27 + return setup_fault_attr(&failslab.attr, str);
  28 +}
  29 +__setup("failslab=", setup_failslab);
  30 +
  31 +#ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
  32 +
  33 +static int __init failslab_debugfs_init(void)
  34 +{
  35 + mode_t mode = S_IFREG | S_IRUSR | S_IWUSR;
  36 + struct dentry *dir;
  37 + int err;
  38 +
  39 + err = init_fault_attr_dentries(&failslab.attr, "failslab");
  40 + if (err)
  41 + return err;
  42 + dir = failslab.attr.dentries.dir;
  43 +
  44 + failslab.ignore_gfp_wait_file =
  45 + debugfs_create_bool("ignore-gfp-wait", mode, dir,
  46 + &failslab.ignore_gfp_wait);
  47 +
  48 + if (!failslab.ignore_gfp_wait_file) {
  49 + err = -ENOMEM;
  50 + debugfs_remove(failslab.ignore_gfp_wait_file);
  51 + cleanup_fault_attr_dentries(&failslab.attr);
  52 + }
  53 +
  54 + return err;
  55 +}
  56 +
  57 +late_initcall(failslab_debugfs_init);
  58 +
  59 +#endif /* CONFIG_FAULT_INJECTION_DEBUG_FS */
... ... @@ -3108,79 +3108,14 @@
3108 3108 #define cache_alloc_debugcheck_after(a,b,objp,d) (objp)
3109 3109 #endif
3110 3110  
3111   -#ifdef CONFIG_FAILSLAB
3112   -
3113   -static struct failslab_attr {
3114   -
3115   - struct fault_attr attr;
3116   -
3117   - u32 ignore_gfp_wait;
3118   -#ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
3119   - struct dentry *ignore_gfp_wait_file;
3120   -#endif
3121   -
3122   -} failslab = {
3123   - .attr = FAULT_ATTR_INITIALIZER,
3124   - .ignore_gfp_wait = 1,
3125   -};
3126   -
3127   -static int __init setup_failslab(char *str)
  3111 +static bool slab_should_failslab(struct kmem_cache *cachep, gfp_t flags)
3128 3112 {
3129   - return setup_fault_attr(&failslab.attr, str);
3130   -}
3131   -__setup("failslab=", setup_failslab);
3132   -
3133   -static int should_failslab(struct kmem_cache *cachep, gfp_t flags)
3134   -{
3135 3113 if (cachep == &cache_cache)
3136   - return 0;
3137   - if (flags & __GFP_NOFAIL)
3138   - return 0;
3139   - if (failslab.ignore_gfp_wait && (flags & __GFP_WAIT))
3140   - return 0;
  3114 + return false;
3141 3115  
3142   - return should_fail(&failslab.attr, obj_size(cachep));
  3116 + return should_failslab(obj_size(cachep), flags);
3143 3117 }
3144 3118  
3145   -#ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
3146   -
3147   -static int __init failslab_debugfs(void)
3148   -{
3149   - mode_t mode = S_IFREG | S_IRUSR | S_IWUSR;
3150   - struct dentry *dir;
3151   - int err;
3152   -
3153   - err = init_fault_attr_dentries(&failslab.attr, "failslab");
3154   - if (err)
3155   - return err;
3156   - dir = failslab.attr.dentries.dir;
3157   -
3158   - failslab.ignore_gfp_wait_file =
3159   - debugfs_create_bool("ignore-gfp-wait", mode, dir,
3160   - &failslab.ignore_gfp_wait);
3161   -
3162   - if (!failslab.ignore_gfp_wait_file) {
3163   - err = -ENOMEM;
3164   - debugfs_remove(failslab.ignore_gfp_wait_file);
3165   - cleanup_fault_attr_dentries(&failslab.attr);
3166   - }
3167   -
3168   - return err;
3169   -}
3170   -
3171   -late_initcall(failslab_debugfs);
3172   -
3173   -#endif /* CONFIG_FAULT_INJECTION_DEBUG_FS */
3174   -
3175   -#else /* CONFIG_FAILSLAB */
3176   -
3177   -static inline int should_failslab(struct kmem_cache *cachep, gfp_t flags)
3178   -{
3179   - return 0;
3180   -}
3181   -
3182   -#endif /* CONFIG_FAILSLAB */
3183   -
3184 3119 static inline void *____cache_alloc(struct kmem_cache *cachep, gfp_t flags)
3185 3120 {
3186 3121 void *objp;
... ... @@ -3383,7 +3318,7 @@
3383 3318 unsigned long save_flags;
3384 3319 void *ptr;
3385 3320  
3386   - if (should_failslab(cachep, flags))
  3321 + if (slab_should_failslab(cachep, flags))
3387 3322 return NULL;
3388 3323  
3389 3324 cache_alloc_debugcheck_before(cachep, flags);
... ... @@ -3459,7 +3394,7 @@
3459 3394 unsigned long save_flags;
3460 3395 void *objp;
3461 3396  
3462   - if (should_failslab(cachep, flags))
  3397 + if (slab_should_failslab(cachep, flags))
3463 3398 return NULL;
3464 3399  
3465 3400 cache_alloc_debugcheck_before(cachep, flags);
... ... @@ -24,6 +24,7 @@
24 24 #include <linux/kallsyms.h>
25 25 #include <linux/memory.h>
26 26 #include <linux/math64.h>
  27 +#include <linux/fault-inject.h>
27 28  
28 29 /*
29 30 * Lock order:
... ... @@ -1596,6 +1597,10 @@
1596 1597 unsigned int objsize;
1597 1598  
1598 1599 might_sleep_if(gfpflags & __GFP_WAIT);
  1600 +
  1601 + if (should_failslab(s->objsize, gfpflags))
  1602 + return NULL;
  1603 +
1599 1604 local_irq_save(flags);
1600 1605 c = get_cpu_slab(s, smp_processor_id());
1601 1606 objsize = c->objsize;