* [PATCH] test5-1 vmfix-3.0
@ 2000-07-19 21:40 Roger Larsson
2000-07-20 6:48 ` Mike Galbraith
2000-07-21 20:47 ` Roger Larsson
0 siblings, 2 replies; 3+ messages in thread
From: Roger Larsson @ 2000-07-19 21:40 UTC (permalink / raw)
To: Mike Galbraith, Zdenek Kabelac, linux-kernel, linux-mm
[-- Attachment #1: Type: text/plain, Size: 1228 bytes --]
Hi,
Another attempt.
With this patch I get noticeable improvements in streaming write +16%!
(streaming write throughput is close to streaming read :-)
dbench results are mixed - slightly worse than plain test5-1...
It now survives mmap002, as opposed to vmfix-2.x :-) there were
bugs of cause.
* Basic idea in this patch is to keep free pages of zones in the
range [pages_high ... pages_low]. Kswapd will only run until
one zone gets pages_high. In this situation pages from all zones
are free able.
* In addition kswapd will run if any zone has less than pages_low.
* Actually implemented by using three values in zone_wake_kswapd
0 = zone initially above pages_high, allocs allowed until zone
gets < pages_low
1 = zone < pages_low
-1 = additional alloc done after zone become < pages_low
Most of the time there will only be one zone to with
zone_wake_kswapd zero. This zone will get the allocs until it
also gets < pages_low, then kswapd starts and runs until any
zone gets > pages_high - it will probably be another zone. Now
that one gets the allocs, ...
* There are some additional stuff that needs cleaning / further
investigations.
/RogerL
--
Home page:
http://www.norran.net/nra02596/
[-- Attachment #2: patch-2.4.0-test5-1-vmfix.30 --]
[-- Type: text/plain, Size: 7961 bytes --]
--- linux/mm/vmscan.c.orig Sat Jul 15 23:44:34 2000
+++ linux/mm/vmscan.c Wed Jul 19 20:27:20 2000
@@ -419,7 +419,7 @@ out:
}
/*
- * Check if there is any memory pressure (free_pages < pages_low)
+ * Check if there is any memory pressure (zone_wake_kswapd < 0)
*/
static inline int memory_pressure(void)
{
@@ -430,7 +430,7 @@ static inline int memory_pressure(void)
for(i = 0; i < MAX_NR_ZONES; i++) {
zone_t *zone = pgdat->node_zones+ i;
if (zone->size &&
- zone->free_pages < zone->pages_low)
+ zone->zone_wake_kswapd < 0)
return 1;
}
pgdat = pgdat->node_next;
@@ -440,24 +440,31 @@ static inline int memory_pressure(void)
}
/*
- * Check if there recently has been memory pressure (zone_wake_kswapd)
+ * Check if any zone have recently been critical (low_on_memory)
+ * any zone with current memory pressure (zone_wake_kswapd < 0)
+ * all zones have recently had memory_pressure (zone_wake_kswapd)
*/
static inline int keep_kswapd_awake(void)
{
+ int all_recent = 1;
pg_data_t *pgdat = pgdat_list;
do {
int i;
for(i = 0; i < MAX_NR_ZONES; i++) {
zone_t *zone = pgdat->node_zones+ i;
- if (zone->size &&
- zone->zone_wake_kswapd)
- return 1;
+ if (zone->size) {
+ if (zone->zone_wake_kswapd < 0 ||
+ zone->low_on_memory)
+ return 1;
+ if (!zone->zone_wake_kswapd)
+ all_recent = 0;
+ }
}
pgdat = pgdat->node_next;
} while (pgdat);
- return 0;
+ return all_recent;
}
/*
@@ -484,7 +491,7 @@ static int do_try_to_free_pages(unsigned
priority = 64;
do {
- if (current->need_resched) {
+ if ((gfp_mask & __GFP_IO) && current->need_resched) {
schedule();
/* time has passed - pressure too? */
if (!memory_pressure())
@@ -496,9 +503,6 @@ static int do_try_to_free_pages(unsigned
goto done;
}
- /* not (been) low on memory - it is
- * pointless to try to swap out.
- */
if (!keep_kswapd_awake())
goto done;
@@ -516,12 +520,10 @@ static int do_try_to_free_pages(unsigned
* In the inner funtions there is a comment:
* "To help debugging, a zero exit status indicates
* all slabs were released." (-arca?)
- * lets handle it in a primitive but working way...
+ * remove it... to visualize the problem.
* if (count <= 0)
* goto done;
*/
- if (!keep_kswapd_awake())
- goto done;
while (shm_swap(priority, gfp_mask)) {
if (!--count)
@@ -596,10 +598,7 @@ int kswapd(void *unused)
for (;;) {
if (!keep_kswapd_awake()) {
- /* wake up regulary to do an early attempt too free
- * pages - pages will not actually be freed.
- */
- interruptible_sleep_on_timeout(&kswapd_wait, HZ);
+ interruptible_sleep_on(&kswapd_wait);
}
do_try_to_free_pages(GFP_KSWAPD);
@@ -628,24 +627,30 @@ int try_to_free_pages(unsigned int gfp_m
if (gfp_mask & __GFP_WAIT) {
current->state = TASK_RUNNING;
current->flags |= PF_MEMALLOC;
- retval = do_try_to_free_pages(gfp_mask);
+ do {
+ retval = do_try_to_free_pages(gfp_mask);
+ } while (!retval);
current->flags &= ~PF_MEMALLOC;
}
- else {
- /* make sure kswapd runs */
- if (waitqueue_active(&kswapd_wait))
- wake_up_interruptible(&kswapd_wait);
- }
+
+ /* someone needed memory that kswapd had not provided
+ * make sure kswapd runs, should not happen often */
+ if (waitqueue_active(&kswapd_wait))
+ wake_up_interruptible(&kswapd_wait);
return retval;
}
static int __init kswapd_init(void)
{
- printk("Starting kswapd v1.6\n");
+ printk("Starting kswapd v1.7\n");
swap_setup();
kernel_thread(kswapd, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
return 0;
}
module_init(kswapd_init)
+
+
+
+
--- linux/mm/page_alloc.c.orig Sat Jul 15 23:44:46 2000
+++ linux/mm/page_alloc.c Wed Jul 19 19:48:57 2000
@@ -30,7 +30,7 @@ pg_data_t *pgdat_list;
static char *zone_names[MAX_NR_ZONES] = { "DMA", "Normal", "HighMem" };
static int zone_balance_ratio[MAX_NR_ZONES] = { 128, 128, 128, };
-static int zone_balance_min[MAX_NR_ZONES] = { 10 , 10, 10, };
+static int zone_balance_min[MAX_NR_ZONES] = { 10 , 10, 10, };
static int zone_balance_max[MAX_NR_ZONES] = { 255 , 255, 255, };
/*
@@ -141,8 +141,13 @@ void __free_pages_ok (struct page *page,
spin_unlock_irqrestore(&zone->lock, flags);
+
if (zone->free_pages > zone->pages_high) {
- zone->zone_wake_kswapd = 0;
+ zone->zone_wake_kswapd = 0;
+ }
+ else if (zone->zone_wake_kswapd < 0 &&
+ zone->free_pages > zone->pages_low) {
+ zone->zone_wake_kswapd = 1;
zone->low_on_memory = 0;
}
}
@@ -217,7 +222,7 @@ static struct page * rmqueue(zone_t *zon
*/
struct page * __alloc_pages(zonelist_t *zonelist, unsigned long order)
{
- zone_t **zone = zonelist->zones;
+ zone_t **zone;
extern wait_queue_head_t kswapd_wait;
/*
@@ -228,21 +233,6 @@ struct page * __alloc_pages(zonelist_t *
* in a higher zone fails.
*/
- for (;;) {
- zone_t *z = *(zone++);
- if (!z)
- break;
- if (!z->size)
- BUG();
-
- /* If there are zones with a lot of free memory allocate from them */
- if (z->free_pages > z->pages_high) {
- struct page *page = rmqueue(z, order);
- if (page)
- return page;
- }
- }
-
zone = zonelist->zones;
for (;;) {
zone_t *z = *(zone++);
@@ -256,6 +246,16 @@ struct page * __alloc_pages(zonelist_t *
struct page *page = rmqueue(z, order);
if (z->free_pages < z->pages_low) {
z->zone_wake_kswapd = 1;
+
+ /* Usually zone_wake_kswapd is set to -1
+ * on second alloc below pages_low
+ * but if this was a big one
+ * - do not let it pass unnoticed
+ */
+ if (z->free_pages < z->pages_low - MAX_ORDER) {
+ z->zone_wake_kswapd = -1;
+ }
+
if (waitqueue_active(&kswapd_wait))
wake_up_interruptible(&kswapd_wait);
}
@@ -264,6 +264,21 @@ struct page * __alloc_pages(zonelist_t *
}
}
+ /* Three possibilities to get here
+ * - Previous alloc_pages resulted in last zone set to have
+ * zone_wake_kswapd and start it. kswapd has not been able
+ * to release enough pages so that one zone does not have
+ * zone_wake_kswapd set.
+ * - Different sets of zones (zonelist)
+ * previous did not have all zones with zone_wake_kswapd but
+ * this one has... should kswapd be woken up? it will run once.
+ * - SMP race, kswapd went to sleep slightly after it as running
+ * in 'if (waitqueue_active(...))' above.
+ * + anyway the test is very cheap to do...
+ */
+ if (waitqueue_active(&kswapd_wait))
+ wake_up_interruptible(&kswapd_wait);
+
/*
* Ok, we don't have any zones that don't need some
* balancing.. See if we have any that aren't critical..
@@ -275,8 +290,17 @@ struct page * __alloc_pages(zonelist_t *
break;
if (!z->low_on_memory) {
struct page *page = rmqueue(z, order);
- if (z->free_pages < z->pages_min)
- z->low_on_memory = 1;
+ if (z->free_pages < z->pages_low) {
+ z->zone_wake_kswapd = -1;
+
+ if (z->free_pages < z->pages_min)
+ z->low_on_memory = 1;
+
+ /* make kswapd notice new condition */
+ if (waitqueue_active(&kswapd_wait))
+ wake_up_interruptible(&kswapd_wait);
+ }
+
if (page)
return page;
}
@@ -385,7 +409,10 @@ void show_free_areas_core(int nid)
zone_t *zone = NODE_DATA(nid)->node_zones + type;
unsigned long nr, total, flags;
- printk(" %s: ", zone->name);
+ printk(" %s %ld (%ld %ld %ld) %d %d: ",
+ zone->name, zone->free_pages,
+ zone->pages_min, zone->pages_low, zone->pages_high,
+ zone->zone_wake_kswapd, zone->low_on_memory);
total = 0;
if (zone->size) {
@@ -573,8 +600,8 @@ void __init free_area_init_core(int nid,
else if (mask > zone_balance_max[j])
mask = zone_balance_max[j];
zone->pages_min = mask;
- zone->pages_low = mask*2;
- zone->pages_high = mask*3;
+ zone->pages_low = mask*3;
+ zone->pages_high = mask*4;
zone->low_on_memory = 0;
zone->zone_wake_kswapd = 0;
zone->zone_mem_map = mem_map + offset;
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] test5-1 vmfix-3.0
2000-07-19 21:40 [PATCH] test5-1 vmfix-3.0 Roger Larsson
@ 2000-07-20 6:48 ` Mike Galbraith
2000-07-21 20:47 ` Roger Larsson
1 sibling, 0 replies; 3+ messages in thread
From: Mike Galbraith @ 2000-07-20 6:48 UTC (permalink / raw)
To: Roger Larsson; +Cc: Zdenek Kabelac, linux-kernel, linux-mm
On Wed, 19 Jul 2000, Roger Larsson wrote:
> Hi,
>
> Another attempt.
Not much difference for make -j test.
For reference, I reran ac22clas [record holder] on the same tree.
test4+test5-1vmscan_oneliner+vmfix-3.0
real 10m16.038s (~mobile, one run went 12.5)
user 6m26.130s (solid)
sys 0m33.070s (solid)
ac22-clas:
real 7m35.950s (solid)
user 6m27.630s (solid)
sys 0m29.570s (solid)
-Mike
--
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.eu.org/Linux-MM/
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] test5-1 vmfix-3.0
2000-07-19 21:40 [PATCH] test5-1 vmfix-3.0 Roger Larsson
2000-07-20 6:48 ` Mike Galbraith
@ 2000-07-21 20:47 ` Roger Larsson
1 sibling, 0 replies; 3+ messages in thread
From: Roger Larsson @ 2000-07-21 20:47 UTC (permalink / raw)
To: linux-kernel, linux-mm
Hi again,
Reread what I had written.
One documentation error.
Roger Larsson wrote:
>
> Hi,
>
> Another attempt.
>
> With this patch I get noticeable improvements in streaming write +16%!
> (streaming write throughput is close to streaming read :-)
>
> dbench results are mixed - slightly worse than plain test5-1...
> It now survives mmap002, as opposed to vmfix-2.x :-) there were
> bugs of cause.
>
> * Basic idea in this patch is to keep free pages of zones in the
> range [pages_high ... pages_low].
This part:
> Kswapd will only run until
> one zone gets pages_high. In this situation pages from all zones
> are free able.
Should read:
Kswapd will start when all zones have zone_wake_kswapd
(free_pages < pages_low). In this situation pages from all zones are
freeable. Kswapd will run until one zone drops zone_wake_kswapd
(free_pages > pages_high).
> * In addition kswapd will run if any zone has less than pages_low.
>
> * Actually implemented by using three values in zone_wake_kswapd
> 0 = zone initially above pages_high, allocs allowed until zone
> gets < pages_low
> 1 = zone < pages_low
> -1 = additional alloc done after zone become < pages_low
> Most of the time there will only be one zone to with
> zone_wake_kswapd zero. This zone will get the allocs until it
> also gets < pages_low, then kswapd starts and runs until any
> zone gets > pages_high - it will probably be another zone. Now
> that one gets the allocs, ...
>
> * There are some additional stuff that needs cleaning / further
> investigations.
>
> /RogerL
>
> --
> Home page:
> http://www.norran.net/nra02596/
>
> ------------------------------------------------------------------------
> Name: patch-2.4.0-test5-1-vmfix.30
> patch-2.4.0-test5-1-vmfix.30 Type: Plain Text (text/plain)
> Encoding: 7bit
--
Home page:
http://www.norran.net/nra02596/
--
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.eu.org/Linux-MM/
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2000-07-21 20:47 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-07-19 21:40 [PATCH] test5-1 vmfix-3.0 Roger Larsson
2000-07-20 6:48 ` Mike Galbraith
2000-07-21 20:47 ` Roger Larsson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox