patch-2.3.23 linux/mm/vmalloc.c

Next file: linux/mm/vmscan.c
Previous file: linux/mm/swapfile.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.22/linux/mm/vmalloc.c linux/mm/vmalloc.c
@@ -20,7 +20,7 @@
 	if (pmd_none(*pmd))
 		return;
 	if (pmd_bad(*pmd)) {
-		printk("free_area_pte: bad pmd (%08lx)\n", pmd_val(*pmd));
+		pmd_ERROR(*pmd);
 		pmd_clear(pmd);
 		return;
 	}
@@ -29,7 +29,7 @@
 	end = address + size;
 	if (end > PMD_SIZE)
 		end = PMD_SIZE;
-	while (address < end) {
+	do {
 		pte_t page = *pte;
 		pte_clear(pte);
 		address += PAGE_SIZE;
@@ -37,11 +37,13 @@
 		if (pte_none(page))
 			continue;
 		if (pte_present(page)) {
-			free_page(pte_page(page));
+			unsigned long map_nr = pte_pagenr(page);
+			if (map_nr < max_mapnr)
+				__free_page(mem_map + map_nr);
 			continue;
 		}
 		printk("Whee.. Swapped out page in kernel page table\n");
-	}
+	} while (address < end);
 }
 
 static inline void free_area_pmd(pgd_t * dir, unsigned long address, unsigned long size)
@@ -52,7 +54,7 @@
 	if (pgd_none(*dir))
 		return;
 	if (pgd_bad(*dir)) {
-		printk("free_area_pmd: bad pgd (%08lx)\n", pgd_val(*dir));
+		pgd_ERROR(*dir);
 		pgd_clear(dir);
 		return;
 	}
@@ -61,11 +63,11 @@
 	end = address + size;
 	if (end > PGDIR_SIZE)
 		end = PGDIR_SIZE;
-	while (address < end) {
+	do {
 		free_area_pte(pmd, address, end - address);
 		address = (address + PMD_SIZE) & PMD_MASK;
 		pmd++;
-	}
+	} while (address < end);
 }
 
 void vmfree_area_pages(unsigned long address, unsigned long size)
@@ -75,11 +77,11 @@
 
 	dir = pgd_offset_k(address);
 	flush_cache_all();
-	while (address < end) {
+	do {
 		free_area_pmd(dir, address, end - address);
 		address = (address + PGDIR_SIZE) & PGDIR_MASK;
 		dir++;
-	}
+	} while (address && (address < end));
 	flush_tlb_all();
 }
 
@@ -91,17 +93,17 @@
 	end = address + size;
 	if (end > PMD_SIZE)
 		end = PMD_SIZE;
-	while (address < end) {
-		unsigned long page;
+	do {
+		struct page * page;
 		if (!pte_none(*pte))
 			printk("alloc_area_pte: page already exists\n");
-		page = __get_free_page(GFP_KERNEL|GFP_BIGMEM);
+		page = get_free_highpage(GFP_KERNEL|__GFP_HIGHMEM);
 		if (!page)
 			return -ENOMEM;
 		set_pte(pte, mk_pte(page, PAGE_KERNEL));
 		address += PAGE_SIZE;
 		pte++;
-	}
+	} while (address < end);
 	return 0;
 }
 
@@ -113,7 +115,7 @@
 	end = address + size;
 	if (end > PGDIR_SIZE)
 		end = PGDIR_SIZE;
-	while (address < end) {
+	do {
 		pte_t * pte = pte_alloc_kernel(pmd, address);
 		if (!pte)
 			return -ENOMEM;
@@ -121,7 +123,7 @@
 			return -ENOMEM;
 		address = (address + PMD_SIZE) & PMD_MASK;
 		pmd++;
-	}
+	} while (address < end);
 	return 0;
 }
 
@@ -132,7 +134,7 @@
 
 	dir = pgd_offset_k(address);
 	flush_cache_all();
-	while (address < end) {
+	do {
 		pmd_t *pmd;
 		pgd_t olddir = *dir;
 		
@@ -145,7 +147,7 @@
 			set_pgdir(address, *dir);
 		address = (address + PGDIR_SIZE) & PGDIR_MASK;
 		dir++;
-	}
+	} while (address && (address < end));
 	flush_tlb_all();
 	return 0;
 }
@@ -202,14 +204,19 @@
 	struct vm_struct *area;
 
 	size = PAGE_ALIGN(size);
-	if (!size || size > (max_mapnr << PAGE_SHIFT))
+	if (!size || size > (max_mapnr << PAGE_SHIFT)) {
+		BUG();
 		return NULL;
+	}
 	area = get_vm_area(size);
-	if (!area)
+	if (!area) {
+		BUG();
 		return NULL;
+	}
 	addr = area->addr;
 	if (vmalloc_area_pages(VMALLOC_VMADDR(addr), size)) {
 		vfree(addr);
+		BUG();
 		return NULL;
 	}
 	return addr;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)