Skip to contentSkip to conversation

failslab for SLUB

PATCH In review Akinobu Mita 3 participants 6 messages Dec 23, 2008

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 failslab for SLUB

Currently fault-injection capability for SLAB allocator is only available to SLAB. This patch makes it available to SLUB, too.

Cc Christoph Lameter <[email protected]>
Cc Pekka Enberg <[email protected]>
Cc Matt Mackall <[email protected]>
---
 lib/Kconfig.debug |    1 
 mm/slub.c         |   66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 67 insertions(+)
mm/slub.c +66 -0
Index: 2.6-rc/mm/slub.c
===================================================================
@@ -24,6 +24,7 @@
 #include <linux/kallsyms.h>
 #include <linux/memory.h>
 #include <linux/math64.h>
+#include <linux/fault-inject.h>
 
 /*
  * Lock order:
@@ -1573,6 +1574,68 @@ debug:
 	goto unlock_out;
 }
 
+#ifdef CONFIG_FAILSLAB
+
+static struct {
+	struct fault_attr attr;
+	u32 ignore_gfp_wait;
+#ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
+	struct dentry *ignore_gfp_wait_file;
+#endif
+} failslub = {
+	.attr = FAULT_ATTR_INITIALIZER,
+	.ignore_gfp_wait = 1,
+};
+
+static bool should_failslub(struct kmem_cache *s, gfp_t gfpflags)
+{
+	if (gfpflags & __GFP_NOFAIL)
+		return false;
+	if (failslub.ignore_gfp_wait && (gfpflags & __GFP_WAIT))
+		return false;
+
+	return should_fail(&failslub.attr, s->objsize);
+}
+
+#ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
+
+static int __init failslub_debugfs(void)
+{
+	mode_t mode = S_IFREG | S_IRUSR | S_IWUSR;
+	struct dentry *dir;
+	int err;
+
+	err = init_fault_attr_dentries(&failslub.attr, "failslab");
+	if (err)
+		return err;
+	dir = failslub.attr.dentries.dir;
+
+	failslub.ignore_gfp_wait_file =
+		debugfs_create_bool("ignore-gfp-wait", mode, dir,
+				      &failslub.ignore_gfp_wait);
+
+	if (!failslub.ignore_gfp_wait_file) {
+		err = -ENOMEM;
+		debugfs_remove(failslub.ignore_gfp_wait_file);
+		cleanup_fault_attr_dentries(&failslub.attr);
+	}
+
+	return err;
+}
+
+late_initcall(failslub_debugfs);
+
+#endif /* CONFIG_FAULT_INJECTION_DEBUG_FS */
+
+#else /* CONFIG_FAILSLAB */
+
+static inline bool should_failslub(struct kmem_cache *cachep, gfp_t flags)
+{
+	return false;
+}
+
+#endif /* CONFIG_FAILSLAB */
+
 /*
  * Inlined fastpath so that allocation functions (kmalloc, kmem_cache_alloc)
  * have the fastpath folded into their functions. So no function call
@@ -1591,6 +1654,9 @@ static __always_inline void *slab_alloc(
 	unsigned long flags;
 	unsigned int objsize;
 
+	if (should_failslub(s, gfpflags))
+		return NULL;
+
 	local_irq_save(flags);
 	c = get_cpu_slab(s, smp_processor_id());
 	objsize = c->objsize;
lib/Kconfig.debug +1 -0
Index: 2.6-rc/lib/Kconfig.debug
===================================================================
@@ -699,6 +699,7 @@ config FAULT_INJECTION
 config FAILSLAB
 	bool "Fault-injection capability for kmalloc"
 	depends on FAULT_INJECTION
+	depends on SLAB || SLUB
 	help
 	  Provide fault-injection capability for kmalloc.
 

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#1 lore raw

Hi Akinobu,

Quoted 2 lines · Akinobu Mita

Currently fault-injection capability for SLAB allocator is only available to SLAB. This patch makes it available to SLUB, too.

The code duplication in your patch is unfortunate. What do you think of this patch instead?

Pekka

#3 lore raw
In reply to Pekka J Enberg
Quoted 34 lines · Pekka J Enberg

Hi Akinobu,

Quoted 2 lines · Akinobu Mita

Currently fault-injection capability for SLAB allocator is only available to SLAB. This patch makes it available to SLUB, too.

The code duplication in your patch is unfortunate. What do you think of this patch instead?

Pekka

Quoted 1 line
Quoted 1 line

From 98bb6a5dade01ab007b3994a1456b7cac6b1f905 Mon Sep 17 00:00:00 2001

From: Akinobu Mita <[email protected]>
Date: Tue, 23 Dec 2008 19:37:01 +0900
Subject: [PATCH] SLUB: failslab support

Currently fault-injection capability for SLAB allocator is only available to SLAB. This patch makes it available to SLUB, too.

[[email protected]: unify slab and slub implementations]
Cc Christoph Lameter <[email protected]>
Cc Matt Mackall <[email protected]>
---
 include/linux/fault-inject.h |    9 +++++
 lib/Kconfig.debug            |    1 +
 mm/Makefile                  |    1 +
 mm/failslab.c                |   59 +++++++++++++++++++++++++++++++++
 mm/slab.c                    |   75 +++---------------------------------------
 mm/slub.c                    |    4 ++
 6 files changed, 79 insertions(+), 70 deletions(-)
 create mode 100644 mm/failslab.c

[...]

Quoted 153 lines
mm/failslab.c new file +59 -0
new file mode 100644
index 0000000..7c6ea64
@@ -0,0 +1,59 @@
+#include <linux/fault-inject.h>
+
+static struct {
+	struct fault_attr attr;
+	u32 ignore_gfp_wait;
+#ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
+	struct dentry *ignore_gfp_wait_file;
+#endif
+} failslab = {
+	.attr = FAULT_ATTR_INITIALIZER,
+	.ignore_gfp_wait = 1,
+};
+
+bool should_failslab(size_t size, gfp_t gfpflags)
+{
+	if (gfpflags & __GFP_NOFAIL)
+		return false;
+
+        if (failslab.ignore_gfp_wait && (gfpflags & __GFP_WAIT))
+		return false;
+
+	return should_fail(&failslab.attr, size);
+}
+
+static int __init setup_failslab(char *str)
+{
+	return setup_fault_attr(&failslab.attr, str);
+}
+__setup("failslab=", setup_failslab);
+
+#ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
+
+static int __init failslab_debugfs_init(void)
+{
+	mode_t mode = S_IFREG | S_IRUSR | S_IWUSR;
+	struct dentry *dir;
+	int err;
+
+	err = init_fault_attr_dentries(&failslab.attr, "failslab");
+	if (err)
+		return err;
+	dir = failslab.attr.dentries.dir;
+
+	failslab.ignore_gfp_wait_file =
+		debugfs_create_bool("ignore-gfp-wait", mode, dir,
+				      &failslab.ignore_gfp_wait);
+
+	if (!failslab.ignore_gfp_wait_file) {
+		err = -ENOMEM;
+		debugfs_remove(failslab.ignore_gfp_wait_file);
+		cleanup_fault_attr_dentries(&failslab.attr);
+	}
+
+	return err;
+}
+
+late_initcall(failslab_debugfs_init);
+
+#endif /* CONFIG_FAULT_INJECTION_DEBUG_FS */
mm/slab.c +3 -68
index 0918751..c347dd8 100644
@@ -3106,79 +3106,14 @@ static void *cache_alloc_debugcheck_after(struct kmem_cache *cachep,
 #define cache_alloc_debugcheck_after(a,b,objp,d) (objp)
 #endif
 
-#ifdef CONFIG_FAILSLAB
-
-static struct failslab_attr {
-
-	struct fault_attr attr;
-
-	u32 ignore_gfp_wait;
-#ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
-	struct dentry *ignore_gfp_wait_file;
-#endif
-
-} failslab = {
-	.attr = FAULT_ATTR_INITIALIZER,
-	.ignore_gfp_wait = 1,
-};
-
-static int __init setup_failslab(char *str)
-{
-	return setup_fault_attr(&failslab.attr, str);
-}
-__setup("failslab=", setup_failslab);
-
-static int should_failslab(struct kmem_cache *cachep, gfp_t flags)
+static bool slab_should_failslab(struct kmem_cache *cachep, gfp_t flags)
 {
 	if (cachep == &cache_cache)
-		return 0;
-	if (flags & __GFP_NOFAIL)
-		return 0;
-	if (failslab.ignore_gfp_wait && (flags & __GFP_WAIT))
-		return 0;
+		return false;
 
-	return should_fail(&failslab.attr, obj_size(cachep));
+	return should_failslab(obj_size(cachep), flags);
 }
 
-#ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
-
-static int __init failslab_debugfs(void)
-{
-	mode_t mode = S_IFREG | S_IRUSR | S_IWUSR;
-	struct dentry *dir;
-	int err;
-
-	err = init_fault_attr_dentries(&failslab.attr, "failslab");
-	if (err)
-		return err;
-	dir = failslab.attr.dentries.dir;
-
-	failslab.ignore_gfp_wait_file =
-		debugfs_create_bool("ignore-gfp-wait", mode, dir,
-				      &failslab.ignore_gfp_wait);
-
-	if (!failslab.ignore_gfp_wait_file) {
-		err = -ENOMEM;
-		debugfs_remove(failslab.ignore_gfp_wait_file);
-		cleanup_fault_attr_dentries(&failslab.attr);
-	}
-
-	return err;
-}
-
-late_initcall(failslab_debugfs);
-
-#endif /* CONFIG_FAULT_INJECTION_DEBUG_FS */
-
-#else /* CONFIG_FAILSLAB */
-
-static inline int should_failslab(struct kmem_cache *cachep, gfp_t flags)
-{
-	return 0;
-}
-
-#endif /* CONFIG_FAILSLAB */
-
 static inline void *____cache_alloc(struct kmem_cache *cachep, gfp_t flags)
 {
 	void *objp;

mm/slab.c __cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, int nodeid, · line 3319

Quoted 5 lines
mm/slab.c +1 -1
@@ -3381,7 +3316,7 @@ __cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, int nodeid,
 	unsigned long save_flags;
 	void *ptr;
 
-	if (should_failslab(cachep, flags))
+	if (slab_should_failslab(cachep, flags))

should_failslab()?

mm/slab.c __cache_alloc(struct kmem_cache *cachep, gfp_t flags, void *caller) · line 3395

Quoted 9 lines
mm/slab.c +1 -1
 		return NULL;
 
 	cache_alloc_debugcheck_before(cachep, flags);
@@ -3457,7 +3392,7 @@ __cache_alloc(struct kmem_cache *cachep, gfp_t flags, void *caller)
 	unsigned long save_flags;
 	void *objp;
 
-	if (should_failslab(cachep, flags))
+	if (slab_should_failslab(cachep, flags))

should_failslab()?

Hannes

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#4 lore raw

Hi Hannes,

Quoted 8 lines · Johannes Weiner
Quoted 1 line

static inline void *____cache_alloc(struct kmem_cache *cachep,

gfp_t flags)

Quoted 6 lines

{

(quoted diff) +0 -0
 	void *objp;
@@ -3381,7 +3316,7 @@ __cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, int nodeid,
 	unsigned long save_flags;
 	void *ptr;
 
Quoted 4 lines

Review __cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, int nodeid, · line 3319

Quoted 2 lines
(quoted diff) +1 -1
-	if (should_failslab(cachep, flags))
+	if (slab_should_failslab(cachep, flags))

should_failslab()?

No, look at what slab_should_failslab() does. We need to exclude cache_cache in SLAB but not in SLUB.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#5 lore raw
Quoted 11 lines · Pekka Enberg

Hi Hannes,

Quoted 8 lines · Johannes Weiner
Quoted 1 line

static inline void *____cache_alloc(struct kmem_cache *cachep,

gfp_t flags)

Quoted 6 lines

{

(quoted diff) +0 -0
 	void *objp;
@@ -3381,7 +3316,7 @@ __cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, int nodeid,
 	unsigned long save_flags;
 	void *ptr;
 
Quoted 7 lines
Quoted 4 lines

Review __cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, int nodeid, · line 3319

Quoted 2 lines
(quoted diff) +1 -1
-	if (should_failslab(cachep, flags))
+	if (slab_should_failslab(cachep, flags))

should_failslab()?

No, look at what slab_should_failslab() does. We need to exclude cache_cache in SLAB but not in SLUB.

Ah, crap. I missed that small '+' and thought it had been dropped.

Sorry, Pekka.

Hannes

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>