Magellan Linux

Contents of /trunk/kernel26-alx/patches-2.6.21-r14/0016-2.6.21-mm-background_scan-2.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 447 - (show annotations) (download)
Tue Jan 22 17:55:52 2008 UTC (16 years, 3 months ago) by niro
File size: 4567 byte(s)
-2.6.21-alx-r14 - fixed some natsemi errors on wys terminals

1 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 The -ck patches modify mm/vmscan.c and add a timer to wake up kswapd every 5
10 seconds. This timer is initialized after the creation of the kswapd thread.
11
12 The kswapd() thread function calls mod_timer at the front of its infinite
13 service loop (to reset the timer to 5 seconds in the future). mod_timer()
14 includes a BUG_ON() to assert that the timer's callback function is set.
15
16 Since the wakeup timer is initialized after the kswapd thread is created, if
17 kswapd gets scheduled before kswapd_run() has prepared the timer, the
18 BUG_ON() check will throw a stack trace and immediately terminate the kswapd
19 thread.
20
21 This patch modifies the kswapd_run() function in mm/vmscan.c to initialize the
22 watermark timer before starting the kswapd thread.
23
24 Signed-off-by: Chase Venters <chase.venters at clientec.com>
25
26 include/linux/mmzone.h | 2 ++
27 mm/vmscan.c | 42 ++++++++++++++++++++++++++++++++++++++++++
28 2 files changed, 44 insertions(+)
29
30 Index: linux-2.6.21-ck2/include/linux/mmzone.h
31 ===================================================================
32 --- linux-2.6.21-ck2.orig/include/linux/mmzone.h 2007-05-14 19:49:55.000000000 +1000
33 +++ linux-2.6.21-ck2/include/linux/mmzone.h 2007-05-14 19:49:56.000000000 +1000
34 @@ -13,6 +13,7 @@
35 #include <linux/init.h>
36 #include <linux/seqlock.h>
37 #include <linux/nodemask.h>
38 +#include <linux/timer.h>
39 #include <asm/atomic.h>
40 #include <asm/page.h>
41
42 @@ -449,6 +450,7 @@ typedef struct pglist_data {
43 wait_queue_head_t kswapd_wait;
44 struct task_struct *kswapd;
45 int kswapd_max_order;
46 + struct timer_list watermark_timer;
47 } pg_data_t;
48
49 #define node_present_pages(nid) (NODE_DATA(nid)->node_present_pages)
50 Index: linux-2.6.21-ck2/mm/vmscan.c
51 ===================================================================
52 --- linux-2.6.21-ck2.orig/mm/vmscan.c 2007-05-14 19:49:56.000000000 +1000
53 +++ linux-2.6.21-ck2/mm/vmscan.c 2007-05-14 19:49:56.000000000 +1000
54 @@ -37,6 +37,7 @@
55 #include <linux/rwsem.h>
56 #include <linux/delay.h>
57 #include <linux/kthread.h>
58 +#include <linux/timer.h>
59 #include <linux/freezer.h>
60
61 #include <asm/tlbflush.h>
62 @@ -1335,6 +1336,8 @@ out:
63 return nr_reclaimed;
64 }
65
66 +#define WT_EXPIRY (HZ * 5) /* Time to wakeup watermark_timer */
67 +
68 /*
69 * The background pageout daemon, started as a kernel thread
70 * from the init process.
71 @@ -1384,6 +1387,8 @@ static int kswapd(void *p)
72
73 try_to_freeze();
74
75 + /* kswapd has been busy so delay watermark_timer */
76 + mod_timer(&pgdat->watermark_timer, jiffies + WT_EXPIRY);
77 prepare_to_wait(&pgdat->kswapd_wait, &wait, TASK_INTERRUPTIBLE);
78 new_order = pgdat->kswapd_max_order;
79 pgdat->kswapd_max_order = 0;
80 @@ -1604,20 +1609,57 @@ static int __devinit cpu_callback(struct
81 }
82
83 /*
84 + * We wake up kswapd every WT_EXPIRY till free ram is above pages_lots
85 + */
86 +static void watermark_wakeup(unsigned long data)
87 +{
88 + pg_data_t *pgdat = (pg_data_t *)data;
89 + struct timer_list *wt = &pgdat->watermark_timer;
90 + int i;
91 +
92 + if (!waitqueue_active(&pgdat->kswapd_wait) || above_background_load())
93 + goto out;
94 + for (i = pgdat->nr_zones - 1; i >= 0; i--) {
95 + struct zone *z = pgdat->node_zones + i;
96 +
97 + if (!populated_zone(z) || is_highmem(z)) {
98 + /* We are better off leaving highmem full */
99 + continue;
100 + }
101 + if (!zone_watermark_ok(z, 0, z->pages_lots, 0, 0)) {
102 + wake_up_interruptible(&pgdat->kswapd_wait);
103 + goto out;
104 + }
105 + }
106 +out:
107 + mod_timer(wt, jiffies + WT_EXPIRY);
108 + return;
109 +}
110 +
111 +/*
112 * This kswapd start function will be called by init and node-hot-add.
113 * On node-hot-add, kswapd will moved to proper cpus if cpus are hot-added.
114 */
115 int kswapd_run(int nid)
116 {
117 pg_data_t *pgdat = NODE_DATA(nid);
118 + struct timer_list *wt;
119 int ret = 0;
120
121 if (pgdat->kswapd)
122 return 0;
123
124 + wt = &pgdat->watermark_timer;
125 + init_timer(wt);
126 + wt->data = (unsigned long)pgdat;
127 + wt->function = watermark_wakeup;
128 + wt->expires = jiffies + WT_EXPIRY;
129 + add_timer(wt);
130 +
131 pgdat->kswapd = kthread_run(kswapd, pgdat, "kswapd%d", nid);
132 if (IS_ERR(pgdat->kswapd)) {
133 /* failure at boot is fatal */
134 + del_timer(wt);
135 BUG_ON(system_state == SYSTEM_BOOTING);
136 printk("Failed to start kswapd on node %d\n",nid);
137 ret = -1;