Annotation of /trunk/kernel26-alx/patches-2.6.17-r5/0023-2.6.17-mm-background_scan-1.patch
Parent Directory | Revision Log
Revision 199 -
(hide annotations)
(download)
Fri May 18 11:04:36 2007 UTC (17 years, 4 months ago) by niro
File size: 3654 byte(s)
Fri May 18 11:04:36 2007 UTC (17 years, 4 months ago) by niro
File size: 3654 byte(s)
-import
1 | niro | 199 | Add a background scanning timer to restore the watermarks to the pages_lots |
2 | level and only call on it if kswapd has not been called upon for the last 5 | ||
3 | seconds. This allows us to balance all zones to the more generous pages_lots | ||
4 | watermark at a time unrelated to page allocation thus leading to lighter | ||
5 | levels of vm load when called upon under page allocation. | ||
6 | |||
7 | Signed-off-by: Con Kolivas <kernel@kolivas.org> | ||
8 | |||
9 | include/linux/mmzone.h | 2 ++ | ||
10 | mm/vmscan.c | 39 +++++++++++++++++++++++++++++++++++++++ | ||
11 | 2 files changed, 41 insertions(+) | ||
12 | |||
13 | Index: linux-ck-dev/include/linux/mmzone.h | ||
14 | =================================================================== | ||
15 | --- linux-ck-dev.orig/include/linux/mmzone.h 2006-06-18 15:25:02.000000000 +1000 | ||
16 | +++ linux-ck-dev/include/linux/mmzone.h 2006-06-18 15:25:07.000000000 +1000 | ||
17 | @@ -14,6 +14,7 @@ | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/seqlock.h> | ||
20 | #include <linux/nodemask.h> | ||
21 | +#include <linux/timer.h> | ||
22 | #include <asm/atomic.h> | ||
23 | #include <asm/page.h> | ||
24 | |||
25 | @@ -312,6 +313,7 @@ typedef struct pglist_data { | ||
26 | wait_queue_head_t kswapd_wait; | ||
27 | struct task_struct *kswapd; | ||
28 | int kswapd_max_order; | ||
29 | + struct timer_list watermark_timer; | ||
30 | } pg_data_t; | ||
31 | |||
32 | #define node_present_pages(nid) (NODE_DATA(nid)->node_present_pages) | ||
33 | Index: linux-ck-dev/mm/vmscan.c | ||
34 | =================================================================== | ||
35 | --- linux-ck-dev.orig/mm/vmscan.c 2006-06-18 15:25:05.000000000 +1000 | ||
36 | +++ linux-ck-dev/mm/vmscan.c 2006-06-18 15:25:07.000000000 +1000 | ||
37 | @@ -35,6 +35,7 @@ | ||
38 | #include <linux/notifier.h> | ||
39 | #include <linux/rwsem.h> | ||
40 | #include <linux/delay.h> | ||
41 | +#include <linux/timer.h> | ||
42 | |||
43 | #include <asm/tlbflush.h> | ||
44 | #include <asm/div64.h> | ||
45 | @@ -1244,6 +1245,8 @@ out: | ||
46 | return nr_reclaimed; | ||
47 | } | ||
48 | |||
49 | +#define WT_EXPIRY (HZ * 5) /* Time to wakeup watermark_timer */ | ||
50 | + | ||
51 | /* | ||
52 | * The background pageout daemon, started as a kernel thread | ||
53 | * from the init process. | ||
54 | @@ -1294,6 +1297,8 @@ static int kswapd(void *p) | ||
55 | |||
56 | try_to_freeze(); | ||
57 | |||
58 | + /* kswapd has been busy so delay watermark_timer */ | ||
59 | + mod_timer(&pgdat->watermark_timer, jiffies + WT_EXPIRY); | ||
60 | prepare_to_wait(&pgdat->kswapd_wait, &wait, TASK_INTERRUPTIBLE); | ||
61 | new_order = pgdat->kswapd_max_order; | ||
62 | pgdat->kswapd_max_order = 0; | ||
63 | @@ -1517,12 +1522,41 @@ static int cpu_callback(struct notifier_ | ||
64 | } | ||
65 | #endif /* CONFIG_HOTPLUG_CPU */ | ||
66 | |||
67 | +/* | ||
68 | + * We wake up kswapd every WT_EXPIRY till free ram is above pages_lots | ||
69 | + */ | ||
70 | +static void watermark_wakeup(unsigned long data) | ||
71 | +{ | ||
72 | + pg_data_t *pgdat = (pg_data_t *)data; | ||
73 | + struct timer_list *wt = &pgdat->watermark_timer; | ||
74 | + int i; | ||
75 | + | ||
76 | + if (!waitqueue_active(&pgdat->kswapd_wait) || above_background_load()) | ||
77 | + goto out; | ||
78 | + for (i = pgdat->nr_zones - 1; i >= 0; i--) { | ||
79 | + struct zone *z = pgdat->node_zones + i; | ||
80 | + | ||
81 | + if (!populated_zone(z) || is_highmem(z)) { | ||
82 | + /* We are better off leaving highmem full */ | ||
83 | + continue; | ||
84 | + } | ||
85 | + if (!zone_watermark_ok(z, 0, z->pages_lots, 0, 0)) { | ||
86 | + wake_up_interruptible(&pgdat->kswapd_wait); | ||
87 | + goto out; | ||
88 | + } | ||
89 | + } | ||
90 | +out: | ||
91 | + mod_timer(wt, jiffies + WT_EXPIRY); | ||
92 | + return; | ||
93 | +} | ||
94 | + | ||
95 | static int __init kswapd_init(void) | ||
96 | { | ||
97 | pg_data_t *pgdat; | ||
98 | |||
99 | swap_setup(); | ||
100 | for_each_online_pgdat(pgdat) { | ||
101 | + struct timer_list *wt = &pgdat->watermark_timer; | ||
102 | pid_t pid; | ||
103 | |||
104 | pid = kernel_thread(kswapd, pgdat, CLONE_KERNEL); | ||
105 | @@ -1530,6 +1564,11 @@ static int __init kswapd_init(void) | ||
106 | read_lock(&tasklist_lock); | ||
107 | pgdat->kswapd = find_task_by_pid(pid); | ||
108 | read_unlock(&tasklist_lock); | ||
109 | + init_timer(wt); | ||
110 | + wt->data = (unsigned long)pgdat; | ||
111 | + wt->function = watermark_wakeup; | ||
112 | + wt->expires = jiffies + WT_EXPIRY; | ||
113 | + add_timer(wt); | ||
114 | } | ||
115 | total_memory = nr_free_pagecache_pages(); | ||
116 | hotcpu_notifier(cpu_callback, 0); |