From: Nick Piggin <npiggin@suse.de>
To: Andrew Morton <akpm@linux-foundation.org>,
Matt Mackall <mpm@selenic.com>,
Linux Memory Management List <linux-mm@kvack.org>
Subject: [patch 2/3] slob: remove bigblock tracking
Date: Tue, 22 May 2007 09:39:58 +0200 [thread overview]
Message-ID: <20070522073958.GE17051@wotan.suse.de> (raw)
In-Reply-To: <20070522073910.GD17051@wotan.suse.de>
Remove the bigblock lists in favour of using compound pages and going
directly to the page allocator. Allocation size is stored in page->private,
which also makes ksize more accurate than it previously was.
Saves ~.5K of code, and 12-24 bytes overhead per >= PAGE_SIZE allocation.
Signed-off-by: Nick Piggin <npiggin@suse.de>
---
Index: linux-2.6/mm/slob.c
===================================================================
--- linux-2.6.orig/mm/slob.c
+++ linux-2.6/mm/slob.c
@@ -18,9 +18,11 @@
* Above this is an implementation of kmalloc/kfree. Blocks returned
* from kmalloc are 4-byte aligned and prepended with a 4-byte header.
* If kmalloc is asked for objects of PAGE_SIZE or larger, it calls
- * __get_free_pages directly so that it can return page-aligned blocks
- * and keeps a linked list of such pages and their orders. These
- * objects are detected in kfree() by their page alignment.
+ * __get_free_pages directly, allocating compound pages so the page order
+ * does not have to be separately tracked, and also stores the exact
+ * allocation size in page->private so that it can be used to accurately
+ * provide ksize(). These objects are detected in kfree() because slob_page()
+ * is false for them.
*
* SLAB is emulated on top of SLOB by simply calling constructors and
* destructors for every SLAB allocation. Objects are returned with the
@@ -29,7 +31,8 @@
* alignment. Again, objects of page-size or greater are allocated by
* calling __get_free_pages. As SLAB objects know their size, no separate
* size bookkeeping is necessary and there is essentially no allocation
- * space overhead.
+ * space overhead, and compound pages aren't needed for multi-page
+ * allocations.
*/
#include <linux/kernel.h>
@@ -381,48 +384,26 @@ out:
* End of slob allocator proper. Begin kmem_cache_alloc and kmalloc frontend.
*/
-struct bigblock {
- int order;
- void *pages;
- struct bigblock *next;
-};
-typedef struct bigblock bigblock_t;
-
-static bigblock_t *bigblocks;
-
-static DEFINE_SPINLOCK(block_lock);
-
-
void *__kmalloc(size_t size, gfp_t gfp)
{
- slob_t *m;
- bigblock_t *bb;
- unsigned long flags;
-
if (size < PAGE_SIZE - SLOB_UNIT) {
+ slob_t *m;
m = slob_alloc(size + SLOB_UNIT, gfp, 0);
if (m)
m->units = size;
return m+1;
- }
-
- bb = slob_alloc(sizeof(bigblock_t), gfp, 0);
- if (!bb)
- return 0;
-
- bb->order = get_order(size);
- bb->pages = (void *)__get_free_pages(gfp, bb->order);
+ } else {
+ void *ret;
- if (bb->pages) {
- spin_lock_irqsave(&block_lock, flags);
- bb->next = bigblocks;
- bigblocks = bb;
- spin_unlock_irqrestore(&block_lock, flags);
- return bb->pages;
+ ret = (void *) __get_free_pages(gfp | __GFP_COMP,
+ get_order(size));
+ if (ret) {
+ struct page *page;
+ page = virt_to_page(ret);
+ page->private = size;
+ }
+ return ret;
}
-
- slob_free(bb, sizeof(bigblock_t));
- return 0;
}
EXPORT_SYMBOL(__kmalloc);
@@ -462,59 +443,33 @@ EXPORT_SYMBOL(krealloc);
void kfree(const void *block)
{
struct slob_page *sp;
- slob_t *m;
- bigblock_t *bb, **last = &bigblocks;
- unsigned long flags;
if (!block)
return;
sp = (struct slob_page *)virt_to_page(block);
- if (!slob_page(sp)) {
- /* on the big block list */
- spin_lock_irqsave(&block_lock, flags);
- for (bb = bigblocks; bb; last = &bb->next, bb = bb->next) {
- if (bb->pages == block) {
- *last = bb->next;
- spin_unlock_irqrestore(&block_lock, flags);
- free_pages((unsigned long)block, bb->order);
- slob_free(bb, sizeof(bigblock_t));
- return;
- }
- }
- spin_unlock_irqrestore(&block_lock, flags);
- WARN_ON(1);
- return;
- }
-
- m = (slob_t *)block - 1;
- slob_free(m, m->units + SLOB_UNIT);
- return;
+ if (slob_page(sp)) {
+ slob_t *m = (slob_t *)block - 1;
+ slob_free(m, m->units + SLOB_UNIT);
+ } else
+ put_page(&sp->page);
}
EXPORT_SYMBOL(kfree);
+/* can't use ksize for kmem_cache_alloc memory, only kmalloc */
size_t ksize(const void *block)
{
struct slob_page *sp;
- bigblock_t *bb;
- unsigned long flags;
if (!block)
return 0;
sp = (struct slob_page *)virt_to_page(block);
- if (!slob_page(sp)) {
- spin_lock_irqsave(&block_lock, flags);
- for (bb = bigblocks; bb; bb = bb->next)
- if (bb->pages == block) {
- spin_unlock_irqrestore(&slob_lock, flags);
- return PAGE_SIZE << bb->order;
- }
- spin_unlock_irqrestore(&block_lock, flags);
- }
-
- return ((slob_t *)block - 1)->units + SLOB_UNIT;
+ if (slob_page(sp))
+ return ((slob_t *)block - 1)->units + SLOB_UNIT;
+ else
+ return sp->page.private;
}
struct kmem_cache {
--
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>
next prev parent reply other threads:[~2007-05-22 7:39 UTC|newest]
Thread overview: 66+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-05-22 7:39 [patch 1/3] slob: rework freelist handling Nick Piggin
2007-05-22 7:39 ` Nick Piggin [this message]
2007-05-22 7:41 ` [patch 3/3] slob: improved alignment handling Nick Piggin
2007-05-22 14:53 ` [patch 1/3] slob: rework freelist handling Matt Mackall
2007-05-22 19:18 ` Christoph Lameter
2007-05-23 3:06 ` Nick Piggin
2007-05-23 4:55 ` Christoph Lameter
2007-05-23 4:59 ` Nick Piggin
2007-05-23 5:01 ` Christoph Lameter
2007-05-23 5:03 ` Nick Piggin
2007-05-23 5:06 ` Christoph Lameter
2007-05-23 5:11 ` Nick Piggin
2007-05-23 5:14 ` Christoph Lameter
2007-05-23 5:22 ` Nick Piggin
2007-05-23 5:28 ` Christoph Lameter
2007-05-23 6:17 ` Nick Piggin
2007-05-23 6:28 ` Christoph Lameter
2007-05-23 7:12 ` Nick Piggin
2007-05-23 17:03 ` Christoph Lameter
2007-05-23 18:32 ` Matt Mackall
2007-05-23 19:15 ` Christoph Lameter
2007-05-23 19:58 ` Matt Mackall
2007-05-23 20:02 ` Christoph Lameter
2007-05-23 20:16 ` Christoph Lameter
2007-05-23 21:14 ` Matt Mackall
2007-05-23 21:06 ` Matt Mackall
2007-05-23 22:26 ` Christoph Lameter
2007-05-23 22:42 ` Matt Mackall
2007-05-23 22:48 ` Christoph Lameter
2007-05-24 2:05 ` Nick Piggin
2007-05-24 2:45 ` Christoph Lameter
2007-05-24 2:47 ` Nick Piggin
2007-05-24 2:55 ` Christoph Lameter
2007-05-24 3:17 ` Nick Piggin
2007-05-24 2:49 ` Christoph Lameter
2007-05-24 3:15 ` Nick Piggin
2007-05-24 3:51 ` Christoph Lameter
2007-05-24 6:11 ` Matt Mackall
2007-05-24 16:36 ` Christoph Lameter
2007-05-24 17:22 ` Matt Mackall
2007-05-24 17:27 ` Christoph Lameter
2007-05-24 17:44 ` Matt Mackall
2007-05-23 6:38 ` Christoph Lameter
2007-05-23 7:18 ` Nick Piggin
2007-05-23 17:06 ` Christoph Lameter
2007-05-23 7:46 ` Nick Piggin
2007-05-23 17:07 ` Christoph Lameter
2007-05-23 19:35 ` Matt Mackall
2007-05-23 19:59 ` Christoph Lameter
2007-05-23 20:51 ` Matt Mackall
2007-05-24 3:39 ` Nick Piggin
2007-05-24 3:55 ` Christoph Lameter
2007-05-24 4:13 ` Nick Piggin
2007-05-24 4:23 ` Christoph Lameter
2007-05-24 4:31 ` Nick Piggin
2007-05-24 4:35 ` Christoph Lameter
2007-05-24 4:39 ` Nick Piggin
2007-05-24 4:46 ` Christoph Lameter
2007-05-24 4:49 ` Nick Piggin
2007-05-24 5:07 ` Christoph Lameter
2007-05-24 3:24 ` Nick Piggin
2007-05-24 3:49 ` Christoph Lameter
2007-05-24 4:01 ` Nick Piggin
2007-05-24 4:05 ` Christoph Lameter
2007-05-24 4:24 ` Nick Piggin
2007-05-23 18:04 ` Christoph Lameter
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=20070522073958.GE17051@wotan.suse.de \
--to=npiggin@suse.de \
--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