diff options
author | David S. Miller <davem@davemloft.net> | 2009-03-01 21:35:16 -0800 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-03-01 21:35:16 -0800 |
commit | aa4abc9bcce0d2a7ec189e897f8f8c58ca04643b (patch) | |
tree | 22ef88d84a2e06380bb6a853c3ba28657e4e5f92 /mm/vmalloc.c | |
parent | 814c01dc7c533033b4e99981a2e24a6195bfb43c (diff) | |
parent | 52c0326beaa3cb0049d0f1c51c6ad5d4a04e4430 (diff) | |
download | op-kernel-dev-aa4abc9bcce0d2a7ec189e897f8f8c58ca04643b.zip op-kernel-dev-aa4abc9bcce0d2a7ec189e897f8f8c58ca04643b.tar.gz |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts:
drivers/net/wireless/iwlwifi/iwl-tx.c
net/8021q/vlan_core.c
net/core/dev.c
Diffstat (limited to 'mm/vmalloc.c')
-rw-r--r-- | mm/vmalloc.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 903cad4..520a759 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -323,6 +323,7 @@ static struct vmap_area *alloc_vmap_area(unsigned long size, unsigned long addr; int purged = 0; + BUG_ON(!size); BUG_ON(size & ~PAGE_MASK); va = kmalloc_node(sizeof(struct vmap_area), @@ -334,6 +335,9 @@ retry: addr = ALIGN(vstart, align); spin_lock(&vmap_area_lock); + if (addr + size - 1 < addr) + goto overflow; + /* XXX: could have a last_hole cache */ n = vmap_area_root.rb_node; if (n) { @@ -365,6 +369,8 @@ retry: while (addr + size > first->va_start && addr + size <= vend) { addr = ALIGN(first->va_end + PAGE_SIZE, align); + if (addr + size - 1 < addr) + goto overflow; n = rb_next(&first->rb_node); if (n) @@ -375,6 +381,7 @@ retry: } found: if (addr + size > vend) { +overflow: spin_unlock(&vmap_area_lock); if (!purged) { purge_vmap_area_lazy(); @@ -498,6 +505,7 @@ static void __purge_vmap_area_lazy(unsigned long *start, unsigned long *end, static DEFINE_SPINLOCK(purge_lock); LIST_HEAD(valist); struct vmap_area *va; + struct vmap_area *n_va; int nr = 0; /* @@ -537,7 +545,7 @@ static void __purge_vmap_area_lazy(unsigned long *start, unsigned long *end, if (nr) { spin_lock(&vmap_area_lock); - list_for_each_entry(va, &valist, purge_list) + list_for_each_entry_safe(va, n_va, &valist, purge_list) __free_vmap_area(va); spin_unlock(&vmap_area_lock); } |