aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mm/vmregion.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mm/vmregion.c')
-rw-r--r--arch/arm/mm/vmregion.c17
1 files changed, 8 insertions, 9 deletions
diff --git a/arch/arm/mm/vmregion.c b/arch/arm/mm/vmregion.c
index 935993e1b1ef..036fdbfdd62f 100644
--- a/arch/arm/mm/vmregion.c
+++ b/arch/arm/mm/vmregion.c
@@ -38,7 +38,7 @@ struct arm_vmregion *
38arm_vmregion_alloc(struct arm_vmregion_head *head, size_t align, 38arm_vmregion_alloc(struct arm_vmregion_head *head, size_t align,
39 size_t size, gfp_t gfp) 39 size_t size, gfp_t gfp)
40{ 40{
41 unsigned long addr = head->vm_start, end = head->vm_end - size; 41 unsigned long start = head->vm_start, addr = head->vm_end;
42 unsigned long flags; 42 unsigned long flags;
43 struct arm_vmregion *c, *new; 43 struct arm_vmregion *c, *new;
44 44
@@ -54,21 +54,20 @@ arm_vmregion_alloc(struct arm_vmregion_head *head, size_t align,
54 54
55 spin_lock_irqsave(&head->vm_lock, flags); 55 spin_lock_irqsave(&head->vm_lock, flags);
56 56
57 list_for_each_entry(c, &head->vm_list, vm_list) { 57 addr = rounddown(addr - size, align);
58 if ((addr + size) < addr) 58 list_for_each_entry_reverse(c, &head->vm_list, vm_list) {
59 goto nospc; 59 if (addr >= c->vm_end)
60 if ((addr + size) <= c->vm_start)
61 goto found; 60 goto found;
62 addr = ALIGN(c->vm_end, align); 61 addr = rounddown(c->vm_start - size, align);
63 if (addr > end) 62 if (addr < start)
64 goto nospc; 63 goto nospc;
65 } 64 }
66 65
67 found: 66 found:
68 /* 67 /*
69 * Insert this entry _before_ the one we found. 68 * Insert this entry after the one we found.
70 */ 69 */
71 list_add_tail(&new->vm_list, &c->vm_list); 70 list_add(&new->vm_list, &c->vm_list);
72 new->vm_start = addr; 71 new->vm_start = addr;
73 new->vm_end = addr + size; 72 new->vm_end = addr + size;
74 new->vm_active = 1; 73 new->vm_active = 1;