* [with-PATCH] deferred swapping + page aging (fwd)
@ 2000-05-26 20:59 Rik van Riel
2000-05-29 15:59 ` [PATCH] " Roger Larsson
0 siblings, 1 reply; 2+ messages in thread
From: Rik van Riel @ 2000-05-26 20:59 UTC (permalink / raw)
To: linux-mm
[Arghhhh, this time with patch ;)]
-------
Hi,
Here is a WORKING version of the deferred swapping & page aging
patch for 2.4.0-test1.
The patch implements:
- deferred IO for pageout
- rudimentary page aging, a start of what we want
for when we have an active list later
TODO:
- deferred swapping for other IO (file, shm)
- page aging for all pages
- inactive / laundry / cache queues
- ...
regards,
Rik
--
The Internet is not a network of computers. It is a network
of people. That is its real strength.
Wanna talk about the kernel? irc.openprojects.net / #kernelnewbies
http://www.conectiva.com/ http://www.surriel.com/
--- linux-2.4.0-test1/mm/filemap.c.orig Thu May 25 12:27:47 2000
+++ linux-2.4.0-test1/mm/filemap.c Fri May 26 15:05:34 2000
@@ -264,7 +264,16 @@
page = list_entry(page_lru, struct page, lru);
list_del(page_lru);
- if (PageTestandClearReferenced(page))
+ if (PageTestandClearReferenced(page)) {
+ page->age += 3;
+ if (page->age > 10)
+ page->age = 0;
+ goto dispose_continue;
+ }
+ if (page->age)
+ page->age--;
+
+ if (page->age)
goto dispose_continue;
count--;
@@ -317,28 +326,34 @@
goto cache_unlock_continue;
/*
+ * Page is from a zone we don't care about.
+ * Don't drop page cache entries in vain.
+ */
+ if (page->zone->free_pages > page->zone->pages_high)
+ goto cache_unlock_continue;
+
+ /*
* Is it a page swap page? If so, we want to
* drop it if it is no longer used, even if it
* were to be marked referenced..
*/
if (PageSwapCache(page)) {
- spin_unlock(&pagecache_lock);
- __delete_from_swap_cache(page);
- goto made_inode_progress;
- }
-
- /*
- * Page is from a zone we don't care about.
- * Don't drop page cache entries in vain.
- */
- if (page->zone->free_pages > page->zone->pages_high)
+ if (!PageDirty(page)) {
+ spin_unlock(&pagecache_lock);
+ __delete_from_swap_cache(page);
+ goto made_inode_progress;
+ }
+ /* PageDeferswap -> we swap out the page now. */
+ if (gfp_mask & __GFP_IO)
+ goto async_swap;
goto cache_unlock_continue;
+ }
/* is it a page-cache page? */
if (page->mapping) {
if (!PageDirty(page) && !pgcache_under_min()) {
- __remove_inode_page(page);
spin_unlock(&pagecache_lock);
+ __remove_inode_page(page);
goto made_inode_progress;
}
goto cache_unlock_continue;
@@ -351,6 +366,14 @@
unlock_continue:
spin_lock(&pagemap_lru_lock);
UnlockPage(page);
+ page_cache_release(page);
+ goto dispose_continue;
+async_swap:
+ spin_unlock(&pagecache_lock);
+ /* Do NOT unlock the page ... that is done after IO. */
+ ClearPageDirty(page);
+ rw_swap_page(WRITE, page, 0);
+ spin_lock(&pagemap_lru_lock);
page_cache_release(page);
dispose_continue:
list_add(page_lru, &lru_cache);
--- linux-2.4.0-test1/mm/page_alloc.c.orig Thu May 25 12:27:47 2000
+++ linux-2.4.0-test1/mm/page_alloc.c Fri May 26 17:23:00 2000
@@ -93,6 +93,8 @@
BUG();
if (PageDecrAfter(page))
BUG();
+ if (PageDirty(page))
+ BUG();
zone = page->zone;
--- linux-2.4.0-test1/mm/swap_state.c.orig Thu May 25 12:27:47 2000
+++ linux-2.4.0-test1/mm/swap_state.c Fri May 26 16:57:58 2000
@@ -73,6 +73,7 @@
PAGE_BUG(page);
PageClearSwapCache(page);
+ ClearPageDirty(page);
remove_inode_page(page);
}
--- linux-2.4.0-test1/mm/vmscan.c.orig Thu May 25 12:27:47 2000
+++ linux-2.4.0-test1/mm/vmscan.c Fri May 26 16:55:03 2000
@@ -62,6 +62,10 @@
goto out_failed;
}
+ /* Can only do this if we age all active pages. */
+ if (PageActive(page) && page->age > 1)
+ goto out_failed;
+
if (TryLockPage(page))
goto out_failed;
@@ -74,6 +78,8 @@
* memory, and we should just continue our scan.
*/
if (PageSwapCache(page)) {
+ if (pte_dirty(pte))
+ SetPageDirty(page);
entry.val = page->index;
swap_duplicate(entry);
set_pte(page_table, swp_entry_to_pte(entry));
@@ -181,7 +187,10 @@
vmlist_access_unlock(vma->vm_mm);
/* OK, do a physical asynchronous write to swap. */
- rw_swap_page(WRITE, page, 0);
+ // rw_swap_page(WRITE, page, 0);
+ /* Let shrink_mmap handle this swapout. */
+ SetPageDirty(page);
+ UnlockPage(page);
out_free_success:
page_cache_release(page);
--- linux-2.4.0-test1/include/linux/mm.h.orig Thu May 25 12:28:10 2000
+++ linux-2.4.0-test1/include/linux/mm.h Fri May 26 17:52:30 2000
@@ -153,6 +153,7 @@
struct buffer_head * buffers;
unsigned long virtual; /* nonzero if kmapped */
struct zone_struct *zone;
+ unsigned int age;
} mem_map_t;
#define get_page(p) atomic_inc(&(p)->count)
@@ -169,7 +170,7 @@
#define PG_dirty 4
#define PG_decr_after 5
#define PG_unused_01 6
-#define PG__unused_02 7
+#define PG_active 7
#define PG_slab 8
#define PG_swap_cache 9
#define PG_skip 10
@@ -185,6 +186,7 @@
#define ClearPageUptodate(page) clear_bit(PG_uptodate, &(page)->flags)
#define PageDirty(page) test_bit(PG_dirty, &(page)->flags)
#define SetPageDirty(page) set_bit(PG_dirty, &(page)->flags)
+#define ClearPageDirty(page) clear_bit(PG_dirty, &(page)->flags)
#define PageLocked(page) test_bit(PG_locked, &(page)->flags)
#define LockPage(page) set_bit(PG_locked, &(page)->flags)
#define TryLockPage(page) test_and_set_bit(PG_locked, &(page)->flags)
@@ -192,6 +194,9 @@
clear_bit(PG_locked, &(page)->flags); \
wake_up(&page->wait); \
} while (0)
+#define PageActive(page) test_bit(PG_active, &(page)->flags)
+#define SetPageActive(page) set_bit(PG_active, &(page)->flags)
+#define ClearPageActive(page) clear_bit(PG_active, &(page)->flags)
#define PageError(page) test_bit(PG_error, &(page)->flags)
#define SetPageError(page) set_bit(PG_error, &(page)->flags)
#define ClearPageError(page) clear_bit(PG_error, &(page)->flags)
--- linux-2.4.0-test1/include/linux/swap.h.orig Thu May 25 12:28:13 2000
+++ linux-2.4.0-test1/include/linux/swap.h Fri May 26 16:54:41 2000
@@ -168,12 +168,15 @@
spin_lock(&pagemap_lru_lock); \
list_add(&(page)->lru, &lru_cache); \
nr_lru_pages++; \
+ page->age = 4; \
+ SetPageActive(page); \
spin_unlock(&pagemap_lru_lock); \
} while (0)
#define __lru_cache_del(page) \
do { \
list_del(&(page)->lru); \
+ ClearPageActive(page); \
nr_lru_pages--; \
} while (0)
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/
^ permalink raw reply [flat|nested] 2+ messages in thread
* [PATCH] Re: [with-PATCH] deferred swapping + page aging (fwd)
2000-05-26 20:59 [with-PATCH] deferred swapping + page aging (fwd) Rik van Riel
@ 2000-05-29 15:59 ` Roger Larsson
0 siblings, 0 replies; 2+ messages in thread
From: Roger Larsson @ 2000-05-29 15:59 UTC (permalink / raw)
To: Rik van Riel; +Cc: linux-mm
[-- Attachment #1: Type: text/plain, Size: 9215 bytes --]
Hi,
This patch improves Riels patch by using fewer list modifications.
It could be applied to most shrink_mmaps but Riels version will
gain the most.
Function:
- Do not delete + insert all pages while scanning.
- Scan until a suitable page is found, then move the head.
/RogerL
Rik van Riel wrote:
>
> [Arghhhh, this time with patch ;)]
> -------
> Hi,
>
> Here is a WORKING version of the deferred swapping & page aging
> patch for 2.4.0-test1.
>
> The patch implements:
> - deferred IO for pageout
> - rudimentary page aging, a start of what we want
> for when we have an active list later
>
> TODO:
> - deferred swapping for other IO (file, shm)
> - page aging for all pages
> - inactive / laundry / cache queues
> - ...
>
> regards,
>
> Rik
> --
> The Internet is not a network of computers. It is a network
> of people. That is its real strength.
>
> Wanna talk about the kernel? irc.openprojects.net / #kernelnewbies
> http://www.conectiva.com/ http://www.surriel.com/
>
> --- linux-2.4.0-test1/mm/filemap.c.orig Thu May 25 12:27:47 2000
> +++ linux-2.4.0-test1/mm/filemap.c Fri May 26 15:05:34 2000
> @@ -264,7 +264,16 @@
> page = list_entry(page_lru, struct page, lru);
> list_del(page_lru);
>
> - if (PageTestandClearReferenced(page))
> + if (PageTestandClearReferenced(page)) {
> + page->age += 3;
> + if (page->age > 10)
> + page->age = 0;
> + goto dispose_continue;
> + }
> + if (page->age)
> + page->age--;
> +
> + if (page->age)
> goto dispose_continue;
>
> count--;
> @@ -317,28 +326,34 @@
> goto cache_unlock_continue;
>
> /*
> + * Page is from a zone we don't care about.
> + * Don't drop page cache entries in vain.
> + */
> + if (page->zone->free_pages > page->zone->pages_high)
> + goto cache_unlock_continue;
> +
> + /*
> * Is it a page swap page? If so, we want to
> * drop it if it is no longer used, even if it
> * were to be marked referenced..
> */
> if (PageSwapCache(page)) {
> - spin_unlock(&pagecache_lock);
> - __delete_from_swap_cache(page);
> - goto made_inode_progress;
> - }
> -
> - /*
> - * Page is from a zone we don't care about.
> - * Don't drop page cache entries in vain.
> - */
> - if (page->zone->free_pages > page->zone->pages_high)
> + if (!PageDirty(page)) {
> + spin_unlock(&pagecache_lock);
> + __delete_from_swap_cache(page);
> + goto made_inode_progress;
> + }
> + /* PageDeferswap -> we swap out the page now. */
> + if (gfp_mask & __GFP_IO)
> + goto async_swap;
> goto cache_unlock_continue;
> + }
>
> /* is it a page-cache page? */
> if (page->mapping) {
> if (!PageDirty(page) && !pgcache_under_min()) {
> - __remove_inode_page(page);
> spin_unlock(&pagecache_lock);
> + __remove_inode_page(page);
> goto made_inode_progress;
> }
> goto cache_unlock_continue;
> @@ -351,6 +366,14 @@
> unlock_continue:
> spin_lock(&pagemap_lru_lock);
> UnlockPage(page);
> + page_cache_release(page);
> + goto dispose_continue;
> +async_swap:
> + spin_unlock(&pagecache_lock);
> + /* Do NOT unlock the page ... that is done after IO. */
> + ClearPageDirty(page);
> + rw_swap_page(WRITE, page, 0);
> + spin_lock(&pagemap_lru_lock);
> page_cache_release(page);
> dispose_continue:
> list_add(page_lru, &lru_cache);
> --- linux-2.4.0-test1/mm/page_alloc.c.orig Thu May 25 12:27:47 2000
> +++ linux-2.4.0-test1/mm/page_alloc.c Fri May 26 17:23:00 2000
> @@ -93,6 +93,8 @@
> BUG();
> if (PageDecrAfter(page))
> BUG();
> + if (PageDirty(page))
> + BUG();
>
> zone = page->zone;
>
> --- linux-2.4.0-test1/mm/swap_state.c.orig Thu May 25 12:27:47 2000
> +++ linux-2.4.0-test1/mm/swap_state.c Fri May 26 16:57:58 2000
> @@ -73,6 +73,7 @@
> PAGE_BUG(page);
>
> PageClearSwapCache(page);
> + ClearPageDirty(page);
> remove_inode_page(page);
> }
>
> --- linux-2.4.0-test1/mm/vmscan.c.orig Thu May 25 12:27:47 2000
> +++ linux-2.4.0-test1/mm/vmscan.c Fri May 26 16:55:03 2000
> @@ -62,6 +62,10 @@
> goto out_failed;
> }
>
> + /* Can only do this if we age all active pages. */
> + if (PageActive(page) && page->age > 1)
> + goto out_failed;
> +
> if (TryLockPage(page))
> goto out_failed;
>
> @@ -74,6 +78,8 @@
> * memory, and we should just continue our scan.
> */
> if (PageSwapCache(page)) {
> + if (pte_dirty(pte))
> + SetPageDirty(page);
> entry.val = page->index;
> swap_duplicate(entry);
> set_pte(page_table, swp_entry_to_pte(entry));
> @@ -181,7 +187,10 @@
> vmlist_access_unlock(vma->vm_mm);
>
> /* OK, do a physical asynchronous write to swap. */
> - rw_swap_page(WRITE, page, 0);
> + // rw_swap_page(WRITE, page, 0);
> + /* Let shrink_mmap handle this swapout. */
> + SetPageDirty(page);
> + UnlockPage(page);
>
> out_free_success:
> page_cache_release(page);
> --- linux-2.4.0-test1/include/linux/mm.h.orig Thu May 25 12:28:10 2000
> +++ linux-2.4.0-test1/include/linux/mm.h Fri May 26 17:52:30 2000
> @@ -153,6 +153,7 @@
> struct buffer_head * buffers;
> unsigned long virtual; /* nonzero if kmapped */
> struct zone_struct *zone;
> + unsigned int age;
> } mem_map_t;
>
> #define get_page(p) atomic_inc(&(p)->count)
> @@ -169,7 +170,7 @@
> #define PG_dirty 4
> #define PG_decr_after 5
> #define PG_unused_01 6
> -#define PG__unused_02 7
> +#define PG_active 7
> #define PG_slab 8
> #define PG_swap_cache 9
> #define PG_skip 10
> @@ -185,6 +186,7 @@
> #define ClearPageUptodate(page) clear_bit(PG_uptodate, &(page)->flags)
> #define PageDirty(page) test_bit(PG_dirty, &(page)->flags)
> #define SetPageDirty(page) set_bit(PG_dirty, &(page)->flags)
> +#define ClearPageDirty(page) clear_bit(PG_dirty, &(page)->flags)
> #define PageLocked(page) test_bit(PG_locked, &(page)->flags)
> #define LockPage(page) set_bit(PG_locked, &(page)->flags)
> #define TryLockPage(page) test_and_set_bit(PG_locked, &(page)->flags)
> @@ -192,6 +194,9 @@
> clear_bit(PG_locked, &(page)->flags); \
> wake_up(&page->wait); \
> } while (0)
> +#define PageActive(page) test_bit(PG_active, &(page)->flags)
> +#define SetPageActive(page) set_bit(PG_active, &(page)->flags)
> +#define ClearPageActive(page) clear_bit(PG_active, &(page)->flags)
> #define PageError(page) test_bit(PG_error, &(page)->flags)
> #define SetPageError(page) set_bit(PG_error, &(page)->flags)
> #define ClearPageError(page) clear_bit(PG_error, &(page)->flags)
> --- linux-2.4.0-test1/include/linux/swap.h.orig Thu May 25 12:28:13 2000
> +++ linux-2.4.0-test1/include/linux/swap.h Fri May 26 16:54:41 2000
> @@ -168,12 +168,15 @@
> spin_lock(&pagemap_lru_lock); \
> list_add(&(page)->lru, &lru_cache); \
> nr_lru_pages++; \
> + page->age = 4; \
> + SetPageActive(page); \
> spin_unlock(&pagemap_lru_lock); \
> } while (0)
>
> #define __lru_cache_del(page) \
> do { \
> list_del(&(page)->lru); \
> + ClearPageActive(page); \
> nr_lru_pages--; \
> } while (0)
>
>
> --
> To unsubscribe, send a message with 'unsubscribe linux-mm' in
> the body to majordomo@kvack.org. For more info on Linux MM,
> see: http://www.linux.eu.org/Linux-MM/
--
Home page:
http://www.norran.net/nra02596/
[-- Attachment #2: patch-2.4.0-test1-deferred_swap-speedup.1 --]
[-- Type: text/plain, Size: 1600 bytes --]
261c261
< /* we need pagemap_lru_lock for list_del() ... subtle code below */
---
> /* we need pagemap_lru_lock for lru_cache head movement... subtle code below */
263c263,268
< while (count > 0 && (page_lru = lru_cache.prev) != &lru_cache) {
---
> page_lru = &lru_cache;
> while (count > 0) {
> page_lru = page_lru->prev;
> if (page_lru == &lru_cache)
> break; /* one whole run */
>
265d269
< list_del(page_lru);
270,271c274,275
< page->age = 0;
< goto dispose_continue;
---
> page->age = 10;
> continue;
277c281
< goto dispose_continue;
---
> continue;
285c289
< goto dispose_continue;
---
> continue;
288c292,302
< goto dispose_continue;
---
> continue;
>
> /* move header before unlock...
> * NOTE: the page to scan might move on while having
> * pagemap_lru unlocked. Avoid rescanning same pages
> * by moving head and set page_lru to NULL to avoid
> * misuses!
> */
> list_del(&lru_cache);
> list_add_tail(&lru_cache, page_lru);
> page_lru = NULL;
324a339,341
> if (page_count(page) < 2)
> BUG();
>
348c365
< goto async_swap;
---
> goto async_swap_continue;
371c388
< async_swap:
---
> async_swap_continue:
375a393
> /* no lock held here? SMP? is page_cache_get enough? */
379c397
< list_add(page_lru, &lru_cache);
---
> page_lru = &lru_cache;
386,388d403
< UnlockPage(page);
< page_cache_release(page);
< ret = 1;
389a405
> list_del(&page->lru); /* page_lru is NULL... */
391a408,410
> UnlockPage(page);
> page_cache_release(page);
> ret = 1;
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2000-05-29 15:59 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-05-26 20:59 [with-PATCH] deferred swapping + page aging (fwd) Rik van Riel
2000-05-29 15:59 ` [PATCH] " Roger Larsson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox