linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [VM PATCH] Faster reclamation of dirty pages and unused inode/dcache entries in 2.4.22
@ 2003-08-29 15:01 Shantanu Goel
  2003-08-29 14:57 ` Antonio Vargas
  2003-08-29 19:11 ` [VM PATCH] Faster reclamation of dirty pages and unused inode/dcache entries in 2.4.22 Rahul Karnik
  0 siblings, 2 replies; 21+ messages in thread
From: Shantanu Goel @ 2003-08-29 15:01 UTC (permalink / raw)
  To: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1191 bytes --]

Hi kernel hackers,

The VM subsystem in Linux 2.4.22 can cause spurious
swapouts in the presence of lots of dirty pages. 
Presently, as dirty pages are encountered,
shrink_cache() schedules a writepage() and moves the
page to the head of the inactive list.  When a lot of
dirty pages are present, this can break the FIFO
ordering of the inactive list because clean pages
further down the list will be reclaimed first.  The
following patch records the pages being laundered, and
once SWAP_CLUSTER_MAX pages have been accumulated or
the scan is complete, goes back and attempts to move
them back to the tail of the list.

The second part of the patch reclaims unused
inode/dentry/dquot entries more aggressively.  I have
observed that on an NFS server where swap out activity
is low, the VM can shrink the page cache to the point
where most pages are used up by unused inode/dentry
entries.  This is because page cache reclamation
succeeds most of the time except when a swap_out()
happens.

Feedback and comments are welcome.

Thanks,
Shantanu Goel

__________________________________
Do you Yahoo!?
Yahoo! SiteBuilder - Free, easy-to-use web site design software
http://sitebuilder.yahoo.com

[-- Attachment #2: 2.4.22-vm-writeback-inode.patch --]
[-- Type: application/octet-stream, Size: 3331 bytes --]

--- vmscan.c.~1~	2002-11-28 18:53:15.000000000 -0500
+++ vmscan.c	2003-08-28 19:09:48.000000000 -0400
@@ -23,6 +23,11 @@
 #include <linux/init.h>
 #include <linux/highmem.h>
 #include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/dcache.h>
+#ifdef CONFIG_QUOTA
+#include <linux/quota.h>
+#endif
 
 #include <asm/pgalloc.h>
 
@@ -334,12 +339,52 @@
 	return 0;
 }
 
+/*
+ * Wait for pages being laundered and move them
+ * to tail of inactive list if they are still freeable.
+ */
+static void process_laundry(struct page **laundry, int nr_pages)
+{
+	int i;
+	struct page *page;
+
+	for (i = nr_pages - 1; i >= 0; i--) {
+		page = laundry[i];
+		spin_lock(&pagemap_lru_lock);
+
+		if (!PageLRU(page) || PageActive(page))
+			goto next_page;
+
+		if (TryLockPage(page)) {
+			if (PageLaunder(page)) {
+				spin_unlock(&pagemap_lru_lock);
+				wait_on_page(page);
+				i++;
+				continue;
+			}
+			goto next_page;
+		}
+
+		if (!PageDirty(page) && !PageError(page) && page->mapping && (page_count(page) - !!page->buffers) == 2) {
+			list_del(&page->lru);
+			list_add_tail(&page->lru, &inactive_list);
+		}
+
+		UnlockPage(page);
+next_page:
+		spin_unlock(&pagemap_lru_lock);
+		page_cache_release(page);
+	}
+}
+
 static int FASTCALL(shrink_cache(int nr_pages, zone_t * classzone, unsigned int gfp_mask, int priority));
 static int shrink_cache(int nr_pages, zone_t * classzone, unsigned int gfp_mask, int priority)
 {
 	struct list_head * entry;
+	int nr_laundry = 0;
 	int max_scan = nr_inactive_pages / priority;
 	int max_mapped = min((nr_pages << (10 - priority)), max_scan / 10);
+	struct page *laundry[SWAP_CLUSTER_MAX];
 
 	spin_lock(&pagemap_lru_lock);
 	while (--max_scan >= 0 && (entry = inactive_list.prev) != &inactive_list) {
@@ -408,8 +453,14 @@
 				page_cache_get(page);
 				spin_unlock(&pagemap_lru_lock);
 
-				writepage(page);
-				page_cache_release(page);
+				if (!writepage(page)) {
+					laundry[nr_laundry++] = page;
+					if (nr_laundry == SWAP_CLUSTER_MAX) {
+						process_laundry(laundry, nr_laundry);
+						nr_laundry = 0;
+					}
+				} else
+					page_cache_release(page);
 
 				spin_lock(&pagemap_lru_lock);
 				continue;
@@ -483,7 +534,7 @@
 			 */
 			spin_unlock(&pagemap_lru_lock);
 			swap_out(priority, gfp_mask, classzone);
-			return nr_pages;
+			goto out;
 		}
 
 		/*
@@ -519,6 +570,9 @@
 		break;
 	}
 	spin_unlock(&pagemap_lru_lock);
+out:
+	if (nr_laundry)
+		process_laundry(laundry, nr_laundry);
 
 	return nr_pages;
 }
@@ -572,14 +626,22 @@
 	refill_inactive(ratio);
 
 	nr_pages = shrink_cache(nr_pages, classzone, gfp_mask, priority);
-	if (nr_pages <= 0)
-		return 0;
 
-	shrink_dcache_memory(priority, gfp_mask);
-	shrink_icache_memory(priority, gfp_mask);
+	/*
+	 * Keep an eye on unused inode/dcache/quota entries.
+	 */
+	ratio = (inodes_stat.nr_unused * sizeof(struct inode)) >> PAGE_SHIFT;
+	ratio += (dentry_stat.nr_unused * sizeof(struct dentry)) >> PAGE_SHIFT;
+#ifdef CONFIG_QUOTA
+	ratio += (dqstats.free_dquots * sizeof(struct dquot)) >> PAGE_SHIFT;
+#endif
+	if (nr_pages > 0 || ratio > SWAP_CLUSTER_MAX) {
+		shrink_dcache_memory(priority, gfp_mask);
+		shrink_icache_memory(priority, gfp_mask);
 #ifdef CONFIG_QUOTA
-	shrink_dqcache_memory(DEF_PRIORITY, gfp_mask);
+		shrink_dqcache_memory(priority, gfp_mask);
 #endif
+	}
 
 	return nr_pages;
 }

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2003-09-21 18:35 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-08-29 15:01 [VM PATCH] Faster reclamation of dirty pages and unused inode/dcache entries in 2.4.22 Shantanu Goel
2003-08-29 14:57 ` Antonio Vargas
2003-08-29 17:55   ` Shantanu Goel
2003-08-29 18:06     ` Mike Fedyk
2003-08-29 18:46       ` Shantanu Goel
2003-08-29 18:57         ` Mike Fedyk
2003-08-29 19:28           ` Andrea Arcangeli
2003-08-29 19:46             ` Shantanu Goel
2003-08-29 19:55               ` Andrea Arcangeli
2003-08-29 20:20                 ` Shantanu Goel
2003-08-30  5:01                   ` Antonio Vargas
2003-09-20 13:39                     ` A couple of 2.4.23-pre4 VM nits Shantanu Goel
2003-09-21  2:46                       ` Andrea Arcangeli
2003-09-21  5:32                         ` Shantanu Goel
2003-09-21 14:04                           ` Andrea Arcangeli
2003-09-21 14:51                             ` Shantanu Goel
2003-09-21 15:14                               ` Andrea Arcangeli
2003-09-21 15:28                                 ` Shantanu Goel
2003-09-21 15:57                                   ` Andrea Arcangeli
2003-09-21 18:37                         ` Marcelo Tosatti
2003-08-29 19:11 ` [VM PATCH] Faster reclamation of dirty pages and unused inode/dcache entries in 2.4.22 Rahul Karnik

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).