diff options
author | Michel Lespinasse <walken@google.com> | 2013-02-27 20:02:40 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-27 22:10:09 -0500 |
commit | a003119771f337abeb4a5d7564ac2d22c193fb8b (patch) | |
tree | 7c3eadd04e82f7fb97f643656587f2221c1225eb /arch/parisc/kernel | |
parent | f7a3c997af148b13a6225898c9bde1cb858924ba (diff) |
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>
Diffstat (limited to 'arch/parisc/kernel')
-rw-r--r-- | arch/parisc/kernel/sys_parisc.c | 48 |
1 files changed, 17 insertions, 31 deletions
diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c index 54d619d4cac6..5dfd248e3f1a 100644 --- a/arch/parisc/kernel/sys_parisc.c +++ b/arch/parisc/kernel/sys_parisc.c | |||
@@ -35,22 +35,17 @@ | |||
35 | 35 | ||
36 | static unsigned long get_unshared_area(unsigned long addr, unsigned long len) | 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); | 40 | info.flags = 0; |
41 | 41 | info.length = len; | |
42 | for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) { | 42 | info.low_limit = PAGE_ALIGN(addr); |
43 | /* At this point: (!vma || addr < vma->vm_end). */ | 43 | info.high_limit = TASK_SIZE; |
44 | if (TASK_SIZE - len < addr) | 44 | info.align_mask = 0; |
45 | return -ENOMEM; | 45 | info.align_offset = 0; |
46 | if (!vma || addr + len <= vma->vm_start) | 46 | return vm_unmapped_area(&info); |
47 | return addr; | ||
48 | addr = vma->vm_end; | ||
49 | } | ||
50 | } | 47 | } |
51 | 48 | ||
52 | #define DCACHE_ALIGN(addr) (((addr) + (SHMLBA - 1)) &~ (SHMLBA - 1)) | ||
53 | |||
54 | /* | 49 | /* |
55 | * We need to know the offset to use. Old scheme was to look for | 50 | * We need to know the offset to use. Old scheme was to look for |
56 | * existing mapping and use the same offset. New scheme is to use the | 51 | * existing mapping and use the same offset. New scheme is to use the |
@@ -63,30 +58,21 @@ static unsigned long get_unshared_area(unsigned long addr, unsigned long len) | |||
63 | */ | 58 | */ |
64 | static int get_offset(struct address_space *mapping) | 59 | static int get_offset(struct address_space *mapping) |
65 | { | 60 | { |
66 | int offset = (unsigned long) mapping << (PAGE_SHIFT - 8); | 61 | return (unsigned long) mapping >> 8; |
67 | return offset & 0x3FF000; | ||
68 | } | 62 | } |
69 | 63 | ||
70 | static unsigned long get_shared_area(struct address_space *mapping, | 64 | static unsigned long get_shared_area(struct address_space *mapping, |
71 | unsigned long addr, unsigned long len, unsigned long pgoff) | 65 | unsigned long addr, unsigned long len, unsigned long pgoff) |
72 | { | 66 | { |
73 | struct vm_area_struct *vma; | 67 | struct vm_unmapped_area_info info; |
74 | int offset = mapping ? get_offset(mapping) : 0; | ||
75 | 68 | ||
76 | offset = (offset + (pgoff << PAGE_SHIFT)) & 0x3FF000; | 69 | info.flags = 0; |
77 | 70 | info.length = len; | |
78 | addr = DCACHE_ALIGN(addr - offset) + offset; | 71 | info.low_limit = PAGE_ALIGN(addr); |
79 | 72 | info.high_limit = TASK_SIZE; | |
80 | for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) { | 73 | info.align_mask = PAGE_MASK & (SHMLBA - 1); |
81 | /* At this point: (!vma || addr < vma->vm_end). */ | 74 | info.align_offset = (get_offset(mapping) + pgoff) << PAGE_SHIFT; |
82 | if (TASK_SIZE - len < addr) | 75 | return vm_unmapped_area(&info); |
83 | return -ENOMEM; | ||
84 | if (!vma || addr + len <= vma->vm_start) | ||
85 | return addr; | ||
86 | addr = DCACHE_ALIGN(vma->vm_end - offset) + offset; | ||
87 | if (addr < vma->vm_end) /* handle wraparound */ | ||
88 | return -ENOMEM; | ||
89 | } | ||
90 | } | 76 | } |
91 | 77 | ||
92 | unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, | 78 | unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, |