linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Nick Piggin <nickpiggin@yahoo.com.au>
To: Matt Mackall <mpm@selenic.com>,
	Andrew Morton <akpm@linux-foundation.org>
Cc: Linux Memory Management <linux-mm@kvack.org>
Subject: [patch] slob: implement RCU freeing
Date: Thu, 10 May 2007 17:15:46 +1000	[thread overview]
Message-ID: <4642C6A2.1090809@yahoo.com.au> (raw)
In-Reply-To: <20070510022707.GO11115@waste.org>

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

Matt Mackall wrote:

> Looks good to me, but haven't had time to actually test it.
> 
> Acked-by: Matt Mackall <mpm@selenic.com>

Updated to current, added a comment, and test booted it again.
Works OK.

-- 
SUSE Labs, Novell Inc.

[-- Attachment #2: slob-add-rcu.patch --]
[-- Type: text/plain, Size: 3950 bytes --]

The SLOB allocator should implement SLAB_DESTROY_BY_RCU correctly, because even
on UP, RCU freeing semantics are not equivalent to simply freeing immediately.
This also allows SLOB to be used on SMP.

Signed-off-by: Nick Piggin <npiggin@suse.de>
Acked-by: Matt Mackall <mpm@selenic.com>

Index: linux-2.6/init/Kconfig
===================================================================
--- linux-2.6.orig/init/Kconfig	2007-05-10 14:17:38.000000000 +1000
+++ linux-2.6/init/Kconfig	2007-05-10 14:18:11.000000000 +1000
@@ -519,7 +519,8 @@
 	  slab allocator.
 
 config SLUB
-	depends on EXPERIMENTAL && !ARCH_USES_SLAB_PAGE_STRUCT
+#	depends on EXPERIMENTAL && !ARCH_USES_SLAB_PAGE_STRUCT
+	depends on EXPERIMENTAL
 	bool "SLUB (Unqueued Allocator)"
 	help
 	   SLUB is a slab allocator that minimizes cache line usage
@@ -529,15 +530,11 @@
 	   way and has enhanced diagnostics.
 
 config SLOB
-#
-#	SLOB cannot support SMP because SLAB_DESTROY_BY_RCU does not work
-#	properly.
-#
-	depends on EMBEDDED && !SMP && !SPARSEMEM
+	depends on EMBEDDED && !SPARSEMEM
 	bool "SLOB (Simple Allocator)"
 	help
 	   SLOB replaces the SLAB allocator with a drastically simpler
-	   allocator.  SLOB is more space efficient that SLAB but does not
+	   allocator.  SLOB is more space efficient than SLAB but does not
 	   scale well (single lock for all operations) and is more susceptible
 	   to fragmentation. SLOB it is a great choice to reduce
 	   memory usage and code size for embedded systems.
Index: linux-2.6/mm/slob.c
===================================================================
--- linux-2.6.orig/mm/slob.c	2007-05-10 14:17:38.000000000 +1000
+++ linux-2.6/mm/slob.c	2007-05-10 14:59:35.000000000 +1000
@@ -35,6 +35,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/timer.h>
+#include <linux/rcupdate.h>
 
 struct slob_block {
 	int units;
@@ -53,6 +54,16 @@
 };
 typedef struct bigblock bigblock_t;
 
+/*
+ * struct slob_rcu is inserted at the tail of allocated slob blocks, which
+ * were created with a SLAB_DESTROY_BY_RCU slab. slob_rcu is used to free
+ * the block using call_rcu.
+ */
+struct slob_rcu {
+	struct rcu_head head;
+	int size;
+};
+
 static slob_t arena = { .next = &arena, .units = 1 };
 static slob_t *slobfree = &arena;
 static bigblock_t *bigblocks;
@@ -266,6 +277,7 @@
 
 struct kmem_cache {
 	unsigned int size, align;
+	unsigned long flags;
 	const char *name;
 	void (*ctor)(void *, struct kmem_cache *, unsigned long);
 	void (*dtor)(void *, struct kmem_cache *, unsigned long);
@@ -283,6 +295,12 @@
 	if (c) {
 		c->name = name;
 		c->size = size;
+		if (flags & SLAB_DESTROY_BY_RCU) {
+			BUG_ON(c->dtor);
+			/* leave room for rcu footer at the end of object */
+			c->size += sizeof(struct slob_rcu);
+		}
+		c->flags = flags;
 		c->ctor = ctor;
 		c->dtor = dtor;
 		/* ignore alignment unless it's forced */
@@ -328,15 +346,35 @@
 }
 EXPORT_SYMBOL(kmem_cache_zalloc);
 
-void kmem_cache_free(struct kmem_cache *c, void *b)
+static void __kmem_cache_free(void *b, int size)
 {
-	if (c->dtor)
-		c->dtor(b, c, 0);
-
-	if (c->size < PAGE_SIZE)
-		slob_free(b, c->size);
+	if (size < PAGE_SIZE)
+		slob_free(b, size);
 	else
-		free_pages((unsigned long)b, get_order(c->size));
+		free_pages((unsigned long)b, get_order(size));
+}
+
+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);
+}
+
+void kmem_cache_free(struct kmem_cache *c, void *b)
+{
+	if (unlikely(c->flags & SLAB_DESTROY_BY_RCU)) {
+		struct slob_rcu *slob_rcu;
+		slob_rcu = b + (c->size - sizeof(struct slob_rcu));
+		INIT_RCU_HEAD(&slob_rcu->head);
+		slob_rcu->size = c->size;
+		call_rcu(&slob_rcu->head, kmem_rcu_free);
+	} else {
+		if (c->dtor)
+			c->dtor(b, c, 0);
+		__kmem_cache_free(b, c->size);
+	}
 }
 EXPORT_SYMBOL(kmem_cache_free);
 

       reply	other threads:[~2007-05-10  7:15 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <Pine.LNX.4.64.0705081746500.16914@schroedinger.engr.sgi.com>
     [not found] ` <20070509012725.GZ11115@waste.org>
     [not found]   ` <Pine.LNX.4.64.0705081828300.17376@schroedinger.engr.sgi.com>
     [not found]     ` <20070508.185141.85412154.davem@davemloft.net>
     [not found]       ` <46412BB5.1060605@yahoo.com.au>
     [not found]         ` <20070509174238.b4152887.akpm@linux-foundation.org>
     [not found]           ` <46426EA1.4030408@yahoo.com.au>
     [not found]             ` <20070510022707.GO11115@waste.org>
2007-05-10  7:15               ` Nick Piggin [this message]
2007-05-10  7:19                 ` Nick Piggin
2007-05-10  8:22                 ` Peter Zijlstra
2007-05-10  8:26                   ` Nick Piggin
2007-05-10  8:29                     ` Peter Zijlstra
2007-05-09  4:17 Nick Piggin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4642C6A2.1090809@yahoo.com.au \
    --to=nickpiggin@yahoo.com.au \
    --cc=akpm@linux-foundation.org \
    --cc=linux-mm@kvack.org \
    --cc=mpm@selenic.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox