Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mm: use vm_unmapped_area() on parisc architecture

Update the parisc arch_get_unmapped_area function to make use of
vm_unmapped_area() instead of implementing a brute force search.

[akpm@linux-foundation.org: remove now-unused DCACHE_ALIGN(), per James]
Signed-off-by: Michel Lespinasse <walken@google.com>
Acked-by: Rik van Riel <riel@redhat.com>
Cc: "James E.J. Bottomley" <jejb@parisc-linux.org>
Acked-by: Helge Deller <deller@gmx.de>
Tested-by: Helge Deller <deller@gmx.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Michel Lespinasse and committed by
Linus Torvalds
a0031197 f7a3c997

+17 -31
+17 -31
arch/parisc/kernel/sys_parisc.c
··· 35 35 36 36 static unsigned long get_unshared_area(unsigned long addr, unsigned long len) 37 37 { 38 - struct vm_area_struct *vma; 38 + struct vm_unmapped_area_info info; 39 39 40 - addr = PAGE_ALIGN(addr); 41 - 42 - for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) { 43 - /* At this point: (!vma || addr < vma->vm_end). */ 44 - if (TASK_SIZE - len < addr) 45 - return -ENOMEM; 46 - if (!vma || addr + len <= vma->vm_start) 47 - return addr; 48 - addr = vma->vm_end; 49 - } 40 + info.flags = 0; 41 + info.length = len; 42 + info.low_limit = PAGE_ALIGN(addr); 43 + info.high_limit = TASK_SIZE; 44 + info.align_mask = 0; 45 + info.align_offset = 0; 46 + return vm_unmapped_area(&info); 50 47 } 51 - 52 - #define DCACHE_ALIGN(addr) (((addr) + (SHMLBA - 1)) &~ (SHMLBA - 1)) 53 48 54 49 /* 55 50 * We need to know the offset to use. Old scheme was to look for ··· 58 63 */ 59 64 static int get_offset(struct address_space *mapping) 60 65 { 61 - int offset = (unsigned long) mapping << (PAGE_SHIFT - 8); 62 - return offset & 0x3FF000; 66 + return (unsigned long) mapping >> 8; 63 67 } 64 68 65 69 static unsigned long get_shared_area(struct address_space *mapping, 66 70 unsigned long addr, unsigned long len, unsigned long pgoff) 67 71 { 68 - struct vm_area_struct *vma; 69 - int offset = mapping ? get_offset(mapping) : 0; 72 + struct vm_unmapped_area_info info; 70 73 71 - offset = (offset + (pgoff << PAGE_SHIFT)) & 0x3FF000; 72 - 73 - addr = DCACHE_ALIGN(addr - offset) + offset; 74 - 75 - for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) { 76 - /* At this point: (!vma || addr < vma->vm_end). */ 77 - if (TASK_SIZE - len < addr) 78 - return -ENOMEM; 79 - if (!vma || addr + len <= vma->vm_start) 80 - return addr; 81 - addr = DCACHE_ALIGN(vma->vm_end - offset) + offset; 82 - if (addr < vma->vm_end) /* handle wraparound */ 83 - return -ENOMEM; 84 - } 74 + info.flags = 0; 75 + info.length = len; 76 + info.low_limit = PAGE_ALIGN(addr); 77 + info.high_limit = TASK_SIZE; 78 + info.align_mask = PAGE_MASK & (SHMLBA - 1); 79 + info.align_offset = (get_offset(mapping) + pgoff) << PAGE_SHIFT; 80 + return vm_unmapped_area(&info); 85 81 } 86 82 87 83 unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,