linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* 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 : &reg_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).