svn commit: r210789 - projects/ofed/head/sys/ofed/include/linux
Jeff Roberson
jeff at FreeBSD.org
Tue Aug 3 08:37:17 UTC 2010
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
More information about the svn-src-projects
mailing list