patch-2.4.0-test11 linux/mm/memory.c

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

diff -u --recursive --new-file v2.4.0-test10/linux/mm/memory.c linux/mm/memory.c
@@ -1201,29 +1201,32 @@
 {
 	pte_t entry;
 
+	/*
+	 * We need the page table lock to synchronize with kswapd
+	 * and the SMP-safe atomic PTE updates.
+	 */
+	spin_lock(&mm->page_table_lock);
 	entry = *pte;
 	if (!pte_present(entry)) {
+		/*
+		 * If it truly wasn't present, we know that kswapd
+		 * and the PTE updates will not touch it later. So
+		 * drop the lock.
+		 */
+		spin_unlock(&mm->page_table_lock);
 		if (pte_none(entry))
 			return do_no_page(mm, vma, address, write_access, pte);
 		return do_swap_page(mm, vma, address, pte, pte_to_swp_entry(entry), write_access);
 	}
 
-	/*
-	 * Ok, the entry was present, we need to get the page table
-	 * lock to synchronize with kswapd, and verify that the entry
-	 * didn't change from under us..
-	 */
-	spin_lock(&mm->page_table_lock);
-	if (pte_same(entry, *pte)) {
-		if (write_access) {
-			if (!pte_write(entry))
-				return do_wp_page(mm, vma, address, pte, entry);
+	if (write_access) {
+		if (!pte_write(entry))
+			return do_wp_page(mm, vma, address, pte, entry);
 
-			entry = pte_mkdirty(entry);
-		}
-		entry = pte_mkyoung(entry);
-		establish_pte(vma, address, pte, entry);
+		entry = pte_mkdirty(entry);
 	}
+	entry = pte_mkyoung(entry);
+	establish_pte(vma, address, pte, entry);
 	spin_unlock(&mm->page_table_lock);
 	return 1;
 }

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