Magellan Linux

Annotation of /trunk/kernel26-magellan/patches-2.6.21-r4/0016-2.6.21-mm-background_scan-2.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 222 - (hide annotations) (download)
Tue Jun 12 08:03:28 2007 UTC (16 years, 11 months ago) by niro
File size: 4567 byte(s)
files for 2.6.21-magellan-r4

1 niro 222 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;