Re: mm/swapfile.c problem

Andrea Arcangeli (andrea@suse.de)
Tue, 14 Sep 1999 13:40:55 +0200 (CEST)


On Mon, 13 Sep 1999, Pete Zaitcev wrote:

>--- mm/swapfile.c 1999/08/31 06:50:36 1.59
>+++ mm/swapfile.c 1999/09/14 05:48:49
>@@ -771,8 +771,11 @@
> if (!(swap_flags & SWAP_FLAG_PREFER))
> ++least_priority;
> out:
>- if (swap_header)
>+ if (swap_header) {
>+ mem_map_t *page = mem_map + MAP_NR(swap_header);
>+ UnlockPage(page);
> free_page((long) swap_header);
>+ }
> unlock_kernel();
> return error;
> }

Actually I think the patch is not the right one. Can you verify if the
below patch against 2.3.18ac2 (or 2.3.18) fixes the problem equally well?

diff -urN 2.3.18ac2/mm/page_io.c p/mm/page_io.c
--- 2.3.18ac2/mm/page_io.c Mon Sep 13 03:38:48 1999
+++ p/mm/page_io.c Tue Sep 14 13:37:25 1999
@@ -33,7 +33,7 @@
* that shared pages stay shared while being swapped.
*/

-static void rw_swap_page_base(int rw, unsigned long entry, struct page *page, int wait)
+static int rw_swap_page_base(int rw, unsigned long entry, struct page *page, int wait)
{
unsigned long type, offset;
struct swap_info_struct * p;
@@ -52,7 +52,7 @@
type = SWP_TYPE(entry);
if (type >= nr_swapfiles) {
printk("Internal error: bad swap-device\n");
- return;
+ return 0;
}

/* Don't allow too many pending pages in flight.. */
@@ -63,23 +63,18 @@
offset = SWP_OFFSET(entry);
if (offset >= p->max) {
printk("rw_swap_page: weirdness\n");
- return;
+ return 0;
}
if (p->swap_map && !p->swap_map[offset]) {
printk(KERN_ERR "rw_swap_page: "
"Trying to %s unallocated swap (%08lx)\n",
(rw == READ) ? "read" : "write", entry);
- return;
+ return 0;
}
if (!(p->flags & SWP_USED)) {
printk(KERN_ERR "rw_swap_page: "
"Trying to swap to unused swap-device\n");
- return;
- }
-
- if (!PageLocked(page)) {
- printk(KERN_ERR "VM: swap page is unlocked\n");
- return;
+ return 0;
}

if (rw == READ) {
@@ -104,13 +99,13 @@
for (i=0, j=0; j< PAGE_SIZE ; i++, j += block_size)
if (!(zones[i] = bmap(swapf,block++))) {
printk("rw_swap_page: bad swap file\n");
- return;
+ return 0;
}
zones_used = i;
dev = swapf->i_dev;
} else {
printk(KERN_ERR "rw_swap_page: no swap file or device\n");
- return;
+ return 0;
}
if (!wait) {
set_bit(PG_decr_after, &page->flags);
@@ -124,9 +119,9 @@
* decrementing the page count, and unlocking the page in the
* swap lock map - in the IO completion handler.
*/
- if (!wait) {
- return;
- }
+ if (!wait)
+ return 1;
+
wait_on_page(page);
/* This shouldn't happen, but check to be sure. */
if (page_count(page) == 0)
@@ -138,6 +133,7 @@
(char *) page_address(page),
page_count(page));
#endif
+ return 1;
}

/*
@@ -157,7 +153,8 @@
PAGE_BUG(page);
if (page->inode != &swapper_inode)
PAGE_BUG(page);
- rw_swap_page_base(rw, entry, page, wait);
+ if (!rw_swap_page_base(rw, entry, page, wait))
+ UnlockPage(page);
}

/*
@@ -173,5 +170,6 @@
PAGE_BUG(page);
if (PageSwapCache(page))
PAGE_BUG(page);
- rw_swap_page_base(rw, entry, page, wait);
+ if (!rw_swap_page_base(rw, entry, page, wait))
+ UnlockPage(page);
}

Thanks.

Andrea

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/