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/
next 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