Perhaps somebody who knows more of the mm could verify this.
Marcus
===== mm/vmalloc.c 1.18 vs edited =====
--- 1.18/mm/vmalloc.c Mon Aug 5 22:05:22 2002
+++ edited/mm/vmalloc.c Mon Aug 19 00:37:40 2002
@@ -153,15 +153,20 @@
unsigned long address = VMALLOC_VMADDR(area->addr);
unsigned long end = address + (area->size-PAGE_SIZE);
pgd_t *dir;
+ int err = 0;
dir = pgd_offset_k(address);
spin_lock(&init_mm.page_table_lock);
do {
pmd_t *pmd = pmd_alloc(&init_mm, dir, address);
- if (!pmd)
- return -ENOMEM;
- if (map_area_pmd(pmd, address, end - address, prot, pages))
- return -ENOMEM;
+ if (!pmd) {
+ err = -ENOMEM;
+ break;
+ }
+ if (map_area_pmd(pmd, address, end - address, prot, pages)) {
+ err = -ENOMEM;
+ break;
+ }
address = (address + PGDIR_SIZE) & PGDIR_MASK;
dir++;
@@ -169,7 +174,7 @@
spin_unlock(&init_mm.page_table_lock);
flush_cache_all();
- return 0;
+ return err;
}
@@ -379,14 +384,20 @@
area->nr_pages = nr_pages;
area->pages = pages = kmalloc(array_size, (gfp_mask & ~__GFP_HIGHMEM));
- if (!area->pages)
+ if (!area->pages) {
+ remove_vm_area(area->addr);
+ kfree(area);
return NULL;
+ }
memset(area->pages, 0, array_size);
for (i = 0; i < area->nr_pages; i++) {
area->pages[i] = alloc_page(gfp_mask);
- if (unlikely(!area->pages[i]))
+ if (unlikely(!area->pages[i])) {
+ /* Successfully allocated i pages, free them in __vunmap() */
+ area->nr_pages = i;
goto fail;
+ }
}
if (map_vm_area(area, prot, &pages))
-- Marcus Alanen * Embedded Systems Laboratory * http://www.eslab.cs.abo.fi/ marcus.alanen@abo.fi
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/