linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Nick Piggin <nickpiggin@yahoo.com.au>
To: Andrew Morton <akpm@osdl.org>, Linus Torvalds <torvalds@osdl.org>
Cc: Linux Memory Management <linux-mm@kvack.org>,
	linux-kernel <linux-kernel@vger.kernel.org>
Subject: [RFC][PATCH 3/3] teach kswapd about watermarks
Date: Sun, 05 Sep 2004 15:47:37 +1000	[thread overview]
Message-ID: <413AA879.9020105@yahoo.com.au> (raw)
In-Reply-To: <413AA841.1040003@yahoo.com.au>

[-- Attachment #1: Type: text/plain, Size: 4 bytes --]

3/3

[-- Attachment #2: vm-kswapd-heed-order-watermarks.patch --]
[-- Type: text/x-patch, Size: 4932 bytes --]



Teach kswapd to free memory on behalf of higher order allocators. This could
be important for higher order atomic allocations because they otherwise have
no means to free the memory themselves.

Signed-off-by: Nick Piggin <nickpiggin@yahoo.com.au>


---

 linux-2.6-npiggin/include/linux/mmzone.h |    5 ++--
 linux-2.6-npiggin/mm/page_alloc.c        |    3 +-
 linux-2.6-npiggin/mm/vmscan.c            |   33 ++++++++++++++++++++++---------
 3 files changed, 29 insertions(+), 12 deletions(-)

diff -puN mm/vmscan.c~vm-kswapd-heed-order-watermarks mm/vmscan.c
--- linux-2.6/mm/vmscan.c~vm-kswapd-heed-order-watermarks	2004-09-05 15:12:04.000000000 +1000
+++ linux-2.6-npiggin/mm/vmscan.c	2004-09-05 15:12:04.000000000 +1000
@@ -985,7 +985,7 @@ out:
  * the page allocator fallback scheme to ensure that aging of pages is balanced
  * across the zones.
  */
-static int balance_pgdat(pg_data_t *pgdat, int nr_pages)
+static int balance_pgdat(pg_data_t *pgdat, int nr_pages, int order)
 {
 	int to_free = nr_pages;
 	int priority;
@@ -1023,7 +1023,8 @@ static int balance_pgdat(pg_data_t *pgda
 						priority != DEF_PRIORITY)
 					continue;
 
-				if (zone->free_pages <= zone->pages_high) {
+				if (!zone_watermark_ok(zone, order,
+						zone->pages_high, 0, 0, 0)) {
 					end_zone = i;
 					goto scan;
 				}
@@ -1055,7 +1056,8 @@ scan:
 				continue;
 
 			if (nr_pages == 0) {	/* Not software suspend */
-				if (zone->free_pages <= zone->pages_high)
+				if (!zone_watermark_ok(zone, order,
+						zone->pages_high, end_zone, 0, 0))
 					all_zones_ok = 0;
 			}
 			zone->temp_priority = priority;
@@ -1146,13 +1148,22 @@ int kswapd(void *p)
 	tsk->flags |= PF_MEMALLOC|PF_KSWAPD;
 
 	for ( ; ; ) {
+		unsigned long order = 0, new_order;
 		if (current->flags & PF_FREEZE)
 			refrigerator(PF_FREEZE);
+
 		prepare_to_wait(&pgdat->kswapd_wait, &wait, TASK_INTERRUPTIBLE);
-		schedule();
+		new_order = atomic_read(&pgdat->kswapd_max_order);
+		atomic_set(&pgdat->kswapd_max_order, 0);
+		if (order < new_order) {
+			order = new_order;
+		} else {
+			schedule();
+			order = atomic_read(&pgdat->kswapd_max_order);
+		}
 		finish_wait(&pgdat->kswapd_wait, &wait);
 
-		balance_pgdat(pgdat, 0);
+		balance_pgdat(pgdat, 0, order);
 	}
 	return 0;
 }
@@ -1160,12 +1171,16 @@ int kswapd(void *p)
 /*
  * A zone is low on free memory, so wake its kswapd task to service it.
  */
-void wakeup_kswapd(struct zone *zone)
+void wakeup_kswapd(struct zone *zone, int order)
 {
-	if (zone->free_pages > zone->pages_low)
-		return;
+	pg_data_t *pgdat = zone->zone_pgdat;
+
 	if (!cpuset_zone_allowed(zone))
 		return;
+
+	if (atomic_read(&pgdat->kswapd_max_order) < order)
+		return;
+	atomic_set(&pgdat->kswapd_max_order, order);
 	if (!waitqueue_active(&zone->zone_pgdat->kswapd_wait))
 		return;
 	wake_up_interruptible(&zone->zone_pgdat->kswapd_wait);
@@ -1188,7 +1203,7 @@ int shrink_all_memory(int nr_pages)
 	current->reclaim_state = &reclaim_state;
 	for_each_pgdat(pgdat) {
 		int freed;
-		freed = balance_pgdat(pgdat, nr_to_free);
+		freed = balance_pgdat(pgdat, nr_to_free, 0);
 		ret += freed;
 		nr_to_free -= freed;
 		if (nr_to_free <= 0)
diff -puN mm/page_alloc.c~vm-kswapd-heed-order-watermarks mm/page_alloc.c
--- linux-2.6/mm/page_alloc.c~vm-kswapd-heed-order-watermarks	2004-09-05 15:12:04.000000000 +1000
+++ linux-2.6-npiggin/mm/page_alloc.c	2004-09-05 15:12:04.000000000 +1000
@@ -775,7 +775,7 @@ __alloc_pages(unsigned int gfp_mask, uns
 	}
 
 	for (i = 0; (z = zones[i]) != NULL; i++)
-		wakeup_kswapd(z);
+		wakeup_kswapd(z, order);
 
 	/*
 	 * Go through the zonelist again. Let __GFP_HIGH and allocations
@@ -1613,6 +1613,7 @@ static void __init free_area_init_core(s
 
 	pgdat->nr_zones = 0;
 	init_waitqueue_head(&pgdat->kswapd_wait);
+	atomic_set(&pgdat->kswapd_max_order, 0);
 	
 	for (j = 0; j < MAX_NR_ZONES; j++) {
 		struct zone *zone = pgdat->node_zones + j;
diff -puN include/linux/mmzone.h~vm-kswapd-heed-order-watermarks include/linux/mmzone.h
--- linux-2.6/include/linux/mmzone.h~vm-kswapd-heed-order-watermarks	2004-09-05 15:12:04.000000000 +1000
+++ linux-2.6-npiggin/include/linux/mmzone.h	2004-09-05 15:12:04.000000000 +1000
@@ -263,8 +263,9 @@ typedef struct pglist_data {
 					     range, including holes */
 	int node_id;
 	struct pglist_data *pgdat_next;
-	wait_queue_head_t       kswapd_wait;
+	wait_queue_head_t kswapd_wait;
 	struct task_struct *kswapd;
+	atomic_t kswapd_max_order;
 } pg_data_t;
 
 #define node_present_pages(nid)	(NODE_DATA(nid)->node_present_pages)
@@ -278,7 +279,7 @@ void __get_zone_counts(unsigned long *ac
 void get_zone_counts(unsigned long *active, unsigned long *inactive,
 			unsigned long *free);
 void build_all_zonelists(void);
-void wakeup_kswapd(struct zone *zone);
+void wakeup_kswapd(struct zone *zone, int order);
 int zone_watermark_ok(struct zone *z, int order, unsigned long mark,
 		int alloc_type, int can_try_harder, int gfp_high);
 

_

  reply	other threads:[~2004-09-05  5:47 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-09-05  5:44 [RFC][PATCH 0/3] beat kswapd with the proverbial clue-bat Nick Piggin
2004-09-05  5:45 ` [RFC][PATCH 1/3] account free buddy areas Nick Piggin
2004-09-05  5:46   ` [RFC][PATCH 2/3] alloc-order watermarks Nick Piggin
2004-09-05  5:47     ` Nick Piggin [this message]
2004-09-05  6:04       ` [RFC][PATCH 3/3] teach kswapd about watermarks David S. Miller
2004-09-05  6:20         ` Nick Piggin
2004-09-05  5:50     ` [RFC][PATCH 2/3] alloc-order watermarks Nick Piggin
2004-09-05  6:13   ` [RFC][PATCH 1/3] account free buddy areas Nick Piggin
2004-09-05  6:02 ` [RFC][PATCH 0/3] beat kswapd with the proverbial clue-bat David S. Miller
2004-09-05  6:16   ` Nick Piggin
2004-09-05 10:13     ` Nick Piggin
2004-09-05 17:24       ` Linus Torvalds
2004-09-05 17:36         ` Martin J. Bligh
2004-09-05 17:37         ` Arjan van de Ven
2004-09-05 17:58           ` Linus Torvalds
2004-09-05 18:41             ` Arjan van de Ven
2004-09-06  1:35             ` Nick Piggin
2004-09-15 13:27             ` Jörn Engel
2004-09-15 13:29               ` Arjan van de Ven
2004-09-15 13:34                 ` Jörn Engel
2004-09-15 13:39                   ` Arjan van de Ven
2004-09-15 14:18                     ` Jörn Engel
2004-09-06  1:09         ` Nick Piggin
2004-09-05  6:09 ` Andrew Morton
2004-09-05  6:26   ` Nick Piggin
2004-09-05  6:27   ` Anton Blanchard
2004-09-05 10:09     ` Nick Piggin
2004-09-06  3:33       ` David S. Miller
2004-09-06  8:55         ` Nick Piggin
2004-09-05 16:49 ` Linus Torvalds
2004-09-06  0:54   ` Nick Piggin
2004-09-06  1:49     ` Nick Piggin

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=413AA879.9020105@yahoo.com.au \
    --to=nickpiggin@yahoo.com.au \
    --cc=akpm@osdl.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=torvalds@osdl.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