Messages in this thread Patch in this message |  | | | From | rmk@arm ... | | Subject | Re: Cache incoherencies [example code] | | Date | Thu, 26 Aug 1999 10:55:42 -0400 (EDT) |
| |
Hi Ben,
Here is an example of the modifications required to vmalloc to enable uncached spaces to be allocated. In fact, it allows any pgprot to be specified for the vmalloc'd area. I think that the names of the new functions follow Linus' naming scheme - __vmalloc() is more generic and does `less' than vmalloc().
Note that this is just an example; it seems to compile (on 2.2.5), but I have not tested it at all.
--- vmalloc.c.rmk Thu Aug 26 10:52:39 1999 +++ vmalloc.c Thu Aug 26 10:53:58 1999 @@ -82,7 +82,7 @@ flush_tlb_all(); } -static inline int alloc_area_pte(pte_t * pte, unsigned long address, unsigned long size) +static inline int alloc_area_pte(pte_t * pte, unsigned long address, unsigned long size, pgprot_t prot) { unsigned long end; @@ -97,14 +97,14 @@ page = __get_free_page(GFP_KERNEL); if (!page) return -ENOMEM; - set_pte(pte, mk_pte(page, PAGE_KERNEL)); + set_pte(pte, mk_pte(page, prot)); address += PAGE_SIZE; pte++; } return 0; } -static inline int alloc_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size) +static inline int alloc_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size, pgprot_t prot) { unsigned long end; @@ -116,7 +116,7 @@ pte_t * pte = pte_alloc_kernel(pmd, address); if (!pte) return -ENOMEM; - if (alloc_area_pte(pte, address, end - address)) + if (alloc_area_pte(pte, address, end - address, prot)) return -ENOMEM; address = (address + PMD_SIZE) & PMD_MASK; pmd++; @@ -124,7 +124,7 @@ return 0; } -int vmalloc_area_pages(unsigned long address, unsigned long size) +inline int __vmalloc_area_pages(unsigned long address, unsigned long size, pgprot_t prot) { pgd_t * dir; unsigned long end = address + size; @@ -138,7 +138,7 @@ pmd = pmd_alloc_kernel(dir, address); if (!pmd) return -ENOMEM; - if (alloc_area_pmd(pmd, address, end - address)) + if (alloc_area_pmd(pmd, address, end - address, prot)) return -ENOMEM; if (pgd_val(olddir) != pgd_val(*dir)) set_pgdir(address, *dir); @@ -149,6 +149,11 @@ return 0; } +int vmalloc_area_pages(unsigned long address, unsigned long size) +{ + return __vmalloc_area_pages(address, size, PAGE_KERNEL); +} + struct vm_struct * get_vm_area(unsigned long size) { unsigned long addr; @@ -195,7 +200,7 @@ printk("Trying to vfree() nonexistent vm area (%p)\n", addr); } -void * vmalloc(unsigned long size) +inline void * __vmalloc(unsigned long size, pgprot_t prot) { void * addr; struct vm_struct *area; @@ -207,11 +212,16 @@ if (!area) return NULL; addr = area->addr; - if (vmalloc_area_pages(VMALLOC_VMADDR(addr), size)) { + if (__vmalloc_area_pages(VMALLOC_VMADDR(addr), size, prot)) { vfree(addr); return NULL; } return addr; +} + +void * vmalloc(unsigned long size) +{ + return __vmalloc(size, PAGE_KERNEL); } long vread(char *buf, char *addr, unsigned long count) _____ |_____| ------------------------------------------------- ---+---+- | | Russell King rmk@arm.linux.org.uk --- --- | | | | http://www.arm.linux.org.uk/~rmk/aboutme.html / / | | +-+-+ --- -+- / | THE developer of ARM Linux |+| /|\ / | | | --- | +-+-+ ------------------------------------------------- /\\\ | - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
|  |