Annotation of /trunk/kernel26-alx/patches-2.6.20-r6/0018-2.6.20-mm-kswapd_inherit_prio-1.patch
Parent Directory | Revision Log
Revision 1175 -
(hide annotations)
(download)
Thu Oct 14 12:15:46 2010 UTC (13 years, 11 months ago) by niro
File size: 3939 byte(s)
Thu Oct 14 12:15:46 2010 UTC (13 years, 11 months ago) by niro
File size: 3939 byte(s)
-2.6.20-alx-r6 new magellan 0.5.2 kernel
1 | niro | 1175 | When kswapd is awoken due to reclaim by a running task, set the priority of |
2 | kswapd to that of the calling task thus making memory reclaim cpu activity | ||
3 | affected by nice level. | ||
4 | |||
5 | Signed-off-by: Con Kolivas <kernel@kolivas.org> | ||
6 | |||
7 | include/linux/mmzone.h | 2 +- | ||
8 | mm/page_alloc.c | 2 +- | ||
9 | mm/vmscan.c | 41 +++++++++++++++++++++++++++++++++++++++-- | ||
10 | 3 files changed, 41 insertions(+), 4 deletions(-) | ||
11 | |||
12 | Index: linux-2.6.20-ck1/include/linux/mmzone.h | ||
13 | =================================================================== | ||
14 | --- linux-2.6.20-ck1.orig/include/linux/mmzone.h 2007-02-16 19:01:33.000000000 +1100 | ||
15 | +++ linux-2.6.20-ck1/include/linux/mmzone.h 2007-02-16 19:01:33.000000000 +1100 | ||
16 | @@ -447,7 +447,7 @@ void __get_zone_counts(unsigned long *ac | ||
17 | void get_zone_counts(unsigned long *active, unsigned long *inactive, | ||
18 | unsigned long *free); | ||
19 | void build_all_zonelists(void); | ||
20 | -void wakeup_kswapd(struct zone *zone, int order); | ||
21 | +void wakeup_kswapd(struct zone *zone, int order, struct task_struct *p); | ||
22 | int zone_watermark_ok(struct zone *z, int order, unsigned long mark, | ||
23 | int classzone_idx, int alloc_flags); | ||
24 | enum memmap_context { | ||
25 | Index: linux-2.6.20-ck1/mm/page_alloc.c | ||
26 | =================================================================== | ||
27 | --- linux-2.6.20-ck1.orig/mm/page_alloc.c 2007-02-16 19:01:33.000000000 +1100 | ||
28 | +++ linux-2.6.20-ck1/mm/page_alloc.c 2007-02-16 19:01:33.000000000 +1100 | ||
29 | @@ -1252,7 +1252,7 @@ restart: | ||
30 | goto nopage; | ||
31 | |||
32 | for (z = zonelist->zones; *z; z++) | ||
33 | - wakeup_kswapd(*z, order); | ||
34 | + wakeup_kswapd(*z, order, p); | ||
35 | |||
36 | /* | ||
37 | * OK, we're below the kswapd watermark and have kicked background | ||
38 | Index: linux-2.6.20-ck1/mm/vmscan.c | ||
39 | =================================================================== | ||
40 | --- linux-2.6.20-ck1.orig/mm/vmscan.c 2007-02-16 19:01:33.000000000 +1100 | ||
41 | +++ linux-2.6.20-ck1/mm/vmscan.c 2007-02-16 19:01:33.000000000 +1100 | ||
42 | @@ -963,6 +963,39 @@ static unsigned long shrink_zone(int pri | ||
43 | } | ||
44 | |||
45 | /* | ||
46 | + * Helper functions to adjust nice level of kswapd, based on the priority of | ||
47 | + * the task (p) that called it. If it is already higher priority we do not | ||
48 | + * demote its nice level since it is still working on behalf of a higher | ||
49 | + * priority task. With kernel threads we leave it at nice 0. | ||
50 | + * | ||
51 | + * We don't ever run kswapd real time, so if a real time task calls kswapd we | ||
52 | + * set it to highest SCHED_NORMAL priority. | ||
53 | + */ | ||
54 | +static int effective_sc_prio(struct task_struct *p) | ||
55 | +{ | ||
56 | + if (likely(p->mm)) { | ||
57 | + if (rt_task(p)) | ||
58 | + return -20; | ||
59 | + return task_nice(p); | ||
60 | + } | ||
61 | + return 0; | ||
62 | +} | ||
63 | + | ||
64 | +static void set_kswapd_nice(struct task_struct *kswapd, struct task_struct *p, | ||
65 | + int active) | ||
66 | +{ | ||
67 | + long nice = effective_sc_prio(p); | ||
68 | + | ||
69 | + if (task_nice(kswapd) > nice || !active) | ||
70 | + set_user_nice(kswapd, nice); | ||
71 | +} | ||
72 | + | ||
73 | +static int sc_priority(struct task_struct *p) | ||
74 | +{ | ||
75 | + return (DEF_PRIORITY + (DEF_PRIORITY * effective_sc_prio(p) / 40)); | ||
76 | +} | ||
77 | + | ||
78 | +/* | ||
79 | * This is the direct reclaim path, for page-allocating processes. We only | ||
80 | * try to reclaim pages from zones which will satisfy the caller's allocation | ||
81 | * request. | ||
82 | @@ -1349,6 +1382,7 @@ static int kswapd(void *p) | ||
83 | */ | ||
84 | order = new_order; | ||
85 | } else { | ||
86 | + set_user_nice(tsk, 0); | ||
87 | schedule(); | ||
88 | order = pgdat->kswapd_max_order; | ||
89 | } | ||
90 | @@ -1362,9 +1396,10 @@ static int kswapd(void *p) | ||
91 | /* | ||
92 | * A zone is low on free memory, so wake its kswapd task to service it. | ||
93 | */ | ||
94 | -void wakeup_kswapd(struct zone *zone, int order) | ||
95 | +void wakeup_kswapd(struct zone *zone, int order, struct task_struct *p) | ||
96 | { | ||
97 | pg_data_t *pgdat; | ||
98 | + int active; | ||
99 | |||
100 | if (!populated_zone(zone)) | ||
101 | return; | ||
102 | @@ -1376,7 +1411,9 @@ void wakeup_kswapd(struct zone *zone, in | ||
103 | pgdat->kswapd_max_order = order; | ||
104 | if (!cpuset_zone_allowed_hardwall(zone, GFP_KERNEL)) | ||
105 | return; | ||
106 | - if (!waitqueue_active(&pgdat->kswapd_wait)) | ||
107 | + active = waitqueue_active(&pgdat->kswapd_wait); | ||
108 | + set_kswapd_nice(pgdat->kswapd, p, active); | ||
109 | + if (!active) | ||
110 | return; | ||
111 | wake_up_interruptible(&pgdat->kswapd_wait); | ||
112 | } |