From: James Bottomley <James.Bottomley@steeleye.com>
To: David Brownell <david-b@pacbell.net>
Cc: James Bottomley <James.Bottomley@SteelEye.com>,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH] generic device DMA (dma_pool update)
Date: Tue, 31 Dec 2002 12:44:30 -0600 [thread overview]
Message-ID: <200212311844.gBVIiUe02655@localhost.localdomain> (raw)
In-Reply-To: Message from David Brownell <david-b@pacbell.net> of "Tue, 31 Dec 2002 10:11:50 PST." <3E11DDE6.7050601@pacbell.net>
[-- Attachment #1: Type: text/plain, Size: 1220 bytes --]
david-b@pacbell.net said:
> Nobody's done that yet, and it's been a couple years now since that
> point was made as a desirable evolution path for pci_pool. In fact
> the first (only!) step on that path was the dma_pool update I just
> posted.
> Modifying the slab allocator like that means passing extra parameters
> around (for dma_addr_t), causing extra register pressure even for
> non-dma allocations. I have a hard time seeing that not slow things
> down, even on x86 (etc) where we know we can already get all the
> benefits of the slab allocator without any changes to that critical
> code.
I think the attached should do the necessary with no slow down in the slab
allocator.
Now all that has to happen for use with the dma pools is to wrapper
dma_alloc/free_coherent().
Note that the semantics won't be quite the same as the pci_pool one since you
can't guarantee that allocations don't cross the particular boundary
parameter. There's also going to be a reliance on the concept that the dma
coherent allocators will return a page bounded chunk of memory. Most seem
already to be doing this because the page properties are only controllable at
that level, so it shouldn't be a problem.
James
[-- Attachment #2: tmp.diff --]
[-- Type: text/plain , Size: 4627 bytes --]
===== mm/slab.c 1.52 vs edited =====
--- 1.52/mm/slab.c Sat Dec 21 10:24:34 2002
+++ edited/mm/slab.c Tue Dec 31 12:35:39 2002
@@ -260,6 +260,12 @@
/* de-constructor func */
void (*dtor)(void *, kmem_cache_t *, unsigned long);
+ /* page based allocator */
+ unsigned long FASTCALL((*getpages)(unsigned int gfp_mask, unsigned int order));
+
+ /* release pages allocated above */
+ void FASTCALL((*freepages)(unsigned long addr, unsigned int order));
+
/* 4) cache creation/removal */
const char *name;
struct list_head next;
@@ -715,7 +721,7 @@
* would be relatively rare and ignorable.
*/
flags |= cachep->gfpflags;
- addr = (void*) __get_free_pages(flags, cachep->gfporder);
+ addr = (void*) cachep->getpages(flags, cachep->gfporder);
/* Assume that now we have the pages no one else can legally
* messes with the 'struct page's.
* However vm_scan() might try to test the structure to see if
@@ -741,7 +747,7 @@
dec_page_state(nr_slab);
page++;
}
- free_pages((unsigned long)addr, cachep->gfporder);
+ cachep->freepages((unsigned long)addr, cachep->gfporder);
}
#if DEBUG
@@ -811,13 +817,15 @@
}
/**
- * kmem_cache_create - Create a cache.
+ * kmem_cache_create_alloc - Create a cache with a custom allocator.
* @name: A string which is used in /proc/slabinfo to identify this cache.
* @size: The size of objects to be created in this cache.
* @offset: The offset to use within the page.
* @flags: SLAB flags
* @ctor: A constructor for the objects.
* @dtor: A destructor for the objects.
+ * @getpages: A function to get the memory pages
+ * @freepages: A function to free the corresponding pages
*
* Returns a ptr to the cache on success, NULL on failure.
* Cannot be called within a int, but can be interrupted.
@@ -844,9 +852,12 @@
* as davem.
*/
kmem_cache_t *
-kmem_cache_create (const char *name, size_t size, size_t offset,
- unsigned long flags, void (*ctor)(void*, kmem_cache_t *, unsigned long),
- void (*dtor)(void*, kmem_cache_t *, unsigned long))
+kmem_cache_create_with_alloc (const char *name, size_t size, size_t offset,
+ unsigned long flags,
+ void (*ctor)(void*, kmem_cache_t *, unsigned long),
+ void (*dtor)(void*, kmem_cache_t *, unsigned long),
+ unsigned long FASTCALL((*getpages)(unsigned int gfp_mask, unsigned int order)),
+ void FASTCALL((*freepages)(unsigned long addr, unsigned int order)))
{
const char *func_nm = KERN_ERR "kmem_create: ";
size_t left_over, align, slab_size;
@@ -1010,6 +1021,9 @@
cachep->slabp_cache = kmem_find_general_cachep(slab_size,0);
cachep->ctor = ctor;
cachep->dtor = dtor;
+ BUG_ON(getpages == NULL || freepages == NULL);
+ cachep->getpages = getpages;
+ cachep->freepages = freepages;
cachep->name = name;
if (g_cpucache_up == FULL) {
@@ -1072,6 +1086,50 @@
up(&cache_chain_sem);
opps:
return cachep;
+}
+
+/**
+ * kmem_cache_create_alloc - Create a cache with a custom allocator.
+ * @name: A string which is used in /proc/slabinfo to identify this cache.
+ * @size: The size of objects to be created in this cache.
+ * @offset: The offset to use within the page.
+ * @flags: SLAB flags
+ * @ctor: A constructor for the objects.
+ * @dtor: A destructor for the objects.
+ * @getpages: A function to get the memory pages
+ * @freepages: A function to free the corresponding pages
+ *
+ * Returns a ptr to the cache on success, NULL on failure.
+ * Cannot be called within a int, but can be interrupted.
+ * The @ctor is run when new pages are allocated by the cache
+ * and the @dtor is run before the pages are handed back.
+ *
+ * @name must be valid until the cache is destroyed. This implies that
+ * the module calling this has to destroy the cache before getting
+ * unloaded.
+ *
+ * The flags are
+ *
+ * %SLAB_POISON - Poison the slab with a known test pattern (a5a5a5a5)
+ * to catch references to uninitialised memory.
+ *
+ * %SLAB_RED_ZONE - Insert `Red' zones around the allocated memory to check
+ * for buffer overruns.
+ *
+ * %SLAB_NO_REAP - Don't automatically reap this cache when we're under
+ * memory pressure.
+ *
+ * %SLAB_HWCACHE_ALIGN - Align the objects in this cache to a hardware
+ * cacheline. This can be beneficial if you're counting cycles as closely
+ * as davem.
+ */
+kmem_cache_t *
+kmem_cache_create (const char *name, size_t size, size_t offset,
+ unsigned long flags,
+ void (*ctor)(void*, kmem_cache_t *, unsigned long),
+ void (*dtor)(void*, kmem_cache_t *, unsigned long))
+{
+ return kmem_cache_create_with_alloc(name, size, offset, flags, ctor, dtor, __get_free_pages, free_pages);
}
static inline void check_irq_off(void)
next prev parent reply other threads:[~2002-12-31 18:36 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2002-12-27 20:21 [RFT][PATCH] generic device DMA implementation David Brownell
2002-12-27 21:40 ` James Bottomley
2002-12-28 1:29 ` David Brownell
2002-12-28 16:18 ` James Bottomley
2002-12-28 18:16 ` David Brownell
2002-12-28 1:56 ` David Brownell
2002-12-28 16:13 ` James Bottomley
2002-12-28 17:41 ` David Brownell
2002-12-30 23:11 ` [PATCH] generic device DMA (dma_pool update) David Brownell
2002-12-31 15:00 ` James Bottomley
2002-12-31 17:04 ` David Brownell
2002-12-31 17:23 ` James Bottomley
2002-12-31 18:11 ` David Brownell
2002-12-31 18:44 ` James Bottomley [this message]
2002-12-31 19:29 ` David Brownell
2002-12-31 19:50 ` James Bottomley
2002-12-31 21:17 ` David Brownell
2002-12-31 16:36 ` James Bottomley
2002-12-31 17:32 ` David Brownell
2002-12-27 21:47 ` [RFT][PATCH] generic device DMA implementation James Bottomley
2002-12-28 2:28 ` David Brownell
-- strict thread matches above, loose matches on Subject: below --
2002-12-31 22:02 [PATCH] generic device DMA (dma_pool update) Adam J. Richter
2002-12-31 22:41 ` Andrew Morton
2002-12-31 23:23 ` David Brownell
2002-12-31 23:27 ` Andrew Morton
2002-12-31 23:44 ` David Brownell
2002-12-31 23:47 ` James Bottomley
2003-01-01 17:10 ` James Bottomley
2002-12-31 23:35 ` David Brownell
2002-12-31 23:38 Adam J. Richter
2003-01-01 0:02 Adam J. Richter
2003-01-01 19:21 Adam J. Richter
2003-01-01 19:48 ` James Bottomley
2003-01-02 2:11 ` David Brownell
2003-01-02 4:13 Adam J. Richter
2003-01-02 16:41 ` James Bottomley
2003-01-02 18:26 ` David Brownell
2003-01-02 17:04 Adam J. Richter
2003-01-02 22:07 Adam J. Richter
2003-01-03 0:20 ` Russell King
2003-01-03 4:50 ` David Brownell
2003-01-03 6:11 ` David Brownell
2003-01-03 6:46 ` David Brownell
2003-01-03 6:52 ` William Lee Irwin III
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=200212311844.gBVIiUe02655@localhost.localdomain \
--to=james.bottomley@steeleye.com \
--cc=david-b@pacbell.net \
--cc=linux-kernel@vger.kernel.org \
/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