linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Shantanu Goel <sgoel01@yahoo.com>
To: linux-kernel@vger.kernel.org
Subject: [VM PATCH] Faster reclamation of dirty pages and unused inode/dcache entries in 2.4.22
Date: Fri, 29 Aug 2003 08:01:11 -0700 (PDT)	[thread overview]
Message-ID: <20030829150111.72151.qmail@web12802.mail.yahoo.com> (raw)

[-- 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;
 }

             reply	other threads:[~2003-08-29 15:04 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-08-29 15:01 Shantanu Goel [this message]
2003-08-29 14:57 ` [VM PATCH] Faster reclamation of dirty pages and unused inode/dcache entries in 2.4.22 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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20030829150111.72151.qmail@web12802.mail.yahoo.com \
    --to=sgoel01@yahoo.com \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).