All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] move kmem_cache_free to common code.
@ 2012-10-22 14:05 ` Glauber Costa
  0 siblings, 0 replies; 40+ messages in thread
From: Glauber Costa @ 2012-10-22 14:05 UTC (permalink / raw)
  To: linux-mm; +Cc: linux-kernel, Christoph Lameter, Pekka Enberg, David Rientjes

This is some initial work to make kmem_cache_free at least callable from
a common entry point. This will be useful in future work, like kmemcg-slab,
that needs to further change those callers in both slab and slub.

Patch1 is not really a dependency for 2, but it will be for the work I am doing
in kmemcg-slab, so I'm sending both patches for your appreciation.

Glauber Costa (2):
  slab: commonize slab_cache field in struct page
  slab: move kmem_cache_free to common code

 include/linux/mm_types.h |  7 ++-----
 mm/slab.c                | 13 +------------
 mm/slab.h                |  1 +
 mm/slab_common.c         | 17 +++++++++++++++++
 mm/slob.c                | 11 ++++-------
 mm/slub.c                | 29 +++++++++++++----------------
 6 files changed, 38 insertions(+), 40 deletions(-)

-- 
1.7.11.7


^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 0/2] move kmem_cache_free to common code.
@ 2012-10-22 14:05 ` Glauber Costa
  0 siblings, 0 replies; 40+ messages in thread
From: Glauber Costa @ 2012-10-22 14:05 UTC (permalink / raw)
  To: linux-mm; +Cc: linux-kernel, Christoph Lameter, Pekka Enberg, David Rientjes

This is some initial work to make kmem_cache_free at least callable from
a common entry point. This will be useful in future work, like kmemcg-slab,
that needs to further change those callers in both slab and slub.

Patch1 is not really a dependency for 2, but it will be for the work I am doing
in kmemcg-slab, so I'm sending both patches for your appreciation.

Glauber Costa (2):
  slab: commonize slab_cache field in struct page
  slab: move kmem_cache_free to common code

 include/linux/mm_types.h |  7 ++-----
 mm/slab.c                | 13 +------------
 mm/slab.h                |  1 +
 mm/slab_common.c         | 17 +++++++++++++++++
 mm/slob.c                | 11 ++++-------
 mm/slub.c                | 29 +++++++++++++----------------
 6 files changed, 38 insertions(+), 40 deletions(-)

-- 
1.7.11.7

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

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 1/2] slab: commonize slab_cache field in struct page
  2012-10-22 14:05 ` Glauber Costa
@ 2012-10-22 14:05   ` Glauber Costa
  -1 siblings, 0 replies; 40+ messages in thread
From: Glauber Costa @ 2012-10-22 14:05 UTC (permalink / raw)
  To: linux-mm
  Cc: linux-kernel, Glauber Costa, Christoph Lameter, Pekka Enberg,
	David Rientjes

Right now, slab and slub have fields in struct page to derive which
cache a page belongs to, but they do it slightly differently.

slab uses a field called slab_cache, that lives in the third double
word. slub, uses a field called "slab", living outside of the
doublewords area.

Ideally, we could use the same field for this. Since slub heavily makes
use of the doubleword region, there isn't really much room to move
slub's slab_cache field around. Since slab does not have such strict
placement restrictions, we can move it outside the doubleword area.

The naming used by slab, "slab_cache", is less confusing, and it is
preferred over slub's generic "slab".

Signed-off-by: Glauber Costa <glommer@parallels.com>
CC: Christoph Lameter <cl@linux.com>
CC: Pekka Enberg <penberg@kernel.org>
CC: David Rientjes <rientjes@google.com>
---
 include/linux/mm_types.h |  7 ++-----
 mm/slub.c                | 24 ++++++++++++------------
 2 files changed, 14 insertions(+), 17 deletions(-)

diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index 31f8a3a..2fef4e7 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -128,10 +128,7 @@ struct page {
 		};
 
 		struct list_head list;	/* slobs list of pages */
-		struct {		/* slab fields */
-			struct kmem_cache *slab_cache;
-			struct slab *slab_page;
-		};
+		struct slab *slab_page; /* slab fields */
 	};
 
 	/* Remainder is not double word aligned */
@@ -146,7 +143,7 @@ struct page {
 #if USE_SPLIT_PTLOCKS
 		spinlock_t ptl;
 #endif
-		struct kmem_cache *slab;	/* SLUB: Pointer to slab */
+		struct kmem_cache *slab_cache;	/* SL[AU]B: Pointer to slab */
 		struct page *first_page;	/* Compound tail pages */
 	};
 
diff --git a/mm/slub.c b/mm/slub.c
index a34548e..259bc2c 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -1087,11 +1087,11 @@ static noinline struct kmem_cache_node *free_debug_processing(
 	if (!check_object(s, page, object, SLUB_RED_ACTIVE))
 		goto out;
 
-	if (unlikely(s != page->slab)) {
+	if (unlikely(s != page->slab_cache)) {
 		if (!PageSlab(page)) {
 			slab_err(s, page, "Attempt to free object(0x%p) "
 				"outside of slab", object);
-		} else if (!page->slab) {
+		} else if (!page->slab_cache) {
 			printk(KERN_ERR
 				"SLUB <none>: no slab for object 0x%p.\n",
 						object);
@@ -1352,7 +1352,7 @@ static struct page *new_slab(struct kmem_cache *s, gfp_t flags, int node)
 		goto out;
 
 	inc_slabs_node(s, page_to_nid(page), page->objects);
-	page->slab = s;
+	page->slab_cache = s;
 	__SetPageSlab(page);
 	if (page->pfmemalloc)
 		SetPageSlabPfmemalloc(page);
@@ -1419,7 +1419,7 @@ static void rcu_free_slab(struct rcu_head *h)
 	else
 		page = container_of((struct list_head *)h, struct page, lru);
 
-	__free_slab(page->slab, page);
+	__free_slab(page->slab_cache, page);
 }
 
 static void free_slab(struct kmem_cache *s, struct page *page)
@@ -2612,9 +2612,9 @@ void kmem_cache_free(struct kmem_cache *s, void *x)
 
 	page = virt_to_head_page(x);
 
-	if (kmem_cache_debug(s) && page->slab != s) {
+	if (kmem_cache_debug(s) && page->slab_cache != s) {
 		pr_err("kmem_cache_free: Wrong slab cache. %s but object"
-			" is from  %s\n", page->slab->name, s->name);
+			" is from  %s\n", page->slab_cache->name, s->name);
 		WARN_ON_ONCE(1);
 		return;
 	}
@@ -3413,7 +3413,7 @@ size_t ksize(const void *object)
 		return PAGE_SIZE << compound_order(page);
 	}
 
-	return slab_ksize(page->slab);
+	return slab_ksize(page->slab_cache);
 }
 EXPORT_SYMBOL(ksize);
 
@@ -3438,8 +3438,8 @@ bool verify_mem_not_deleted(const void *x)
 	}
 
 	slab_lock(page);
-	if (on_freelist(page->slab, page, object)) {
-		object_err(page->slab, page, object, "Object is on free-list");
+	if (on_freelist(page->slab_cache, page, object)) {
+		object_err(page->slab_cache, page, object, "Object is on free-list");
 		rv = false;
 	} else {
 		rv = true;
@@ -3470,7 +3470,7 @@ void kfree(const void *x)
 		__free_pages(page, compound_order(page));
 		return;
 	}
-	slab_free(page->slab, page, object, _RET_IP_);
+	slab_free(page->slab_cache, page, object, _RET_IP_);
 }
 EXPORT_SYMBOL(kfree);
 
@@ -3681,11 +3681,11 @@ static void __init kmem_cache_bootstrap_fixup(struct kmem_cache *s)
 
 		if (n) {
 			list_for_each_entry(p, &n->partial, lru)
-				p->slab = s;
+				p->slab_cache = s;
 
 #ifdef CONFIG_SLUB_DEBUG
 			list_for_each_entry(p, &n->full, lru)
-				p->slab = s;
+				p->slab_cache = s;
 #endif
 		}
 	}
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH 1/2] slab: commonize slab_cache field in struct page
@ 2012-10-22 14:05   ` Glauber Costa
  0 siblings, 0 replies; 40+ messages in thread
From: Glauber Costa @ 2012-10-22 14:05 UTC (permalink / raw)
  To: linux-mm
  Cc: linux-kernel, Glauber Costa, Christoph Lameter, Pekka Enberg,
	David Rientjes

Right now, slab and slub have fields in struct page to derive which
cache a page belongs to, but they do it slightly differently.

slab uses a field called slab_cache, that lives in the third double
word. slub, uses a field called "slab", living outside of the
doublewords area.

Ideally, we could use the same field for this. Since slub heavily makes
use of the doubleword region, there isn't really much room to move
slub's slab_cache field around. Since slab does not have such strict
placement restrictions, we can move it outside the doubleword area.

The naming used by slab, "slab_cache", is less confusing, and it is
preferred over slub's generic "slab".

Signed-off-by: Glauber Costa <glommer@parallels.com>
CC: Christoph Lameter <cl@linux.com>
CC: Pekka Enberg <penberg@kernel.org>
CC: David Rientjes <rientjes@google.com>
---
 include/linux/mm_types.h |  7 ++-----
 mm/slub.c                | 24 ++++++++++++------------
 2 files changed, 14 insertions(+), 17 deletions(-)

diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index 31f8a3a..2fef4e7 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -128,10 +128,7 @@ struct page {
 		};
 
 		struct list_head list;	/* slobs list of pages */
-		struct {		/* slab fields */
-			struct kmem_cache *slab_cache;
-			struct slab *slab_page;
-		};
+		struct slab *slab_page; /* slab fields */
 	};
 
 	/* Remainder is not double word aligned */
@@ -146,7 +143,7 @@ struct page {
 #if USE_SPLIT_PTLOCKS
 		spinlock_t ptl;
 #endif
-		struct kmem_cache *slab;	/* SLUB: Pointer to slab */
+		struct kmem_cache *slab_cache;	/* SL[AU]B: Pointer to slab */
 		struct page *first_page;	/* Compound tail pages */
 	};
 
diff --git a/mm/slub.c b/mm/slub.c
index a34548e..259bc2c 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -1087,11 +1087,11 @@ static noinline struct kmem_cache_node *free_debug_processing(
 	if (!check_object(s, page, object, SLUB_RED_ACTIVE))
 		goto out;
 
-	if (unlikely(s != page->slab)) {
+	if (unlikely(s != page->slab_cache)) {
 		if (!PageSlab(page)) {
 			slab_err(s, page, "Attempt to free object(0x%p) "
 				"outside of slab", object);
-		} else if (!page->slab) {
+		} else if (!page->slab_cache) {
 			printk(KERN_ERR
 				"SLUB <none>: no slab for object 0x%p.\n",
 						object);
@@ -1352,7 +1352,7 @@ static struct page *new_slab(struct kmem_cache *s, gfp_t flags, int node)
 		goto out;
 
 	inc_slabs_node(s, page_to_nid(page), page->objects);
-	page->slab = s;
+	page->slab_cache = s;
 	__SetPageSlab(page);
 	if (page->pfmemalloc)
 		SetPageSlabPfmemalloc(page);
@@ -1419,7 +1419,7 @@ static void rcu_free_slab(struct rcu_head *h)
 	else
 		page = container_of((struct list_head *)h, struct page, lru);
 
-	__free_slab(page->slab, page);
+	__free_slab(page->slab_cache, page);
 }
 
 static void free_slab(struct kmem_cache *s, struct page *page)
@@ -2612,9 +2612,9 @@ void kmem_cache_free(struct kmem_cache *s, void *x)
 
 	page = virt_to_head_page(x);
 
-	if (kmem_cache_debug(s) && page->slab != s) {
+	if (kmem_cache_debug(s) && page->slab_cache != s) {
 		pr_err("kmem_cache_free: Wrong slab cache. %s but object"
-			" is from  %s\n", page->slab->name, s->name);
+			" is from  %s\n", page->slab_cache->name, s->name);
 		WARN_ON_ONCE(1);
 		return;
 	}
@@ -3413,7 +3413,7 @@ size_t ksize(const void *object)
 		return PAGE_SIZE << compound_order(page);
 	}
 
-	return slab_ksize(page->slab);
+	return slab_ksize(page->slab_cache);
 }
 EXPORT_SYMBOL(ksize);
 
@@ -3438,8 +3438,8 @@ bool verify_mem_not_deleted(const void *x)
 	}
 
 	slab_lock(page);
-	if (on_freelist(page->slab, page, object)) {
-		object_err(page->slab, page, object, "Object is on free-list");
+	if (on_freelist(page->slab_cache, page, object)) {
+		object_err(page->slab_cache, page, object, "Object is on free-list");
 		rv = false;
 	} else {
 		rv = true;
@@ -3470,7 +3470,7 @@ void kfree(const void *x)
 		__free_pages(page, compound_order(page));
 		return;
 	}
-	slab_free(page->slab, page, object, _RET_IP_);
+	slab_free(page->slab_cache, page, object, _RET_IP_);
 }
 EXPORT_SYMBOL(kfree);
 
@@ -3681,11 +3681,11 @@ static void __init kmem_cache_bootstrap_fixup(struct kmem_cache *s)
 
 		if (n) {
 			list_for_each_entry(p, &n->partial, lru)
-				p->slab = s;
+				p->slab_cache = s;
 
 #ifdef CONFIG_SLUB_DEBUG
 			list_for_each_entry(p, &n->full, lru)
-				p->slab = s;
+				p->slab_cache = s;
 #endif
 		}
 	}
-- 
1.7.11.7

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

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH 2/2] slab: move kmem_cache_free to common code
  2012-10-22 14:05 ` Glauber Costa
@ 2012-10-22 14:05   ` Glauber Costa
  -1 siblings, 0 replies; 40+ messages in thread
From: Glauber Costa @ 2012-10-22 14:05 UTC (permalink / raw)
  To: linux-mm
  Cc: linux-kernel, Glauber Costa, Christoph Lameter, Pekka Enberg,
	David Rientjes

In the effort of commonizing the slab allocators, it would be better if
we had a single entry-point for kmem_cache_free. The low-level freeing
is still left to the allocators, But at least the tracing can be done in
slab_common.c

Signed-off-by: Glauber Costa <glommer@parallels.com>
CC: Christoph Lameter <cl@linux.com>
CC: Pekka Enberg <penberg@kernel.org>
CC: David Rientjes <rientjes@google.com>

---
 mm/slab.c        | 13 +------------
 mm/slab.h        |  1 +
 mm/slab_common.c | 17 +++++++++++++++++
 mm/slob.c        | 11 ++++-------
 mm/slub.c        |  5 +----
 5 files changed, 24 insertions(+), 23 deletions(-)

diff --git a/mm/slab.c b/mm/slab.c
index 98b3460..b8171ab 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -3903,15 +3903,7 @@ void *__kmalloc(size_t size, gfp_t flags)
 EXPORT_SYMBOL(__kmalloc);
 #endif
 
-/**
- * kmem_cache_free - Deallocate an object
- * @cachep: The cache the allocation was from.
- * @objp: The previously allocated object.
- *
- * Free an object which was previously allocated from this
- * cache.
- */
-void kmem_cache_free(struct kmem_cache *cachep, void *objp)
+void __kmem_cache_free(struct kmem_cache *cachep, void *objp)
 {
 	unsigned long flags;
 
@@ -3921,10 +3913,7 @@ void kmem_cache_free(struct kmem_cache *cachep, void *objp)
 		debug_check_no_obj_freed(objp, cachep->object_size);
 	__cache_free(cachep, objp, __builtin_return_address(0));
 	local_irq_restore(flags);
-
-	trace_kmem_cache_free(_RET_IP_, objp);
 }
-EXPORT_SYMBOL(kmem_cache_free);
 
 /**
  * kfree - free previously allocated memory
diff --git a/mm/slab.h b/mm/slab.h
index 66a62d3..dc1024f 100644
--- a/mm/slab.h
+++ b/mm/slab.h
@@ -34,6 +34,7 @@ extern struct kmem_cache *kmem_cache;
 
 /* Functions provided by the slab allocators */
 extern int __kmem_cache_create(struct kmem_cache *, unsigned long flags);
+extern void __kmem_cache_free(struct kmem_cache *s, void *x);
 
 #ifdef CONFIG_SLUB
 struct kmem_cache *__kmem_cache_alias(const char *name, size_t size,
diff --git a/mm/slab_common.c b/mm/slab_common.c
index bf4b4f1..3b9d5c5 100644
--- a/mm/slab_common.c
+++ b/mm/slab_common.c
@@ -19,6 +19,8 @@
 #include <asm/tlbflush.h>
 #include <asm/page.h>
 
+#include <trace/events/kmem.h>
+
 #include "slab.h"
 
 enum slab_state slab_state;
@@ -168,6 +170,21 @@ out_locked:
 }
 EXPORT_SYMBOL(kmem_cache_create);
 
+/**
+ * kmem_cache_free - Deallocate an object
+ * @cachep: The cache the allocation was from.
+ * @objp: The previously allocated object.
+ *
+ * Free an object which was previously allocated from this
+ * cache.
+ */
+void kmem_cache_free(struct kmem_cache *s, void *x)
+{
+	__kmem_cache_free(s, x);
+	trace_kmem_cache_free(_RET_IP_, x);
+}
+EXPORT_SYMBOL(kmem_cache_free);
+
 void kmem_cache_destroy(struct kmem_cache *s)
 {
 	get_online_cpus();
diff --git a/mm/slob.c b/mm/slob.c
index 3edfeaa..d131f75 100644
--- a/mm/slob.c
+++ b/mm/slob.c
@@ -555,7 +555,7 @@ void *kmem_cache_alloc_node(struct kmem_cache *c, gfp_t flags, int node)
 }
 EXPORT_SYMBOL(kmem_cache_alloc_node);
 
-static void __kmem_cache_free(void *b, int size)
+static void do_kmem_cache_free(void *b, int size)
 {
 	if (size < PAGE_SIZE)
 		slob_free(b, size);
@@ -568,10 +568,10 @@ static void kmem_rcu_free(struct rcu_head *head)
 	struct slob_rcu *slob_rcu = (struct slob_rcu *)head;
 	void *b = (void *)slob_rcu - (slob_rcu->size - sizeof(struct slob_rcu));
 
-	__kmem_cache_free(b, slob_rcu->size);
+	do_kmem_cache_free(b, slob_rcu->size);
 }
 
-void kmem_cache_free(struct kmem_cache *c, void *b)
+void __kmem_cache_free(struct kmem_cache *c, void *b)
 {
 	kmemleak_free_recursive(b, c->flags);
 	if (unlikely(c->flags & SLAB_DESTROY_BY_RCU)) {
@@ -580,12 +580,9 @@ void kmem_cache_free(struct kmem_cache *c, void *b)
 		slob_rcu->size = c->size;
 		call_rcu(&slob_rcu->head, kmem_rcu_free);
 	} else {
-		__kmem_cache_free(b, c->size);
+		do_kmem_cache_free(b, c->size);
 	}
-
-	trace_kmem_cache_free(_RET_IP_, b);
 }
-EXPORT_SYMBOL(kmem_cache_free);
 
 unsigned int kmem_cache_size(struct kmem_cache *c)
 {
diff --git a/mm/slub.c b/mm/slub.c
index 259bc2c..0c512de 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -2606,7 +2606,7 @@ redo:
 
 }
 
-void kmem_cache_free(struct kmem_cache *s, void *x)
+void __kmem_cache_free(struct kmem_cache *s, void *x)
 {
 	struct page *page;
 
@@ -2620,10 +2620,7 @@ void kmem_cache_free(struct kmem_cache *s, void *x)
 	}
 
 	slab_free(s, page, x, _RET_IP_);
-
-	trace_kmem_cache_free(_RET_IP_, x);
 }
-EXPORT_SYMBOL(kmem_cache_free);
 
 /*
  * Object placement in a slab is made very easy because we always start at
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH 2/2] slab: move kmem_cache_free to common code
@ 2012-10-22 14:05   ` Glauber Costa
  0 siblings, 0 replies; 40+ messages in thread
From: Glauber Costa @ 2012-10-22 14:05 UTC (permalink / raw)
  To: linux-mm
  Cc: linux-kernel, Glauber Costa, Christoph Lameter, Pekka Enberg,
	David Rientjes

In the effort of commonizing the slab allocators, it would be better if
we had a single entry-point for kmem_cache_free. The low-level freeing
is still left to the allocators, But at least the tracing can be done in
slab_common.c

Signed-off-by: Glauber Costa <glommer@parallels.com>
CC: Christoph Lameter <cl@linux.com>
CC: Pekka Enberg <penberg@kernel.org>
CC: David Rientjes <rientjes@google.com>

---
 mm/slab.c        | 13 +------------
 mm/slab.h        |  1 +
 mm/slab_common.c | 17 +++++++++++++++++
 mm/slob.c        | 11 ++++-------
 mm/slub.c        |  5 +----
 5 files changed, 24 insertions(+), 23 deletions(-)

diff --git a/mm/slab.c b/mm/slab.c
index 98b3460..b8171ab 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -3903,15 +3903,7 @@ void *__kmalloc(size_t size, gfp_t flags)
 EXPORT_SYMBOL(__kmalloc);
 #endif
 
-/**
- * kmem_cache_free - Deallocate an object
- * @cachep: The cache the allocation was from.
- * @objp: The previously allocated object.
- *
- * Free an object which was previously allocated from this
- * cache.
- */
-void kmem_cache_free(struct kmem_cache *cachep, void *objp)
+void __kmem_cache_free(struct kmem_cache *cachep, void *objp)
 {
 	unsigned long flags;
 
@@ -3921,10 +3913,7 @@ void kmem_cache_free(struct kmem_cache *cachep, void *objp)
 		debug_check_no_obj_freed(objp, cachep->object_size);
 	__cache_free(cachep, objp, __builtin_return_address(0));
 	local_irq_restore(flags);
-
-	trace_kmem_cache_free(_RET_IP_, objp);
 }
-EXPORT_SYMBOL(kmem_cache_free);
 
 /**
  * kfree - free previously allocated memory
diff --git a/mm/slab.h b/mm/slab.h
index 66a62d3..dc1024f 100644
--- a/mm/slab.h
+++ b/mm/slab.h
@@ -34,6 +34,7 @@ extern struct kmem_cache *kmem_cache;
 
 /* Functions provided by the slab allocators */
 extern int __kmem_cache_create(struct kmem_cache *, unsigned long flags);
+extern void __kmem_cache_free(struct kmem_cache *s, void *x);
 
 #ifdef CONFIG_SLUB
 struct kmem_cache *__kmem_cache_alias(const char *name, size_t size,
diff --git a/mm/slab_common.c b/mm/slab_common.c
index bf4b4f1..3b9d5c5 100644
--- a/mm/slab_common.c
+++ b/mm/slab_common.c
@@ -19,6 +19,8 @@
 #include <asm/tlbflush.h>
 #include <asm/page.h>
 
+#include <trace/events/kmem.h>
+
 #include "slab.h"
 
 enum slab_state slab_state;
@@ -168,6 +170,21 @@ out_locked:
 }
 EXPORT_SYMBOL(kmem_cache_create);
 
+/**
+ * kmem_cache_free - Deallocate an object
+ * @cachep: The cache the allocation was from.
+ * @objp: The previously allocated object.
+ *
+ * Free an object which was previously allocated from this
+ * cache.
+ */
+void kmem_cache_free(struct kmem_cache *s, void *x)
+{
+	__kmem_cache_free(s, x);
+	trace_kmem_cache_free(_RET_IP_, x);
+}
+EXPORT_SYMBOL(kmem_cache_free);
+
 void kmem_cache_destroy(struct kmem_cache *s)
 {
 	get_online_cpus();
diff --git a/mm/slob.c b/mm/slob.c
index 3edfeaa..d131f75 100644
--- a/mm/slob.c
+++ b/mm/slob.c
@@ -555,7 +555,7 @@ void *kmem_cache_alloc_node(struct kmem_cache *c, gfp_t flags, int node)
 }
 EXPORT_SYMBOL(kmem_cache_alloc_node);
 
-static void __kmem_cache_free(void *b, int size)
+static void do_kmem_cache_free(void *b, int size)
 {
 	if (size < PAGE_SIZE)
 		slob_free(b, size);
@@ -568,10 +568,10 @@ static void kmem_rcu_free(struct rcu_head *head)
 	struct slob_rcu *slob_rcu = (struct slob_rcu *)head;
 	void *b = (void *)slob_rcu - (slob_rcu->size - sizeof(struct slob_rcu));
 
-	__kmem_cache_free(b, slob_rcu->size);
+	do_kmem_cache_free(b, slob_rcu->size);
 }
 
-void kmem_cache_free(struct kmem_cache *c, void *b)
+void __kmem_cache_free(struct kmem_cache *c, void *b)
 {
 	kmemleak_free_recursive(b, c->flags);
 	if (unlikely(c->flags & SLAB_DESTROY_BY_RCU)) {
@@ -580,12 +580,9 @@ void kmem_cache_free(struct kmem_cache *c, void *b)
 		slob_rcu->size = c->size;
 		call_rcu(&slob_rcu->head, kmem_rcu_free);
 	} else {
-		__kmem_cache_free(b, c->size);
+		do_kmem_cache_free(b, c->size);
 	}
-
-	trace_kmem_cache_free(_RET_IP_, b);
 }
-EXPORT_SYMBOL(kmem_cache_free);
 
 unsigned int kmem_cache_size(struct kmem_cache *c)
 {
diff --git a/mm/slub.c b/mm/slub.c
index 259bc2c..0c512de 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -2606,7 +2606,7 @@ redo:
 
 }
 
-void kmem_cache_free(struct kmem_cache *s, void *x)
+void __kmem_cache_free(struct kmem_cache *s, void *x)
 {
 	struct page *page;
 
@@ -2620,10 +2620,7 @@ void kmem_cache_free(struct kmem_cache *s, void *x)
 	}
 
 	slab_free(s, page, x, _RET_IP_);
-
-	trace_kmem_cache_free(_RET_IP_, x);
 }
-EXPORT_SYMBOL(kmem_cache_free);
 
 /*
  * Object placement in a slab is made very easy because we always start at
-- 
1.7.11.7

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

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* Re: [PATCH 1/2] slab: commonize slab_cache field in struct page
  2012-10-22 14:05   ` Glauber Costa
@ 2012-10-22 14:44     ` Christoph Lameter
  -1 siblings, 0 replies; 40+ messages in thread
From: Christoph Lameter @ 2012-10-22 14:44 UTC (permalink / raw)
  To: Glauber Costa; +Cc: linux-mm, linux-kernel, Pekka Enberg, David Rientjes

On Mon, 22 Oct 2012, Glauber Costa wrote:

> The naming used by slab, "slab_cache", is less confusing, and it is
> preferred over slub's generic "slab".

Acked-by: Christoph Lameter <cl@linux.com>

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 1/2] slab: commonize slab_cache field in struct page
@ 2012-10-22 14:44     ` Christoph Lameter
  0 siblings, 0 replies; 40+ messages in thread
From: Christoph Lameter @ 2012-10-22 14:44 UTC (permalink / raw)
  To: Glauber Costa; +Cc: linux-mm, linux-kernel, Pekka Enberg, David Rientjes

On Mon, 22 Oct 2012, Glauber Costa wrote:

> The naming used by slab, "slab_cache", is less confusing, and it is
> preferred over slub's generic "slab".

Acked-by: Christoph Lameter <cl@linux.com>

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

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 2/2] slab: move kmem_cache_free to common code
  2012-10-22 14:05   ` Glauber Costa
@ 2012-10-22 14:45     ` Christoph Lameter
  -1 siblings, 0 replies; 40+ messages in thread
From: Christoph Lameter @ 2012-10-22 14:45 UTC (permalink / raw)
  To: Glauber Costa; +Cc: linux-mm, linux-kernel, Pekka Enberg, David Rientjes

On Mon, 22 Oct 2012, Glauber Costa wrote:

> + * kmem_cache_free - Deallocate an object
> + * @cachep: The cache the allocation was from.
> + * @objp: The previously allocated object.
> + *
> + * Free an object which was previously allocated from this
> + * cache.
> + */
> +void kmem_cache_free(struct kmem_cache *s, void *x)
> +{
> +	__kmem_cache_free(s, x);
> +	trace_kmem_cache_free(_RET_IP_, x);
> +}
> +EXPORT_SYMBOL(kmem_cache_free);
> +

This results in an additional indirection if tracing is off. Wonder if
there is a performance impact?


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 2/2] slab: move kmem_cache_free to common code
@ 2012-10-22 14:45     ` Christoph Lameter
  0 siblings, 0 replies; 40+ messages in thread
From: Christoph Lameter @ 2012-10-22 14:45 UTC (permalink / raw)
  To: Glauber Costa; +Cc: linux-mm, linux-kernel, Pekka Enberg, David Rientjes

On Mon, 22 Oct 2012, Glauber Costa wrote:

> + * kmem_cache_free - Deallocate an object
> + * @cachep: The cache the allocation was from.
> + * @objp: The previously allocated object.
> + *
> + * Free an object which was previously allocated from this
> + * cache.
> + */
> +void kmem_cache_free(struct kmem_cache *s, void *x)
> +{
> +	__kmem_cache_free(s, x);
> +	trace_kmem_cache_free(_RET_IP_, x);
> +}
> +EXPORT_SYMBOL(kmem_cache_free);
> +

This results in an additional indirection if tracing is off. Wonder if
there is a performance impact?

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

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 2/2] slab: move kmem_cache_free to common code
  2012-10-22 14:45     ` Christoph Lameter
@ 2012-10-22 15:10       ` Glauber Costa
  -1 siblings, 0 replies; 40+ messages in thread
From: Glauber Costa @ 2012-10-22 15:10 UTC (permalink / raw)
  To: Christoph Lameter; +Cc: linux-mm, linux-kernel, Pekka Enberg, David Rientjes

On 10/22/2012 06:45 PM, Christoph Lameter wrote:
> On Mon, 22 Oct 2012, Glauber Costa wrote:
> 
>> + * kmem_cache_free - Deallocate an object
>> + * @cachep: The cache the allocation was from.
>> + * @objp: The previously allocated object.
>> + *
>> + * Free an object which was previously allocated from this
>> + * cache.
>> + */
>> +void kmem_cache_free(struct kmem_cache *s, void *x)
>> +{
>> +	__kmem_cache_free(s, x);
>> +	trace_kmem_cache_free(_RET_IP_, x);
>> +}
>> +EXPORT_SYMBOL(kmem_cache_free);
>> +
> 
> This results in an additional indirection if tracing is off. Wonder if
> there is a performance impact?
> 
if tracing is on, you mean?

Tracing already incurs overhead, not sure how much a function call would
add to the tracing overhead.

I would not be concerned with this, but I can measure, if you have any
specific workload in mind.


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 2/2] slab: move kmem_cache_free to common code
@ 2012-10-22 15:10       ` Glauber Costa
  0 siblings, 0 replies; 40+ messages in thread
From: Glauber Costa @ 2012-10-22 15:10 UTC (permalink / raw)
  To: Christoph Lameter; +Cc: linux-mm, linux-kernel, Pekka Enberg, David Rientjes

On 10/22/2012 06:45 PM, Christoph Lameter wrote:
> On Mon, 22 Oct 2012, Glauber Costa wrote:
> 
>> + * kmem_cache_free - Deallocate an object
>> + * @cachep: The cache the allocation was from.
>> + * @objp: The previously allocated object.
>> + *
>> + * Free an object which was previously allocated from this
>> + * cache.
>> + */
>> +void kmem_cache_free(struct kmem_cache *s, void *x)
>> +{
>> +	__kmem_cache_free(s, x);
>> +	trace_kmem_cache_free(_RET_IP_, x);
>> +}
>> +EXPORT_SYMBOL(kmem_cache_free);
>> +
> 
> This results in an additional indirection if tracing is off. Wonder if
> there is a performance impact?
> 
if tracing is on, you mean?

Tracing already incurs overhead, not sure how much a function call would
add to the tracing overhead.

I would not be concerned with this, but I can measure, if you have any
specific workload in mind.

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

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 2/2] slab: move kmem_cache_free to common code
  2012-10-22 15:10       ` Glauber Costa
@ 2012-10-23  0:48         ` JoonSoo Kim
  -1 siblings, 0 replies; 40+ messages in thread
From: JoonSoo Kim @ 2012-10-23  0:48 UTC (permalink / raw)
  To: Glauber Costa
  Cc: Christoph Lameter, linux-mm, linux-kernel, Pekka Enberg, David Rientjes

Hello, Glauber.

2012/10/23 Glauber Costa <glommer@parallels.com>:
> On 10/22/2012 06:45 PM, Christoph Lameter wrote:
>> On Mon, 22 Oct 2012, Glauber Costa wrote:
>>
>>> + * kmem_cache_free - Deallocate an object
>>> + * @cachep: The cache the allocation was from.
>>> + * @objp: The previously allocated object.
>>> + *
>>> + * Free an object which was previously allocated from this
>>> + * cache.
>>> + */
>>> +void kmem_cache_free(struct kmem_cache *s, void *x)
>>> +{
>>> +    __kmem_cache_free(s, x);
>>> +    trace_kmem_cache_free(_RET_IP_, x);
>>> +}
>>> +EXPORT_SYMBOL(kmem_cache_free);
>>> +
>>
>> This results in an additional indirection if tracing is off. Wonder if
>> there is a performance impact?
>>
> if tracing is on, you mean?
>
> Tracing already incurs overhead, not sure how much a function call would
> add to the tracing overhead.
>
> I would not be concerned with this, but I can measure, if you have any
> specific workload in mind.

With this patch, kmem_cache_free() invokes __kmem_cache_free(),
that is, it add one more "call instruction" than before.

I think that Christoph's comment means above fact.

Thanks.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 2/2] slab: move kmem_cache_free to common code
@ 2012-10-23  0:48         ` JoonSoo Kim
  0 siblings, 0 replies; 40+ messages in thread
From: JoonSoo Kim @ 2012-10-23  0:48 UTC (permalink / raw)
  To: Glauber Costa
  Cc: Christoph Lameter, linux-mm, linux-kernel, Pekka Enberg, David Rientjes

Hello, Glauber.

2012/10/23 Glauber Costa <glommer@parallels.com>:
> On 10/22/2012 06:45 PM, Christoph Lameter wrote:
>> On Mon, 22 Oct 2012, Glauber Costa wrote:
>>
>>> + * kmem_cache_free - Deallocate an object
>>> + * @cachep: The cache the allocation was from.
>>> + * @objp: The previously allocated object.
>>> + *
>>> + * Free an object which was previously allocated from this
>>> + * cache.
>>> + */
>>> +void kmem_cache_free(struct kmem_cache *s, void *x)
>>> +{
>>> +    __kmem_cache_free(s, x);
>>> +    trace_kmem_cache_free(_RET_IP_, x);
>>> +}
>>> +EXPORT_SYMBOL(kmem_cache_free);
>>> +
>>
>> This results in an additional indirection if tracing is off. Wonder if
>> there is a performance impact?
>>
> if tracing is on, you mean?
>
> Tracing already incurs overhead, not sure how much a function call would
> add to the tracing overhead.
>
> I would not be concerned with this, but I can measure, if you have any
> specific workload in mind.

With this patch, kmem_cache_free() invokes __kmem_cache_free(),
that is, it add one more "call instruction" than before.

I think that Christoph's comment means above fact.

Thanks.

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

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 2/2] slab: move kmem_cache_free to common code
  2012-10-23  0:48         ` JoonSoo Kim
@ 2012-10-23  8:07           ` Glauber Costa
  -1 siblings, 0 replies; 40+ messages in thread
From: Glauber Costa @ 2012-10-23  8:07 UTC (permalink / raw)
  To: JoonSoo Kim
  Cc: Christoph Lameter, linux-mm, linux-kernel, Pekka Enberg, David Rientjes

On 10/23/2012 04:48 AM, JoonSoo Kim wrote:
> Hello, Glauber.
> 
> 2012/10/23 Glauber Costa <glommer@parallels.com>:
>> On 10/22/2012 06:45 PM, Christoph Lameter wrote:
>>> On Mon, 22 Oct 2012, Glauber Costa wrote:
>>>
>>>> + * kmem_cache_free - Deallocate an object
>>>> + * @cachep: The cache the allocation was from.
>>>> + * @objp: The previously allocated object.
>>>> + *
>>>> + * Free an object which was previously allocated from this
>>>> + * cache.
>>>> + */
>>>> +void kmem_cache_free(struct kmem_cache *s, void *x)
>>>> +{
>>>> +    __kmem_cache_free(s, x);
>>>> +    trace_kmem_cache_free(_RET_IP_, x);
>>>> +}
>>>> +EXPORT_SYMBOL(kmem_cache_free);
>>>> +
>>>
>>> This results in an additional indirection if tracing is off. Wonder if
>>> there is a performance impact?
>>>
>> if tracing is on, you mean?
>>
>> Tracing already incurs overhead, not sure how much a function call would
>> add to the tracing overhead.
>>
>> I would not be concerned with this, but I can measure, if you have any
>> specific workload in mind.
> 
> With this patch, kmem_cache_free() invokes __kmem_cache_free(),
> that is, it add one more "call instruction" than before.
> 
> I think that Christoph's comment means above fact.

Ah, this. Ok, I got fooled by his mention to tracing.

I do agree, but since freeing is ultimately dependent on the allocator
layout, I don't see a clean way of doing this without dropping tears of
sorrow around. The calls in slub/slab/slob would have to be somehow
inlined. Hum... maybe it is possible to do it from
include/linux/sl*b_def.h...

Let me give it a try and see what I can come up with.


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 2/2] slab: move kmem_cache_free to common code
@ 2012-10-23  8:07           ` Glauber Costa
  0 siblings, 0 replies; 40+ messages in thread
From: Glauber Costa @ 2012-10-23  8:07 UTC (permalink / raw)
  To: JoonSoo Kim
  Cc: Christoph Lameter, linux-mm, linux-kernel, Pekka Enberg, David Rientjes

On 10/23/2012 04:48 AM, JoonSoo Kim wrote:
> Hello, Glauber.
> 
> 2012/10/23 Glauber Costa <glommer@parallels.com>:
>> On 10/22/2012 06:45 PM, Christoph Lameter wrote:
>>> On Mon, 22 Oct 2012, Glauber Costa wrote:
>>>
>>>> + * kmem_cache_free - Deallocate an object
>>>> + * @cachep: The cache the allocation was from.
>>>> + * @objp: The previously allocated object.
>>>> + *
>>>> + * Free an object which was previously allocated from this
>>>> + * cache.
>>>> + */
>>>> +void kmem_cache_free(struct kmem_cache *s, void *x)
>>>> +{
>>>> +    __kmem_cache_free(s, x);
>>>> +    trace_kmem_cache_free(_RET_IP_, x);
>>>> +}
>>>> +EXPORT_SYMBOL(kmem_cache_free);
>>>> +
>>>
>>> This results in an additional indirection if tracing is off. Wonder if
>>> there is a performance impact?
>>>
>> if tracing is on, you mean?
>>
>> Tracing already incurs overhead, not sure how much a function call would
>> add to the tracing overhead.
>>
>> I would not be concerned with this, but I can measure, if you have any
>> specific workload in mind.
> 
> With this patch, kmem_cache_free() invokes __kmem_cache_free(),
> that is, it add one more "call instruction" than before.
> 
> I think that Christoph's comment means above fact.

Ah, this. Ok, I got fooled by his mention to tracing.

I do agree, but since freeing is ultimately dependent on the allocator
layout, I don't see a clean way of doing this without dropping tears of
sorrow around. The calls in slub/slab/slob would have to be somehow
inlined. Hum... maybe it is possible to do it from
include/linux/sl*b_def.h...

Let me give it a try and see what I can come up with.

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

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 2/2] slab: move kmem_cache_free to common code
  2012-10-23  8:07           ` Glauber Costa
@ 2012-10-23 10:52             ` Glauber Costa
  -1 siblings, 0 replies; 40+ messages in thread
From: Glauber Costa @ 2012-10-23 10:52 UTC (permalink / raw)
  To: JoonSoo Kim
  Cc: Christoph Lameter, linux-mm, linux-kernel, Pekka Enberg, David Rientjes

[-- Attachment #1: Type: text/plain, Size: 2844 bytes --]

On 10/23/2012 12:07 PM, Glauber Costa wrote:
> On 10/23/2012 04:48 AM, JoonSoo Kim wrote:
>> Hello, Glauber.
>>
>> 2012/10/23 Glauber Costa <glommer@parallels.com>:
>>> On 10/22/2012 06:45 PM, Christoph Lameter wrote:
>>>> On Mon, 22 Oct 2012, Glauber Costa wrote:
>>>>
>>>>> + * kmem_cache_free - Deallocate an object
>>>>> + * @cachep: The cache the allocation was from.
>>>>> + * @objp: The previously allocated object.
>>>>> + *
>>>>> + * Free an object which was previously allocated from this
>>>>> + * cache.
>>>>> + */
>>>>> +void kmem_cache_free(struct kmem_cache *s, void *x)
>>>>> +{
>>>>> +    __kmem_cache_free(s, x);
>>>>> +    trace_kmem_cache_free(_RET_IP_, x);
>>>>> +}
>>>>> +EXPORT_SYMBOL(kmem_cache_free);
>>>>> +
>>>>
>>>> This results in an additional indirection if tracing is off. Wonder if
>>>> there is a performance impact?
>>>>
>>> if tracing is on, you mean?
>>>
>>> Tracing already incurs overhead, not sure how much a function call would
>>> add to the tracing overhead.
>>>
>>> I would not be concerned with this, but I can measure, if you have any
>>> specific workload in mind.
>>
>> With this patch, kmem_cache_free() invokes __kmem_cache_free(),
>> that is, it add one more "call instruction" than before.
>>
>> I think that Christoph's comment means above fact.
> 
> Ah, this. Ok, I got fooled by his mention to tracing.
> 
> I do agree, but since freeing is ultimately dependent on the allocator
> layout, I don't see a clean way of doing this without dropping tears of
> sorrow around. The calls in slub/slab/slob would have to be somehow
> inlined. Hum... maybe it is possible to do it from
> include/linux/sl*b_def.h...
> 
> Let me give it a try and see what I can come up with.
> 

Ok.

I am attaching a PoC for this for your appreciation. This gets quite
ugly, but it's the way I found without including sl{a,u,o}b.c directly -
which would be even worse.

But I guess if we really want to avoid the cost of a function call,
there has to be a tradeoff...

For the record, the proposed usage for this would be:

1) Given a (inline) function, defined in mm/slab.h that translates the
cache from its object address (and then sanity checks it against the
cache parameter), translate_cache():

#define KMEM_CACHE_FREE(allocator_fn)                   \
void kmem_cache_free(struct kmem_cache *s, void *x)     \
{                                                       \
        struct kmem_cache *cachep;                      \
        cachep = translate_cache(s, x);                 \
        if (!cachep)                                    \
                return;                                 \
        allocator_fn(cachep, x);                        \
        trace_kmem_cache_free(_RET_IP_, x);             \
}                                                       \
EXPORT_SYMBOL(kmem_cache_free)



[-- Attachment #2: 0001-slab-move-kmem_cache_free-to-common-code.patch --]
[-- Type: text/x-patch, Size: 4505 bytes --]

>From 825f5179174be825f1219e23bdde769ef9febd45 Mon Sep 17 00:00:00 2001
From: Glauber Costa <glommer@parallels.com>
Date: Mon, 22 Oct 2012 15:20:26 +0400
Subject: [PATCH] slab: move kmem_cache_free to common code

In the effort of commonizing the slab allocators, it would be better if
we had a single entry-point for kmem_cache_free. At the same time, the
different layout of the allocators lead to routines that are necessarily
different.

Because we would also want the allocators to be able to free objects in
their fast paths without issuing a call instruction, we will rely on the
pre-processor to aid us.

Signed-off-by: Glauber Costa <glommer@parallels.com>
CC: Christoph Lameter <cl@linux.com>
CC: Pekka Enberg <penberg@kernel.org>
CC: David Rientjes <rientjes@google.com>
---
 mm/slab.c | 15 +++------------
 mm/slab.h | 26 ++++++++++++++++++++++++++
 mm/slob.c |  6 ++----
 mm/slub.c |  6 ++----
 4 files changed, 33 insertions(+), 20 deletions(-)

diff --git a/mm/slab.c b/mm/slab.c
index 98b3460..bceffcc 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -3903,15 +3903,8 @@ void *__kmalloc(size_t size, gfp_t flags)
 EXPORT_SYMBOL(__kmalloc);
 #endif
 
-/**
- * kmem_cache_free - Deallocate an object
- * @cachep: The cache the allocation was from.
- * @objp: The previously allocated object.
- *
- * Free an object which was previously allocated from this
- * cache.
- */
-void kmem_cache_free(struct kmem_cache *cachep, void *objp)
+static __always_inline void
+__kmem_cache_free(struct kmem_cache *cachep, void *objp)
 {
 	unsigned long flags;
 
@@ -3921,10 +3914,8 @@ void kmem_cache_free(struct kmem_cache *cachep, void *objp)
 		debug_check_no_obj_freed(objp, cachep->object_size);
 	__cache_free(cachep, objp, __builtin_return_address(0));
 	local_irq_restore(flags);
-
-	trace_kmem_cache_free(_RET_IP_, objp);
 }
-EXPORT_SYMBOL(kmem_cache_free);
+KMEM_CACHE_FREE(__kmem_cache_free);
 
 /**
  * kfree - free previously allocated memory
diff --git a/mm/slab.h b/mm/slab.h
index 66a62d3..32063f8 100644
--- a/mm/slab.h
+++ b/mm/slab.h
@@ -92,4 +92,30 @@ void get_slabinfo(struct kmem_cache *s, struct slabinfo *sinfo);
 void slabinfo_show_stats(struct seq_file *m, struct kmem_cache *s);
 ssize_t slabinfo_write(struct file *file, const char __user *buffer,
 		       size_t count, loff_t *ppos);
+
+/*
+ * What goes below for kmem_cache_free is not pretty. But because this
+ * is an extremely hot path, we would like to avoid function calls as
+ * much as we can.
+ *
+ * As ugly as it is, this is a way to guarantee that different allocators,
+ * with different layouts, and therefore, different free functions, can
+ * still live in different files and inline the whole of kmem_cache_free.
+ */
+/**
+ * kmem_cache_free - Deallocate an object
+ * @cachep: The cache the allocation was from.
+ * @objp: The previously allocated object.
+ *
+ * Free an object which was previously allocated from this
+ * cache.
+ *
+ */
+#define KMEM_CACHE_FREE(allocator_fn)			\
+void kmem_cache_free(struct kmem_cache *s, void *x)	\
+{							\
+	allocator_fn(s, x);				\
+	trace_kmem_cache_free(_RET_IP_, x);		\
+}							\
+EXPORT_SYMBOL(kmem_cache_free)
 #endif
diff --git a/mm/slob.c b/mm/slob.c
index 3edfeaa..1580371 100644
--- a/mm/slob.c
+++ b/mm/slob.c
@@ -571,7 +571,7 @@ static void kmem_rcu_free(struct rcu_head *head)
 	__kmem_cache_free(b, slob_rcu->size);
 }
 
-void kmem_cache_free(struct kmem_cache *c, void *b)
+static __always_inline void do_kmem_cache_free(struct kmem_cache *c, void *b)
 {
 	kmemleak_free_recursive(b, c->flags);
 	if (unlikely(c->flags & SLAB_DESTROY_BY_RCU)) {
@@ -582,10 +582,8 @@ void kmem_cache_free(struct kmem_cache *c, void *b)
 	} else {
 		__kmem_cache_free(b, c->size);
 	}
-
-	trace_kmem_cache_free(_RET_IP_, b);
 }
-EXPORT_SYMBOL(kmem_cache_free);
+KMEM_CACHE_FREE(do_kmem_cache_free);
 
 unsigned int kmem_cache_size(struct kmem_cache *c)
 {
diff --git a/mm/slub.c b/mm/slub.c
index 259bc2c..7dd41d7 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -2606,7 +2606,7 @@ redo:
 
 }
 
-void kmem_cache_free(struct kmem_cache *s, void *x)
+static __always_inline void __kmem_cache_free(struct kmem_cache *s, void *x)
 {
 	struct page *page;
 
@@ -2620,10 +2620,8 @@ void kmem_cache_free(struct kmem_cache *s, void *x)
 	}
 
 	slab_free(s, page, x, _RET_IP_);
-
-	trace_kmem_cache_free(_RET_IP_, x);
 }
-EXPORT_SYMBOL(kmem_cache_free);
+KMEM_CACHE_FREE(__kmem_cache_free);
 
 /*
  * Object placement in a slab is made very easy because we always start at
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* Re: [PATCH 2/2] slab: move kmem_cache_free to common code
@ 2012-10-23 10:52             ` Glauber Costa
  0 siblings, 0 replies; 40+ messages in thread
From: Glauber Costa @ 2012-10-23 10:52 UTC (permalink / raw)
  To: JoonSoo Kim
  Cc: Christoph Lameter, linux-mm, linux-kernel, Pekka Enberg, David Rientjes

[-- Attachment #1: Type: text/plain, Size: 2844 bytes --]

On 10/23/2012 12:07 PM, Glauber Costa wrote:
> On 10/23/2012 04:48 AM, JoonSoo Kim wrote:
>> Hello, Glauber.
>>
>> 2012/10/23 Glauber Costa <glommer@parallels.com>:
>>> On 10/22/2012 06:45 PM, Christoph Lameter wrote:
>>>> On Mon, 22 Oct 2012, Glauber Costa wrote:
>>>>
>>>>> + * kmem_cache_free - Deallocate an object
>>>>> + * @cachep: The cache the allocation was from.
>>>>> + * @objp: The previously allocated object.
>>>>> + *
>>>>> + * Free an object which was previously allocated from this
>>>>> + * cache.
>>>>> + */
>>>>> +void kmem_cache_free(struct kmem_cache *s, void *x)
>>>>> +{
>>>>> +    __kmem_cache_free(s, x);
>>>>> +    trace_kmem_cache_free(_RET_IP_, x);
>>>>> +}
>>>>> +EXPORT_SYMBOL(kmem_cache_free);
>>>>> +
>>>>
>>>> This results in an additional indirection if tracing is off. Wonder if
>>>> there is a performance impact?
>>>>
>>> if tracing is on, you mean?
>>>
>>> Tracing already incurs overhead, not sure how much a function call would
>>> add to the tracing overhead.
>>>
>>> I would not be concerned with this, but I can measure, if you have any
>>> specific workload in mind.
>>
>> With this patch, kmem_cache_free() invokes __kmem_cache_free(),
>> that is, it add one more "call instruction" than before.
>>
>> I think that Christoph's comment means above fact.
> 
> Ah, this. Ok, I got fooled by his mention to tracing.
> 
> I do agree, but since freeing is ultimately dependent on the allocator
> layout, I don't see a clean way of doing this without dropping tears of
> sorrow around. The calls in slub/slab/slob would have to be somehow
> inlined. Hum... maybe it is possible to do it from
> include/linux/sl*b_def.h...
> 
> Let me give it a try and see what I can come up with.
> 

Ok.

I am attaching a PoC for this for your appreciation. This gets quite
ugly, but it's the way I found without including sl{a,u,o}b.c directly -
which would be even worse.

But I guess if we really want to avoid the cost of a function call,
there has to be a tradeoff...

For the record, the proposed usage for this would be:

1) Given a (inline) function, defined in mm/slab.h that translates the
cache from its object address (and then sanity checks it against the
cache parameter), translate_cache():

#define KMEM_CACHE_FREE(allocator_fn)                   \
void kmem_cache_free(struct kmem_cache *s, void *x)     \
{                                                       \
        struct kmem_cache *cachep;                      \
        cachep = translate_cache(s, x);                 \
        if (!cachep)                                    \
                return;                                 \
        allocator_fn(cachep, x);                        \
        trace_kmem_cache_free(_RET_IP_, x);             \
}                                                       \
EXPORT_SYMBOL(kmem_cache_free)



[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-slab-move-kmem_cache_free-to-common-code.patch --]
[-- Type: text/x-patch; name="0001-slab-move-kmem_cache_free-to-common-code.patch", Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 2/2] slab: move kmem_cache_free to common code
  2012-10-23  8:07           ` Glauber Costa
@ 2012-10-23 14:12             ` Christoph Lameter
  -1 siblings, 0 replies; 40+ messages in thread
From: Christoph Lameter @ 2012-10-23 14:12 UTC (permalink / raw)
  To: Glauber Costa
  Cc: JoonSoo Kim, linux-mm, linux-kernel, Pekka Enberg, David Rientjes

On Tue, 23 Oct 2012, Glauber Costa wrote:

> I do agree, but since freeing is ultimately dependent on the allocator
> layout, I don't see a clean way of doing this without dropping tears of
> sorrow around. The calls in slub/slab/slob would have to be somehow
> inlined. Hum... maybe it is possible to do it from
> include/linux/sl*b_def.h...
>
> Let me give it a try and see what I can come up with.

The best solution would be something that would have a consolidated
kmem_cache_free() in include/linux/slab.h.


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 2/2] slab: move kmem_cache_free to common code
@ 2012-10-23 14:12             ` Christoph Lameter
  0 siblings, 0 replies; 40+ messages in thread
From: Christoph Lameter @ 2012-10-23 14:12 UTC (permalink / raw)
  To: Glauber Costa
  Cc: JoonSoo Kim, linux-mm, linux-kernel, Pekka Enberg, David Rientjes

On Tue, 23 Oct 2012, Glauber Costa wrote:

> I do agree, but since freeing is ultimately dependent on the allocator
> layout, I don't see a clean way of doing this without dropping tears of
> sorrow around. The calls in slub/slab/slob would have to be somehow
> inlined. Hum... maybe it is possible to do it from
> include/linux/sl*b_def.h...
>
> Let me give it a try and see what I can come up with.

The best solution would be something that would have a consolidated
kmem_cache_free() in include/linux/slab.h.

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

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 2/2] slab: move kmem_cache_free to common code
  2012-10-23 14:12             ` Christoph Lameter
@ 2012-10-23 14:15               ` Glauber Costa
  -1 siblings, 0 replies; 40+ messages in thread
From: Glauber Costa @ 2012-10-23 14:15 UTC (permalink / raw)
  To: Christoph Lameter
  Cc: JoonSoo Kim, linux-mm, linux-kernel, Pekka Enberg, David Rientjes

On 10/23/2012 06:12 PM, Christoph Lameter wrote:
> On Tue, 23 Oct 2012, Glauber Costa wrote:
> 
>> I do agree, but since freeing is ultimately dependent on the allocator
>> layout, I don't see a clean way of doing this without dropping tears of
>> sorrow around. The calls in slub/slab/slob would have to be somehow
>> inlined. Hum... maybe it is possible to do it from
>> include/linux/sl*b_def.h...
>>
>> Let me give it a try and see what I can come up with.
> 
> The best solution would be something that would have a consolidated
> kmem_cache_free() in include/linux/slab.h.
> 

I don't know what exactly do you have in mind, but since the cache
layouts are very different, this is quite hard to do without incurring
without function calls anyway.

Do take a look at what I sent in response to that, and tell me what do
you think.


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 2/2] slab: move kmem_cache_free to common code
@ 2012-10-23 14:15               ` Glauber Costa
  0 siblings, 0 replies; 40+ messages in thread
From: Glauber Costa @ 2012-10-23 14:15 UTC (permalink / raw)
  To: Christoph Lameter
  Cc: JoonSoo Kim, linux-mm, linux-kernel, Pekka Enberg, David Rientjes

On 10/23/2012 06:12 PM, Christoph Lameter wrote:
> On Tue, 23 Oct 2012, Glauber Costa wrote:
> 
>> I do agree, but since freeing is ultimately dependent on the allocator
>> layout, I don't see a clean way of doing this without dropping tears of
>> sorrow around. The calls in slub/slab/slob would have to be somehow
>> inlined. Hum... maybe it is possible to do it from
>> include/linux/sl*b_def.h...
>>
>> Let me give it a try and see what I can come up with.
> 
> The best solution would be something that would have a consolidated
> kmem_cache_free() in include/linux/slab.h.
> 

I don't know what exactly do you have in mind, but since the cache
layouts are very different, this is quite hard to do without incurring
without function calls anyway.

Do take a look at what I sent in response to that, and tell me what do
you think.

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

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 2/2] slab: move kmem_cache_free to common code
  2012-10-23 14:15               ` Glauber Costa
@ 2012-10-23 14:34                 ` Christoph Lameter
  -1 siblings, 0 replies; 40+ messages in thread
From: Christoph Lameter @ 2012-10-23 14:34 UTC (permalink / raw)
  To: Glauber Costa
  Cc: JoonSoo Kim, linux-mm, linux-kernel, Pekka Enberg, David Rientjes

On Tue, 23 Oct 2012, Glauber Costa wrote:

> I don't know what exactly do you have in mind, but since the cache
> layouts are very different, this is quite hard to do without incurring
> without function calls anyway.

True. Sigh.


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 2/2] slab: move kmem_cache_free to common code
@ 2012-10-23 14:34                 ` Christoph Lameter
  0 siblings, 0 replies; 40+ messages in thread
From: Christoph Lameter @ 2012-10-23 14:34 UTC (permalink / raw)
  To: Glauber Costa
  Cc: JoonSoo Kim, linux-mm, linux-kernel, Pekka Enberg, David Rientjes

On Tue, 23 Oct 2012, Glauber Costa wrote:

> I don't know what exactly do you have in mind, but since the cache
> layouts are very different, this is quite hard to do without incurring
> without function calls anyway.

True. Sigh.

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

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 2/2] slab: move kmem_cache_free to common code
  2012-10-23 10:52             ` Glauber Costa
@ 2012-10-23 15:43               ` JoonSoo Kim
  -1 siblings, 0 replies; 40+ messages in thread
From: JoonSoo Kim @ 2012-10-23 15:43 UTC (permalink / raw)
  To: Glauber Costa
  Cc: Christoph Lameter, linux-mm, linux-kernel, Pekka Enberg, David Rientjes

2012/10/23 Glauber Costa <glommer@parallels.com>:
> On 10/23/2012 12:07 PM, Glauber Costa wrote:
>> On 10/23/2012 04:48 AM, JoonSoo Kim wrote:
>>> Hello, Glauber.
>>>
>>> 2012/10/23 Glauber Costa <glommer@parallels.com>:
>>>> On 10/22/2012 06:45 PM, Christoph Lameter wrote:
>>>>> On Mon, 22 Oct 2012, Glauber Costa wrote:
>>>>>
>>>>>> + * kmem_cache_free - Deallocate an object
>>>>>> + * @cachep: The cache the allocation was from.
>>>>>> + * @objp: The previously allocated object.
>>>>>> + *
>>>>>> + * Free an object which was previously allocated from this
>>>>>> + * cache.
>>>>>> + */
>>>>>> +void kmem_cache_free(struct kmem_cache *s, void *x)
>>>>>> +{
>>>>>> +    __kmem_cache_free(s, x);
>>>>>> +    trace_kmem_cache_free(_RET_IP_, x);
>>>>>> +}
>>>>>> +EXPORT_SYMBOL(kmem_cache_free);
>>>>>> +
>>>>>
>>>>> This results in an additional indirection if tracing is off. Wonder if
>>>>> there is a performance impact?
>>>>>
>>>> if tracing is on, you mean?
>>>>
>>>> Tracing already incurs overhead, not sure how much a function call would
>>>> add to the tracing overhead.
>>>>
>>>> I would not be concerned with this, but I can measure, if you have any
>>>> specific workload in mind.
>>>
>>> With this patch, kmem_cache_free() invokes __kmem_cache_free(),
>>> that is, it add one more "call instruction" than before.
>>>
>>> I think that Christoph's comment means above fact.
>>
>> Ah, this. Ok, I got fooled by his mention to tracing.
>>
>> I do agree, but since freeing is ultimately dependent on the allocator
>> layout, I don't see a clean way of doing this without dropping tears of
>> sorrow around. The calls in slub/slab/slob would have to be somehow
>> inlined. Hum... maybe it is possible to do it from
>> include/linux/sl*b_def.h...
>>
>> Let me give it a try and see what I can come up with.
>>
>
> Ok.
>
> I am attaching a PoC for this for your appreciation. This gets quite
> ugly, but it's the way I found without including sl{a,u,o}b.c directly -
> which would be even worse.

Hmm...
This is important issue for sl[aou]b common allocators.
Because there are similar functions like as kmem_cache_alloc, ksize, kfree, ...
So it is good time to resolve this issue.

As far as I know, now, we have 3 solutions.

1. include/linux/slab.h
__always_inline kmem_cache_free()
{
__kmem_cache_free();
blablabla...
}

2. define macro like as Glauber's solution
3. include sl[aou]b.c directly.

Is there other good solution?
Among them, I prefer "solution 3", because future developing cost may
be minimum among them.

"Solution 2" may be error-prone for future developing.
"Solution 1" may make compile-time longer and larger code.

Is my understanding right?
Is "Solution 3" really ugly?

Thanks.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 2/2] slab: move kmem_cache_free to common code
@ 2012-10-23 15:43               ` JoonSoo Kim
  0 siblings, 0 replies; 40+ messages in thread
From: JoonSoo Kim @ 2012-10-23 15:43 UTC (permalink / raw)
  To: Glauber Costa
  Cc: Christoph Lameter, linux-mm, linux-kernel, Pekka Enberg, David Rientjes

2012/10/23 Glauber Costa <glommer@parallels.com>:
> On 10/23/2012 12:07 PM, Glauber Costa wrote:
>> On 10/23/2012 04:48 AM, JoonSoo Kim wrote:
>>> Hello, Glauber.
>>>
>>> 2012/10/23 Glauber Costa <glommer@parallels.com>:
>>>> On 10/22/2012 06:45 PM, Christoph Lameter wrote:
>>>>> On Mon, 22 Oct 2012, Glauber Costa wrote:
>>>>>
>>>>>> + * kmem_cache_free - Deallocate an object
>>>>>> + * @cachep: The cache the allocation was from.
>>>>>> + * @objp: The previously allocated object.
>>>>>> + *
>>>>>> + * Free an object which was previously allocated from this
>>>>>> + * cache.
>>>>>> + */
>>>>>> +void kmem_cache_free(struct kmem_cache *s, void *x)
>>>>>> +{
>>>>>> +    __kmem_cache_free(s, x);
>>>>>> +    trace_kmem_cache_free(_RET_IP_, x);
>>>>>> +}
>>>>>> +EXPORT_SYMBOL(kmem_cache_free);
>>>>>> +
>>>>>
>>>>> This results in an additional indirection if tracing is off. Wonder if
>>>>> there is a performance impact?
>>>>>
>>>> if tracing is on, you mean?
>>>>
>>>> Tracing already incurs overhead, not sure how much a function call would
>>>> add to the tracing overhead.
>>>>
>>>> I would not be concerned with this, but I can measure, if you have any
>>>> specific workload in mind.
>>>
>>> With this patch, kmem_cache_free() invokes __kmem_cache_free(),
>>> that is, it add one more "call instruction" than before.
>>>
>>> I think that Christoph's comment means above fact.
>>
>> Ah, this. Ok, I got fooled by his mention to tracing.
>>
>> I do agree, but since freeing is ultimately dependent on the allocator
>> layout, I don't see a clean way of doing this without dropping tears of
>> sorrow around. The calls in slub/slab/slob would have to be somehow
>> inlined. Hum... maybe it is possible to do it from
>> include/linux/sl*b_def.h...
>>
>> Let me give it a try and see what I can come up with.
>>
>
> Ok.
>
> I am attaching a PoC for this for your appreciation. This gets quite
> ugly, but it's the way I found without including sl{a,u,o}b.c directly -
> which would be even worse.

Hmm...
This is important issue for sl[aou]b common allocators.
Because there are similar functions like as kmem_cache_alloc, ksize, kfree, ...
So it is good time to resolve this issue.

As far as I know, now, we have 3 solutions.

1. include/linux/slab.h
__always_inline kmem_cache_free()
{
__kmem_cache_free();
blablabla...
}

2. define macro like as Glauber's solution
3. include sl[aou]b.c directly.

Is there other good solution?
Among them, I prefer "solution 3", because future developing cost may
be minimum among them.

"Solution 2" may be error-prone for future developing.
"Solution 1" may make compile-time longer and larger code.

Is my understanding right?
Is "Solution 3" really ugly?

Thanks.

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

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 2/2] slab: move kmem_cache_free to common code
  2012-10-22 15:10       ` Glauber Costa
@ 2012-10-23 18:16         ` Christoph Lameter
  -1 siblings, 0 replies; 40+ messages in thread
From: Christoph Lameter @ 2012-10-23 18:16 UTC (permalink / raw)
  To: Glauber Costa; +Cc: linux-mm, linux-kernel, Pekka Enberg, David Rientjes

On Mon, 22 Oct 2012, Glauber Costa wrote:

> > This results in an additional indirection if tracing is off. Wonder if
> > there is a performance impact?
> >
> if tracing is on, you mean?

Sorry I meant *even* if tracing is off.


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 2/2] slab: move kmem_cache_free to common code
@ 2012-10-23 18:16         ` Christoph Lameter
  0 siblings, 0 replies; 40+ messages in thread
From: Christoph Lameter @ 2012-10-23 18:16 UTC (permalink / raw)
  To: Glauber Costa; +Cc: linux-mm, linux-kernel, Pekka Enberg, David Rientjes

On Mon, 22 Oct 2012, Glauber Costa wrote:

> > This results in an additional indirection if tracing is off. Wonder if
> > there is a performance impact?
> >
> if tracing is on, you mean?

Sorry I meant *even* if tracing is off.

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

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 2/2] slab: move kmem_cache_free to common code
  2012-10-23 15:43               ` JoonSoo Kim
@ 2012-10-24  8:31                 ` Glauber Costa
  -1 siblings, 0 replies; 40+ messages in thread
From: Glauber Costa @ 2012-10-24  8:31 UTC (permalink / raw)
  To: JoonSoo Kim
  Cc: Christoph Lameter, linux-mm, linux-kernel, Pekka Enberg, David Rientjes

On 10/23/2012 07:43 PM, JoonSoo Kim wrote:
> 2012/10/23 Glauber Costa <glommer@parallels.com>:
>> On 10/23/2012 12:07 PM, Glauber Costa wrote:
>>> On 10/23/2012 04:48 AM, JoonSoo Kim wrote:
>>>> Hello, Glauber.
>>>>
>>>> 2012/10/23 Glauber Costa <glommer@parallels.com>:
>>>>> On 10/22/2012 06:45 PM, Christoph Lameter wrote:
>>>>>> On Mon, 22 Oct 2012, Glauber Costa wrote:
>>>>>>
>>>>>>> + * kmem_cache_free - Deallocate an object
>>>>>>> + * @cachep: The cache the allocation was from.
>>>>>>> + * @objp: The previously allocated object.
>>>>>>> + *
>>>>>>> + * Free an object which was previously allocated from this
>>>>>>> + * cache.
>>>>>>> + */
>>>>>>> +void kmem_cache_free(struct kmem_cache *s, void *x)
>>>>>>> +{
>>>>>>> +    __kmem_cache_free(s, x);
>>>>>>> +    trace_kmem_cache_free(_RET_IP_, x);
>>>>>>> +}
>>>>>>> +EXPORT_SYMBOL(kmem_cache_free);
>>>>>>> +
>>>>>>
>>>>>> This results in an additional indirection if tracing is off. Wonder if
>>>>>> there is a performance impact?
>>>>>>
>>>>> if tracing is on, you mean?
>>>>>
>>>>> Tracing already incurs overhead, not sure how much a function call would
>>>>> add to the tracing overhead.
>>>>>
>>>>> I would not be concerned with this, but I can measure, if you have any
>>>>> specific workload in mind.
>>>>
>>>> With this patch, kmem_cache_free() invokes __kmem_cache_free(),
>>>> that is, it add one more "call instruction" than before.
>>>>
>>>> I think that Christoph's comment means above fact.
>>>
>>> Ah, this. Ok, I got fooled by his mention to tracing.
>>>
>>> I do agree, but since freeing is ultimately dependent on the allocator
>>> layout, I don't see a clean way of doing this without dropping tears of
>>> sorrow around. The calls in slub/slab/slob would have to be somehow
>>> inlined. Hum... maybe it is possible to do it from
>>> include/linux/sl*b_def.h...
>>>
>>> Let me give it a try and see what I can come up with.
>>>
>>
>> Ok.
>>
>> I am attaching a PoC for this for your appreciation. This gets quite
>> ugly, but it's the way I found without including sl{a,u,o}b.c directly -
>> which would be even worse.
> 
> Hmm...
> This is important issue for sl[aou]b common allocators.
> Because there are similar functions like as kmem_cache_alloc, ksize, kfree, ...
> So it is good time to resolve this issue.
> 
> As far as I know, now, we have 3 solutions.
> 
> 1. include/linux/slab.h
> __always_inline kmem_cache_free()
> {
> __kmem_cache_free();
> blablabla...
> }
> 
> 2. define macro like as Glauber's solution
> 3. include sl[aou]b.c directly.
> 
> Is there other good solution?
> Among them, I prefer "solution 3", because future developing cost may
> be minimum among them.
> 
> "Solution 2" may be error-prone for future developing.
> "Solution 1" may make compile-time longer and larger code.
> 
> Is my understanding right?
> Is "Solution 3" really ugly?
> 

As much as I agree my proposed solution is ugly (I wouldn't necessarily
call it error-prone, it's just that that doesn't belong in there, and it
is hard for people to figure out what is going on at first look), I
don't like "Solution 3" either.

The main reason is that over time, .c files tend to grow with more code.
You are not necessarily seeing what are in the other files, and the
opportunities for name clashes become abundant. Among others...

So what I coded, at least has the advantage of restricting this to only
a selected subset of user-visible functions.



^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 2/2] slab: move kmem_cache_free to common code
@ 2012-10-24  8:31                 ` Glauber Costa
  0 siblings, 0 replies; 40+ messages in thread
From: Glauber Costa @ 2012-10-24  8:31 UTC (permalink / raw)
  To: JoonSoo Kim
  Cc: Christoph Lameter, linux-mm, linux-kernel, Pekka Enberg, David Rientjes

On 10/23/2012 07:43 PM, JoonSoo Kim wrote:
> 2012/10/23 Glauber Costa <glommer@parallels.com>:
>> On 10/23/2012 12:07 PM, Glauber Costa wrote:
>>> On 10/23/2012 04:48 AM, JoonSoo Kim wrote:
>>>> Hello, Glauber.
>>>>
>>>> 2012/10/23 Glauber Costa <glommer@parallels.com>:
>>>>> On 10/22/2012 06:45 PM, Christoph Lameter wrote:
>>>>>> On Mon, 22 Oct 2012, Glauber Costa wrote:
>>>>>>
>>>>>>> + * kmem_cache_free - Deallocate an object
>>>>>>> + * @cachep: The cache the allocation was from.
>>>>>>> + * @objp: The previously allocated object.
>>>>>>> + *
>>>>>>> + * Free an object which was previously allocated from this
>>>>>>> + * cache.
>>>>>>> + */
>>>>>>> +void kmem_cache_free(struct kmem_cache *s, void *x)
>>>>>>> +{
>>>>>>> +    __kmem_cache_free(s, x);
>>>>>>> +    trace_kmem_cache_free(_RET_IP_, x);
>>>>>>> +}
>>>>>>> +EXPORT_SYMBOL(kmem_cache_free);
>>>>>>> +
>>>>>>
>>>>>> This results in an additional indirection if tracing is off. Wonder if
>>>>>> there is a performance impact?
>>>>>>
>>>>> if tracing is on, you mean?
>>>>>
>>>>> Tracing already incurs overhead, not sure how much a function call would
>>>>> add to the tracing overhead.
>>>>>
>>>>> I would not be concerned with this, but I can measure, if you have any
>>>>> specific workload in mind.
>>>>
>>>> With this patch, kmem_cache_free() invokes __kmem_cache_free(),
>>>> that is, it add one more "call instruction" than before.
>>>>
>>>> I think that Christoph's comment means above fact.
>>>
>>> Ah, this. Ok, I got fooled by his mention to tracing.
>>>
>>> I do agree, but since freeing is ultimately dependent on the allocator
>>> layout, I don't see a clean way of doing this without dropping tears of
>>> sorrow around. The calls in slub/slab/slob would have to be somehow
>>> inlined. Hum... maybe it is possible to do it from
>>> include/linux/sl*b_def.h...
>>>
>>> Let me give it a try and see what I can come up with.
>>>
>>
>> Ok.
>>
>> I am attaching a PoC for this for your appreciation. This gets quite
>> ugly, but it's the way I found without including sl{a,u,o}b.c directly -
>> which would be even worse.
> 
> Hmm...
> This is important issue for sl[aou]b common allocators.
> Because there are similar functions like as kmem_cache_alloc, ksize, kfree, ...
> So it is good time to resolve this issue.
> 
> As far as I know, now, we have 3 solutions.
> 
> 1. include/linux/slab.h
> __always_inline kmem_cache_free()
> {
> __kmem_cache_free();
> blablabla...
> }
> 
> 2. define macro like as Glauber's solution
> 3. include sl[aou]b.c directly.
> 
> Is there other good solution?
> Among them, I prefer "solution 3", because future developing cost may
> be minimum among them.
> 
> "Solution 2" may be error-prone for future developing.
> "Solution 1" may make compile-time longer and larger code.
> 
> Is my understanding right?
> Is "Solution 3" really ugly?
> 

As much as I agree my proposed solution is ugly (I wouldn't necessarily
call it error-prone, it's just that that doesn't belong in there, and it
is hard for people to figure out what is going on at first look), I
don't like "Solution 3" either.

The main reason is that over time, .c files tend to grow with more code.
You are not necessarily seeing what are in the other files, and the
opportunities for name clashes become abundant. Among others...

So what I coded, at least has the advantage of restricting this to only
a selected subset of user-visible functions.


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

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 2/2] slab: move kmem_cache_free to common code
  2012-10-22 14:05   ` Glauber Costa
@ 2012-10-24  8:56     ` Pekka Enberg
  -1 siblings, 0 replies; 40+ messages in thread
From: Pekka Enberg @ 2012-10-24  8:56 UTC (permalink / raw)
  To: Glauber Costa; +Cc: linux-mm, linux-kernel, Christoph Lameter, David Rientjes

On Mon, Oct 22, 2012 at 5:05 PM, Glauber Costa <glommer@parallels.com> wrote:
> +/**
> + * kmem_cache_free - Deallocate an object
> + * @cachep: The cache the allocation was from.
> + * @objp: The previously allocated object.
> + *
> + * Free an object which was previously allocated from this
> + * cache.
> + */
> +void kmem_cache_free(struct kmem_cache *s, void *x)
> +{
> +       __kmem_cache_free(s, x);
> +       trace_kmem_cache_free(_RET_IP_, x);
> +}
> +EXPORT_SYMBOL(kmem_cache_free);

As Christoph mentioned, this is going to hurt performance. The proper
way to do this is to implement the *hook* in mm/slab_common.c and call
that from all the allocator specific kmem_cache_free() functions.

                        Pekka

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 2/2] slab: move kmem_cache_free to common code
@ 2012-10-24  8:56     ` Pekka Enberg
  0 siblings, 0 replies; 40+ messages in thread
From: Pekka Enberg @ 2012-10-24  8:56 UTC (permalink / raw)
  To: Glauber Costa; +Cc: linux-mm, linux-kernel, Christoph Lameter, David Rientjes

On Mon, Oct 22, 2012 at 5:05 PM, Glauber Costa <glommer@parallels.com> wrote:
> +/**
> + * kmem_cache_free - Deallocate an object
> + * @cachep: The cache the allocation was from.
> + * @objp: The previously allocated object.
> + *
> + * Free an object which was previously allocated from this
> + * cache.
> + */
> +void kmem_cache_free(struct kmem_cache *s, void *x)
> +{
> +       __kmem_cache_free(s, x);
> +       trace_kmem_cache_free(_RET_IP_, x);
> +}
> +EXPORT_SYMBOL(kmem_cache_free);

As Christoph mentioned, this is going to hurt performance. The proper
way to do this is to implement the *hook* in mm/slab_common.c and call
that from all the allocator specific kmem_cache_free() functions.

                        Pekka

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

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 2/2] slab: move kmem_cache_free to common code
  2012-10-22 14:05   ` Glauber Costa
@ 2012-10-24  8:56     ` Pekka Enberg
  -1 siblings, 0 replies; 40+ messages in thread
From: Pekka Enberg @ 2012-10-24  8:56 UTC (permalink / raw)
  To: Glauber Costa; +Cc: linux-mm, linux-kernel, Christoph Lameter, David Rientjes

On Mon, Oct 22, 2012 at 5:05 PM, Glauber Costa <glommer@parallels.com> wrote:
> +/**
> + * kmem_cache_free - Deallocate an object
> + * @cachep: The cache the allocation was from.
> + * @objp: The previously allocated object.
> + *
> + * Free an object which was previously allocated from this
> + * cache.
> + */
> +void kmem_cache_free(struct kmem_cache *s, void *x)
> +{
> +       __kmem_cache_free(s, x);
> +       trace_kmem_cache_free(_RET_IP_, x);
> +}
> +EXPORT_SYMBOL(kmem_cache_free);

As Christoph mentioned, this is going to hurt performance. The proper
way to do this is to implement the *hook* in mm/slab_common.c and call
that from all the allocator specific kmem_cache_free() functions.

                        Pekka

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 2/2] slab: move kmem_cache_free to common code
@ 2012-10-24  8:56     ` Pekka Enberg
  0 siblings, 0 replies; 40+ messages in thread
From: Pekka Enberg @ 2012-10-24  8:56 UTC (permalink / raw)
  To: Glauber Costa; +Cc: linux-mm, linux-kernel, Christoph Lameter, David Rientjes

On Mon, Oct 22, 2012 at 5:05 PM, Glauber Costa <glommer@parallels.com> wrote:
> +/**
> + * kmem_cache_free - Deallocate an object
> + * @cachep: The cache the allocation was from.
> + * @objp: The previously allocated object.
> + *
> + * Free an object which was previously allocated from this
> + * cache.
> + */
> +void kmem_cache_free(struct kmem_cache *s, void *x)
> +{
> +       __kmem_cache_free(s, x);
> +       trace_kmem_cache_free(_RET_IP_, x);
> +}
> +EXPORT_SYMBOL(kmem_cache_free);

As Christoph mentioned, this is going to hurt performance. The proper
way to do this is to implement the *hook* in mm/slab_common.c and call
that from all the allocator specific kmem_cache_free() functions.

                        Pekka

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

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 1/2] slab: commonize slab_cache field in struct page
  2012-10-22 14:05   ` Glauber Costa
@ 2012-10-24  8:58     ` Pekka Enberg
  -1 siblings, 0 replies; 40+ messages in thread
From: Pekka Enberg @ 2012-10-24  8:58 UTC (permalink / raw)
  To: Glauber Costa; +Cc: linux-mm, linux-kernel, Christoph Lameter, David Rientjes

On Mon, 22 Oct 2012, Glauber Costa wrote:
> Right now, slab and slub have fields in struct page to derive which
> cache a page belongs to, but they do it slightly differently.
> 
> slab uses a field called slab_cache, that lives in the third double
> word. slub, uses a field called "slab", living outside of the
> doublewords area.
> 
> Ideally, we could use the same field for this. Since slub heavily makes
> use of the doubleword region, there isn't really much room to move
> slub's slab_cache field around. Since slab does not have such strict
> placement restrictions, we can move it outside the doubleword area.
> 
> The naming used by slab, "slab_cache", is less confusing, and it is
> preferred over slub's generic "slab".
> 
> Signed-off-by: Glauber Costa <glommer@parallels.com>
> CC: Christoph Lameter <cl@linux.com>
> CC: Pekka Enberg <penberg@kernel.org>
> CC: David Rientjes <rientjes@google.com>

Applied, thanks!

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 1/2] slab: commonize slab_cache field in struct page
@ 2012-10-24  8:58     ` Pekka Enberg
  0 siblings, 0 replies; 40+ messages in thread
From: Pekka Enberg @ 2012-10-24  8:58 UTC (permalink / raw)
  To: Glauber Costa; +Cc: linux-mm, linux-kernel, Christoph Lameter, David Rientjes

On Mon, 22 Oct 2012, Glauber Costa wrote:
> Right now, slab and slub have fields in struct page to derive which
> cache a page belongs to, but they do it slightly differently.
> 
> slab uses a field called slab_cache, that lives in the third double
> word. slub, uses a field called "slab", living outside of the
> doublewords area.
> 
> Ideally, we could use the same field for this. Since slub heavily makes
> use of the doubleword region, there isn't really much room to move
> slub's slab_cache field around. Since slab does not have such strict
> placement restrictions, we can move it outside the doubleword area.
> 
> The naming used by slab, "slab_cache", is less confusing, and it is
> preferred over slub's generic "slab".
> 
> Signed-off-by: Glauber Costa <glommer@parallels.com>
> CC: Christoph Lameter <cl@linux.com>
> CC: Pekka Enberg <penberg@kernel.org>
> CC: David Rientjes <rientjes@google.com>

Applied, thanks!

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

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 2/2] slab: move kmem_cache_free to common code
  2012-10-24  8:56     ` Pekka Enberg
@ 2012-10-24 10:03       ` Glauber Costa
  -1 siblings, 0 replies; 40+ messages in thread
From: Glauber Costa @ 2012-10-24 10:03 UTC (permalink / raw)
  To: Pekka Enberg; +Cc: linux-mm, linux-kernel, Christoph Lameter, David Rientjes

On 10/24/2012 12:56 PM, Pekka Enberg wrote:
> On Mon, Oct 22, 2012 at 5:05 PM, Glauber Costa <glommer@parallels.com> wrote:
>> +/**
>> + * kmem_cache_free - Deallocate an object
>> + * @cachep: The cache the allocation was from.
>> + * @objp: The previously allocated object.
>> + *
>> + * Free an object which was previously allocated from this
>> + * cache.
>> + */
>> +void kmem_cache_free(struct kmem_cache *s, void *x)
>> +{
>> +       __kmem_cache_free(s, x);
>> +       trace_kmem_cache_free(_RET_IP_, x);
>> +}
>> +EXPORT_SYMBOL(kmem_cache_free);
> 
> As Christoph mentioned, this is going to hurt performance. The proper
> way to do this is to implement the *hook* in mm/slab_common.c and call
> that from all the allocator specific kmem_cache_free() functions.
> 
>                         Pekka
> 
We would ideally like the hooks to be inlined as well. Specially for the
memcg-disabled case, this will only get us a function call for no reason.



^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 2/2] slab: move kmem_cache_free to common code
@ 2012-10-24 10:03       ` Glauber Costa
  0 siblings, 0 replies; 40+ messages in thread
From: Glauber Costa @ 2012-10-24 10:03 UTC (permalink / raw)
  To: Pekka Enberg; +Cc: linux-mm, linux-kernel, Christoph Lameter, David Rientjes

On 10/24/2012 12:56 PM, Pekka Enberg wrote:
> On Mon, Oct 22, 2012 at 5:05 PM, Glauber Costa <glommer@parallels.com> wrote:
>> +/**
>> + * kmem_cache_free - Deallocate an object
>> + * @cachep: The cache the allocation was from.
>> + * @objp: The previously allocated object.
>> + *
>> + * Free an object which was previously allocated from this
>> + * cache.
>> + */
>> +void kmem_cache_free(struct kmem_cache *s, void *x)
>> +{
>> +       __kmem_cache_free(s, x);
>> +       trace_kmem_cache_free(_RET_IP_, x);
>> +}
>> +EXPORT_SYMBOL(kmem_cache_free);
> 
> As Christoph mentioned, this is going to hurt performance. The proper
> way to do this is to implement the *hook* in mm/slab_common.c and call
> that from all the allocator specific kmem_cache_free() functions.
> 
>                         Pekka
> 
We would ideally like the hooks to be inlined as well. Specially for the
memcg-disabled case, this will only get us a function call for no reason.


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

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 2/2] slab: move kmem_cache_free to common code
  2012-10-23 15:43               ` JoonSoo Kim
@ 2012-10-24 13:39                 ` Glauber Costa
  -1 siblings, 0 replies; 40+ messages in thread
From: Glauber Costa @ 2012-10-24 13:39 UTC (permalink / raw)
  To: JoonSoo Kim
  Cc: Christoph Lameter, linux-mm, linux-kernel, Pekka Enberg, David Rientjes

On 10/23/2012 07:43 PM, JoonSoo Kim wrote:
> 2012/10/23 Glauber Costa <glommer@parallels.com>:
>> On 10/23/2012 12:07 PM, Glauber Costa wrote:
>>> On 10/23/2012 04:48 AM, JoonSoo Kim wrote:
>>>> Hello, Glauber.
>>>>
>>>> 2012/10/23 Glauber Costa <glommer@parallels.com>:
>>>>> On 10/22/2012 06:45 PM, Christoph Lameter wrote:
>>>>>> On Mon, 22 Oct 2012, Glauber Costa wrote:
>>>>>>
>>>>>>> + * kmem_cache_free - Deallocate an object
>>>>>>> + * @cachep: The cache the allocation was from.
>>>>>>> + * @objp: The previously allocated object.
>>>>>>> + *
>>>>>>> + * Free an object which was previously allocated from this
>>>>>>> + * cache.
>>>>>>> + */
>>>>>>> +void kmem_cache_free(struct kmem_cache *s, void *x)
>>>>>>> +{
>>>>>>> +    __kmem_cache_free(s, x);
>>>>>>> +    trace_kmem_cache_free(_RET_IP_, x);
>>>>>>> +}
>>>>>>> +EXPORT_SYMBOL(kmem_cache_free);
>>>>>>> +
>>>>>>
>>>>>> This results in an additional indirection if tracing is off. Wonder if
>>>>>> there is a performance impact?
>>>>>>
>>>>> if tracing is on, you mean?
>>>>>
>>>>> Tracing already incurs overhead, not sure how much a function call would
>>>>> add to the tracing overhead.
>>>>>
>>>>> I would not be concerned with this, but I can measure, if you have any
>>>>> specific workload in mind.
>>>>
>>>> With this patch, kmem_cache_free() invokes __kmem_cache_free(),
>>>> that is, it add one more "call instruction" than before.
>>>>
>>>> I think that Christoph's comment means above fact.
>>>
>>> Ah, this. Ok, I got fooled by his mention to tracing.
>>>
>>> I do agree, but since freeing is ultimately dependent on the allocator
>>> layout, I don't see a clean way of doing this without dropping tears of
>>> sorrow around. The calls in slub/slab/slob would have to be somehow
>>> inlined. Hum... maybe it is possible to do it from
>>> include/linux/sl*b_def.h...
>>>
>>> Let me give it a try and see what I can come up with.
>>>
>>
>> Ok.
>>
>> I am attaching a PoC for this for your appreciation. This gets quite
>> ugly, but it's the way I found without including sl{a,u,o}b.c directly -
>> which would be even worse.
> 
> Hmm...
> This is important issue for sl[aou]b common allocators.
> Because there are similar functions like as kmem_cache_alloc, ksize, kfree, ...
> So it is good time to resolve this issue.
> 
> As far as I know, now, we have 3 solutions.
> 
> 1. include/linux/slab.h
> __always_inline kmem_cache_free()
> {
> __kmem_cache_free();
> blablabla...
> }
> 
> 2. define macro like as Glauber's solution
> 3. include sl[aou]b.c directly.
> 
> Is there other good solution?
> Among them, I prefer "solution 3", because future developing cost may
> be minimum among them.
> 
> "Solution 2" may be error-prone for future developing.
> "Solution 1" may make compile-time longer and larger code.
> 
> Is my understanding right?
> Is "Solution 3" really ugly?
> 

I just gave it a try. Turns out the result is not *that* bad for my eyes.

I'll post soon.




^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 2/2] slab: move kmem_cache_free to common code
@ 2012-10-24 13:39                 ` Glauber Costa
  0 siblings, 0 replies; 40+ messages in thread
From: Glauber Costa @ 2012-10-24 13:39 UTC (permalink / raw)
  To: JoonSoo Kim
  Cc: Christoph Lameter, linux-mm, linux-kernel, Pekka Enberg, David Rientjes

On 10/23/2012 07:43 PM, JoonSoo Kim wrote:
> 2012/10/23 Glauber Costa <glommer@parallels.com>:
>> On 10/23/2012 12:07 PM, Glauber Costa wrote:
>>> On 10/23/2012 04:48 AM, JoonSoo Kim wrote:
>>>> Hello, Glauber.
>>>>
>>>> 2012/10/23 Glauber Costa <glommer@parallels.com>:
>>>>> On 10/22/2012 06:45 PM, Christoph Lameter wrote:
>>>>>> On Mon, 22 Oct 2012, Glauber Costa wrote:
>>>>>>
>>>>>>> + * kmem_cache_free - Deallocate an object
>>>>>>> + * @cachep: The cache the allocation was from.
>>>>>>> + * @objp: The previously allocated object.
>>>>>>> + *
>>>>>>> + * Free an object which was previously allocated from this
>>>>>>> + * cache.
>>>>>>> + */
>>>>>>> +void kmem_cache_free(struct kmem_cache *s, void *x)
>>>>>>> +{
>>>>>>> +    __kmem_cache_free(s, x);
>>>>>>> +    trace_kmem_cache_free(_RET_IP_, x);
>>>>>>> +}
>>>>>>> +EXPORT_SYMBOL(kmem_cache_free);
>>>>>>> +
>>>>>>
>>>>>> This results in an additional indirection if tracing is off. Wonder if
>>>>>> there is a performance impact?
>>>>>>
>>>>> if tracing is on, you mean?
>>>>>
>>>>> Tracing already incurs overhead, not sure how much a function call would
>>>>> add to the tracing overhead.
>>>>>
>>>>> I would not be concerned with this, but I can measure, if you have any
>>>>> specific workload in mind.
>>>>
>>>> With this patch, kmem_cache_free() invokes __kmem_cache_free(),
>>>> that is, it add one more "call instruction" than before.
>>>>
>>>> I think that Christoph's comment means above fact.
>>>
>>> Ah, this. Ok, I got fooled by his mention to tracing.
>>>
>>> I do agree, but since freeing is ultimately dependent on the allocator
>>> layout, I don't see a clean way of doing this without dropping tears of
>>> sorrow around. The calls in slub/slab/slob would have to be somehow
>>> inlined. Hum... maybe it is possible to do it from
>>> include/linux/sl*b_def.h...
>>>
>>> Let me give it a try and see what I can come up with.
>>>
>>
>> Ok.
>>
>> I am attaching a PoC for this for your appreciation. This gets quite
>> ugly, but it's the way I found without including sl{a,u,o}b.c directly -
>> which would be even worse.
> 
> Hmm...
> This is important issue for sl[aou]b common allocators.
> Because there are similar functions like as kmem_cache_alloc, ksize, kfree, ...
> So it is good time to resolve this issue.
> 
> As far as I know, now, we have 3 solutions.
> 
> 1. include/linux/slab.h
> __always_inline kmem_cache_free()
> {
> __kmem_cache_free();
> blablabla...
> }
> 
> 2. define macro like as Glauber's solution
> 3. include sl[aou]b.c directly.
> 
> Is there other good solution?
> Among them, I prefer "solution 3", because future developing cost may
> be minimum among them.
> 
> "Solution 2" may be error-prone for future developing.
> "Solution 1" may make compile-time longer and larger code.
> 
> Is my understanding right?
> Is "Solution 3" really ugly?
> 

I just gave it a try. Turns out the result is not *that* bad for my eyes.

I'll post soon.



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

^ permalink raw reply	[flat|nested] 40+ messages in thread

end of thread, other threads:[~2012-10-24 13:39 UTC | newest]

Thread overview: 40+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-10-22 14:05 [PATCH 0/2] move kmem_cache_free to common code Glauber Costa
2012-10-22 14:05 ` Glauber Costa
2012-10-22 14:05 ` [PATCH 1/2] slab: commonize slab_cache field in struct page Glauber Costa
2012-10-22 14:05   ` Glauber Costa
2012-10-22 14:44   ` Christoph Lameter
2012-10-22 14:44     ` Christoph Lameter
2012-10-24  8:58   ` Pekka Enberg
2012-10-24  8:58     ` Pekka Enberg
2012-10-22 14:05 ` [PATCH 2/2] slab: move kmem_cache_free to common code Glauber Costa
2012-10-22 14:05   ` Glauber Costa
2012-10-22 14:45   ` Christoph Lameter
2012-10-22 14:45     ` Christoph Lameter
2012-10-22 15:10     ` Glauber Costa
2012-10-22 15:10       ` Glauber Costa
2012-10-23  0:48       ` JoonSoo Kim
2012-10-23  0:48         ` JoonSoo Kim
2012-10-23  8:07         ` Glauber Costa
2012-10-23  8:07           ` Glauber Costa
2012-10-23 10:52           ` Glauber Costa
2012-10-23 10:52             ` Glauber Costa
2012-10-23 15:43             ` JoonSoo Kim
2012-10-23 15:43               ` JoonSoo Kim
2012-10-24  8:31               ` Glauber Costa
2012-10-24  8:31                 ` Glauber Costa
2012-10-24 13:39               ` Glauber Costa
2012-10-24 13:39                 ` Glauber Costa
2012-10-23 14:12           ` Christoph Lameter
2012-10-23 14:12             ` Christoph Lameter
2012-10-23 14:15             ` Glauber Costa
2012-10-23 14:15               ` Glauber Costa
2012-10-23 14:34               ` Christoph Lameter
2012-10-23 14:34                 ` Christoph Lameter
2012-10-23 18:16       ` Christoph Lameter
2012-10-23 18:16         ` Christoph Lameter
2012-10-24  8:56   ` Pekka Enberg
2012-10-24  8:56     ` Pekka Enberg
2012-10-24 10:03     ` Glauber Costa
2012-10-24 10:03       ` Glauber Costa
2012-10-24  8:56   ` Pekka Enberg
2012-10-24  8:56     ` Pekka Enberg

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.