repost: patch for 2.1.104 vmscan.c

Bill Hawes (whawes@transmeta.com)
Sat, 06 Jun 1998 11:37:21 -0700


This is a multi-part message in MIME format.
--------------038696B84554FCD0C7AC3D14
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Hi Linus,

The attached patch adds some diagnostic code to help track down the
"writable swap cache page" problem, and downgrades a panic to a warning
message when a swap cache page count goes from 2 to 1. The latter is a
normal (though unlikely) occurrence with the current swap code, and as
users are reporting getting caught by the panics, this really needs to
be fixed.

The patch aslo makes a minor improvement to try_to_unuse_page() by
passing the page pointer, since it's already known by the caller.

Regards,
Bill

--------------038696B84554FCD0C7AC3D14
Content-Type: text/plain; charset=us-ascii; name="swap_vm104-patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="swap_vm104-patch"

--- linux-2.1.104/include/linux/mm.h.old Wed Apr 8 22:17:13 1998
+++ linux-2.1.104/include/linux/mm.h Fri Jun 5 19:12:14 1998
@@ -309,5 +311,5 @@

/* filemap.c */
-extern unsigned long page_unuse(unsigned long);
+extern unsigned long page_unuse(struct page *);
extern int shrink_mmap(int, int);
extern void truncate_inode_pages(struct inode *, unsigned long);
--- linux-2.1.104/mm/vmscan.c.old Thu Jun 4 18:08:11 1998
+++ linux-2.1.104/mm/vmscan.c Fri Jun 5 19:06:37 1998
@@ -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;
}

--- linux-2.1.104/mm/filemap.c.old Fri Apr 3 19:27:11 1998
+++ linux-2.1.104/mm/filemap.c Fri Jun 5 19:06:37 1998
@@ -216,20 +216,19 @@
* free it from the page hash-queues etc, as we don't want to keep it
* in-core unnecessarily.
*/
-unsigned long page_unuse(unsigned long page)
+unsigned long page_unuse(struct page * page)
{
- struct page * p = mem_map + MAP_NR(page);
- int count = atomic_read(&p->count);
+ int count = atomic_read(&page->count);

if (count != 2)
return count;
- if (!p->inode)
+ if (!page->inode)
return count;
- if (PageSwapCache(p))
+ if (PageSwapCache(page))
panic ("Doing a normal page_unuse of a swap cache page");
- remove_page_from_hash_queue(p);
- remove_page_from_inode_queue(p);
- free_page(page);
+ remove_page_from_hash_queue(page);
+ remove_page_from_inode_queue(page);
+ __free_page(page);
return 1;
}

--- linux-2.1.104/mm/page_alloc.c.old Thu Jun 4 18:08:31 1998
+++ linux-2.1.104/mm/page_alloc.c Fri Jun 5 19:06:37 1998
@@ -182,9 +182,11 @@
if (PageSwapCache(page))
panic ("Freeing swap cache page");
free_pages_ok(page->map_nr, 0);
+ return;
}
if (PageSwapCache(page) && atomic_read(&page->count) == 1)
- panic ("Releasing swap cache page");
+ printk(KERN_WARNING "VM: Releasing swap cache page at %p",
+ __builtin_return_address(0));
}

void free_pages(unsigned long addr, unsigned long order)
@@ -202,8 +204,9 @@
return;
}
if (PageSwapCache(map) && atomic_read(&map->count) == 1)
- panic ("Releasing swap cache pages at %p",
- __builtin_return_address(0));
+ printk(KERN_WARNING
+ "VM: Releasing swap cache pages at %p",
+ __builtin_return_address(0));
}
}

--------------038696B84554FCD0C7AC3D14--

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu