linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Ed Tomlinson <tomlins@cam.org>
To: linux-mm@kvack.org
Subject: [RFC][PATCH] dcache and rmap
Date: Sun, 5 May 2002 21:17:16 -0400	[thread overview]
Message-ID: <200205052117.16268.tomlins@cam.org> (raw)

Hi, 

I got tired of finding my box with 50-60% percent of memory tied up in dentry/inode 
caches every morning after update-db runs or after doing a find / -name "*" to generate
a list of files for backups.  So I decided to make a stab at fixing this.

The problem is that when there is not much memory pressure the vm is happy to let the
above caches expand and expand...  What I did was factored the shrink calls out of 
do_try_to_free_pages and placed an additional call to shrink in kswapd which can get
called if kswapd does not need to use do_try_to_free_pages.

The issue then becomes when to call the new shrink_caches function?  I changed the
dcache logic to estimate and track the number of new pages alloced to dentries.  Once a
threshold is exceeded, kswapd calls shrink_caches.   Using a threshold of 32 pages works
well here.

Patch is against 19-pre7-ac2. 

Comments?
Ed Tomlinson

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	1.422   -> 1.425  
#	         fs/dcache.c	1.18    -> 1.21   
#	         mm/vmscan.c	1.60    -> 1.61   
#	include/linux/dcache.h	1.11    -> 1.12   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/05/04	ed@oscar.et.ca	1.423
# Modify the cache shrinking logic to apply pressure when the dcache
# grows by more than <n> pages (currently 32).  Note the slab growth
# detection code, though not perfect, is okay for this use.
# --------------------------------------------
# 02/05/04	ed@oscar.et.ca	1.424
# Fix comments
# --------------------------------------------
# 02/05/04	ed@oscar.et.ca	1.425
# grammar
# --------------------------------------------
#
diff -Nru a/fs/dcache.c b/fs/dcache.c
--- a/fs/dcache.c	Sat May  4 23:17:36 2002
+++ b/fs/dcache.c	Sat May  4 23:17:36 2002
@@ -305,6 +305,22 @@
 	spin_lock(&dcache_lock);
 }
 
+
+/**
+ * Have we allocated over n pages worth of
+ * dentries entries? 
+ */
+
+#define DENTRIES_PER_PAGE (PAGE_SIZE/(sizeof(struct dentry)+8))
+
+static int dcache_alloc_count = 0;
+
+int try_to_shrink(int pages)
+{ 
+	return dcache_alloc_count > pages; 
+}
+
+
 /**
  * prune_dcache - shrink the dcache
  * @count: number of entries to try and free
@@ -567,7 +583,13 @@
 
 	count = dentry_stat.nr_unused / priority;
 
-	prune_dcache(count);
+	prune_dcache(count); 
+
+	/*
+	 * relieve some pressure...
+	 */
+	dcache_alloc_count /= 2;
+
 	return kmem_cache_shrink_nr(dentry_cache);
 }
 
@@ -585,8 +607,17 @@
  
 struct dentry * d_alloc(struct dentry * parent, const struct qstr *name)
 {
+	static int nr_entry_base = 0;
 	char * str;
 	struct dentry *dentry;
+ 
+	if (dentry_stat.nr_dentry < nr_entry_base) 
+		nr_entry_base = dentry_stat.nr_dentry;
+		  
+	if (dentry_stat.nr_dentry-nr_entry_base > DENTRIES_PER_PAGE) {
+	        dcache_alloc_count++;
+		nr_entry_base = dentry_stat.nr_dentry;
+	}
 
 	dentry = kmem_cache_alloc(dentry_cache, GFP_KERNEL); 
 	if (!dentry)
diff -Nru a/include/linux/dcache.h b/include/linux/dcache.h
--- a/include/linux/dcache.h	Sat May  4 23:17:36 2002
+++ b/include/linux/dcache.h	Sat May  4 23:17:36 2002
@@ -173,6 +173,7 @@
 /* dcache memory management */
 extern int shrink_dcache_memory(int, unsigned int);
 extern void prune_dcache(int);
+extern int try_to_shink(int);
 
 /* icache memory management (defined in linux/fs/inode.c) */
 extern int shrink_icache_memory(int, int);
diff -Nru a/mm/vmscan.c b/mm/vmscan.c
--- a/mm/vmscan.c	Sat May  4 23:17:36 2002
+++ b/mm/vmscan.c	Sat May  4 23:17:36 2002
@@ -562,6 +562,24 @@
 		if (inactive_high(zone) > 0)
 			refill_inactive_zone(zone, priority);
 }
+	
+static int shrink_caches(unsigned int pri, unsigned int gfp_mask)
+{
+	int ret = 0;
+
+        /*
+         * Eat memory from 
+         * dentry, inode and filesystem quota caches.
+         */
+        ret += shrink_dcache_memory(pri, gfp_mask);
+        ret += shrink_icache_memory(1, gfp_mask);
+#ifdef CONFIG_QUOTA
+        ret += shrink_dqcache_memory(pri, gfp_mask);
+#endif
+
+	return ret;
+}
+
 
 /*
  * Worker function for kswapd and try_to_free_pages, we get
@@ -571,6 +589,7 @@
  * This function will also move pages to the inactive list,
  * if needed.
  */
+
 static int do_try_to_free_pages(unsigned int gfp_mask)
 {
 	int ret = 0;
@@ -580,11 +599,7 @@
 	 * dentry, inode and filesystem quota caches.
 	 */
 	ret += page_launder(gfp_mask);
-	ret += shrink_dcache_memory(DEF_PRIORITY, gfp_mask);
-	ret += shrink_icache_memory(1, gfp_mask);
-#ifdef CONFIG_QUOTA
-	ret += shrink_dqcache_memory(DEF_PRIORITY, gfp_mask);
-#endif
+	ret += shrink_caches(DEF_PRIORITY, gfp_mask);
 
 	/*
 	 * Move pages from the active list to the inactive list.
@@ -653,6 +668,9 @@
  * If there are applications that are active memory-allocators
  * (most normal use), this basically shouldn't matter.
  */
+
+#define DCACHE_PAGES (32) 
+
 int kswapd(void *unused)
 {
 	struct task_struct *tsk = current;
@@ -691,6 +709,9 @@
 		 */
 		if (free_high(ALL_ZONES) >= 0 || free_low(ANY_ZONE) > 0)
 			do_try_to_free_pages(GFP_KSWAPD);
+		else 
+			if (try_to_shrink(DCACHE_PAGES))
+				shrink_caches(DEF_PRIORITY, GFP_KSWAPD);
 
 		refill_freelist();

 -----------------------------


 
--
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-mm.org/

             reply	other threads:[~2002-05-06  1:17 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-05-06  1:17 Ed Tomlinson [this message]
2002-05-06  2:55 ` Martin J. Bligh
2002-05-06  7:54   ` Ed Tomlinson
2002-05-06 14:40     ` Martin J. Bligh
2002-05-06 15:12       ` Ed Tomlinson
2002-05-07  1:44 ` William Lee Irwin III
2002-05-07 11:41   ` Ed Tomlinson
2002-05-07 12:57     ` William Lee Irwin III
2002-05-07 14:10       ` Christoph Hellwig
2002-05-07 14:48         ` William Lee Irwin III
2002-05-13 11:07       ` Nikita Danilov
2002-05-13 11:50         ` Ed Tomlinson
2002-05-13 21:23           ` Andrew Morton
2002-05-07  1:01 Lever, Charles
2002-05-07  2:05 ` Martin J. Bligh

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=200205052117.16268.tomlins@cam.org \
    --to=tomlins@cam.org \
    --cc=linux-mm@kvack.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