From: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
To: minchan Kim <barrioskmc@gmail.com>
Cc: kosaki.motohiro@jp.fujitsu.com,
KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>,
Balbir Singh <balbir@linux.vnet.ibm.com>,
Rik van Riel <riel@redhat.com>,
Lee Schermerhorn <Lee.Schermerhorn@hp.com>,
linux-mm@kvack.org, linux-kernel@vger.kernel.org
Subject: Re: [RFC][PATCH] the proposal of improve page reclaim by throttle
Date: Wed, 20 Feb 2008 19:09:15 +0900 [thread overview]
Message-ID: <20080220185648.6447.KOSAKI.MOTOHIRO@jp.fujitsu.com> (raw)
In-Reply-To: <44c63dc40802200149r6b03d970g2fbde74b85ad5443@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 959 bytes --]
Hi
> > > * max parallel reclaim tasks:
> > > * max consumption time of
> > > try_to_free_pages():
> >
> > sorry, I inserted debug code to my patch at that time.
>
> Could you send me that debug code ?
> If you will send it to me, I will test it my environment (ARM-920T, Core2Duo).
> And I will report test result.
attached it.
but it is very messy ;-)
usage:
./benchloop.sh
sample output
=========================================================
max reclaim 2
Running with 120*40 (== 4800) tasks.
Time: 34.177
14.17user 284.38system 1:43.85elapsed 287%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (3813major+148922minor)pagefaults 0swaps
max prepare time: 4599 0
max reclaim time: 2350 5781
total
8271
max reclaimer
4
max overkill
62131
max saved overkill
9740
max reclaimer represent to max parallel reclaim tasks.
total represetnto max consumption time of try_to_free_pages().
Thanks
[-- Attachment #2: reclaim-throttle-3.patch --]
[-- Type: application/octet-stream, Size: 7106 bytes --]
---
include/linux/mmzone.h | 1
include/linux/nodemask.h | 2
kernel/sysctl.c | 78 ++++++++++++++++++++++++++++++++++++++
mm/vmscan.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++-
4 files changed, 173 insertions(+), 3 deletions(-)
Index: b/kernel/sysctl.c
===================================================================
--- a/kernel/sysctl.c 2008-02-15 20:14:40.000000000 +0900
+++ b/kernel/sysctl.c 2008-02-16 16:45:58.000000000 +0900
@@ -187,6 +187,18 @@ int sysctl_legacy_va_layout;
extern int prove_locking;
extern int lock_stat;
+extern int max_reclaimer;
+extern unsigned long max_reclaim_time;
+extern unsigned long max_reclaim_prepare_time;
+extern int reclaim_limit;
+extern unsigned long max_overkill_reclaim;
+
+extern unsigned long max_reclaim_time_aux;
+extern unsigned long max_reclaim_prepare_time_aux;
+extern unsigned long max_total_time;
+
+
+
/* The default sysctl tables: */
static struct ctl_table root_table[] = {
@@ -1155,6 +1167,72 @@ static struct ctl_table vm_table[] = {
.extra2 = &one,
},
#endif
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "max_reclaimer",
+ .data = &max_reclaimer,
+ .maxlen = sizeof(max_reclaimer),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec,
+ .strategy = &sysctl_intvec,
+ },
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "max_reclaim_time",
+ .data = &max_reclaim_time,
+ .maxlen = sizeof(max_reclaim_time),
+ .mode = 0644,
+ .proc_handler = &proc_doulongvec_minmax,
+ },
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "max_reclaim_prepare_time",
+ .data = &max_reclaim_prepare_time,
+ .maxlen = sizeof(max_reclaim_prepare_time),
+ .mode = 0644,
+ .proc_handler = &proc_doulongvec_minmax,
+ },
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "reclaim_limit",
+ .data = &reclaim_limit,
+ .maxlen = sizeof(reclaim_limit),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec,
+ },
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "max_overkill_reclaim",
+ .data = &max_overkill_reclaim,
+ .maxlen = sizeof(max_overkill_reclaim),
+ .mode = 0644,
+ .proc_handler = &proc_doulongvec_minmax,
+ },
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "max_reclaim_time_aux",
+ .data = &max_reclaim_time_aux,
+ .maxlen = sizeof(max_reclaim_time_aux),
+ .mode = 0644,
+ .proc_handler = &proc_doulongvec_minmax,
+ },
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "max_reclaim_prepare_time_aux",
+ .data = &max_reclaim_prepare_time_aux,
+ .maxlen = sizeof(max_reclaim_prepare_time_aux),
+ .mode = 0644,
+ .proc_handler = &proc_doulongvec_minmax,
+ },
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "max_total_time",
+ .data = &max_total_time,
+ .maxlen = sizeof(max_total_time),
+ .mode = 0644,
+ .proc_handler = &proc_doulongvec_minmax,
+ },
+
/*
* NOTE: do not add new entries to this table unless you have read
* Documentation/sysctl/ctl_unnumbered.txt
Index: b/mm/vmscan.c
===================================================================
--- a/mm/vmscan.c 2008-02-15 20:14:40.000000000 +0900
+++ b/mm/vmscan.c 2008-02-17 11:50:50.000000000 +0900
@@ -1421,6 +1421,23 @@ out:
return ret;
}
+static DEFINE_SPINLOCK(research_reclaim_max_lock);
+static atomic_t nr_reclaimers = ATOMIC_INIT(0);
+static DECLARE_WAIT_QUEUE_HEAD(reclaim_throttle_waitq);
+
+// limit
+int reclaim_limit = 2;
+#define RECLAIM_LIMIT (reclaim_limit * num_highmem_nodes())
+
+// record
+int max_reclaimer = 0;
+unsigned long max_reclaim_time = 0;
+unsigned long max_reclaim_time_aux = 0;
+unsigned long max_reclaim_prepare_time = 0;
+unsigned long max_reclaim_prepare_time_aux = 0;
+unsigned long max_overkill_reclaim = 0;
+unsigned long max_total_time = 0;
+
unsigned long try_to_free_pages(struct zone **zones, int order, gfp_t gfp_mask)
{
struct scan_control sc = {
@@ -1433,8 +1450,82 @@ unsigned long try_to_free_pages(struct z
.mem_cgroup = NULL,
.isolate_pages = isolate_pages_global,
};
-
- return do_try_to_free_pages(zones, gfp_mask, &sc);
+ unsigned long nr_reclaimed;
+ u64 start_time;
+ u64 prepared_time;
+ u64 end_time;
+ u64 preparing_time;
+ u64 reclaiming_time;
+ unsigned long free_mem;
+ int record_max_prepare_time = 0;
+ unsigned long total_time;
+
+ start_time = jiffies_64;
+
+ if (unlikely(!atomic_add_unless(&nr_reclaimers, 1, RECLAIM_LIMIT)))
+ wait_event(reclaim_throttle_waitq,
+ atomic_add_unless(&nr_reclaimers, 1, RECLAIM_LIMIT));
+
+ spin_lock(&research_reclaim_max_lock);
+ if (atomic_read(&nr_reclaimers) > max_reclaimer)
+ max_reclaimer = atomic_read(&nr_reclaimers);
+
+ prepared_time = jiffies_64;
+ preparing_time = prepared_time - start_time;
+ if (preparing_time > max_reclaim_time) {
+ record_max_prepare_time = 1;
+ max_reclaim_prepare_time = preparing_time;
+ }
+ spin_unlock(&research_reclaim_max_lock);
+
+ /* more reclaim until needed? */
+ if (preparing_time > HZ) {
+ int i;
+
+ for (i = 0; zones[i] != NULL; i++) {
+ struct zone *zone = zones[i];
+ int classzone_idx = zone_idx(zones[0]);
+
+ if (!populated_zone(zone))
+ continue;
+
+ if (zone_watermark_ok(zone, order, 4*zone->pages_high,
+ classzone_idx, 0)) {
+ nr_reclaimed = 1;
+ goto out;
+ }
+ }
+ }
+
+ nr_reclaimed = do_try_to_free_pages(zones, gfp_mask, &sc);
+
+ spin_lock(&research_reclaim_max_lock);
+ end_time = jiffies_64;
+ reclaiming_time = end_time - prepared_time;
+
+ if (record_max_prepare_time)
+ max_reclaim_prepare_time_aux = reclaiming_time;
+
+ if (reclaiming_time > max_reclaim_time) {
+ max_reclaim_time_aux = preparing_time;
+ max_reclaim_time = reclaiming_time;
+ }
+
+ total_time = preparing_time + reclaiming_time;
+ if( total_time > max_total_time ){
+ max_total_time = total_time;
+ }
+
+ free_mem = global_page_state(NR_FREE_PAGES);
+ if (free_mem > max_overkill_reclaim)
+ max_overkill_reclaim = free_mem;
+ spin_unlock(&research_reclaim_max_lock);
+
+out:
+ atomic_dec(&nr_reclaimers);
+ wake_up_all(&reclaim_throttle_waitq);
+
+ return nr_reclaimed;
}
#ifdef CONFIG_CGROUP_MEM_CONT
Index: b/include/linux/mmzone.h
===================================================================
--- a/include/linux/mmzone.h 2008-02-15 20:14:40.000000000 +0900
+++ b/include/linux/mmzone.h 2008-02-15 20:14:49.000000000 +0900
@@ -334,7 +334,6 @@ struct zone {
*/
unsigned long spanned_pages; /* total size, including holes */
unsigned long present_pages; /* amount of memory (excluding holes) */
-
/*
* rarely used fields:
*/
Index: b/include/linux/nodemask.h
===================================================================
--- a/include/linux/nodemask.h 2008-02-15 20:14:40.000000000 +0900
+++ b/include/linux/nodemask.h 2008-02-15 20:14:49.000000000 +0900
@@ -431,6 +431,8 @@ static inline int num_node_state(enum no
#define num_online_nodes() num_node_state(N_ONLINE)
#define num_possible_nodes() num_node_state(N_POSSIBLE)
+#define num_highmem_nodes() num_node_state(N_HIGH_MEMORY)
+
#define node_online(node) node_state((node), N_ONLINE)
#define node_possible(node) node_state((node), N_POSSIBLE)
[-- Attachment #3: benchloop.sh --]
[-- Type: application/octet-stream, Size: 1515 bytes --]
#!/bin/sh
for i in 2 10000; do
for j in 1 2 3; do
sudo sh -c "echo $i > /proc/sys/vm/reclaim_limit"
sudo sh -c "echo 0 > /proc/sys/vm/max_reclaim_prepare_time"
sudo sh -c "echo 0 > /proc/sys/vm/max_reclaim_time"
sudo sh -c "echo 0 > /proc/sys/vm/max_reclaim_prepare_time_aux"
sudo sh -c "echo 0 > /proc/sys/vm/max_reclaim_time_aux"
sudo sh -c "echo 0 > /proc/sys/vm/max_total_time"
sudo sh -c "echo 0 > /proc/sys/vm/max_reclaimer"
sudo sh -c "echo 0 > /proc/sys/vm/max_overkill_reclaim"
sudo sh -c "echo 0 > /proc/sys/vm/max_saved_overkill_reclaim"
sudo sh -c "echo 3 > /proc/sys/vm/drop_caches"
echo "max reclaim $i"
/usr/bin/time ./hackbench 120 process 1000 2>&1 | uniq
prepare_time=`cat /proc/sys/vm/max_reclaim_prepare_time`
prepare_time_aux=`cat /proc/sys/vm/max_reclaim_prepare_time_aux`
echo "max prepare time: $prepare_time $prepare_time_aux"
reclaim_time_aux=`cat /proc/sys/vm/max_reclaim_time_aux`
reclaim_time=`cat /proc/sys/vm/max_reclaim_time`
echo "max reclaim time: $reclaim_time_aux $reclaim_time"
echo "total"
cat /proc/sys/vm/max_total_time
echo "max reclaimer"
cat /proc/sys/vm/max_reclaimer
echo "max overkill"
cat /proc/sys/vm/max_overkill_reclaim
echo "max saved overkill"
cat /proc/sys/vm/max_saved_overkill_reclaim
sudo sh -c "echo 1000 > /proc/sys/vm/reclaim_limit"
done
done
next prev parent reply other threads:[~2008-02-20 10:09 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-02-19 5:44 KOSAKI Motohiro
2008-02-19 6:34 ` Nick Piggin
2008-02-19 7:09 ` KOSAKI Motohiro
2008-02-19 13:31 ` Rik van Riel
2008-02-20 8:56 ` minchan Kim
2008-02-20 9:24 ` KOSAKI Motohiro
2008-02-20 9:49 ` minchan Kim
2008-02-20 10:09 ` KOSAKI Motohiro [this message]
2008-02-21 9:38 ` minchan Kim
2008-02-21 10:55 ` KOSAKI Motohiro
2008-02-21 12:29 ` minchan Kim
2008-02-21 12:41 ` KOSAKI Motohiro
2008-02-21 9:48 ` Balbir Singh
2008-02-21 11:01 ` KOSAKI Motohiro
2008-02-21 11:02 ` Balbir Singh
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=20080220185648.6447.KOSAKI.MOTOHIRO@jp.fujitsu.com \
--to=kosaki.motohiro@jp.fujitsu.com \
--cc=Lee.Schermerhorn@hp.com \
--cc=balbir@linux.vnet.ibm.com \
--cc=barrioskmc@gmail.com \
--cc=kamezawa.hiroyu@jp.fujitsu.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=riel@redhat.com \
/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