patch-2.1.89 linux/mm/memory.c

Next file: linux/mm/mlock.c
Previous file: linux/mm/filemap.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.88/linux/mm/memory.c linux/mm/memory.c
@@ -267,8 +267,10 @@
 				}
 				if (cow)
 					pte = pte_wrprotect(pte);
+#if 0	/* No longer needed with the new swap cache code */
 				if (delete_from_swap_cache(&mem_map[page_nr]))
 					pte = pte_mkdirty(pte);
+#endif
 				set_pte(dst_pte, pte_mkold(pte));
 				set_pte(src_pte, pte);
 				atomic_inc(&mem_map[page_nr].count);
@@ -616,8 +618,11 @@
 	unsigned long old_page, new_page;
 	struct page * page_map;
 	
-	new_page = __get_free_page(GFP_KERNEL);
 	pte = *page_table;
+	new_page = __get_free_page(GFP_KERNEL);
+	/* Did someone else copy this page for us while we slept? */
+	if (pte_val(*page_table) != pte_val(pte))
+		goto end_wp_page;
 	if (!pte_present(pte))
 		goto end_wp_page;
 	if (pte_write(pte))
@@ -626,15 +631,12 @@
 	if (MAP_NR(old_page) >= max_mapnr)
 		goto bad_wp_page;
 	tsk->min_flt++;
-
 	page_map = mem_map + MAP_NR(old_page);
-	if (PageSwapCache(page_map))
-		delete_from_swap_cache(page_map);
 	
 	/*
 	 * Do we need to copy?
 	 */
-	if (atomic_read(&mem_map[MAP_NR(old_page)].count) != 1) {
+	if (is_page_shared(page_map)) {
 		if (new_page) {
 			if (PageReserved(mem_map + MAP_NR(old_page)))
 				++vma->vm_mm->rss;
@@ -654,6 +656,8 @@
 		oom(tsk);
 		return;
 	}
+	if (PageSwapCache(page_map))
+		delete_from_swap_cache(page_map);
 	flush_cache_page(vma, address);
 	set_pte(page_table, pte_mkdirty(pte_mkwrite(pte)));
 	flush_tlb_page(vma, address);

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov