* pci_alloc_consistent for small allocations?
@ 2001-09-02 15:08 Adam J. Richter
2001-09-02 15:15 ` Russell King
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Adam J. Richter @ 2001-09-02 15:08 UTC (permalink / raw)
To: linux-kernel
In looking at the ieee1394 OHCI driver, I noticed that it
appears to make 104 calls to pci_alloc_consistent for data structures
that are 16 or 64 bytes. Currently, on x86, pci_alloc_consistent
allocates at least one full page per call, so it looks like the
ohci1394 driver allocates 416kB per controller as a result of these
data structures.
It is easy enough to change the ohci driver to just
do a few pci_alloc_consistent calls, but, in grepping through the
kernel, I see that there are lots of calls to pci_alloc_consistent
calls requesting small amounts of memory. So, I think it might reduce
kernel memory consumption to have pci_alloc_consistent do something
slightly smarter for allocations of less than a page. Two pretty
simple approaches come to mind:
1. If it is the case that a side effect of the slab memory allocator
is that allocations of less than a page (or a certain size) never cross
page boundaries, then the x86 version of pci_alloc_consistent can just
use kmalloc/kfree when the size is below a certain amount. Could someone
tell me if this is the case?
2. Assuming that is not the case, I have written, but not yet tested,
a change to pci_alloc_consistent for x86 where sub-page allocations can share
a single page. The first four bytes of a shared page are used as a
reference counter. This would be two bytes were it not for alignment
considerations. This change can only aggregate small allocations when
they occur in succession. I have attached the patch for illustration, but,
it could use some better variable naming and, I repeat, I have not tested
it at all yet. In the middle of working on it, I thought of option #1 and
figured I should ask on linux-kernel before investing more time in this idea.
Adam J. Richter __ ______________ 4880 Stevens Creek Blvd, Suite 104
adam@yggdrasil.com \ / San Jose, California 95129-1034
+1 408 261-6630 | g g d r a s i l United States of America
fax +1 408 261-6631 "Free Software For The Rest Of Us."
--- linux-2.4.10-pre3/arch/i386/kernel/pci-dma.c Mon Feb 14 15:34:21 2000
+++ linux/arch/i386/kernel/pci-dma.c Sun Sep 2 07:50:33 2001
@@ -13,15 +13,40 @@
#include <linux/pci.h>
#include <asm/io.h>
+static void *reg_partial; /* = NULL */
+static void *dma_partial; /* = NULL */
+
void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
dma_addr_t *dma_handle)
{
void *ret;
int gfp = GFP_ATOMIC;
+ void **partial;
+ int avail;
if (hwdev == NULL || hwdev->dma_mask != 0xffffffff)
gfp |= GFP_DMA;
- ret = (void *)__get_free_pages(gfp, get_order(size));
+
+ partial = (gfp & GFP_DMA) ? &dma_partial : ®_partial;
+
+ /* if *partial is NULL or has been incremented to the beginning
+ of a new page, avail will be zero, and *partial will not be
+ used. */
+ avail = (-((unsigned long)*partial)) & PAGE_MASK;
+
+ if (avail >= size) {
+ ret = *partial;
+ *(int*)(((unsigned long)*partial) & ~PAGE_MASK) += 1;
+ (*partial) += size;
+ } else {
+ ret = (void *)__get_free_pages(gfp, get_order(size));
+
+ if (ret != NULL && (avail + size + sizeof(int) < PAGE_SIZE)) {
+ *(int*)ret = 1;
+ ret += sizeof(int);
+ *partial = ret + size;
+ }
+ }
if (ret != NULL) {
memset(ret, 0, size);
@@ -33,5 +58,9 @@
void pci_free_consistent(struct pci_dev *hwdev, size_t size,
void *vaddr, dma_addr_t dma_handle)
{
+ if (((unsigned long)vaddr & PAGE_MASK) != 0) {
+ if (--*(int*)(((unsigned long)vaddr) & ~PAGE_MASK) != 0)
+ return; /* shared page */
+ }
free_pages((unsigned long)vaddr, get_order(size));
}
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: pci_alloc_consistent for small allocations?
2001-09-02 15:08 pci_alloc_consistent for small allocations? Adam J. Richter
@ 2001-09-02 15:15 ` Russell King
2001-09-02 16:43 ` Johannes Erdfelt
2001-09-02 23:05 ` David S. Miller
2 siblings, 0 replies; 5+ messages in thread
From: Russell King @ 2001-09-02 15:15 UTC (permalink / raw)
To: Adam J. Richter; +Cc: linux-kernel
On Sun, Sep 02, 2001 at 08:08:00AM -0700, Adam J. Richter wrote:
> In looking at the ieee1394 OHCI driver, I noticed that it
> appears to make 104 calls to pci_alloc_consistent for data structures
> that are 16 or 64 bytes. Currently, on x86, pci_alloc_consistent
> allocates at least one full page per call, so it looks like the
> ohci1394 driver allocates 416kB per controller as a result of these
> data structures.
You might want to look through the PCI stuff in drivers/pci - there's a
generic method for handling this on USB already.
--
Russell King (rmk@arm.linux.org.uk) The developer of ARM Linux
http://www.arm.linux.org.uk/personal/aboutme.html
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: pci_alloc_consistent for small allocations?
2001-09-02 15:08 pci_alloc_consistent for small allocations? Adam J. Richter
2001-09-02 15:15 ` Russell King
@ 2001-09-02 16:43 ` Johannes Erdfelt
2001-09-02 23:05 ` David S. Miller
2 siblings, 0 replies; 5+ messages in thread
From: Johannes Erdfelt @ 2001-09-02 16:43 UTC (permalink / raw)
To: Adam J. Richter; +Cc: linux-kernel
On Sun, Sep 02, 2001, Adam J. Richter <adam@yggdrasil.com> wrote:
> In looking at the ieee1394 OHCI driver, I noticed that it
> appears to make 104 calls to pci_alloc_consistent for data structures
> that are 16 or 64 bytes. Currently, on x86, pci_alloc_consistent
> allocates at least one full page per call, so it looks like the
> ohci1394 driver allocates 416kB per controller as a result of these
> data structures.
>
> It is easy enough to change the ohci driver to just
> do a few pci_alloc_consistent calls, but, in grepping through the
> kernel, I see that there are lots of calls to pci_alloc_consistent
> calls requesting small amounts of memory. So, I think it might reduce
> kernel memory consumption to have pci_alloc_consistent do something
> slightly smarter for allocations of less than a page. Two pretty
> simple approaches come to mind:
>
> 1. If it is the case that a side effect of the slab memory allocator
> is that allocations of less than a page (or a certain size) never cross
> page boundaries, then the x86 version of pci_alloc_consistent can just
> use kmalloc/kfree when the size is below a certain amount. Could someone
> tell me if this is the case?
>
> 2. Assuming that is not the case, I have written, but not yet tested,
> a change to pci_alloc_consistent for x86 where sub-page allocations can share
> a single page. The first four bytes of a shared page are used as a
> reference counter. This would be two bytes were it not for alignment
> considerations. This change can only aggregate small allocations when
> they occur in succession. I have attached the patch for illustration, but,
> it could use some better variable naming and, I repeat, I have not tested
> it at all yet. In the middle of working on it, I thought of option #1 and
> figured I should ask on linux-kernel before investing more time in this idea.
Just use pci_pool. We developed the API for USB where we ran into the
same problem.
JE
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: pci_alloc_consistent for small allocations?
2001-09-02 15:08 pci_alloc_consistent for small allocations? Adam J. Richter
2001-09-02 15:15 ` Russell King
2001-09-02 16:43 ` Johannes Erdfelt
@ 2001-09-02 23:05 ` David S. Miller
2 siblings, 0 replies; 5+ messages in thread
From: David S. Miller @ 2001-09-02 23:05 UTC (permalink / raw)
To: adam; +Cc: linux-kernel
Read Documentation/DMA-mapping.txt and read about pci_pool.
I don't know why I bother documenting anything if people
don't even read it. :-)
Later,
David S. Miller
davem@redhat.com
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: pci_alloc_consistent for small allocations?
[not found] <mailman.999443581.14164.linux-kernel2news@redhat.com>
@ 2001-09-04 0:20 ` Pete Zaitcev
0 siblings, 0 replies; 5+ messages in thread
From: Pete Zaitcev @ 2001-09-04 0:20 UTC (permalink / raw)
To: adam, linux-kernel
> In looking at the ieee1394 OHCI driver, I noticed that it
> appears to make 104 calls to pci_alloc_consistent for data structures
> that are 16 or 64 bytes. Currently, on x86, pci_alloc_consistent
> allocates at least one full page per call, so it looks like the
> ohci1394 driver allocates 416kB per controller as a result of these
> data structures.
Sounds you are looking at a very obsolete codebase -or-
something backed out pci_pool_alloc()/pci_pool_free()
from the recent kernel...
If you can reproduce this on 2.4.8, send me a note
with detailed description of whatever you were doing
to get your number 104, I'll fix or disspel it.
-- Pete
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2001-09-04 0:20 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-09-02 15:08 pci_alloc_consistent for small allocations? Adam J. Richter
2001-09-02 15:15 ` Russell King
2001-09-02 16:43 ` Johannes Erdfelt
2001-09-02 23:05 ` David S. Miller
[not found] <mailman.999443581.14164.linux-kernel2news@redhat.com>
2001-09-04 0:20 ` Pete Zaitcev
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).