Date: Tue, 3 Aug 2010 08:37:16 +0000 (UTC) From: Jeff Roberson <jeff@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r210789 - projects/ofed/head/sys/ofed/include/linux Message-ID: <201008030837.o738bGc1090163@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jeff Date: Tue Aug 3 08:37:16 2010 New Revision: 210789 URL: http://svn.freebsd.org/changeset/base/210789 Log: - Use a simpler method for deriving the KVA address of a page that exists in the kmem or kernel objects as suggested by Alan Cox. This is not only cheaper than the other method but also is compatible with more page sources. Sponsored by: Isilon Systems, iX Systems, and Panasas. Modified: projects/ofed/head/sys/ofed/include/linux/dma-mapping.h projects/ofed/head/sys/ofed/include/linux/gfp.h projects/ofed/head/sys/ofed/include/linux/mm.h projects/ofed/head/sys/ofed/include/linux/scatterlist.h Modified: projects/ofed/head/sys/ofed/include/linux/dma-mapping.h ============================================================================== --- projects/ofed/head/sys/ofed/include/linux/dma-mapping.h Tue Aug 3 08:34:41 2010 (r210788) +++ projects/ofed/head/sys/ofed/include/linux/dma-mapping.h Tue Aug 3 08:37:16 2010 (r210789) @@ -117,8 +117,6 @@ dma_set_coherent_mask(struct device *dev return 0; } -MALLOC_DECLARE(M_LINUX_DMA); - static inline void * dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flag) @@ -132,7 +130,8 @@ dma_alloc_coherent(struct device *dev, s else high = BUS_SPACE_MAXADDR_32BIT; align = PAGE_SIZE << get_order(size); - mem = contigmalloc(size, M_LINUX_DMA, flag, 0, high, align, 0); + mem = (void *)kmem_alloc_contig(kmem_map, size, flag, 0, high, align, + 0, VM_MEMATTR_DEFAULT); if (mem) *dma_handle = vtophys(mem); else @@ -144,7 +143,8 @@ static inline void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr_t dma_handle) { - contigfree(cpu_addr, size, M_LINUX_DMA); + + kmem_free(kmem_map, (vm_offset_t)cpu_addr, size); } /* XXX This only works with no iommu. */ @@ -186,7 +186,7 @@ dma_map_page(struct device *dev, struct unsigned long offset, size_t size, enum dma_data_direction direction) { - return VM_PAGE_TO_PHYS(page) + offset; + return VM_PAGE_TO_PHYS(page) + offset; } static inline void Modified: projects/ofed/head/sys/ofed/include/linux/gfp.h ============================================================================== --- projects/ofed/head/sys/ofed/include/linux/gfp.h Tue Aug 3 08:34:41 2010 (r210788) +++ projects/ofed/head/sys/ofed/include/linux/gfp.h Tue Aug 3 08:37:16 2010 (r210789) @@ -50,19 +50,20 @@ #define GFP_HIGHUSER_MOVABLE M_WAITOK #define GFP_IOFS M_NOWAIT +static inline void * +page_address(struct page *page) +{ + + if (page->object != kmem_object && page->object != kernel_object) + return (NULL); + return (void *)(VM_MIN_KERNEL_ADDRESS + IDX_TO_OFF(page->pindex)); +} + static inline unsigned long _get_page(gfp_t mask) { - vm_page_t m; - vm_offset_t p; - p = kmem_malloc(kmem_map, PAGE_SIZE, mask | M_ZERO); - if (p) { - m = virt_to_page(p); - m->flags |= PG_KVA; - m->object = (vm_object_t)p; - } - return (p); + return kmem_malloc(kmem_map, PAGE_SIZE, mask); } #define get_zeroed_page(mask) _get_page((mask) | M_ZERO) @@ -72,47 +73,30 @@ _get_page(gfp_t mask) static inline void free_page(unsigned long page) { - vm_page_t m; - m = virt_to_page(page); - if (m->flags & PG_KVA) { - m->flags &= ~PG_KVA; - m->object = kmem_object; - } + if (page == 0) + return; kmem_free(kmem_map, page, PAGE_SIZE); } static inline void __free_page(struct page *m) { - void *p; - if ((m->flags & PG_KVA) == 0) + if (m->object != kmem_object) panic("__free_page: Freed page %p not allocated via wrappers.", m); - p = m->object; - m->flags &= ~PG_KVA; - m->object = kmem_object; - kmem_free(kmem_map, (vm_offset_t)p, PAGE_SIZE); + kmem_free(kmem_map, (vm_offset_t)page_address(m), PAGE_SIZE); } static inline void __free_pages(void *p, unsigned int order) { - unsigned long start; - unsigned long page; - vm_page_t m; size_t size; + if (p == 0) + return; size = PAGE_SIZE << order; - start = (unsigned long)p; - for (page = start; page < start + size; page += PAGE_SIZE) { - m = virt_to_page(page); - if (m->flags & PG_KVA) { - m->flags &= ~PG_KVA; - m->object = kmem_object; - } - } kmem_free(kmem_map, (vm_offset_t)p, size); } @@ -124,22 +108,15 @@ __free_pages(void *p, unsigned int order static inline struct page * alloc_pages(gfp_t gfp_mask, unsigned int order) { - unsigned long start; unsigned long page; - vm_page_t m; size_t size; size = PAGE_SIZE << order; - start = kmem_alloc_contig(kmem_map, size, gfp_mask, 0, -1, + page = kmem_alloc_contig(kmem_map, size, gfp_mask, 0, -1, size, 0, VM_MEMATTR_DEFAULT); - if (start == 0) + if (page == 0) return (NULL); - for (page = start; page < start + size; page += PAGE_SIZE) { - m = virt_to_page(page); - m->flags |= PG_KVA; - m->object = (vm_object_t)page; - } - return (virt_to_page(start)); + return (virt_to_page(page)); } #endif /* _LINUX_GFP_H_ */ Modified: projects/ofed/head/sys/ofed/include/linux/mm.h ============================================================================== --- projects/ofed/head/sys/ofed/include/linux/mm.h Tue Aug 3 08:34:41 2010 (r210788) +++ projects/ofed/head/sys/ofed/include/linux/mm.h Tue Aug 3 08:37:16 2010 (r210789) @@ -37,6 +37,10 @@ struct vm_area_struct { }; +/* + * Compute log2 of the power of two rounded up count of pages + * needed for size bytes. + */ static inline int get_order(unsigned long size) { @@ -55,10 +59,7 @@ static inline void * lowmem_page_address(struct page *page) { - if (page->flags & PG_KVA) - return (page->object); - return (NULL); + return page_address(page); } - #endif /* _LINUX_MM_H_ */ Modified: projects/ofed/head/sys/ofed/include/linux/scatterlist.h ============================================================================== --- projects/ofed/head/sys/ofed/include/linux/scatterlist.h Tue Aug 3 08:34:41 2010 (r210788) +++ projects/ofed/head/sys/ofed/include/linux/scatterlist.h Tue Aug 3 08:37:16 2010 (r210789) @@ -57,13 +57,15 @@ sg_set_page(struct scatterlist *sg, stru sg_page(sg) = page; sg_dma_len(sg) = len; sg->offset = offset; + if (offset > PAGE_SIZE) + panic("sg_set_page: Invalid offset %d\n", offset); } static inline void sg_set_buf(struct scatterlist *sg, const void *buf, unsigned int buflen) { - sg_set_page(sg, PHYS_TO_VM_PAGE(vtophys(buf)), buflen, - ((uintptr_t)buf) & PAGE_MASK); + sg_set_page(sg, virt_to_page(buf), buflen, + ((uintptr_t)buf) & ~PAGE_MASK); } static inline void
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201008030837.o738bGc1090163>