Skip to contentSkip to conversation

mm swapping improvements

PATCH In review Nick Piggin 1 participant 2 messages Jan 30, 2004

Subsystems (8)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 mm swapping improvements

Hi list,

Attached is a patchset against 2.6.2-rc2-mm1 which includes two of Nikita's patches and one of my own, and backs out the RSS limit patch due to some problems (discussion of these patches on linux-mm). The patchset improves VM performance under swapping quite significantly for kbuild - its now close 2.4 or better in some cases.

I haven't done many other tests so I would like anyone who's had swapping related slowdowns when moving from 2.4 to 2.6, and is interested in helping improve it to test out the patch please. I can make a patch against the -linus kernel if anyone would like.

Some benchmarks: http://www.kerneltrap.org/~npiggin/vm/3/
Green is 2.6, red is 2.4, purple is 2.6 with this patch.

Thank you.
Nick

PS (the usual disclaimer about mm patches vs your data)

 linux-2.6-npiggin/include/linux/init_task.h |    2 
 linux-2.6-npiggin/include/linux/mmzone.h    |    6 +
 linux-2.6-npiggin/include/linux/sched.h     |    1 
 linux-2.6-npiggin/include/linux/swap.h      |    4 
 linux-2.6-npiggin/kernel/sys.c              |    8 -
 linux-2.6-npiggin/mm/page_alloc.c           |   20 +++
 linux-2.6-npiggin/mm/rmap.c                 |   19 ---
 linux-2.6-npiggin/mm/vmscan.c               |  162 +++++++++++++++++-----------
 8 files changed, 130 insertions(+), 92 deletions(-)
include/linux/init_task.h renamed from include/linux/init_task.h~rollup +0 -2
diff -puN include/linux/init_task.h~rollup include/linux/init_task.h
@@ -2,7 +2,6 @@
 #define _LINUX__INIT_TASK_H
 
 #include <linux/file.h>
-#include <asm/resource.h>
 
 #define INIT_FILES \
 { 							\
@@ -43,7 +42,6 @@
 	.mmlist		= LIST_HEAD_INIT(name.mmlist),		\
 	.cpu_vm_mask	= CPU_MASK_ALL,				\
 	.default_kioctx = INIT_KIOCTX(name.default_kioctx, name),	\
-	.rlimit_rss	= RLIM_INFINITY			\
 }
 
 #define INIT_SIGNALS(sig) {	\
include/linux/mmzone.h renamed from include/linux/mmzone.h~rollup +6 -0
diff -puN include/linux/mmzone.h~rollup include/linux/mmzone.h
@@ -149,6 +149,12 @@ struct zone {
 	unsigned long		zone_start_pfn;
 
 	/*
+	 * dummy page used as place holder during scanning of
+	 * active_list in refill_inactive_zone()
+	 */
+	struct page *scan_page;
+
+	/*
 	 * rarely used fields:
 	 */
 	char			*name;
include/linux/sched.h renamed from include/linux/sched.h~rollup +0 -1
diff -puN include/linux/sched.h~rollup include/linux/sched.h
@@ -206,7 +206,6 @@ struct mm_struct {
 	unsigned long arg_start, arg_end, env_start, env_end;
 	unsigned long rss, total_vm, locked_vm;
 	unsigned long def_flags;
-	unsigned long rlimit_rss;
 	cpumask_t cpu_vm_mask;
 
 	unsigned long saved_auxv[40]; /* for /proc/PID/auxv */
include/linux/swap.h renamed from include/linux/swap.h~rollup +2 -2
diff -puN include/linux/swap.h~rollup include/linux/swap.h
@@ -179,7 +179,7 @@ extern int vm_swappiness;
 
 /* linux/mm/rmap.c */
 #ifdef CONFIG_MMU
-int FASTCALL(page_referenced(struct page *, int *));
+int FASTCALL(page_referenced(struct page *));
 struct pte_chain *FASTCALL(page_add_rmap(struct page *, pte_t *,
 					struct pte_chain *));
 void FASTCALL(page_remove_rmap(struct page *, pte_t *));
@@ -188,7 +188,7 @@ int FASTCALL(try_to_unmap(struct page *)
 /* linux/mm/shmem.c */
 extern int shmem_unuse(swp_entry_t entry, struct page *page);
 #else
-#define page_referenced(page, _x)	TestClearPageReferenced(page)
+#define page_referenced(page)	TestClearPageReferenced(page)
 #define try_to_unmap(page)	SWAP_FAIL
 #endif /* CONFIG_MMU */
 
kernel/sys.c renamed from kernel/sys.c~rollup +0 -8
diff -puN kernel/sys.c~rollup kernel/sys.c
@@ -1306,14 +1306,6 @@ asmlinkage long sys_setrlimit(unsigned i
 	if (retval)
 		return retval;
 
-	/* The rlimit is specified in bytes, convert to pages for mm. */
-	if (resource == RLIMIT_RSS && current->mm) {
-		unsigned long pages = RLIM_INFINITY;
-		if (new_rlim.rlim_cur != RLIM_INFINITY)
-			pages = new_rlim.rlim_cur >> PAGE_SHIFT;
-		current->mm->rlimit_rss = pages;
-	}
-
 	*old_rlim = new_rlim;
 	return 0;
 }
mm/page_alloc.c renamed from mm/page_alloc.c~rollup +20 -0
diff -puN mm/page_alloc.c~rollup mm/page_alloc.c
@@ -1211,6 +1211,9 @@ void __init memmap_init_zone(struct page
 	memmap_init_zone((start), (size), (nid), (zone), (start_pfn))
 #endif
 
+/* dummy pages used to scan active lists */
+static struct page scan_pages[MAX_NUMNODES][MAX_NR_ZONES];
+
 /*
  * Set up the zone data structures:
  *   - mark all pages reserved
@@ -1233,6 +1236,7 @@ static void __init free_area_init_core(s
 		struct zone *zone = pgdat->node_zones + j;
 		unsigned long size, realsize;
 		unsigned long batch;
+		struct page *scan_page;
 
 		zone_table[NODEZONE(nid, j)] = zone;
 		realsize = size = zones_size[j];
@@ -1287,6 +1291,22 @@ static void __init free_area_init_core(s
 		atomic_set(&zone->refill_counter, 0);
 		zone->nr_active = 0;
 		zone->nr_inactive = 0;
+
+		/* initialize dummy page used for scanning */
+		scan_page = &scan_pages[nid][j];
+		zone->scan_page = scan_page;
+		memset(scan_page, 0, sizeof *scan_page);
+		scan_page->flags =
+			(1 << PG_locked) |
+			(1 << PG_error) |
+			(1 << PG_lru) |
+			(1 << PG_active) |
+			(1 << PG_reserved);
+		set_page_zone(scan_page, j);
+		page_cache_get(scan_page);
+		INIT_LIST_HEAD(&scan_page->list);
+		list_add(&scan_page->lru, &zone->active_list);
+
 		if (!size)
 			continue;
 
mm/rmap.c renamed from mm/rmap.c~rollup +1 -18
diff -puN mm/rmap.c~rollup mm/rmap.c
@@ -104,8 +104,6 @@ pte_chain_encode(struct pte_chain *pte_c
 /**
  * page_referenced - test if the page was referenced
  * @page: the page to test
- * @rsslimit: set if the process(es) using the page is(are) over RSS limit.
- *            Cleared otherwise.
  *
  * Quick test_and_clear_referenced for all mappings to a page,
  * returns the number of processes which referenced the page.
@@ -113,13 +111,9 @@ pte_chain_encode(struct pte_chain *pte_c
  *
  * If the page has a single-entry pte_chain, collapse that back to a PageDirect
  * representation.  This way, it's only done under memory pressure.
- *
- * The pte_chain_lock() is sufficient to pin down mm_structs which we examine
- * them.
  */
-int page_referenced(struct page *page, int *rsslimit)
+int page_referenced(struct page * page)
 {
-	struct mm_struct * mm;
 	struct pte_chain *pc;
 	int referenced = 0;
 
@@ -133,17 +127,10 @@ int page_referenced(struct page *page, i
 		pte_t *pte = rmap_ptep_map(page->pte.direct);
 		if (ptep_test_and_clear_young(pte))
 			referenced++;
-
-		mm = ptep_to_mm(pte);
-		if (mm->rss > mm->rlimit_rss)
-			*rsslimit = 1;
 		rmap_ptep_unmap(pte);
 	} else {
 		int nr_chains = 0;
 
-		/* We clear it if any task using the page is under its limit. */
-		*rsslimit = 1;
-
 		/* Check all the page tables mapping this page. */
 		for (pc = page->pte.chain; pc; pc = pte_chain_next(pc)) {
 			int i;
@@ -155,10 +142,6 @@ int page_referenced(struct page *page, i
 				p = rmap_ptep_map(pte_paddr);
 				if (ptep_test_and_clear_young(p))
 					referenced++;
-
-				mm = ptep_to_mm(p);
-				if (mm->rss < mm->rlimit_rss)
-					*rsslimit = 0;
 				rmap_ptep_unmap(p);
 				nr_chains++;
 			}
mm/vmscan.c renamed from mm/vmscan.c~rollup +101 -61

256 lines not on this page · raw message

_

#1 lore raw
Quoted 8 lines · Nick Piggin

Hi list,

Attached is a patchset against 2.6.2-rc2-mm1 which includes two of Nikita's patches and one of my own, and backs out the RSS limit patch due to some problems (discussion of these patches on linux-mm). The patchset improves VM performance under swapping quite significantly for kbuild - its now close 2.4 or better in some cases.

Quoted 8 lines

I haven't done many other tests so I would like anyone who's had swapping related slowdowns when moving from 2.4 to 2.6, and is interested in helping improve it to test out the patch please. I can make a patch against the -linus kernel if anyone would like.

Some benchmarks: http://www.kerneltrap.org/~npiggin/vm/3/
Green is 2.6, red is 2.4, purple is 2.6 with this patch.

OK here is the patch for 2.6.2-rc2. Only compile tested but there isn't much difference between -linus and -mm in this area so it should be fine.

 linux-2.6-npiggin/include/linux/mmzone.h |    6 +
 linux-2.6-npiggin/mm/page_alloc.c        |   20 ++++
 linux-2.6-npiggin/mm/vmscan.c            |  152 +++++++++++++++++++------------
 3 files changed, 124 insertions(+), 54 deletions(-)
include/linux/mmzone.h renamed from include/linux/mmzone.h~rollup +6 -0
diff -puN include/linux/mmzone.h~rollup include/linux/mmzone.h
@@ -149,6 +149,12 @@ struct zone {
 	unsigned long		zone_start_pfn;
 
 	/*
+	 * dummy page used as place holder during scanning of
+	 * active_list in refill_inactive_zone()
+	 */
+	struct page *scan_page;
+
+	/*
 	 * rarely used fields:
 	 */
 	char			*name;
mm/page_alloc.c renamed from mm/page_alloc.c~rollup +20 -0
diff -puN mm/page_alloc.c~rollup mm/page_alloc.c
@@ -1230,6 +1230,9 @@ void __init memmap_init_zone(struct page
 	memmap_init_zone((start), (size), (nid), (zone), (start_pfn))
 #endif
 
+/* dummy pages used to scan active lists */
+static struct page scan_pages[MAX_NUMNODES][MAX_NR_ZONES];
+
 /*
  * Set up the zone data structures:
  *   - mark all pages reserved
@@ -1252,6 +1255,7 @@ static void __init free_area_init_core(s
 		struct zone *zone = pgdat->node_zones + j;
 		unsigned long size, realsize;
 		unsigned long batch;
+		struct page *scan_page;
 
 		zone_table[NODEZONE(nid, j)] = zone;
 		realsize = size = zones_size[j];
@@ -1306,6 +1310,22 @@ static void __init free_area_init_core(s
 		atomic_set(&zone->refill_counter, 0);
 		zone->nr_active = 0;
 		zone->nr_inactive = 0;
+
+		/* initialize dummy page used for scanning */
+		scan_page = &scan_pages[nid][j];
+		zone->scan_page = scan_page;
+		memset(scan_page, 0, sizeof *scan_page);
+		scan_page->flags =
+			(1 << PG_locked) |
+			(1 << PG_error) |
+			(1 << PG_lru) |
+			(1 << PG_active) |
+			(1 << PG_reserved);
+		set_page_zone(scan_page, j);
+		page_cache_get(scan_page);
+		INIT_LIST_HEAD(&scan_page->list);
+		list_add(&scan_page->lru, &zone->active_list);
+
 		if (!size)
 			continue;
 
mm/vmscan.c renamed from mm/vmscan.c~rollup +98 -54

235 lines not on this page · raw message

_