[patch] free_after logic removed

Andrea Arcangeli (andrea@suse.de)
Fri, 20 Aug 1999 19:04:43 +0200 (CEST)


On Fri, 20 Aug 1999, Andrea Arcangeli wrote:

>This patch removes the swap_free_after logic. Now everything uses

This incremental patch (incremental with the one that removes the
swap_free_after logic) removes also the free_after logic. The free_after
logic is not needed anymore (it wasn't needed also in 2.2.x) since in the
swapin code we hold an additional reference in the swap cache (exactly as
we always do in the page-cache code), and in the swapout path now we take
a reference in the swap cache during the swapout and the page won't be
removed from the swap cache while it's locked. Once the page will be
unlocked we'll be allowed to free from shrink_mmap infact.

The free_after logic was necessary when we was used to swapout a page by
first removing it from the swapcache, then starting I/O and then removing
the last real reference to the page. So the additional reference that we
was accounted in the free_after bit was the only reference to the page
that was avoiding us to really free the page after starting the I/O.

Here it is the patch:

diff -urN 2.3.15-pre1-no-swap-free/fs/buffer.c 2.3.15-pre1-no-free-after/fs/buffer.c
--- 2.3.15-pre1-no-swap-free/fs/buffer.c Fri Aug 20 18:39:10 1999
+++ 2.3.15-pre1-no-free-after/fs/buffer.c Fri Aug 20 18:46:53 1999
@@ -702,7 +702,6 @@
unsigned long flags;
struct buffer_head *tmp;
struct page *page;
- int free;

mark_buffer_uptodate(bh, uptodate);

@@ -722,7 +721,7 @@
* deemed complete once all buffers have been visited
* (b_count==0) and are now unlocked. We must make sure that
* only the _last_ buffer that decrements its count is the one
- * that free's the page..
+ * that unlock the page..
*/
spin_lock_irqsave(&page_uptodate_lock, flags);
unlock_buffer(bh);
@@ -747,22 +746,14 @@

/*
* Run the hooks that have to be done when a page I/O has completed.
- *
- * Note - we need to test the flags before we unlock the page, but
- * we must not actually free the page until after the unlock!
*/
if (test_and_clear_bit(PG_decr_after, &page->flags))
atomic_dec(&nr_async_pages);

- free = test_and_clear_bit(PG_free_after, &page->flags);
-
if (page->owner != (void *)-1)
PAGE_BUG(page);
page->owner = current;
UnlockPage(page);
-
- if (free)
- __free_page(page);

return;

diff -urN 2.3.15-pre1-no-swap-free/include/linux/mm.h 2.3.15-pre1-no-free-after/include/linux/mm.h
--- 2.3.15-pre1-no-swap-free/include/linux/mm.h Fri Aug 20 18:32:19 1999
+++ 2.3.15-pre1-no-free-after/include/linux/mm.h Fri Aug 20 18:45:18 1999
@@ -145,7 +145,6 @@
#define PG_error 1
#define PG_referenced 2
#define PG_uptodate 3
-#define PG_free_after 4
#define PG_decr_after 5
#define PG_DMA 7
#define PG_Slab 8
@@ -179,7 +178,6 @@
#define SetPageError(page) ({ int _ret = test_and_set_bit(PG_error, &(page)->flags); _ret; })
#define ClearPageError(page) do { if (!test_and_clear_bit(PG_error, &(page)->flags)) BUG(); } while (0)
#define PageReferenced(page) (test_bit(PG_referenced, &(page)->flags))
-#define PageFreeAfter(page) (test_bit(PG_free_after, &(page)->flags))
#define PageDecrAfter(page) (test_bit(PG_decr_after, &(page)->flags))
#define PageDMA(page) (test_bit(PG_DMA, &(page)->flags))
#define PageSlab(page) (test_bit(PG_Slab, &(page)->flags))
@@ -257,8 +255,6 @@
* PG_uptodate tells whether the page's contents is valid.
* When a read completes, the page becomes uptodate, unless a disk I/O
* error happened.
- * When a write completes, and PG_free_after is set, the page is
- * freed without any further delay.
*
* For choosing which pages to swap out, inode pages carry a
* PG_referenced bit, which is set any time the system accesses
diff -urN 2.3.15-pre1-no-swap-free/include/linux/swap.h 2.3.15-pre1-no-free-after/include/linux/swap.h
--- 2.3.15-pre1-no-swap-free/include/linux/swap.h Fri Aug 20 18:31:23 1999
+++ 2.3.15-pre1-no-free-after/include/linux/swap.h Fri Aug 20 18:45:25 1999
@@ -157,8 +157,6 @@
count = page_count(page);
if (PageSwapCache(page))
count += swap_count(page->offset) - 2;
- if (PageFreeAfter(page))
- count--;
return count > 1;
}

diff -urN 2.3.15-pre1-no-swap-free/mm/page_io.c 2.3.15-pre1-no-free-after/mm/page_io.c
--- 2.3.15-pre1-no-swap-free/mm/page_io.c Fri Aug 20 18:29:15 1999
+++ 2.3.15-pre1-no-free-after/mm/page_io.c Fri Aug 20 18:47:39 1999
@@ -88,7 +88,6 @@
} else
kstat.pswpout++;

- get_page(page);
if (p->swap_device) {
zones[0] = offset;
zones_used = 1;
@@ -111,14 +110,12 @@
dev = swapf->i_dev;
} else {
printk(KERN_ERR "rw_swap_page: no swap file or device\n");
- put_page(page);
return;
}
if (!wait) {
set_bit(PG_decr_after, &page->flags);
atomic_inc(&nr_async_pages);
}
- set_bit(PG_free_after, &page->flags);

/* block_size == PAGE_SIZE/zones_used */
brw_page(rw, page, dev, zones, block_size, 0);

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/