From: Christoph Lameter <clameter@sgi.com>
To: mpm@selenic.com
Cc: Marcelo Tosatti <marcelo@kvack.org>,
linux-kernel@vger.kernel.org,
Nick Piggin <nickpiggin@yahoo.com.au>, Andi Kleen <ak@suse.de>,
Christoph Lameter <clameter@sgi.com>, Dave Chinner <dgc@sgi.com>,
Manfred Spraul <manfred@colorfullife.com>
Subject: [MODSLAB 3/7] A Kmalloc subsystem
Date: Tue, 15 Aug 2006 19:22:53 -0700 (PDT) [thread overview]
Message-ID: <20060816022253.13379.76984.sendpatchset@schroedinger.engr.sgi.com> (raw)
In-Reply-To: <20060816022238.13379.24081.sendpatchset@schroedinger.engr.sgi.com>
Kmalloc layer for the modular slab
New ideas:
1. Generate slabs on the fly (May have issues with GFP_KERNEL).
2. use fls to calculate array position.
Signed-off-by: Christoph Lameter <clameter@sgi.com>
Index: linux-2.6.18-rc4/include/linux/kmalloc.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.18-rc4/include/linux/kmalloc.h 2006-08-15 18:37:47.757837824 -0700
@@ -0,0 +1,72 @@
+#ifndef _LINUX_KMALLOC_H
+#define _LINUX_KMALLOC_H
+/*
+ * In kernel dynamic memory allocator.
+ *
+ * (C) 2006 Silicon Graphics, Inc,
+ * Christoph Lameter <clameter@sgi.com>
+ */
+
+#include <linux/allocator.h>
+#include <linux/config.h>
+#include <linux/types.h>
+
+#ifdef CONFIG_NUMA_SLAB
+#define kmalloc_allocator numa_slab_allocator
+#else
+#define kmalloc_allocator slabifier_allocator
+#endif
+
+/*
+ * We keep the general caches in an array of slab caches that are used for
+ * 2^x bytes of allocations. For each size we generate a DMA and a
+ * non DMA cache (Do not get confused: DMA simply means memory for
+ * legacy I/O. The regular caches can be used for devices that can
+ * do DMA to all of memory).
+ */
+extern struct slab_cache *kmalloc_caches[2][BITS_PER_LONG];
+
+struct slab_cache *kmalloc_generate_slab(int index, gfp_t flags);
+
+/*
+ * Find (and possibly create) the slab cache for a given combination of
+ * allocation flags and size.
+ *
+ * Believe it or not but this should result in a simple load
+ * from a global memory address for a constant flag and size,
+ * a comparison and two function calls with the same parameters.
+ */
+static inline struct slab_cache *kmalloc_slab(size_t size, gfp_t flags)
+{
+ struct slab_cache *s;
+ int index = fls(size - 1);
+
+ s = kmalloc_caches[!!(flags & __GFP_DMA)][index];
+ if (!s)
+ s = kmalloc_generate_slab(index, flags);
+ return s;
+}
+
+static inline void *kmalloc(size_t size, gfp_t flags)
+{
+ return kmalloc_allocator.alloc(kmalloc_slab(size, flags), flags);
+}
+
+static inline void *kmalloc_node(size_t size, gfp_t flags, int node)
+{
+ return kmalloc_allocator.alloc_node(kmalloc_slab(size, flags),
+ flags, node);
+}
+
+static inline void kfree(const void *x)
+{
+ kmalloc_allocator.free(NULL, x);
+}
+
+/* Allocate and zero the specified number of bytes */
+extern void *kzalloc(size_t, gfp_t);
+
+/* Figure out what size the chunk is */
+extern size_t ksize(const void *);
+
+#endif /* _LINUX_KMALLOC_H */
Index: linux-2.6.18-rc4/mm/kmalloc.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.18-rc4/mm/kmalloc.c 2006-08-15 18:35:04.744461494 -0700
@@ -0,0 +1,114 @@
+/*
+ * Implement basic generic caches for memory allocation.
+ *
+ * This is an on demand implementation. General slabs
+ * are only created if there is an actual need for allocations
+ * of that size.
+ *
+ * (C) 2006 Silicon Graphics. Inc. Christoph Lameter <clameter@sgi.com>
+ */
+
+#include <linux/mm.h>
+#include <linux/allocator.h>
+#include <linux/module.h>
+
+// #define KMALLOC_DEBUG
+
+struct slab_cache *kmalloc_caches[2][BITS_PER_LONG] __cacheline_aligned;
+EXPORT_SYMBOL(kmalloc_caches);
+
+/* Smallest size of a cache in 2^x */
+#define LOW 5 /* 32 byte */
+
+#if BITS_PER_LONG == 64
+/* 64 bit platform. Maximum size is 2 Gigabyte */
+#define HIGH 31
+#else
+/* 32 bit. Take the customary max of 128k */
+#define HIGH 17
+#endif
+
+/*
+ * Given a slab size find the correct order to use.
+ * We only support powers of two so there is really
+ * no need for anything special. Objects will always
+ * fit exactly into the slabs.
+ */
+static int order(size_t size)
+{
+ if (size >= PAGE_SIZE)
+ /* One object per slab */
+ return fls(size -1) - PAGE_SHIFT + 1;
+
+ /* Multiple objects but let slab_create() figure out how much */
+ return 0;
+}
+
+static DEFINE_SPINLOCK(kmalloc_lock);
+
+/*
+ * Create a general slab
+ */
+struct slab_cache *kmalloc_generate_slab(int index, gfp_t flags)
+{
+ int dma = !!(flags & __GFP_DMA);
+ struct slab_cache *s;
+ long realsize;
+ const struct page_allocator *a = &page_allocator;
+
+#ifdef KMALLOC_DEBUG
+ printk(KERN_CRIT "kmalloc_generate_slab(%d, %x)\n", index, flags);
+#endif
+ if (index < LOW) {
+ s = kmalloc_caches[dma][LOW];
+ if (s) {
+ kmalloc_caches[dma][index] = s;
+ return s;
+ }
+ index = LOW;
+ }
+
+ if (index > HIGH) {
+ printk(KERN_CRIT "Kmalloc size(%ld) too large.\n",
+ 1L << index);
+ BUG();
+ }
+
+ realsize = 1 << index;
+
+ if (dma)
+ a = dmaify_page_allocator(a);
+
+ s = kmalloc_allocator.create(&kmalloc_allocator, a, -1,
+ dma ? "kmalloc-DMA" : "kmalloc", realsize,
+ L1_CACHE_BYTES, order(realsize), realsize, realsize, 0);
+
+ if (!s)
+ panic("Creation of kmalloc slab dma=%d index=%d failed.\n",
+ dma, index);
+ spin_lock_irq(&kmalloc_lock);
+ if (kmalloc_caches[dma][index])
+ kmalloc_allocator.destroy(s);
+ else
+ kmalloc_caches[dma][index] = s;
+ spin_unlock_irq(&kmalloc_lock);
+ return s;
+}
+EXPORT_SYMBOL(kmalloc_generate_slab);
+
+void *kzalloc(size_t size, gfp_t flags)
+{
+ void *x = kmalloc(size, flags);
+
+ if (x)
+ memset(x, 0, size);
+ return x;
+}
+EXPORT_SYMBOL(kzalloc);
+
+size_t ksize(const void *object)
+{
+ return kmalloc_allocator.object_size(NULL, object);
+};
+EXPORT_SYMBOL(ksize);
+
Index: linux-2.6.18-rc4/mm/Makefile
===================================================================
--- linux-2.6.18-rc4.orig/mm/Makefile 2006-08-15 18:35:03.591212358 -0700
+++ linux-2.6.18-rc4/mm/Makefile 2006-08-15 18:35:04.744461494 -0700
@@ -24,5 +24,6 @@ obj-$(CONFIG_SLAB) += slab.o
obj-$(CONFIG_MEMORY_HOTPLUG) += memory_hotplug.o
obj-$(CONFIG_FS_XIP) += filemap_xip.o
obj-$(CONFIG_MIGRATION) += migrate.o
-obj-$(CONFIG_MODULAR_SLAB) += allocator.o
+obj-$(CONFIG_MODULAR_SLAB) += allocator.o kmalloc.o
+
next prev parent reply other threads:[~2006-08-16 2:24 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-08-16 2:22 [MODSLAB 0/7] A modular slab allocator V1 Christoph Lameter
2006-08-16 2:22 ` [MODSLAB 1/7] Extract allocpercpu from Slab Christoph Lameter
2006-08-16 2:22 ` [MODSLAB 2/7] Allocator Framework and misc features Christoph Lameter
2006-08-16 2:22 ` Christoph Lameter [this message]
2006-08-16 7:43 ` [MODSLAB 3/7] A Kmalloc subsystem Andi Kleen
2006-08-17 0:24 ` Christoph Lameter
2006-08-17 5:19 ` Manfred Spraul
2006-08-17 11:42 ` Andi Kleen
2006-08-17 16:26 ` Christoph Lameter
2006-08-19 7:08 ` Manfred Spraul
2006-08-19 16:46 ` Christoph Lameter
2006-08-19 18:54 ` Manfred Spraul
2006-08-19 19:17 ` Christoph Lameter
2006-08-18 6:17 ` Christoph Lameter
2006-08-18 7:17 ` KAMEZAWA Hiroyuki
2006-08-18 16:58 ` Christoph Lameter
2006-08-18 18:19 ` KAMEZAWA Hiroyuki
2006-08-18 18:44 ` Christoph Lameter
2006-08-18 19:13 ` KAMEZAWA Hiroyuki
2006-08-18 19:19 ` Christoph Lameter
2006-08-16 2:22 ` [MODSLAB 4/7] Slabulator: Emulate the existing Slab Layer Christoph Lameter
2006-08-16 2:23 ` [MODSLAB 5/7] A slab allocator: SLABIFIER Christoph Lameter
2006-08-16 2:23 ` [MODSLAB 6/7] A slab allocator: NUMA Slab allocator Christoph Lameter
2006-08-16 2:23 ` [MODSLAB 7/7] A slab allocator: Page " Christoph Lameter
2006-08-16 7:52 ` [MODSLAB 0/7] A modular slab allocator V1 Andi Kleen
2006-08-16 8:41 ` Matt Mackall
2006-08-16 9:38 ` David Chinner
2006-08-16 15:08 ` Christoph Lameter
2006-08-16 15:05 ` Christoph Lameter
2006-08-16 8:12 ` David Chinner
2006-08-16 8:32 ` Andi Kleen
2006-08-16 9:18 ` David Chinner
2006-08-16 15:06 ` Christoph Lameter
2006-08-16 16:15 ` Manfred Spraul
2006-08-16 21:49 ` Christoph Lameter
2006-08-16 22:16 ` Christoph Lameter
2006-08-16 22:34 ` Christoph Lameter
2006-08-16 22:45 ` 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=20060816022253.13379.76984.sendpatchset@schroedinger.engr.sgi.com \
--to=clameter@sgi.com \
--cc=ak@suse.de \
--cc=dgc@sgi.com \
--cc=linux-kernel@vger.kernel.org \
--cc=manfred@colorfullife.com \
--cc=marcelo@kvack.org \
--cc=mpm@selenic.com \
--cc=nickpiggin@yahoo.com.au \
/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
Powered by JetHome