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 ` [RFC][PATCH] dcache and rmap 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
-- strict thread matches above, loose matches on Subject: below --
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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.