patch-2.1.107 linux/mm/vmscan.c

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

diff -u --recursive --new-file v2.1.106/linux/mm/vmscan.c linux/mm/vmscan.c
@@ -88,7 +88,7 @@
 	 * pages, then delete the swap cache.  We can only do this if
 	 * the swap page's reference count is one: ie. there are no
 	 * other references to it beyond the swap cache (as there must
-	 * still be pte's pointing to it if count > 1).
+	 * still be PTEs pointing to it if count > 1).
 	 * 
 	 * If the page has NOT been touched, and its age reaches zero,
 	 * then we are swapping it out:
@@ -107,7 +107,17 @@
 
 	if (PageSwapCache(page_map)) {
 		if (pte_write(pte)) {
+			struct page *found;
 			printk ("VM: Found a writable swap-cached page!\n");
+			/* Try to diagnose the problem ... */
+			found = find_page(&swapper_inode, page_map->offset);
+			if (found) {
+				printk("page=%p@%08lx, found=%p, count=%d\n",
+					page_map, page_map->offset,
+					found, atomic_read(&found->count));
+				__free_page(found);
+			} else 
+				printk ("Spurious, page not in cache\n");
 			return 0;
 		}
 	}
@@ -144,9 +154,8 @@
 			 * we have the swap cache set up to associate the
 			 * page with that swap entry.
 			 */
-			if (PageSwapCache(page_map)) {
-				entry = page_map->offset;
-			} else {
+        		entry = in_swap_cache(page_map);
+			if (!entry) {
 				entry = get_swap_page();
 				if (!entry)
 					return 0; /* No swap space left */
@@ -219,8 +228,8 @@
 	flush_cache_page(vma, address);
 	pte_clear(page_table);
 	flush_tlb_page(vma, address);
-	entry = page_unuse(page);
-	free_page(page);
+	entry = page_unuse(page_map);
+	__free_page(page_map);
 	return entry;
 }
 
@@ -584,6 +593,7 @@
 	}
 	/* As if we could ever get here - maybe we want to make this killable */
 	remove_wait_queue(&kswapd_wait, &wait);
+	unlock_kernel();
 	return 0;
 }
 

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