Messages in this thread Patch in this message | | | Date | Fri, 22 Sep 2006 12:07:49 -0700 (PDT) | From | Christoph Lameter <> | Subject | Re: ZONE_DMA |
| |
On Fri, 22 Sep 2006, Jesse Barnes wrote:
> Right, being able to allocate from specific ranges would obviate the need > for GFP_DMA and the various zones. It would come with a cost though since > the VM would have to become aware of pressure at various ranges rather > than just on zones like we have now. I think that's where things get > tricky.
Here is a hyperthetical use scenario (no code yet to do this in the page allocator, fake patch for discussion only):
Index: linux-2.6.18-rc7-mm1/arch/i386/kernel/pci-dma.c =================================================================== --- linux-2.6.18-rc7-mm1.orig/arch/i386/kernel/pci-dma.c 2006-09-12 20:41:36.000000000 -0500 +++ linux-2.6.18-rc7-mm1/arch/i386/kernel/pci-dma.c 2006-09-22 13:59:29.017611573 -0500 @@ -26,6 +26,8 @@ void *dma_alloc_coherent(struct device * dma_addr_t *dma_handle, gfp_t gfp) { void *ret; + unsigned long low = 0L; + unsigned long high = 0xffffffff; struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL; int order = get_order(size); /* ignore region specifiers */ @@ -44,10 +46,14 @@ void *dma_alloc_coherent(struct device * return NULL; } - if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff)) - gfp |= GFP_DMA; + if (dev == NULL) + /* Apply safe ISA LIMITS */ + high = 16*1024*1024L; + else + if (dev->coherent_dma_mask < 0xffffffff) + high = dev->coherent_dma_mask; - ret = (void *)__get_free_pages(gfp, order); + ret = page_address(alloc_pages_range(low, high, gfp, order)); if (ret != NULL) { memset(ret, 0, size); Index: linux-2.6.18-rc7-mm1/include/linux/gfp.h =================================================================== --- linux-2.6.18-rc7-mm1.orig/include/linux/gfp.h 2006-09-19 09:26:58.000000000 -0500 +++ linux-2.6.18-rc7-mm1/include/linux/gfp.h 2006-09-22 14:02:34.298613635 -0500 @@ -136,6 +136,9 @@ static inline struct page *alloc_pages_n NODE_DATA(nid)->node_zonelists + gfp_zone(gfp_mask)); } +extern struct page *alloc_pages_range(unsigned long low, unsigned long high, + gfp_t gfp_mask, unsigned int order); + #ifdef CONFIG_NUMA extern struct page *alloc_pages_current(gfp_t gfp_mask, unsigned order); - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |