diff options
247 files changed, 5666 insertions, 2683 deletions
diff --git a/Documentation/accounting/getdelays.c b/Documentation/accounting/getdelays.c index 7ea231172c85..aa73e72fd793 100644 --- a/Documentation/accounting/getdelays.c +++ b/Documentation/accounting/getdelays.c | |||
@@ -246,7 +246,8 @@ void print_ioacct(struct taskstats *t) | |||
246 | 246 | ||
247 | int main(int argc, char *argv[]) | 247 | int main(int argc, char *argv[]) |
248 | { | 248 | { |
249 | int c, rc, rep_len, aggr_len, len2, cmd_type; | 249 | int c, rc, rep_len, aggr_len, len2; |
250 | int cmd_type = TASKSTATS_CMD_ATTR_UNSPEC; | ||
250 | __u16 id; | 251 | __u16 id; |
251 | __u32 mypid; | 252 | __u32 mypid; |
252 | 253 | ||
diff --git a/Documentation/atomic_ops.txt b/Documentation/atomic_ops.txt index 4ef245010457..396bec3b74ed 100644 --- a/Documentation/atomic_ops.txt +++ b/Documentation/atomic_ops.txt | |||
@@ -229,10 +229,10 @@ kernel. It is the use of atomic counters to implement reference | |||
229 | counting, and it works such that once the counter falls to zero it can | 229 | counting, and it works such that once the counter falls to zero it can |
230 | be guaranteed that no other entity can be accessing the object: | 230 | be guaranteed that no other entity can be accessing the object: |
231 | 231 | ||
232 | static void obj_list_add(struct obj *obj) | 232 | static void obj_list_add(struct obj *obj, struct list_head *head) |
233 | { | 233 | { |
234 | obj->active = 1; | 234 | obj->active = 1; |
235 | list_add(&obj->list); | 235 | list_add(&obj->list, head); |
236 | } | 236 | } |
237 | 237 | ||
238 | static void obj_list_del(struct obj *obj) | 238 | static void obj_list_del(struct obj *obj) |
diff --git a/Documentation/fb/vesafb.txt b/Documentation/fb/vesafb.txt index ee277dd204b0..950d5a658cb3 100644 --- a/Documentation/fb/vesafb.txt +++ b/Documentation/fb/vesafb.txt | |||
@@ -95,7 +95,7 @@ There is no way to change the vesafb video mode and/or timings after | |||
95 | booting linux. If you are not happy with the 60 Hz refresh rate, you | 95 | booting linux. If you are not happy with the 60 Hz refresh rate, you |
96 | have these options: | 96 | have these options: |
97 | 97 | ||
98 | * configure and load the DOS-Tools for your the graphics board (if | 98 | * configure and load the DOS-Tools for the graphics board (if |
99 | available) and boot linux with loadlin. | 99 | available) and boot linux with loadlin. |
100 | * use a native driver (matroxfb/atyfb) instead if vesafb. If none | 100 | * use a native driver (matroxfb/atyfb) instead if vesafb. If none |
101 | is available, write a new one! | 101 | is available, write a new one! |
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt index cd8717a36271..ebff3c10a07f 100644 --- a/Documentation/filesystems/proc.txt +++ b/Documentation/filesystems/proc.txt | |||
@@ -1003,11 +1003,13 @@ CHAPTER 3: PER-PROCESS PARAMETERS | |||
1003 | 3.1 /proc/<pid>/oom_adj - Adjust the oom-killer score | 1003 | 3.1 /proc/<pid>/oom_adj - Adjust the oom-killer score |
1004 | ------------------------------------------------------ | 1004 | ------------------------------------------------------ |
1005 | 1005 | ||
1006 | This file can be used to adjust the score used to select which processes | 1006 | This file can be used to adjust the score used to select which processes should |
1007 | should be killed in an out-of-memory situation. Giving it a high score will | 1007 | be killed in an out-of-memory situation. The oom_adj value is a characteristic |
1008 | increase the likelihood of this process being killed by the oom-killer. Valid | 1008 | of the task's mm, so all threads that share an mm with pid will have the same |
1009 | values are in the range -16 to +15, plus the special value -17, which disables | 1009 | oom_adj value. A high value will increase the likelihood of this process being |
1010 | oom-killing altogether for this process. | 1010 | killed by the oom-killer. Valid values are in the range -16 to +15 as |
1011 | explained below and a special value of -17, which disables oom-killing | ||
1012 | altogether for threads sharing pid's mm. | ||
1011 | 1013 | ||
1012 | The process to be killed in an out-of-memory situation is selected among all others | 1014 | The process to be killed in an out-of-memory situation is selected among all others |
1013 | based on its badness score. This value equals the original memory size of the process | 1015 | based on its badness score. This value equals the original memory size of the process |
@@ -1021,6 +1023,9 @@ the parent's score if they do not share the same memory. Thus forking servers | |||
1021 | are the prime candidates to be killed. Having only one 'hungry' child will make | 1023 | are the prime candidates to be killed. Having only one 'hungry' child will make |
1022 | parent less preferable than the child. | 1024 | parent less preferable than the child. |
1023 | 1025 | ||
1026 | /proc/<pid>/oom_adj cannot be changed for kthreads since they are immune from | ||
1027 | oom-killing already. | ||
1028 | |||
1024 | /proc/<pid>/oom_score shows process' current badness score. | 1029 | /proc/<pid>/oom_score shows process' current badness score. |
1025 | 1030 | ||
1026 | The following heuristics are then applied: | 1031 | The following heuristics are then applied: |
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index ad3800630772..5578248c18a4 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -546,6 +546,10 @@ and is between 256 and 4096 characters. It is defined in the file | |||
546 | console=brl,ttyS0 | 546 | console=brl,ttyS0 |
547 | For now, only VisioBraille is supported. | 547 | For now, only VisioBraille is supported. |
548 | 548 | ||
549 | consoleblank= [KNL] The console blank (screen saver) timeout in | ||
550 | seconds. Defaults to 10*60 = 10mins. A value of 0 | ||
551 | disables the blank timer. | ||
552 | |||
549 | coredump_filter= | 553 | coredump_filter= |
550 | [KNL] Change the default value for | 554 | [KNL] Change the default value for |
551 | /proc/<pid>/coredump_filter. | 555 | /proc/<pid>/coredump_filter. |
diff --git a/Documentation/sysctl/vm.txt b/Documentation/sysctl/vm.txt index 6fab2dcbb4d3..c4de6359d440 100644 --- a/Documentation/sysctl/vm.txt +++ b/Documentation/sysctl/vm.txt | |||
@@ -233,8 +233,8 @@ These protections are added to score to judge whether this zone should be used | |||
233 | for page allocation or should be reclaimed. | 233 | for page allocation or should be reclaimed. |
234 | 234 | ||
235 | In this example, if normal pages (index=2) are required to this DMA zone and | 235 | In this example, if normal pages (index=2) are required to this DMA zone and |
236 | pages_high is used for watermark, the kernel judges this zone should not be | 236 | watermark[WMARK_HIGH] is used for watermark, the kernel judges this zone should |
237 | used because pages_free(1355) is smaller than watermark + protection[2] | 237 | not be used because pages_free(1355) is smaller than watermark + protection[2] |
238 | (4 + 2004 = 2008). If this protection value is 0, this zone would be used for | 238 | (4 + 2004 = 2008). If this protection value is 0, this zone would be used for |
239 | normal page requirement. If requirement is DMA zone(index=0), protection[0] | 239 | normal page requirement. If requirement is DMA zone(index=0), protection[0] |
240 | (=0) is used. | 240 | (=0) is used. |
@@ -280,9 +280,10 @@ The default value is 65536. | |||
280 | min_free_kbytes: | 280 | min_free_kbytes: |
281 | 281 | ||
282 | This is used to force the Linux VM to keep a minimum number | 282 | This is used to force the Linux VM to keep a minimum number |
283 | of kilobytes free. The VM uses this number to compute a pages_min | 283 | of kilobytes free. The VM uses this number to compute a |
284 | value for each lowmem zone in the system. Each lowmem zone gets | 284 | watermark[WMARK_MIN] value for each lowmem zone in the system. |
285 | a number of reserved free pages based proportionally on its size. | 285 | Each lowmem zone gets a number of reserved free pages based |
286 | proportionally on its size. | ||
286 | 287 | ||
287 | Some minimal amount of memory is needed to satisfy PF_MEMALLOC | 288 | Some minimal amount of memory is needed to satisfy PF_MEMALLOC |
288 | allocations; if you set this to lower than 1024KB, your system will | 289 | allocations; if you set this to lower than 1024KB, your system will |
@@ -314,10 +315,14 @@ min_unmapped_ratio: | |||
314 | 315 | ||
315 | This is available only on NUMA kernels. | 316 | This is available only on NUMA kernels. |
316 | 317 | ||
317 | A percentage of the total pages in each zone. Zone reclaim will only | 318 | This is a percentage of the total pages in each zone. Zone reclaim will |
318 | occur if more than this percentage of pages are file backed and unmapped. | 319 | only occur if more than this percentage of pages are in a state that |
319 | This is to insure that a minimal amount of local pages is still available for | 320 | zone_reclaim_mode allows to be reclaimed. |
320 | file I/O even if the node is overallocated. | 321 | |
322 | If zone_reclaim_mode has the value 4 OR'd, then the percentage is compared | ||
323 | against all file-backed unmapped pages including swapcache pages and tmpfs | ||
324 | files. Otherwise, only unmapped pages backed by normal files but not tmpfs | ||
325 | files and similar are considered. | ||
321 | 326 | ||
322 | The default is 1 percent. | 327 | The default is 1 percent. |
323 | 328 | ||
diff --git a/Documentation/vm/Makefile b/Documentation/vm/Makefile index 6f562f778b28..27479d43a9b0 100644 --- a/Documentation/vm/Makefile +++ b/Documentation/vm/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | obj- := dummy.o | 2 | obj- := dummy.o |
3 | 3 | ||
4 | # List of programs to build | 4 | # List of programs to build |
5 | hostprogs-y := slabinfo | 5 | hostprogs-y := slabinfo slqbinfo page-types |
6 | 6 | ||
7 | # Tell kbuild to always build the programs | 7 | # Tell kbuild to always build the programs |
8 | always := $(hostprogs-y) | 8 | always := $(hostprogs-y) |
diff --git a/Documentation/vm/balance b/Documentation/vm/balance index bd3d31bc4915..c46e68cf9344 100644 --- a/Documentation/vm/balance +++ b/Documentation/vm/balance | |||
@@ -75,15 +75,15 @@ Page stealing from process memory and shm is done if stealing the page would | |||
75 | alleviate memory pressure on any zone in the page's node that has fallen below | 75 | alleviate memory pressure on any zone in the page's node that has fallen below |
76 | its watermark. | 76 | its watermark. |
77 | 77 | ||
78 | pages_min/pages_low/pages_high/low_on_memory/zone_wake_kswapd: These are | 78 | watemark[WMARK_MIN/WMARK_LOW/WMARK_HIGH]/low_on_memory/zone_wake_kswapd: These |
79 | per-zone fields, used to determine when a zone needs to be balanced. When | 79 | are per-zone fields, used to determine when a zone needs to be balanced. When |
80 | the number of pages falls below pages_min, the hysteric field low_on_memory | 80 | the number of pages falls below watermark[WMARK_MIN], the hysteric field |
81 | gets set. This stays set till the number of free pages becomes pages_high. | 81 | low_on_memory gets set. This stays set till the number of free pages becomes |
82 | When low_on_memory is set, page allocation requests will try to free some | 82 | watermark[WMARK_HIGH]. When low_on_memory is set, page allocation requests will |
83 | pages in the zone (providing GFP_WAIT is set in the request). Orthogonal | 83 | try to free some pages in the zone (providing GFP_WAIT is set in the request). |
84 | to this, is the decision to poke kswapd to free some zone pages. That | 84 | Orthogonal to this, is the decision to poke kswapd to free some zone pages. |
85 | decision is not hysteresis based, and is done when the number of free | 85 | That decision is not hysteresis based, and is done when the number of free |
86 | pages is below pages_low; in which case zone_wake_kswapd is also set. | 86 | pages is below watermark[WMARK_LOW]; in which case zone_wake_kswapd is also set. |
87 | 87 | ||
88 | 88 | ||
89 | (Good) Ideas that I have heard: | 89 | (Good) Ideas that I have heard: |
diff --git a/Documentation/vm/page-types.c b/Documentation/vm/page-types.c new file mode 100644 index 000000000000..0833f44ba16b --- /dev/null +++ b/Documentation/vm/page-types.c | |||
@@ -0,0 +1,698 @@ | |||
1 | /* | ||
2 | * page-types: Tool for querying page flags | ||
3 | * | ||
4 | * Copyright (C) 2009 Intel corporation | ||
5 | * Copyright (C) 2009 Wu Fengguang <fengguang.wu@intel.com> | ||
6 | */ | ||
7 | |||
8 | #include <stdio.h> | ||
9 | #include <stdlib.h> | ||
10 | #include <unistd.h> | ||
11 | #include <stdint.h> | ||
12 | #include <stdarg.h> | ||
13 | #include <string.h> | ||
14 | #include <getopt.h> | ||
15 | #include <limits.h> | ||
16 | #include <sys/types.h> | ||
17 | #include <sys/errno.h> | ||
18 | #include <sys/fcntl.h> | ||
19 | |||
20 | |||
21 | /* | ||
22 | * kernel page flags | ||
23 | */ | ||
24 | |||
25 | #define KPF_BYTES 8 | ||
26 | #define PROC_KPAGEFLAGS "/proc/kpageflags" | ||
27 | |||
28 | /* copied from kpageflags_read() */ | ||
29 | #define KPF_LOCKED 0 | ||
30 | #define KPF_ERROR 1 | ||
31 | #define KPF_REFERENCED 2 | ||
32 | #define KPF_UPTODATE 3 | ||
33 | #define KPF_DIRTY 4 | ||
34 | #define KPF_LRU 5 | ||
35 | #define KPF_ACTIVE 6 | ||
36 | #define KPF_SLAB 7 | ||
37 | #define KPF_WRITEBACK 8 | ||
38 | #define KPF_RECLAIM 9 | ||
39 | #define KPF_BUDDY 10 | ||
40 | |||
41 | /* [11-20] new additions in 2.6.31 */ | ||
42 | #define KPF_MMAP 11 | ||
43 | #define KPF_ANON 12 | ||
44 | #define KPF_SWAPCACHE 13 | ||
45 | #define KPF_SWAPBACKED 14 | ||
46 | #define KPF_COMPOUND_HEAD 15 | ||
47 | #define KPF_COMPOUND_TAIL 16 | ||
48 | #define KPF_HUGE 17 | ||
49 | #define KPF_UNEVICTABLE 18 | ||
50 | #define KPF_NOPAGE 20 | ||
51 | |||
52 | /* [32-] kernel hacking assistances */ | ||
53 | #define KPF_RESERVED 32 | ||
54 | #define KPF_MLOCKED 33 | ||
55 | #define KPF_MAPPEDTODISK 34 | ||
56 | #define KPF_PRIVATE 35 | ||
57 | #define KPF_PRIVATE_2 36 | ||
58 | #define KPF_OWNER_PRIVATE 37 | ||
59 | #define KPF_ARCH 38 | ||
60 | #define KPF_UNCACHED 39 | ||
61 | |||
62 | /* [48-] take some arbitrary free slots for expanding overloaded flags | ||
63 | * not part of kernel API | ||
64 | */ | ||
65 | #define KPF_READAHEAD 48 | ||
66 | #define KPF_SLOB_FREE 49 | ||
67 | #define KPF_SLUB_FROZEN 50 | ||
68 | #define KPF_SLUB_DEBUG 51 | ||
69 | |||
70 | #define KPF_ALL_BITS ((uint64_t)~0ULL) | ||
71 | #define KPF_HACKERS_BITS (0xffffULL << 32) | ||
72 | #define KPF_OVERLOADED_BITS (0xffffULL << 48) | ||
73 | #define BIT(name) (1ULL << KPF_##name) | ||
74 | #define BITS_COMPOUND (BIT(COMPOUND_HEAD) | BIT(COMPOUND_TAIL)) | ||
75 | |||
76 | static char *page_flag_names[] = { | ||
77 | [KPF_LOCKED] = "L:locked", | ||
78 | [KPF_ERROR] = "E:error", | ||
79 | [KPF_REFERENCED] = "R:referenced", | ||
80 | [KPF_UPTODATE] = "U:uptodate", | ||
81 | [KPF_DIRTY] = "D:dirty", | ||
82 | [KPF_LRU] = "l:lru", | ||
83 | [KPF_ACTIVE] = "A:active", | ||
84 | [KPF_SLAB] = "S:slab", | ||
85 | [KPF_WRITEBACK] = "W:writeback", | ||
86 | [KPF_RECLAIM] = "I:reclaim", | ||
87 | [KPF_BUDDY] = "B:buddy", | ||
88 | |||
89 | [KPF_MMAP] = "M:mmap", | ||
90 | [KPF_ANON] = "a:anonymous", | ||
91 | [KPF_SWAPCACHE] = "s:swapcache", | ||
92 | [KPF_SWAPBACKED] = "b:swapbacked", | ||
93 | [KPF_COMPOUND_HEAD] = "H:compound_head", | ||
94 | [KPF_COMPOUND_TAIL] = "T:compound_tail", | ||
95 | [KPF_HUGE] = "G:huge", | ||
96 | [KPF_UNEVICTABLE] = "u:unevictable", | ||
97 | [KPF_NOPAGE] = "n:nopage", | ||
98 | |||
99 | [KPF_RESERVED] = "r:reserved", | ||
100 | [KPF_MLOCKED] = "m:mlocked", | ||
101 | [KPF_MAPPEDTODISK] = "d:mappedtodisk", | ||
102 | [KPF_PRIVATE] = "P:private", | ||
103 | [KPF_PRIVATE_2] = "p:private_2", | ||
104 | [KPF_OWNER_PRIVATE] = "O:owner_private", | ||
105 | [KPF_ARCH] = "h:arch", | ||
106 | [KPF_UNCACHED] = "c:uncached", | ||
107 | |||
108 | [KPF_READAHEAD] = "I:readahead", | ||
109 | [KPF_SLOB_FREE] = "P:slob_free", | ||
110 | [KPF_SLUB_FROZEN] = "A:slub_frozen", | ||
111 | [KPF_SLUB_DEBUG] = "E:slub_debug", | ||
112 | }; | ||
113 | |||
114 | |||
115 | /* | ||
116 | * data structures | ||
117 | */ | ||
118 | |||
119 | static int opt_raw; /* for kernel developers */ | ||
120 | static int opt_list; /* list pages (in ranges) */ | ||
121 | static int opt_no_summary; /* don't show summary */ | ||
122 | static pid_t opt_pid; /* process to walk */ | ||
123 | |||
124 | #define MAX_ADDR_RANGES 1024 | ||
125 | static int nr_addr_ranges; | ||
126 | static unsigned long opt_offset[MAX_ADDR_RANGES]; | ||
127 | static unsigned long opt_size[MAX_ADDR_RANGES]; | ||
128 | |||
129 | #define MAX_BIT_FILTERS 64 | ||
130 | static int nr_bit_filters; | ||
131 | static uint64_t opt_mask[MAX_BIT_FILTERS]; | ||
132 | static uint64_t opt_bits[MAX_BIT_FILTERS]; | ||
133 | |||
134 | static int page_size; | ||
135 | |||
136 | #define PAGES_BATCH (64 << 10) /* 64k pages */ | ||
137 | static int kpageflags_fd; | ||
138 | static uint64_t kpageflags_buf[KPF_BYTES * PAGES_BATCH]; | ||
139 | |||
140 | #define HASH_SHIFT 13 | ||
141 | #define HASH_SIZE (1 << HASH_SHIFT) | ||
142 | #define HASH_MASK (HASH_SIZE - 1) | ||
143 | #define HASH_KEY(flags) (flags & HASH_MASK) | ||
144 | |||
145 | static unsigned long total_pages; | ||
146 | static unsigned long nr_pages[HASH_SIZE]; | ||
147 | static uint64_t page_flags[HASH_SIZE]; | ||
148 | |||
149 | |||
150 | /* | ||
151 | * helper functions | ||
152 | */ | ||
153 | |||
154 | #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) | ||
155 | |||
156 | #define min_t(type, x, y) ({ \ | ||
157 | type __min1 = (x); \ | ||
158 | type __min2 = (y); \ | ||
159 | __min1 < __min2 ? __min1 : __min2; }) | ||
160 | |||
161 | unsigned long pages2mb(unsigned long pages) | ||
162 | { | ||
163 | return (pages * page_size) >> 20; | ||
164 | } | ||
165 | |||
166 | void fatal(const char *x, ...) | ||
167 | { | ||
168 | va_list ap; | ||
169 | |||
170 | va_start(ap, x); | ||
171 | vfprintf(stderr, x, ap); | ||
172 | va_end(ap); | ||
173 | exit(EXIT_FAILURE); | ||
174 | } | ||
175 | |||
176 | |||
177 | /* | ||
178 | * page flag names | ||
179 | */ | ||
180 | |||
181 | char *page_flag_name(uint64_t flags) | ||
182 | { | ||
183 | static char buf[65]; | ||
184 | int present; | ||
185 | int i, j; | ||
186 | |||
187 | for (i = 0, j = 0; i < ARRAY_SIZE(page_flag_names); i++) { | ||
188 | present = (flags >> i) & 1; | ||
189 | if (!page_flag_names[i]) { | ||
190 | if (present) | ||
191 | fatal("unkown flag bit %d\n", i); | ||
192 | continue; | ||
193 | } | ||
194 | buf[j++] = present ? page_flag_names[i][0] : '_'; | ||
195 | } | ||
196 | |||
197 | return buf; | ||
198 | } | ||
199 | |||
200 | char *page_flag_longname(uint64_t flags) | ||
201 | { | ||
202 | static char buf[1024]; | ||
203 | int i, n; | ||
204 | |||
205 | for (i = 0, n = 0; i < ARRAY_SIZE(page_flag_names); i++) { | ||
206 | if (!page_flag_names[i]) | ||
207 | continue; | ||
208 | if ((flags >> i) & 1) | ||
209 | n += snprintf(buf + n, sizeof(buf) - n, "%s,", | ||
210 | page_flag_names[i] + 2); | ||
211 | } | ||
212 | if (n) | ||
213 | n--; | ||
214 | buf[n] = '\0'; | ||
215 | |||
216 | return buf; | ||
217 | } | ||
218 | |||
219 | |||
220 | /* | ||
221 | * page list and summary | ||
222 | */ | ||
223 | |||
224 | void show_page_range(unsigned long offset, uint64_t flags) | ||
225 | { | ||
226 | static uint64_t flags0; | ||
227 | static unsigned long index; | ||
228 | static unsigned long count; | ||
229 | |||
230 | if (flags == flags0 && offset == index + count) { | ||
231 | count++; | ||
232 | return; | ||
233 | } | ||
234 | |||
235 | if (count) | ||
236 | printf("%lu\t%lu\t%s\n", | ||
237 | index, count, page_flag_name(flags0)); | ||
238 | |||
239 | flags0 = flags; | ||
240 | index = offset; | ||
241 | count = 1; | ||
242 | } | ||
243 | |||
244 | void show_page(unsigned long offset, uint64_t flags) | ||
245 | { | ||
246 | printf("%lu\t%s\n", offset, page_flag_name(flags)); | ||
247 | } | ||
248 | |||
249 | void show_summary(void) | ||
250 | { | ||
251 | int i; | ||
252 | |||
253 | printf(" flags\tpage-count MB" | ||
254 | " symbolic-flags\t\t\tlong-symbolic-flags\n"); | ||
255 | |||
256 | for (i = 0; i < ARRAY_SIZE(nr_pages); i++) { | ||
257 | if (nr_pages[i]) | ||
258 | printf("0x%016llx\t%10lu %8lu %s\t%s\n", | ||
259 | (unsigned long long)page_flags[i], | ||
260 | nr_pages[i], | ||
261 | pages2mb(nr_pages[i]), | ||
262 | page_flag_name(page_flags[i]), | ||
263 | page_flag_longname(page_flags[i])); | ||
264 | } | ||
265 | |||
266 | printf(" total\t%10lu %8lu\n", | ||
267 | total_pages, pages2mb(total_pages)); | ||
268 | } | ||
269 | |||
270 | |||
271 | /* | ||
272 | * page flag filters | ||
273 | */ | ||
274 | |||
275 | int bit_mask_ok(uint64_t flags) | ||
276 | { | ||
277 | int i; | ||
278 | |||
279 | for (i = 0; i < nr_bit_filters; i++) { | ||
280 | if (opt_bits[i] == KPF_ALL_BITS) { | ||
281 | if ((flags & opt_mask[i]) == 0) | ||
282 | return 0; | ||
283 | } else { | ||
284 | if ((flags & opt_mask[i]) != opt_bits[i]) | ||
285 | return 0; | ||
286 | } | ||
287 | } | ||
288 | |||
289 | return 1; | ||
290 | } | ||
291 | |||
292 | uint64_t expand_overloaded_flags(uint64_t flags) | ||
293 | { | ||
294 | /* SLOB/SLUB overload several page flags */ | ||
295 | if (flags & BIT(SLAB)) { | ||
296 | if (flags & BIT(PRIVATE)) | ||
297 | flags ^= BIT(PRIVATE) | BIT(SLOB_FREE); | ||
298 | if (flags & BIT(ACTIVE)) | ||
299 | flags ^= BIT(ACTIVE) | BIT(SLUB_FROZEN); | ||
300 | if (flags & BIT(ERROR)) | ||
301 | flags ^= BIT(ERROR) | BIT(SLUB_DEBUG); | ||
302 | } | ||
303 | |||
304 | /* PG_reclaim is overloaded as PG_readahead in the read path */ | ||
305 | if ((flags & (BIT(RECLAIM) | BIT(WRITEBACK))) == BIT(RECLAIM)) | ||
306 | flags ^= BIT(RECLAIM) | BIT(READAHEAD); | ||
307 | |||
308 | return flags; | ||
309 | } | ||
310 | |||
311 | uint64_t well_known_flags(uint64_t flags) | ||
312 | { | ||
313 | /* hide flags intended only for kernel hacker */ | ||
314 | flags &= ~KPF_HACKERS_BITS; | ||
315 | |||
316 | /* hide non-hugeTLB compound pages */ | ||
317 | if ((flags & BITS_COMPOUND) && !(flags & BIT(HUGE))) | ||
318 | flags &= ~BITS_COMPOUND; | ||
319 | |||
320 | return flags; | ||
321 | } | ||
322 | |||
323 | |||
324 | /* | ||
325 | * page frame walker | ||
326 | */ | ||
327 | |||
328 | int hash_slot(uint64_t flags) | ||
329 | { | ||
330 | int k = HASH_KEY(flags); | ||
331 | int i; | ||
332 | |||
333 | /* Explicitly reserve slot 0 for flags 0: the following logic | ||
334 | * cannot distinguish an unoccupied slot from slot (flags==0). | ||
335 | */ | ||
336 | if (flags == 0) | ||
337 | return 0; | ||
338 | |||
339 | /* search through the remaining (HASH_SIZE-1) slots */ | ||
340 | for (i = 1; i < ARRAY_SIZE(page_flags); i++, k++) { | ||
341 | if (!k || k >= ARRAY_SIZE(page_flags)) | ||
342 | k = 1; | ||
343 | if (page_flags[k] == 0) { | ||
344 | page_flags[k] = flags; | ||
345 | return k; | ||
346 | } | ||
347 | if (page_flags[k] == flags) | ||
348 | return k; | ||
349 | } | ||
350 | |||
351 | fatal("hash table full: bump up HASH_SHIFT?\n"); | ||
352 | exit(EXIT_FAILURE); | ||
353 | } | ||
354 | |||
355 | void add_page(unsigned long offset, uint64_t flags) | ||
356 | { | ||
357 | flags = expand_overloaded_flags(flags); | ||
358 | |||
359 | if (!opt_raw) | ||
360 | flags = well_known_flags(flags); | ||
361 | |||
362 | if (!bit_mask_ok(flags)) | ||
363 | return; | ||
364 | |||
365 | if (opt_list == 1) | ||
366 | show_page_range(offset, flags); | ||
367 | else if (opt_list == 2) | ||
368 | show_page(offset, flags); | ||
369 | |||
370 | nr_pages[hash_slot(flags)]++; | ||
371 | total_pages++; | ||
372 | } | ||
373 | |||
374 | void walk_pfn(unsigned long index, unsigned long count) | ||
375 | { | ||
376 | unsigned long batch; | ||
377 | unsigned long n; | ||
378 | unsigned long i; | ||
379 | |||
380 | if (index > ULONG_MAX / KPF_BYTES) | ||
381 | fatal("index overflow: %lu\n", index); | ||
382 | |||
383 | lseek(kpageflags_fd, index * KPF_BYTES, SEEK_SET); | ||
384 | |||
385 | while (count) { | ||
386 | batch = min_t(unsigned long, count, PAGES_BATCH); | ||
387 | n = read(kpageflags_fd, kpageflags_buf, batch * KPF_BYTES); | ||
388 | if (n == 0) | ||
389 | break; | ||
390 | if (n < 0) { | ||
391 | perror(PROC_KPAGEFLAGS); | ||
392 | exit(EXIT_FAILURE); | ||
393 | } | ||
394 | |||
395 | if (n % KPF_BYTES != 0) | ||
396 | fatal("partial read: %lu bytes\n", n); | ||
397 | n = n / KPF_BYTES; | ||
398 | |||
399 | for (i = 0; i < n; i++) | ||
400 | add_page(index + i, kpageflags_buf[i]); | ||
401 | |||
402 | index += batch; | ||
403 | count -= batch; | ||
404 | } | ||
405 | } | ||
406 | |||
407 | void walk_addr_ranges(void) | ||
408 | { | ||
409 | int i; | ||
410 | |||
411 | kpageflags_fd = open(PROC_KPAGEFLAGS, O_RDONLY); | ||
412 | if (kpageflags_fd < 0) { | ||
413 | perror(PROC_KPAGEFLAGS); | ||
414 | exit(EXIT_FAILURE); | ||
415 | } | ||
416 | |||
417 | if (!nr_addr_ranges) | ||
418 | walk_pfn(0, ULONG_MAX); | ||
419 | |||
420 | for (i = 0; i < nr_addr_ranges; i++) | ||
421 | walk_pfn(opt_offset[i], opt_size[i]); | ||
422 | |||
423 | close(kpageflags_fd); | ||
424 | } | ||
425 | |||
426 | |||
427 | /* | ||
428 | * user interface | ||
429 | */ | ||
430 | |||
431 | const char *page_flag_type(uint64_t flag) | ||
432 | { | ||
433 | if (flag & KPF_HACKERS_BITS) | ||
434 | return "(r)"; | ||
435 | if (flag & KPF_OVERLOADED_BITS) | ||
436 | return "(o)"; | ||
437 | return " "; | ||
438 | } | ||
439 | |||
440 | void usage(void) | ||
441 | { | ||
442 | int i, j; | ||
443 | |||
444 | printf( | ||
445 | "page-types [options]\n" | ||
446 | " -r|--raw Raw mode, for kernel developers\n" | ||
447 | " -a|--addr addr-spec Walk a range of pages\n" | ||
448 | " -b|--bits bits-spec Walk pages with specified bits\n" | ||
449 | #if 0 /* planned features */ | ||
450 | " -p|--pid pid Walk process address space\n" | ||
451 | " -f|--file filename Walk file address space\n" | ||
452 | #endif | ||
453 | " -l|--list Show page details in ranges\n" | ||
454 | " -L|--list-each Show page details one by one\n" | ||
455 | " -N|--no-summary Don't show summay info\n" | ||
456 | " -h|--help Show this usage message\n" | ||
457 | "addr-spec:\n" | ||
458 | " N one page at offset N (unit: pages)\n" | ||
459 | " N+M pages range from N to N+M-1\n" | ||
460 | " N,M pages range from N to M-1\n" | ||
461 | " N, pages range from N to end\n" | ||
462 | " ,M pages range from 0 to M\n" | ||
463 | "bits-spec:\n" | ||
464 | " bit1,bit2 (flags & (bit1|bit2)) != 0\n" | ||
465 | " bit1,bit2=bit1 (flags & (bit1|bit2)) == bit1\n" | ||
466 | " bit1,~bit2 (flags & (bit1|bit2)) == bit1\n" | ||
467 | " =bit1,bit2 flags == (bit1|bit2)\n" | ||
468 | "bit-names:\n" | ||
469 | ); | ||
470 | |||
471 | for (i = 0, j = 0; i < ARRAY_SIZE(page_flag_names); i++) { | ||
472 | if (!page_flag_names[i]) | ||
473 | continue; | ||
474 | printf("%16s%s", page_flag_names[i] + 2, | ||
475 | page_flag_type(1ULL << i)); | ||
476 | if (++j > 3) { | ||
477 | j = 0; | ||
478 | putchar('\n'); | ||
479 | } | ||
480 | } | ||
481 | printf("\n " | ||
482 | "(r) raw mode bits (o) overloaded bits\n"); | ||
483 | } | ||
484 | |||
485 | unsigned long long parse_number(const char *str) | ||
486 | { | ||
487 | unsigned long long n; | ||
488 | |||
489 | n = strtoll(str, NULL, 0); | ||
490 | |||
491 | if (n == 0 && str[0] != '0') | ||
492 | fatal("invalid name or number: %s\n", str); | ||
493 | |||
494 | return n; | ||
495 | } | ||
496 | |||
497 | void parse_pid(const char *str) | ||
498 | { | ||
499 | opt_pid = parse_number(str); | ||
500 | } | ||
501 | |||
502 | void parse_file(const char *name) | ||
503 | { | ||
504 | } | ||
505 | |||
506 | void add_addr_range(unsigned long offset, unsigned long size) | ||
507 | { | ||
508 | if (nr_addr_ranges >= MAX_ADDR_RANGES) | ||
509 | fatal("too much addr ranges\n"); | ||
510 | |||
511 | opt_offset[nr_addr_ranges] = offset; | ||
512 | opt_size[nr_addr_ranges] = size; | ||
513 | nr_addr_ranges++; | ||
514 | } | ||
515 | |||
516 | void parse_addr_range(const char *optarg) | ||
517 | { | ||
518 | unsigned long offset; | ||
519 | unsigned long size; | ||
520 | char *p; | ||
521 | |||
522 | p = strchr(optarg, ','); | ||
523 | if (!p) | ||
524 | p = strchr(optarg, '+'); | ||
525 | |||
526 | if (p == optarg) { | ||
527 | offset = 0; | ||
528 | size = parse_number(p + 1); | ||
529 | } else if (p) { | ||
530 | offset = parse_number(optarg); | ||
531 | if (p[1] == '\0') | ||
532 | size = ULONG_MAX; | ||
533 | else { | ||
534 | size = parse_number(p + 1); | ||
535 | if (*p == ',') { | ||
536 | if (size < offset) | ||
537 | fatal("invalid range: %lu,%lu\n", | ||
538 | offset, size); | ||
539 | size -= offset; | ||
540 | } | ||
541 | } | ||
542 | } else { | ||
543 | offset = parse_number(optarg); | ||
544 | size = 1; | ||
545 | } | ||
546 | |||
547 | add_addr_range(offset, size); | ||
548 | } | ||
549 | |||
550 | void add_bits_filter(uint64_t mask, uint64_t bits) | ||
551 | { | ||
552 | if (nr_bit_filters >= MAX_BIT_FILTERS) | ||
553 | fatal("too much bit filters\n"); | ||
554 | |||
555 | opt_mask[nr_bit_filters] = mask; | ||
556 | opt_bits[nr_bit_filters] = bits; | ||
557 | nr_bit_filters++; | ||
558 | } | ||
559 | |||
560 | uint64_t parse_flag_name(const char *str, int len) | ||
561 | { | ||
562 | int i; | ||
563 | |||
564 | if (!*str || !len) | ||
565 | return 0; | ||
566 | |||
567 | if (len <= 8 && !strncmp(str, "compound", len)) | ||
568 | return BITS_COMPOUND; | ||
569 | |||
570 | for (i = 0; i < ARRAY_SIZE(page_flag_names); i++) { | ||
571 | if (!page_flag_names[i]) | ||
572 | continue; | ||
573 | if (!strncmp(str, page_flag_names[i] + 2, len)) | ||
574 | return 1ULL << i; | ||
575 | } | ||
576 | |||
577 | return parse_number(str); | ||
578 | } | ||
579 | |||
580 | uint64_t parse_flag_names(const char *str, int all) | ||
581 | { | ||
582 | const char *p = str; | ||
583 | uint64_t flags = 0; | ||
584 | |||
585 | while (1) { | ||
586 | if (*p == ',' || *p == '=' || *p == '\0') { | ||
587 | if ((*str != '~') || (*str == '~' && all && *++str)) | ||
588 | flags |= parse_flag_name(str, p - str); | ||
589 | if (*p != ',') | ||
590 | break; | ||
591 | str = p + 1; | ||
592 | } | ||
593 | p++; | ||
594 | } | ||
595 | |||
596 | return flags; | ||
597 | } | ||
598 | |||
599 | void parse_bits_mask(const char *optarg) | ||
600 | { | ||
601 | uint64_t mask; | ||
602 | uint64_t bits; | ||
603 | const char *p; | ||
604 | |||
605 | p = strchr(optarg, '='); | ||
606 | if (p == optarg) { | ||
607 | mask = KPF_ALL_BITS; | ||
608 | bits = parse_flag_names(p + 1, 0); | ||
609 | } else if (p) { | ||
610 | mask = parse_flag_names(optarg, 0); | ||
611 | bits = parse_flag_names(p + 1, 0); | ||
612 | } else if (strchr(optarg, '~')) { | ||
613 | mask = parse_flag_names(optarg, 1); | ||
614 | bits = parse_flag_names(optarg, 0); | ||
615 | } else { | ||
616 | mask = parse_flag_names(optarg, 0); | ||
617 | bits = KPF_ALL_BITS; | ||
618 | } | ||
619 | |||
620 | add_bits_filter(mask, bits); | ||
621 | } | ||
622 | |||
623 | |||
624 | struct option opts[] = { | ||
625 | { "raw" , 0, NULL, 'r' }, | ||
626 | { "pid" , 1, NULL, 'p' }, | ||
627 | { "file" , 1, NULL, 'f' }, | ||
628 | { "addr" , 1, NULL, 'a' }, | ||
629 | { "bits" , 1, NULL, 'b' }, | ||
630 | { "list" , 0, NULL, 'l' }, | ||
631 | { "list-each" , 0, NULL, 'L' }, | ||
632 | { "no-summary", 0, NULL, 'N' }, | ||
633 | { "help" , 0, NULL, 'h' }, | ||
634 | { NULL , 0, NULL, 0 } | ||
635 | }; | ||
636 | |||
637 | int main(int argc, char *argv[]) | ||
638 | { | ||
639 | int c; | ||
640 | |||
641 | page_size = getpagesize(); | ||
642 | |||
643 | while ((c = getopt_long(argc, argv, | ||
644 | "rp:f:a:b:lLNh", opts, NULL)) != -1) { | ||
645 | switch (c) { | ||
646 | case 'r': | ||
647 | opt_raw = 1; | ||
648 | break; | ||
649 | case 'p': | ||
650 | parse_pid(optarg); | ||
651 | break; | ||
652 | case 'f': | ||
653 | parse_file(optarg); | ||
654 | break; | ||
655 | case 'a': | ||
656 | parse_addr_range(optarg); | ||
657 | break; | ||
658 | case 'b': | ||
659 | parse_bits_mask(optarg); | ||
660 | break; | ||
661 | case 'l': | ||
662 | opt_list = 1; | ||
663 | break; | ||
664 | case 'L': | ||
665 | opt_list = 2; | ||
666 | break; | ||
667 | case 'N': | ||
668 | opt_no_summary = 1; | ||
669 | break; | ||
670 | case 'h': | ||
671 | usage(); | ||
672 | exit(0); | ||
673 | default: | ||
674 | usage(); | ||
675 | exit(1); | ||
676 | } | ||
677 | } | ||
678 | |||
679 | if (opt_list == 1) | ||
680 | printf("offset\tcount\tflags\n"); | ||
681 | if (opt_list == 2) | ||
682 | printf("offset\tflags\n"); | ||
683 | |||
684 | walk_addr_ranges(); | ||
685 | |||
686 | if (opt_list == 1) | ||
687 | show_page_range(0, 0); /* drain the buffer */ | ||
688 | |||
689 | if (opt_no_summary) | ||
690 | return 0; | ||
691 | |||
692 | if (opt_list) | ||
693 | printf("\n\n"); | ||
694 | |||
695 | show_summary(); | ||
696 | |||
697 | return 0; | ||
698 | } | ||
diff --git a/Documentation/vm/pagemap.txt b/Documentation/vm/pagemap.txt index ce72c0fe6177..600a304a828c 100644 --- a/Documentation/vm/pagemap.txt +++ b/Documentation/vm/pagemap.txt | |||
@@ -12,9 +12,9 @@ There are three components to pagemap: | |||
12 | value for each virtual page, containing the following data (from | 12 | value for each virtual page, containing the following data (from |
13 | fs/proc/task_mmu.c, above pagemap_read): | 13 | fs/proc/task_mmu.c, above pagemap_read): |
14 | 14 | ||
15 | * Bits 0-55 page frame number (PFN) if present | 15 | * Bits 0-54 page frame number (PFN) if present |
16 | * Bits 0-4 swap type if swapped | 16 | * Bits 0-4 swap type if swapped |
17 | * Bits 5-55 swap offset if swapped | 17 | * Bits 5-54 swap offset if swapped |
18 | * Bits 55-60 page shift (page size = 1<<page shift) | 18 | * Bits 55-60 page shift (page size = 1<<page shift) |
19 | * Bit 61 reserved for future use | 19 | * Bit 61 reserved for future use |
20 | * Bit 62 page swapped | 20 | * Bit 62 page swapped |
@@ -36,7 +36,7 @@ There are three components to pagemap: | |||
36 | * /proc/kpageflags. This file contains a 64-bit set of flags for each | 36 | * /proc/kpageflags. This file contains a 64-bit set of flags for each |
37 | page, indexed by PFN. | 37 | page, indexed by PFN. |
38 | 38 | ||
39 | The flags are (from fs/proc/proc_misc, above kpageflags_read): | 39 | The flags are (from fs/proc/page.c, above kpageflags_read): |
40 | 40 | ||
41 | 0. LOCKED | 41 | 0. LOCKED |
42 | 1. ERROR | 42 | 1. ERROR |
@@ -49,6 +49,68 @@ There are three components to pagemap: | |||
49 | 8. WRITEBACK | 49 | 8. WRITEBACK |
50 | 9. RECLAIM | 50 | 9. RECLAIM |
51 | 10. BUDDY | 51 | 10. BUDDY |
52 | 11. MMAP | ||
53 | 12. ANON | ||
54 | 13. SWAPCACHE | ||
55 | 14. SWAPBACKED | ||
56 | 15. COMPOUND_HEAD | ||
57 | 16. COMPOUND_TAIL | ||
58 | 16. HUGE | ||
59 | 18. UNEVICTABLE | ||
60 | 20. NOPAGE | ||
61 | |||
62 | Short descriptions to the page flags: | ||
63 | |||
64 | 0. LOCKED | ||
65 | page is being locked for exclusive access, eg. by undergoing read/write IO | ||
66 | |||
67 | 7. SLAB | ||
68 | page is managed by the SLAB/SLOB/SLUB/SLQB kernel memory allocator | ||
69 | When compound page is used, SLUB/SLQB will only set this flag on the head | ||
70 | page; SLOB will not flag it at all. | ||
71 | |||
72 | 10. BUDDY | ||
73 | a free memory block managed by the buddy system allocator | ||
74 | The buddy system organizes free memory in blocks of various orders. | ||
75 | An order N block has 2^N physically contiguous pages, with the BUDDY flag | ||
76 | set for and _only_ for the first page. | ||
77 | |||
78 | 15. COMPOUND_HEAD | ||
79 | 16. COMPOUND_TAIL | ||
80 | A compound page with order N consists of 2^N physically contiguous pages. | ||
81 | A compound page with order 2 takes the form of "HTTT", where H donates its | ||
82 | head page and T donates its tail page(s). The major consumers of compound | ||
83 | pages are hugeTLB pages (Documentation/vm/hugetlbpage.txt), the SLUB etc. | ||
84 | memory allocators and various device drivers. However in this interface, | ||
85 | only huge/giga pages are made visible to end users. | ||
86 | 17. HUGE | ||
87 | this is an integral part of a HugeTLB page | ||
88 | |||
89 | 20. NOPAGE | ||
90 | no page frame exists at the requested address | ||
91 | |||
92 | [IO related page flags] | ||
93 | 1. ERROR IO error occurred | ||
94 | 3. UPTODATE page has up-to-date data | ||
95 | ie. for file backed page: (in-memory data revision >= on-disk one) | ||
96 | 4. DIRTY page has been written to, hence contains new data | ||
97 | ie. for file backed page: (in-memory data revision > on-disk one) | ||
98 | 8. WRITEBACK page is being synced to disk | ||
99 | |||
100 | [LRU related page flags] | ||
101 | 5. LRU page is in one of the LRU lists | ||
102 | 6. ACTIVE page is in the active LRU list | ||
103 | 18. UNEVICTABLE page is in the unevictable (non-)LRU list | ||
104 | It is somehow pinned and not a candidate for LRU page reclaims, | ||
105 | eg. ramfs pages, shmctl(SHM_LOCK) and mlock() memory segments | ||
106 | 2. REFERENCED page has been referenced since last LRU list enqueue/requeue | ||
107 | 9. RECLAIM page will be reclaimed soon after its pageout IO completed | ||
108 | 11. MMAP a memory mapped page | ||
109 | 12. ANON a memory mapped page that is not part of a file | ||
110 | 13. SWAPCACHE page is mapped to swap space, ie. has an associated swap entry | ||
111 | 14. SWAPBACKED page is backed by swap/RAM | ||
112 | |||
113 | The page-types tool in this directory can be used to query the above flags. | ||
52 | 114 | ||
53 | Using pagemap to do something useful: | 115 | Using pagemap to do something useful: |
54 | 116 | ||
diff --git a/MAINTAINERS b/MAINTAINERS index af8ef6527f22..fb94addb34de 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -36,6 +36,12 @@ trivial patch so apply some common sense. | |||
36 | (scripts/checkpatch.pl) to catch trival style violations. | 36 | (scripts/checkpatch.pl) to catch trival style violations. |
37 | See Documentation/CodingStyle for guidance here. | 37 | See Documentation/CodingStyle for guidance here. |
38 | 38 | ||
39 | PLEASE CC: the maintainers and mailing lists that are generated | ||
40 | by scripts/get_maintainer.pl. The results returned by the | ||
41 | script will be best if you have git installed and are making | ||
42 | your changes in a branch derived from Linus' latest git tree. | ||
43 | See Documentation/SubmittingPatches for details. | ||
44 | |||
39 | PLEASE try to include any credit lines you want added with the | 45 | PLEASE try to include any credit lines you want added with the |
40 | patch. It avoids people being missed off by mistake and makes | 46 | patch. It avoids people being missed off by mistake and makes |
41 | it easier to know who wants adding and who doesn't. | 47 | it easier to know who wants adding and who doesn't. |
@@ -489,7 +495,7 @@ AOA (Apple Onboard Audio) ALSA DRIVER | |||
489 | P: Johannes Berg | 495 | P: Johannes Berg |
490 | M: johannes@sipsolutions.net | 496 | M: johannes@sipsolutions.net |
491 | L: linuxppc-dev@ozlabs.org | 497 | L: linuxppc-dev@ozlabs.org |
492 | L: alsa-devel@alsa-project.org (subscribers-only) | 498 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) |
493 | S: Maintained | 499 | S: Maintained |
494 | F: sound/aoa/ | 500 | F: sound/aoa/ |
495 | 501 | ||
@@ -912,7 +918,6 @@ P: Dan Williams | |||
912 | M: dan.j.williams@intel.com | 918 | M: dan.j.williams@intel.com |
913 | P: Maciej Sosnowski | 919 | P: Maciej Sosnowski |
914 | M: maciej.sosnowski@intel.com | 920 | M: maciej.sosnowski@intel.com |
915 | L: linux-kernel@vger.kernel.org | ||
916 | W: http://sourceforge.net/projects/xscaleiop | 921 | W: http://sourceforge.net/projects/xscaleiop |
917 | S: Supported | 922 | S: Supported |
918 | F: Documentation/crypto/async-tx-api.txt | 923 | F: Documentation/crypto/async-tx-api.txt |
@@ -1008,7 +1013,6 @@ F: drivers/mmc/host/at91_mci.c | |||
1008 | ATMEL AT91 / AT32 SERIAL DRIVER | 1013 | ATMEL AT91 / AT32 SERIAL DRIVER |
1009 | P: Haavard Skinnemoen | 1014 | P: Haavard Skinnemoen |
1010 | M: hskinnemoen@atmel.com | 1015 | M: hskinnemoen@atmel.com |
1011 | L: linux-kernel@vger.kernel.org | ||
1012 | S: Supported | 1016 | S: Supported |
1013 | F: drivers/serial/atmel_serial.c | 1017 | F: drivers/serial/atmel_serial.c |
1014 | 1018 | ||
@@ -1064,7 +1068,6 @@ F: kernel/audit* | |||
1064 | AUXILIARY DISPLAY DRIVERS | 1068 | AUXILIARY DISPLAY DRIVERS |
1065 | P: Miguel Ojeda Sandonis | 1069 | P: Miguel Ojeda Sandonis |
1066 | M: miguel.ojeda.sandonis@gmail.com | 1070 | M: miguel.ojeda.sandonis@gmail.com |
1067 | L: linux-kernel@vger.kernel.org | ||
1068 | W: http://miguelojeda.es/auxdisplay.htm | 1071 | W: http://miguelojeda.es/auxdisplay.htm |
1069 | W: http://jair.lab.fi.uva.es/~migojed/auxdisplay.htm | 1072 | W: http://jair.lab.fi.uva.es/~migojed/auxdisplay.htm |
1070 | S: Maintained | 1073 | S: Maintained |
@@ -1134,7 +1137,6 @@ F: drivers/net/hamradio/baycom* | |||
1134 | BEFS FILE SYSTEM | 1137 | BEFS FILE SYSTEM |
1135 | P: Sergey S. Kostyliov | 1138 | P: Sergey S. Kostyliov |
1136 | M: rathamahata@php4.ru | 1139 | M: rathamahata@php4.ru |
1137 | L: linux-kernel@vger.kernel.org | ||
1138 | S: Maintained | 1140 | S: Maintained |
1139 | F: Documentation/filesystems/befs.txt | 1141 | F: Documentation/filesystems/befs.txt |
1140 | F: fs/befs/ | 1142 | F: fs/befs/ |
@@ -1142,7 +1144,6 @@ F: fs/befs/ | |||
1142 | BFS FILE SYSTEM | 1144 | BFS FILE SYSTEM |
1143 | P: Tigran A. Aivazian | 1145 | P: Tigran A. Aivazian |
1144 | M: tigran@aivazian.fsnet.co.uk | 1146 | M: tigran@aivazian.fsnet.co.uk |
1145 | L: linux-kernel@vger.kernel.org | ||
1146 | S: Maintained | 1147 | S: Maintained |
1147 | F: Documentation/filesystems/bfs.txt | 1148 | F: Documentation/filesystems/bfs.txt |
1148 | F: fs/bfs/ | 1149 | F: fs/bfs/ |
@@ -1199,7 +1200,6 @@ F: drivers/i2c/busses/i2c-bfin-twi.c | |||
1199 | BLOCK LAYER | 1200 | BLOCK LAYER |
1200 | P: Jens Axboe | 1201 | P: Jens Axboe |
1201 | M: axboe@kernel.dk | 1202 | M: axboe@kernel.dk |
1202 | L: linux-kernel@vger.kernel.org | ||
1203 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-2.6-block.git | 1203 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-2.6-block.git |
1204 | S: Maintained | 1204 | S: Maintained |
1205 | F: block/ | 1205 | F: block/ |
@@ -1326,7 +1326,6 @@ P: Muli Ben-Yehuda | |||
1326 | M: muli@il.ibm.com | 1326 | M: muli@il.ibm.com |
1327 | P: Jon D. Mason | 1327 | P: Jon D. Mason |
1328 | M: jdmason@kudzu.us | 1328 | M: jdmason@kudzu.us |
1329 | L: linux-kernel@vger.kernel.org | ||
1330 | L: discuss@x86-64.org | 1329 | L: discuss@x86-64.org |
1331 | S: Maintained | 1330 | S: Maintained |
1332 | F: arch/x86/kernel/pci-calgary_64.c | 1331 | F: arch/x86/kernel/pci-calgary_64.c |
@@ -1378,7 +1377,6 @@ F: include/linux/usb/wusb* | |||
1378 | CFAG12864B LCD DRIVER | 1377 | CFAG12864B LCD DRIVER |
1379 | P: Miguel Ojeda Sandonis | 1378 | P: Miguel Ojeda Sandonis |
1380 | M: miguel.ojeda.sandonis@gmail.com | 1379 | M: miguel.ojeda.sandonis@gmail.com |
1381 | L: linux-kernel@vger.kernel.org | ||
1382 | W: http://miguelojeda.es/auxdisplay.htm | 1380 | W: http://miguelojeda.es/auxdisplay.htm |
1383 | W: http://jair.lab.fi.uva.es/~migojed/auxdisplay.htm | 1381 | W: http://jair.lab.fi.uva.es/~migojed/auxdisplay.htm |
1384 | S: Maintained | 1382 | S: Maintained |
@@ -1388,7 +1386,6 @@ F: include/linux/cfag12864b.h | |||
1388 | CFAG12864BFB LCD FRAMEBUFFER DRIVER | 1386 | CFAG12864BFB LCD FRAMEBUFFER DRIVER |
1389 | P: Miguel Ojeda Sandonis | 1387 | P: Miguel Ojeda Sandonis |
1390 | M: miguel.ojeda.sandonis@gmail.com | 1388 | M: miguel.ojeda.sandonis@gmail.com |
1391 | L: linux-kernel@vger.kernel.org | ||
1392 | W: http://miguelojeda.es/auxdisplay.htm | 1389 | W: http://miguelojeda.es/auxdisplay.htm |
1393 | W: http://jair.lab.fi.uva.es/~migojed/auxdisplay.htm | 1390 | W: http://jair.lab.fi.uva.es/~migojed/auxdisplay.htm |
1394 | S: Maintained | 1391 | S: Maintained |
@@ -1408,7 +1405,6 @@ X: net/wireless/wext* | |||
1408 | CHECKPATCH | 1405 | CHECKPATCH |
1409 | P: Andy Whitcroft | 1406 | P: Andy Whitcroft |
1410 | M: apw@canonical.com | 1407 | M: apw@canonical.com |
1411 | L: linux-kernel@vger.kernel.org | ||
1412 | S: Supported | 1408 | S: Supported |
1413 | F: scripts/checkpatch.pl | 1409 | F: scripts/checkpatch.pl |
1414 | 1410 | ||
@@ -1437,7 +1433,7 @@ F: drivers/usb/host/ohci-ep93xx.c | |||
1437 | CIRRUS LOGIC CS4270 SOUND DRIVER | 1433 | CIRRUS LOGIC CS4270 SOUND DRIVER |
1438 | P: Timur Tabi | 1434 | P: Timur Tabi |
1439 | M: timur@freescale.com | 1435 | M: timur@freescale.com |
1440 | L: alsa-devel@alsa-project.org | 1436 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) |
1441 | S: Supported | 1437 | S: Supported |
1442 | F: sound/soc/codecs/cs4270* | 1438 | F: sound/soc/codecs/cs4270* |
1443 | 1439 | ||
@@ -1462,6 +1458,7 @@ P: Joe Eykholt | |||
1462 | M: jeykholt@cisco.com | 1458 | M: jeykholt@cisco.com |
1463 | L: linux-scsi@vger.kernel.org | 1459 | L: linux-scsi@vger.kernel.org |
1464 | S: Supported | 1460 | S: Supported |
1461 | F: drivers/scsi/fnic/ | ||
1465 | 1462 | ||
1466 | CODA FILE SYSTEM | 1463 | CODA FILE SYSTEM |
1467 | P: Jan Harkes | 1464 | P: Jan Harkes |
@@ -1534,7 +1531,6 @@ F: drivers/usb/atm/cxacru.c | |||
1534 | CONFIGFS | 1531 | CONFIGFS |
1535 | P: Joel Becker | 1532 | P: Joel Becker |
1536 | M: joel.becker@oracle.com | 1533 | M: joel.becker@oracle.com |
1537 | L: linux-kernel@vger.kernel.org | ||
1538 | S: Supported | 1534 | S: Supported |
1539 | F: fs/configfs/ | 1535 | F: fs/configfs/ |
1540 | F: include/linux/configfs.h | 1536 | F: include/linux/configfs.h |
@@ -1592,7 +1588,6 @@ F: arch/x86/kernel/msr.c | |||
1592 | CPUSETS | 1588 | CPUSETS |
1593 | P: Paul Menage | 1589 | P: Paul Menage |
1594 | M: menage@google.com | 1590 | M: menage@google.com |
1595 | L: linux-kernel@vger.kernel.org | ||
1596 | W: http://www.bullopensource.org/cpuset/ | 1591 | W: http://www.bullopensource.org/cpuset/ |
1597 | W: http://oss.sgi.com/projects/cpusets/ | 1592 | W: http://oss.sgi.com/projects/cpusets/ |
1598 | S: Supported | 1593 | S: Supported |
@@ -1799,7 +1794,6 @@ DEVICE NUMBER REGISTRY | |||
1799 | P: Torben Mathiasen | 1794 | P: Torben Mathiasen |
1800 | M: device@lanana.org | 1795 | M: device@lanana.org |
1801 | W: http://lanana.org/docs/device-list/index.html | 1796 | W: http://lanana.org/docs/device-list/index.html |
1802 | L: linux-kernel@vger.kernel.org | ||
1803 | S: Maintained | 1797 | S: Maintained |
1804 | 1798 | ||
1805 | DEVICE-MAPPER (LVM) | 1799 | DEVICE-MAPPER (LVM) |
@@ -1825,7 +1819,6 @@ F: drivers/char/digi* | |||
1825 | DIRECTORY NOTIFICATION (DNOTIFY) | 1819 | DIRECTORY NOTIFICATION (DNOTIFY) |
1826 | P: Eric Paris | 1820 | P: Eric Paris |
1827 | M: eparis@parisplace.org | 1821 | M: eparis@parisplace.org |
1828 | L: linux-kernel@vger.kernel.org | ||
1829 | S: Maintained | 1822 | S: Maintained |
1830 | F: Documentation/filesystems/dnotify.txt | 1823 | F: Documentation/filesystems/dnotify.txt |
1831 | F: fs/notify/dnotify/ | 1824 | F: fs/notify/dnotify/ |
@@ -1842,7 +1835,6 @@ S: Maintained | |||
1842 | DISKQUOTA | 1835 | DISKQUOTA |
1843 | P: Jan Kara | 1836 | P: Jan Kara |
1844 | M: jack@suse.cz | 1837 | M: jack@suse.cz |
1845 | L: linux-kernel@vger.kernel.org | ||
1846 | S: Maintained | 1838 | S: Maintained |
1847 | F: Documentation/filesystems/quota.txt | 1839 | F: Documentation/filesystems/quota.txt |
1848 | F: fs/quota/ | 1840 | F: fs/quota/ |
@@ -1864,7 +1856,6 @@ P: Maciej Sosnowski | |||
1864 | M: maciej.sosnowski@intel.com | 1856 | M: maciej.sosnowski@intel.com |
1865 | P: Dan Williams | 1857 | P: Dan Williams |
1866 | M: dan.j.williams@intel.com | 1858 | M: dan.j.williams@intel.com |
1867 | L: linux-kernel@vger.kernel.org | ||
1868 | S: Supported | 1859 | S: Supported |
1869 | F: drivers/dma/ | 1860 | F: drivers/dma/ |
1870 | F: include/linux/dma* | 1861 | F: include/linux/dma* |
@@ -1916,7 +1907,6 @@ F: drivers/scsi/dpt/ | |||
1916 | DRIVER CORE, KOBJECTS, AND SYSFS | 1907 | DRIVER CORE, KOBJECTS, AND SYSFS |
1917 | P: Greg Kroah-Hartman | 1908 | P: Greg Kroah-Hartman |
1918 | M: gregkh@suse.de | 1909 | M: gregkh@suse.de |
1919 | L: linux-kernel@vger.kernel.org | ||
1920 | T: quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/ | 1910 | T: quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/ |
1921 | S: Supported | 1911 | S: Supported |
1922 | F: Documentation/kobject.txt | 1912 | F: Documentation/kobject.txt |
@@ -1982,8 +1972,8 @@ F: net/bridge/netfilter/ebt*.c | |||
1982 | ECRYPT FILE SYSTEM | 1972 | ECRYPT FILE SYSTEM |
1983 | P: Tyler Hicks | 1973 | P: Tyler Hicks |
1984 | M: tyhicks@linux.vnet.ibm.com | 1974 | M: tyhicks@linux.vnet.ibm.com |
1985 | M: Dustin Kirkland | 1975 | P: Dustin Kirkland |
1986 | P: kirkland@canonical.com | 1976 | M: kirkland@canonical.com |
1987 | L: ecryptfs-devel@lists.launchpad.net | 1977 | L: ecryptfs-devel@lists.launchpad.net |
1988 | W: https://launchpad.net/ecryptfs | 1978 | W: https://launchpad.net/ecryptfs |
1989 | S: Supported | 1979 | S: Supported |
@@ -2263,7 +2253,6 @@ F: drivers/firewire/ | |||
2263 | F: include/linux/firewire*.h | 2253 | F: include/linux/firewire*.h |
2264 | 2254 | ||
2265 | FIRMWARE LOADER (request_firmware) | 2255 | FIRMWARE LOADER (request_firmware) |
2266 | L: linux-kernel@vger.kernel.org | ||
2267 | S: Orphan | 2256 | S: Orphan |
2268 | F: Documentation/firmware_class/ | 2257 | F: Documentation/firmware_class/ |
2269 | F: drivers/base/firmware*.c | 2258 | F: drivers/base/firmware*.c |
@@ -2300,7 +2289,6 @@ M: leoli@freescale.com | |||
2300 | P: Zhang Wei | 2289 | P: Zhang Wei |
2301 | M: zw@zh-kernel.org | 2290 | M: zw@zh-kernel.org |
2302 | L: linuxppc-dev@ozlabs.org | 2291 | L: linuxppc-dev@ozlabs.org |
2303 | L: linux-kernel@vger.kernel.org | ||
2304 | S: Maintained | 2292 | S: Maintained |
2305 | F: drivers/dma/fsldma.* | 2293 | F: drivers/dma/fsldma.* |
2306 | 2294 | ||
@@ -2366,7 +2354,7 @@ F: drivers/serial/ucc_uart.c | |||
2366 | FREESCALE SOC SOUND DRIVERS | 2354 | FREESCALE SOC SOUND DRIVERS |
2367 | P: Timur Tabi | 2355 | P: Timur Tabi |
2368 | M: timur@freescale.com | 2356 | M: timur@freescale.com |
2369 | L: alsa-devel@alsa-project.org | 2357 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) |
2370 | L: linuxppc-dev@ozlabs.org | 2358 | L: linuxppc-dev@ozlabs.org |
2371 | S: Supported | 2359 | S: Supported |
2372 | F: sound/soc/fsl/fsl* | 2360 | F: sound/soc/fsl/fsl* |
@@ -2500,7 +2488,6 @@ F: drivers/hwmon/hdaps.c | |||
2500 | 2488 | ||
2501 | HYPERVISOR VIRTUAL CONSOLE DRIVER | 2489 | HYPERVISOR VIRTUAL CONSOLE DRIVER |
2502 | L: linuxppc-dev@ozlabs.org | 2490 | L: linuxppc-dev@ozlabs.org |
2503 | L: linux-kernel@vger.kernel.org | ||
2504 | S: Odd Fixes | 2491 | S: Odd Fixes |
2505 | F: drivers/char/hvc_* | 2492 | F: drivers/char/hvc_* |
2506 | 2493 | ||
@@ -2567,7 +2554,6 @@ F: sound/parisc/harmony.* | |||
2567 | HAYES ESP SERIAL DRIVER | 2554 | HAYES ESP SERIAL DRIVER |
2568 | P: Andrew J. Robinson | 2555 | P: Andrew J. Robinson |
2569 | M: arobinso@nyx.net | 2556 | M: arobinso@nyx.net |
2570 | L: linux-kernel@vger.kernel.org | ||
2571 | W: http://www.nyx.net/~arobinso | 2557 | W: http://www.nyx.net/~arobinso |
2572 | S: Maintained | 2558 | S: Maintained |
2573 | F: Documentation/serial/hayes-esp.txt | 2559 | F: Documentation/serial/hayes-esp.txt |
@@ -2593,7 +2579,6 @@ F: include/linux/cciss_ioctl.h | |||
2593 | HFS FILESYSTEM | 2579 | HFS FILESYSTEM |
2594 | P: Roman Zippel | 2580 | P: Roman Zippel |
2595 | M: zippel@linux-m68k.org | 2581 | M: zippel@linux-m68k.org |
2596 | L: linux-kernel@vger.kernel.org | ||
2597 | S: Maintained | 2582 | S: Maintained |
2598 | F: Documentation/filesystems/hfs.txt | 2583 | F: Documentation/filesystems/hfs.txt |
2599 | F: fs/hfs/ | 2584 | F: fs/hfs/ |
@@ -2633,7 +2618,6 @@ F: include/linux/hid* | |||
2633 | HIGH-RESOLUTION TIMERS, CLOCKEVENTS, DYNTICKS | 2618 | HIGH-RESOLUTION TIMERS, CLOCKEVENTS, DYNTICKS |
2634 | P: Thomas Gleixner | 2619 | P: Thomas Gleixner |
2635 | M: tglx@linutronix.de | 2620 | M: tglx@linutronix.de |
2636 | L: linux-kernel@vger.kernel.org | ||
2637 | S: Maintained | 2621 | S: Maintained |
2638 | F: Documentation/timers/ | 2622 | F: Documentation/timers/ |
2639 | F: kernel/hrtimer.c | 2623 | F: kernel/hrtimer.c |
@@ -2772,7 +2756,6 @@ F: drivers/i2c/busses/i2c-tiny-usb.c | |||
2772 | i386 BOOT CODE | 2756 | i386 BOOT CODE |
2773 | P: H. Peter Anvin | 2757 | P: H. Peter Anvin |
2774 | M: hpa@zytor.com | 2758 | M: hpa@zytor.com |
2775 | L: Linux-Kernel@vger.kernel.org | ||
2776 | S: Maintained | 2759 | S: Maintained |
2777 | F: arch/x86/boot/ | 2760 | F: arch/x86/boot/ |
2778 | 2761 | ||
@@ -2902,7 +2885,6 @@ P: Robert Love | |||
2902 | M: rlove@rlove.org | 2885 | M: rlove@rlove.org |
2903 | P: Eric Paris | 2886 | P: Eric Paris |
2904 | M: eparis@parisplace.org | 2887 | M: eparis@parisplace.org |
2905 | L: linux-kernel@vger.kernel.org | ||
2906 | S: Maintained | 2888 | S: Maintained |
2907 | F: Documentation/filesystems/inotify.txt | 2889 | F: Documentation/filesystems/inotify.txt |
2908 | F: fs/notify/inotify/ | 2890 | F: fs/notify/inotify/ |
@@ -2950,7 +2932,6 @@ F: arch/x86/kernel/microcode_intel.c | |||
2950 | INTEL I/OAT DMA DRIVER | 2932 | INTEL I/OAT DMA DRIVER |
2951 | P: Maciej Sosnowski | 2933 | P: Maciej Sosnowski |
2952 | M: maciej.sosnowski@intel.com | 2934 | M: maciej.sosnowski@intel.com |
2953 | L: linux-kernel@vger.kernel.org | ||
2954 | S: Supported | 2935 | S: Supported |
2955 | F: drivers/dma/ioat* | 2936 | F: drivers/dma/ioat* |
2956 | 2937 | ||
@@ -2966,7 +2947,6 @@ F: include/linux/intel-iommu.h | |||
2966 | INTEL IOP-ADMA DMA DRIVER | 2947 | INTEL IOP-ADMA DMA DRIVER |
2967 | P: Dan Williams | 2948 | P: Dan Williams |
2968 | M: dan.j.williams@intel.com | 2949 | M: dan.j.williams@intel.com |
2969 | L: linux-kernel@vger.kernel.org | ||
2970 | S: Supported | 2950 | S: Supported |
2971 | F: drivers/dma/iop-adma.c | 2951 | F: drivers/dma/iop-adma.c |
2972 | 2952 | ||
@@ -3279,7 +3259,6 @@ M: vgoyal@redhat.com | |||
3279 | P: Haren Myneni | 3259 | P: Haren Myneni |
3280 | M: hbabu@us.ibm.com | 3260 | M: hbabu@us.ibm.com |
3281 | L: kexec@lists.infradead.org | 3261 | L: kexec@lists.infradead.org |
3282 | L: linux-kernel@vger.kernel.org | ||
3283 | W: http://lse.sourceforge.net/kdump/ | 3262 | W: http://lse.sourceforge.net/kdump/ |
3284 | S: Maintained | 3263 | S: Maintained |
3285 | F: Documentation/kdump/ | 3264 | F: Documentation/kdump/ |
@@ -3389,7 +3368,6 @@ KEXEC | |||
3389 | P: Eric Biederman | 3368 | P: Eric Biederman |
3390 | M: ebiederm@xmission.com | 3369 | M: ebiederm@xmission.com |
3391 | W: http://ftp.kernel.org/pub/linux/kernel/people/horms/kexec-tools/ | 3370 | W: http://ftp.kernel.org/pub/linux/kernel/people/horms/kexec-tools/ |
3392 | L: linux-kernel@vger.kernel.org | ||
3393 | L: kexec@lists.infradead.org | 3371 | L: kexec@lists.infradead.org |
3394 | S: Maintained | 3372 | S: Maintained |
3395 | F: include/linux/kexec.h | 3373 | F: include/linux/kexec.h |
@@ -3427,7 +3405,6 @@ F: mm/kmemleak-test.c | |||
3427 | KMEMTRACE | 3405 | KMEMTRACE |
3428 | P: Eduard - Gabriel Munteanu | 3406 | P: Eduard - Gabriel Munteanu |
3429 | M: eduard.munteanu@linux360.ro | 3407 | M: eduard.munteanu@linux360.ro |
3430 | L: linux-kernel@vger.kernel.org | ||
3431 | S: Maintained | 3408 | S: Maintained |
3432 | F: Documentation/trace/kmemtrace.txt | 3409 | F: Documentation/trace/kmemtrace.txt |
3433 | F: include/trace/kmemtrace.h | 3410 | F: include/trace/kmemtrace.h |
@@ -3442,7 +3419,6 @@ P: David S. Miller | |||
3442 | M: davem@davemloft.net | 3419 | M: davem@davemloft.net |
3443 | P: Masami Hiramatsu | 3420 | P: Masami Hiramatsu |
3444 | M: mhiramat@redhat.com | 3421 | M: mhiramat@redhat.com |
3445 | L: linux-kernel@vger.kernel.org | ||
3446 | S: Maintained | 3422 | S: Maintained |
3447 | F: Documentation/kprobes.txt | 3423 | F: Documentation/kprobes.txt |
3448 | F: include/linux/kprobes.h | 3424 | F: include/linux/kprobes.h |
@@ -3451,7 +3427,6 @@ F: kernel/kprobes.c | |||
3451 | KS0108 LCD CONTROLLER DRIVER | 3427 | KS0108 LCD CONTROLLER DRIVER |
3452 | P: Miguel Ojeda Sandonis | 3428 | P: Miguel Ojeda Sandonis |
3453 | M: miguel.ojeda.sandonis@gmail.com | 3429 | M: miguel.ojeda.sandonis@gmail.com |
3454 | L: linux-kernel@vger.kernel.org | ||
3455 | W: http://miguelojeda.es/auxdisplay.htm | 3430 | W: http://miguelojeda.es/auxdisplay.htm |
3456 | W: http://jair.lab.fi.uva.es/~migojed/auxdisplay.htm | 3431 | W: http://jair.lab.fi.uva.es/~migojed/auxdisplay.htm |
3457 | S: Maintained | 3432 | S: Maintained |
@@ -3615,7 +3590,6 @@ P: Peter Zijlstra | |||
3615 | M: peterz@infradead.org | 3590 | M: peterz@infradead.org |
3616 | P: Ingo Molnar | 3591 | P: Ingo Molnar |
3617 | M: mingo@redhat.com | 3592 | M: mingo@redhat.com |
3618 | L: linux-kernel@vger.kernel.org | ||
3619 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/peterz/linux-2.6-lockdep.git | 3593 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/peterz/linux-2.6-lockdep.git |
3620 | S: Maintained | 3594 | S: Maintained |
3621 | F: Documentation/lockdep*.txt | 3595 | F: Documentation/lockdep*.txt |
@@ -3667,7 +3641,6 @@ L: linux-m32r-ja@ml.linux-m32r.org (in Japanese) | |||
3667 | W: http://www.linux-m32r.org/ | 3641 | W: http://www.linux-m32r.org/ |
3668 | S: Maintained | 3642 | S: Maintained |
3669 | F: arch/m32r/ | 3643 | F: arch/m32r/ |
3670 | F: include/asm-m32r/ | ||
3671 | 3644 | ||
3672 | M68K ARCHITECTURE | 3645 | M68K ARCHITECTURE |
3673 | P: Geert Uytterhoeven | 3646 | P: Geert Uytterhoeven |
@@ -3751,7 +3724,6 @@ F: include/linux/mv643xx.h | |||
3751 | MARVELL SOC MMC/SD/SDIO CONTROLLER DRIVER | 3724 | MARVELL SOC MMC/SD/SDIO CONTROLLER DRIVER |
3752 | P: Nicolas Pitre | 3725 | P: Nicolas Pitre |
3753 | M: nico@cam.org | 3726 | M: nico@cam.org |
3754 | L: linux-kernel@vger.kernel.org | ||
3755 | S: Maintained | 3727 | S: Maintained |
3756 | 3728 | ||
3757 | MARVELL YUKON / SYSKONNECT DRIVER | 3729 | MARVELL YUKON / SYSKONNECT DRIVER |
@@ -3805,7 +3777,6 @@ F: drivers/scsi/megaraid/ | |||
3805 | 3777 | ||
3806 | MEMORY MANAGEMENT | 3778 | MEMORY MANAGEMENT |
3807 | L: linux-mm@kvack.org | 3779 | L: linux-mm@kvack.org |
3808 | L: linux-kernel@vger.kernel.org | ||
3809 | W: http://www.linux-mm.org | 3780 | W: http://www.linux-mm.org |
3810 | S: Maintained | 3781 | S: Maintained |
3811 | F: include/linux/mm.h | 3782 | F: include/linux/mm.h |
@@ -3819,7 +3790,6 @@ M: xemul@openvz.org | |||
3819 | P: KAMEZAWA Hiroyuki | 3790 | P: KAMEZAWA Hiroyuki |
3820 | M: kamezawa.hiroyu@jp.fujitsu.com | 3791 | M: kamezawa.hiroyu@jp.fujitsu.com |
3821 | L: linux-mm@kvack.org | 3792 | L: linux-mm@kvack.org |
3822 | L: linux-kernel@vger.kernel.org | ||
3823 | S: Maintained | 3793 | S: Maintained |
3824 | F: mm/memcontrol.c | 3794 | F: mm/memcontrol.c |
3825 | 3795 | ||
@@ -3862,7 +3832,6 @@ F: arch/mips/ | |||
3862 | MISCELLANEOUS MCA-SUPPORT | 3832 | MISCELLANEOUS MCA-SUPPORT |
3863 | P: James Bottomley | 3833 | P: James Bottomley |
3864 | M: James.Bottomley@HansenPartnership.com | 3834 | M: James.Bottomley@HansenPartnership.com |
3865 | L: linux-kernel@vger.kernel.org | ||
3866 | S: Maintained | 3835 | S: Maintained |
3867 | F: Documentation/ia64/mca.txt | 3836 | F: Documentation/ia64/mca.txt |
3868 | F: Documentation/mca.txt | 3837 | F: Documentation/mca.txt |
@@ -3872,7 +3841,6 @@ F: include/linux/mca* | |||
3872 | MODULE SUPPORT | 3841 | MODULE SUPPORT |
3873 | P: Rusty Russell | 3842 | P: Rusty Russell |
3874 | M: rusty@rustcorp.com.au | 3843 | M: rusty@rustcorp.com.au |
3875 | L: linux-kernel@vger.kernel.org | ||
3876 | S: Maintained | 3844 | S: Maintained |
3877 | F: include/linux/module.h | 3845 | F: include/linux/module.h |
3878 | F: kernel/module.c | 3846 | F: kernel/module.c |
@@ -3896,7 +3864,6 @@ F: drivers/mmc/host/imxmmc.* | |||
3896 | MOUSE AND MISC DEVICES [GENERAL] | 3864 | MOUSE AND MISC DEVICES [GENERAL] |
3897 | P: Alessandro Rubini | 3865 | P: Alessandro Rubini |
3898 | M: rubini@ipvvis.unipv.it | 3866 | M: rubini@ipvvis.unipv.it |
3899 | L: linux-kernel@vger.kernel.org | ||
3900 | S: Maintained | 3867 | S: Maintained |
3901 | F: drivers/input/mouse/ | 3868 | F: drivers/input/mouse/ |
3902 | F: include/linux/gpio_mouse.h | 3869 | F: include/linux/gpio_mouse.h |
@@ -3904,7 +3871,6 @@ F: include/linux/gpio_mouse.h | |||
3904 | MOXA SMARTIO/INDUSTIO/INTELLIO SERIAL CARD | 3871 | MOXA SMARTIO/INDUSTIO/INTELLIO SERIAL CARD |
3905 | P: Jiri Slaby | 3872 | P: Jiri Slaby |
3906 | M: jirislaby@gmail.com | 3873 | M: jirislaby@gmail.com |
3907 | L: linux-kernel@vger.kernel.org | ||
3908 | S: Maintained | 3874 | S: Maintained |
3909 | F: Documentation/serial/moxa-smartio | 3875 | F: Documentation/serial/moxa-smartio |
3910 | F: drivers/char/mxser.* | 3876 | F: drivers/char/mxser.* |
@@ -3920,7 +3886,6 @@ F: drivers/platform/x86/msi-laptop.c | |||
3920 | MULTIFUNCTION DEVICES (MFD) | 3886 | MULTIFUNCTION DEVICES (MFD) |
3921 | P: Samuel Ortiz | 3887 | P: Samuel Ortiz |
3922 | M: sameo@linux.intel.com | 3888 | M: sameo@linux.intel.com |
3923 | L: linux-kernel@vger.kernel.org | ||
3924 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6.git | 3889 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6.git |
3925 | S: Supported | 3890 | S: Supported |
3926 | F: drivers/mfd/ | 3891 | F: drivers/mfd/ |
@@ -3928,7 +3893,6 @@ F: drivers/mfd/ | |||
3928 | MULTIMEDIA CARD (MMC), SECURE DIGITAL (SD) AND SDIO SUBSYSTEM | 3893 | MULTIMEDIA CARD (MMC), SECURE DIGITAL (SD) AND SDIO SUBSYSTEM |
3929 | P: Pierre Ossman | 3894 | P: Pierre Ossman |
3930 | M: pierre@ossman.eu | 3895 | M: pierre@ossman.eu |
3931 | L: linux-kernel@vger.kernel.org | ||
3932 | S: Maintained | 3896 | S: Maintained |
3933 | F: drivers/mmc/ | 3897 | F: drivers/mmc/ |
3934 | F: include/linux/mmc/ | 3898 | F: include/linux/mmc/ |
@@ -3936,7 +3900,6 @@ F: include/linux/mmc/ | |||
3936 | MULTIMEDIA CARD (MMC) ETC. OVER SPI | 3900 | MULTIMEDIA CARD (MMC) ETC. OVER SPI |
3937 | P: David Brownell | 3901 | P: David Brownell |
3938 | M: dbrownell@users.sourceforge.net | 3902 | M: dbrownell@users.sourceforge.net |
3939 | L: linux-kernel@vger.kernel.org | ||
3940 | S: Odd Fixes | 3903 | S: Odd Fixes |
3941 | F: drivers/mmc/host/mmc_spi.c | 3904 | F: drivers/mmc/host/mmc_spi.c |
3942 | F: include/linux/spi/mmc_spi.h | 3905 | F: include/linux/spi/mmc_spi.h |
@@ -3951,7 +3914,6 @@ F: sound/oss/msnd* | |||
3951 | MULTITECH MULTIPORT CARD (ISICOM) | 3914 | MULTITECH MULTIPORT CARD (ISICOM) |
3952 | P: Jiri Slaby | 3915 | P: Jiri Slaby |
3953 | M: jirislaby@gmail.com | 3916 | M: jirislaby@gmail.com |
3954 | L: linux-kernel@vger.kernel.org | ||
3955 | S: Maintained | 3917 | S: Maintained |
3956 | F: drivers/char/isicom.c | 3918 | F: drivers/char/isicom.c |
3957 | F: include/linux/isicom.h | 3919 | F: include/linux/isicom.h |
@@ -4195,7 +4157,6 @@ NTFS FILESYSTEM | |||
4195 | P: Anton Altaparmakov | 4157 | P: Anton Altaparmakov |
4196 | M: aia21@cantab.net | 4158 | M: aia21@cantab.net |
4197 | L: linux-ntfs-dev@lists.sourceforge.net | 4159 | L: linux-ntfs-dev@lists.sourceforge.net |
4198 | L: linux-kernel@vger.kernel.org | ||
4199 | W: http://www.linux-ntfs.org/ | 4160 | W: http://www.linux-ntfs.org/ |
4200 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/aia21/ntfs-2.6.git | 4161 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/aia21/ntfs-2.6.git |
4201 | S: Maintained | 4162 | S: Maintained |
@@ -4429,7 +4390,6 @@ M: akataria@vmware.com | |||
4429 | P: Rusty Russell | 4390 | P: Rusty Russell |
4430 | M: rusty@rustcorp.com.au | 4391 | M: rusty@rustcorp.com.au |
4431 | L: virtualization@lists.osdl.org | 4392 | L: virtualization@lists.osdl.org |
4432 | L: linux-kernel@vger.kernel.org | ||
4433 | S: Supported | 4393 | S: Supported |
4434 | F: Documentation/ia64/paravirt_ops.txt | 4394 | F: Documentation/ia64/paravirt_ops.txt |
4435 | F: arch/*/kernel/paravirt* | 4395 | F: arch/*/kernel/paravirt* |
@@ -4480,7 +4440,6 @@ F: include/linux/leds-pca9532.h | |||
4480 | PCI ERROR RECOVERY | 4440 | PCI ERROR RECOVERY |
4481 | P: Linas Vepstas | 4441 | P: Linas Vepstas |
4482 | M: linas@austin.ibm.com | 4442 | M: linas@austin.ibm.com |
4483 | L: linux-kernel@vger.kernel.org | ||
4484 | L: linux-pci@vger.kernel.org | 4443 | L: linux-pci@vger.kernel.org |
4485 | S: Supported | 4444 | S: Supported |
4486 | F: Documentation/PCI/pci-error-recovery.txt | 4445 | F: Documentation/PCI/pci-error-recovery.txt |
@@ -4489,7 +4448,6 @@ F: Documentation/powerpc/eeh-pci-error-recovery.txt | |||
4489 | PCI SUBSYSTEM | 4448 | PCI SUBSYSTEM |
4490 | P: Jesse Barnes | 4449 | P: Jesse Barnes |
4491 | M: jbarnes@virtuousgeek.org | 4450 | M: jbarnes@virtuousgeek.org |
4492 | L: linux-kernel@vger.kernel.org | ||
4493 | L: linux-pci@vger.kernel.org | 4451 | L: linux-pci@vger.kernel.org |
4494 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6.git | 4452 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6.git |
4495 | S: Supported | 4453 | S: Supported |
@@ -4524,7 +4482,6 @@ F: drivers/net/pcnet32.c | |||
4524 | PER-TASK DELAY ACCOUNTING | 4482 | PER-TASK DELAY ACCOUNTING |
4525 | P: Balbir Singh | 4483 | P: Balbir Singh |
4526 | M: balbir@linux.vnet.ibm.com | 4484 | M: balbir@linux.vnet.ibm.com |
4527 | L: linux-kernel@vger.kernel.org | ||
4528 | S: Maintained | 4485 | S: Maintained |
4529 | F: include/linux/delayacct.h | 4486 | F: include/linux/delayacct.h |
4530 | F: kernel/delayacct.c | 4487 | F: kernel/delayacct.c |
@@ -4556,7 +4513,6 @@ F: drivers/mtd/devices/phram.c | |||
4556 | PKTCDVD DRIVER | 4513 | PKTCDVD DRIVER |
4557 | P: Peter Osterlund | 4514 | P: Peter Osterlund |
4558 | M: petero2@telia.com | 4515 | M: petero2@telia.com |
4559 | L: linux-kernel@vger.kernel.org | ||
4560 | S: Maintained | 4516 | S: Maintained |
4561 | F: drivers/block/pktcdvd.c | 4517 | F: drivers/block/pktcdvd.c |
4562 | F: include/linux/pktcdvd.h | 4518 | F: include/linux/pktcdvd.h |
@@ -4564,7 +4520,6 @@ F: include/linux/pktcdvd.h | |||
4564 | POSIX CLOCKS and TIMERS | 4520 | POSIX CLOCKS and TIMERS |
4565 | P: Thomas Gleixner | 4521 | P: Thomas Gleixner |
4566 | M: tglx@linutronix.de | 4522 | M: tglx@linutronix.de |
4567 | L: linux-kernel@vger.kernel.org | ||
4568 | S: Supported | 4523 | S: Supported |
4569 | F: fs/timerfd.c | 4524 | F: fs/timerfd.c |
4570 | F: include/linux/timer* | 4525 | F: include/linux/timer* |
@@ -4575,7 +4530,6 @@ P: Anton Vorontsov | |||
4575 | M: cbou@mail.ru | 4530 | M: cbou@mail.ru |
4576 | P: David Woodhouse | 4531 | P: David Woodhouse |
4577 | M: dwmw2@infradead.org | 4532 | M: dwmw2@infradead.org |
4578 | L: linux-kernel@vger.kernel.org | ||
4579 | T: git git://git.infradead.org/battery-2.6.git | 4533 | T: git git://git.infradead.org/battery-2.6.git |
4580 | S: Maintained | 4534 | S: Maintained |
4581 | F: include/linux/power_supply.h | 4535 | F: include/linux/power_supply.h |
@@ -4627,7 +4581,6 @@ F: include/linux/if_pppol2tp.h | |||
4627 | PREEMPTIBLE KERNEL | 4581 | PREEMPTIBLE KERNEL |
4628 | P: Robert Love | 4582 | P: Robert Love |
4629 | M: rml@tech9.net | 4583 | M: rml@tech9.net |
4630 | L: linux-kernel@vger.kernel.org | ||
4631 | L: kpreempt-tech@lists.sourceforge.net | 4584 | L: kpreempt-tech@lists.sourceforge.net |
4632 | W: ftp://ftp.kernel.org/pub/linux/kernel/people/rml/preempt-kernel | 4585 | W: ftp://ftp.kernel.org/pub/linux/kernel/people/rml/preempt-kernel |
4633 | S: Supported | 4586 | S: Supported |
@@ -4690,7 +4643,6 @@ P: Roland McGrath | |||
4690 | M: roland@redhat.com | 4643 | M: roland@redhat.com |
4691 | P: Oleg Nesterov | 4644 | P: Oleg Nesterov |
4692 | M: oleg@redhat.com | 4645 | M: oleg@redhat.com |
4693 | L: linux-kernel@vger.kernel.org | ||
4694 | S: Maintained | 4646 | S: Maintained |
4695 | F: include/asm-generic/syscall.h | 4647 | F: include/asm-generic/syscall.h |
4696 | F: include/linux/ptrace.h | 4648 | F: include/linux/ptrace.h |
@@ -4776,7 +4728,6 @@ F: drivers/net/qlge/ | |||
4776 | QNX4 FILESYSTEM | 4728 | QNX4 FILESYSTEM |
4777 | P: Anders Larsen | 4729 | P: Anders Larsen |
4778 | M: al@alarsen.net | 4730 | M: al@alarsen.net |
4779 | L: linux-kernel@vger.kernel.org | ||
4780 | W: http://www.alarsen.net/linux/qnx4fs/ | 4731 | W: http://www.alarsen.net/linux/qnx4fs/ |
4781 | S: Maintained | 4732 | S: Maintained |
4782 | F: fs/qnx4/ | 4733 | F: fs/qnx4/ |
@@ -4823,7 +4774,6 @@ F: drivers/char/random.c | |||
4823 | RAPIDIO SUBSYSTEM | 4774 | RAPIDIO SUBSYSTEM |
4824 | P: Matt Porter | 4775 | P: Matt Porter |
4825 | M: mporter@kernel.crashing.org | 4776 | M: mporter@kernel.crashing.org |
4826 | L: linux-kernel@vger.kernel.org | ||
4827 | S: Maintained | 4777 | S: Maintained |
4828 | F: drivers/rapidio/ | 4778 | F: drivers/rapidio/ |
4829 | 4779 | ||
@@ -4837,7 +4787,8 @@ F: drivers/net/wireless/ray* | |||
4837 | RCUTORTURE MODULE | 4787 | RCUTORTURE MODULE |
4838 | P: Josh Triplett | 4788 | P: Josh Triplett |
4839 | M: josh@freedesktop.org | 4789 | M: josh@freedesktop.org |
4840 | L: linux-kernel@vger.kernel.org | 4790 | P: Paul E. McKenney |
4791 | M: paulmck@linux.vnet.ibm.com | ||
4841 | S: Maintained | 4792 | S: Maintained |
4842 | F: Documentation/RCU/torture.txt | 4793 | F: Documentation/RCU/torture.txt |
4843 | F: kernel/rcutorture.c | 4794 | F: kernel/rcutorture.c |
@@ -4845,7 +4796,6 @@ F: kernel/rcutorture.c | |||
4845 | RDC R-321X SoC | 4796 | RDC R-321X SoC |
4846 | P: Florian Fainelli | 4797 | P: Florian Fainelli |
4847 | M: florian@openwrt.org | 4798 | M: florian@openwrt.org |
4848 | L: linux-kernel@vger.kernel.org | ||
4849 | S: Maintained | 4799 | S: Maintained |
4850 | 4800 | ||
4851 | RDC R6040 FAST ETHERNET DRIVER | 4801 | RDC R6040 FAST ETHERNET DRIVER |
@@ -4865,8 +4815,9 @@ F: net/rds/ | |||
4865 | READ-COPY UPDATE (RCU) | 4815 | READ-COPY UPDATE (RCU) |
4866 | P: Dipankar Sarma | 4816 | P: Dipankar Sarma |
4867 | M: dipankar@in.ibm.com | 4817 | M: dipankar@in.ibm.com |
4818 | P: Paul E. McKenney | ||
4819 | M: paulmck@linux.vnet.ibm.com | ||
4868 | W: http://www.rdrop.com/users/paulmck/rclock/ | 4820 | W: http://www.rdrop.com/users/paulmck/rclock/ |
4869 | L: linux-kernel@vger.kernel.org | ||
4870 | S: Supported | 4821 | S: Supported |
4871 | F: Documentation/RCU/rcu.txt | 4822 | F: Documentation/RCU/rcu.txt |
4872 | F: Documentation/RCU/rcuref.txt | 4823 | F: Documentation/RCU/rcuref.txt |
@@ -4877,7 +4828,6 @@ F: kernel/rcupdate.c | |||
4877 | REAL TIME CLOCK DRIVER | 4828 | REAL TIME CLOCK DRIVER |
4878 | P: Paul Gortmaker | 4829 | P: Paul Gortmaker |
4879 | M: p_gortmaker@yahoo.com | 4830 | M: p_gortmaker@yahoo.com |
4880 | L: linux-kernel@vger.kernel.org | ||
4881 | S: Maintained | 4831 | S: Maintained |
4882 | F: Documentation/rtc.txt | 4832 | F: Documentation/rtc.txt |
4883 | F: drivers/rtc/ | 4833 | F: drivers/rtc/ |
@@ -5015,7 +4965,6 @@ S3C24XX SD/MMC Driver | |||
5015 | P: Ben Dooks | 4965 | P: Ben Dooks |
5016 | M: ben-linux@fluff.org | 4966 | M: ben-linux@fluff.org |
5017 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 4967 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
5018 | L: linux-kernel@vger.kernel.org | ||
5019 | S: Supported | 4968 | S: Supported |
5020 | F: drivers/mmc/host/s3cmci.* | 4969 | F: drivers/mmc/host/s3cmci.* |
5021 | 4970 | ||
@@ -5041,7 +4990,6 @@ P: Ingo Molnar | |||
5041 | M: mingo@elte.hu | 4990 | M: mingo@elte.hu |
5042 | P: Peter Zijlstra | 4991 | P: Peter Zijlstra |
5043 | M: peterz@infradead.org | 4992 | M: peterz@infradead.org |
5044 | L: linux-kernel@vger.kernel.org | ||
5045 | S: Maintained | 4993 | S: Maintained |
5046 | F: kernel/sched* | 4994 | F: kernel/sched* |
5047 | F: include/linux/sched.h | 4995 | F: include/linux/sched.h |
@@ -5143,7 +5091,6 @@ F: drivers/mmc/host/sdhci.* | |||
5143 | SECURITY SUBSYSTEM | 5091 | SECURITY SUBSYSTEM |
5144 | P: James Morris | 5092 | P: James Morris |
5145 | M: jmorris@namei.org | 5093 | M: jmorris@namei.org |
5146 | L: linux-kernel@vger.kernel.org | ||
5147 | L: linux-security-module@vger.kernel.org (suggested Cc:) | 5094 | L: linux-security-module@vger.kernel.org (suggested Cc:) |
5148 | T: git git://www.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6.git | 5095 | T: git git://www.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6.git |
5149 | W: http://security.wiki.kernel.org/ | 5096 | W: http://security.wiki.kernel.org/ |
@@ -5162,7 +5109,6 @@ P: James Morris | |||
5162 | M: jmorris@namei.org | 5109 | M: jmorris@namei.org |
5163 | P: Eric Paris | 5110 | P: Eric Paris |
5164 | M: eparis@parisplace.org | 5111 | M: eparis@parisplace.org |
5165 | L: linux-kernel@vger.kernel.org (kernel issues) | ||
5166 | L: selinux@tycho.nsa.gov (subscribers-only, general discussion) | 5112 | L: selinux@tycho.nsa.gov (subscribers-only, general discussion) |
5167 | W: http://selinuxproject.org | 5113 | W: http://selinuxproject.org |
5168 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6.git | 5114 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6.git |
@@ -5425,7 +5371,6 @@ F: include/linux/sony-laptop.h | |||
5425 | SONY MEMORYSTICK CARD SUPPORT | 5371 | SONY MEMORYSTICK CARD SUPPORT |
5426 | P: Alex Dubov | 5372 | P: Alex Dubov |
5427 | M: oakad@yahoo.com | 5373 | M: oakad@yahoo.com |
5428 | L: linux-kernel@vger.kernel.org | ||
5429 | W: http://tifmxx.berlios.de/ | 5374 | W: http://tifmxx.berlios.de/ |
5430 | S: Maintained | 5375 | S: Maintained |
5431 | F: drivers/memstick/host/tifm_ms.c | 5376 | F: drivers/memstick/host/tifm_ms.c |
@@ -5435,7 +5380,7 @@ P: Jaroslav Kysela | |||
5435 | M: perex@perex.cz | 5380 | M: perex@perex.cz |
5436 | P: Takashi Iwai | 5381 | P: Takashi Iwai |
5437 | M: tiwai@suse.de | 5382 | M: tiwai@suse.de |
5438 | L: alsa-devel@alsa-project.org (subscribers-only) | 5383 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) |
5439 | W: http://www.alsa-project.org/ | 5384 | W: http://www.alsa-project.org/ |
5440 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6.git | 5385 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6.git |
5441 | T: git git://git.alsa-project.org/alsa-kernel.git | 5386 | T: git git://git.alsa-project.org/alsa-kernel.git |
@@ -5450,7 +5395,7 @@ M: lrg@slimlogic.co.uk | |||
5450 | P: Mark Brown | 5395 | P: Mark Brown |
5451 | M: broonie@opensource.wolfsonmicro.com | 5396 | M: broonie@opensource.wolfsonmicro.com |
5452 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound-2.6.git | 5397 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound-2.6.git |
5453 | L: alsa-devel@alsa-project.org (subscribers-only) | 5398 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) |
5454 | W: http://alsa-project.org/main/index.php/ASoC | 5399 | W: http://alsa-project.org/main/index.php/ASoC |
5455 | S: Supported | 5400 | S: Supported |
5456 | F: sound/soc/ | 5401 | F: sound/soc/ |
@@ -5468,7 +5413,6 @@ F: arch/sparc/ | |||
5468 | SPECIALIX IO8+ MULTIPORT SERIAL CARD DRIVER | 5413 | SPECIALIX IO8+ MULTIPORT SERIAL CARD DRIVER |
5469 | P: Roger Wolff | 5414 | P: Roger Wolff |
5470 | M: R.E.Wolff@BitWizard.nl | 5415 | M: R.E.Wolff@BitWizard.nl |
5471 | L: linux-kernel@vger.kernel.org | ||
5472 | S: Supported | 5416 | S: Supported |
5473 | F: Documentation/serial/specialix.txt | 5417 | F: Documentation/serial/specialix.txt |
5474 | F: drivers/char/specialix* | 5418 | F: drivers/char/specialix* |
@@ -5514,7 +5458,6 @@ F: fs/squashfs/ | |||
5514 | SRM (Alpha) environment access | 5458 | SRM (Alpha) environment access |
5515 | P: Jan-Benedict Glaw | 5459 | P: Jan-Benedict Glaw |
5516 | M: jbglaw@lug-owl.de | 5460 | M: jbglaw@lug-owl.de |
5517 | L: linux-kernel@vger.kernel.org | ||
5518 | S: Maintained | 5461 | S: Maintained |
5519 | F: arch/alpha/kernel/srm_env.c | 5462 | F: arch/alpha/kernel/srm_env.c |
5520 | 5463 | ||
@@ -5529,7 +5472,6 @@ S: Maintained | |||
5529 | STAGING SUBSYSTEM | 5472 | STAGING SUBSYSTEM |
5530 | P: Greg Kroah-Hartman | 5473 | P: Greg Kroah-Hartman |
5531 | M: gregkh@suse.de | 5474 | M: gregkh@suse.de |
5532 | L: linux-kernel@vger.kernel.org | ||
5533 | T: quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/ | 5475 | T: quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/ |
5534 | S: Maintained | 5476 | S: Maintained |
5535 | F: drivers/staging/ | 5477 | F: drivers/staging/ |
@@ -5609,7 +5551,6 @@ F: include/linux/sysv_fs.h | |||
5609 | TASKSTATS STATISTICS INTERFACE | 5551 | TASKSTATS STATISTICS INTERFACE |
5610 | P: Balbir Singh | 5552 | P: Balbir Singh |
5611 | M: balbir@linux.vnet.ibm.com | 5553 | M: balbir@linux.vnet.ibm.com |
5612 | L: linux-kernel@vger.kernel.org | ||
5613 | S: Maintained | 5554 | S: Maintained |
5614 | F: Documentation/accounting/taskstats* | 5555 | F: Documentation/accounting/taskstats* |
5615 | F: include/linux/taskstats* | 5556 | F: include/linux/taskstats* |
@@ -5702,7 +5643,6 @@ P: Kentaro Takeda | |||
5702 | M: takedakn@nttdata.co.jp | 5643 | M: takedakn@nttdata.co.jp |
5703 | P: Tetsuo Handa | 5644 | P: Tetsuo Handa |
5704 | M: penguin-kernel@I-love.SAKURA.ne.jp | 5645 | M: penguin-kernel@I-love.SAKURA.ne.jp |
5705 | L: linux-kernel@vger.kernel.org (kernel issues) | ||
5706 | L: tomoyo-users-en@lists.sourceforge.jp (subscribers-only, for developers and users in English) | 5646 | L: tomoyo-users-en@lists.sourceforge.jp (subscribers-only, for developers and users in English) |
5707 | L: tomoyo-dev@lists.sourceforge.jp (subscribers-only, for developers in Japanese) | 5647 | L: tomoyo-dev@lists.sourceforge.jp (subscribers-only, for developers in Japanese) |
5708 | L: tomoyo-users@lists.sourceforge.jp (subscribers-only, for users in Japanese) | 5648 | L: tomoyo-users@lists.sourceforge.jp (subscribers-only, for users in Japanese) |
@@ -5754,14 +5694,17 @@ F: drivers/char/tpm/ | |||
5754 | TRIVIAL PATCHES | 5694 | TRIVIAL PATCHES |
5755 | P: Jiri Kosina | 5695 | P: Jiri Kosina |
5756 | M: trivial@kernel.org | 5696 | M: trivial@kernel.org |
5757 | L: linux-kernel@vger.kernel.org | ||
5758 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial.git | 5697 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial.git |
5759 | S: Maintained | 5698 | S: Maintained |
5699 | F: drivers/char/tty_* | ||
5700 | F: drivers/serial/serial_core.c | ||
5701 | F: include/linux/serial_core.h | ||
5702 | F: include/linux/serial.h | ||
5703 | F: include/linux/tty.h | ||
5760 | 5704 | ||
5761 | TTY LAYER | 5705 | TTY LAYER |
5762 | P: Alan Cox | 5706 | P: Alan Cox |
5763 | M: alan@lxorguk.ukuu.org.uk | 5707 | M: alan@lxorguk.ukuu.org.uk |
5764 | L: linux-kernel@vger.kernel.org | ||
5765 | S: Maintained | 5708 | S: Maintained |
5766 | T: stgit http://zeniv.linux.org.uk/~alan/ttydev/ | 5709 | T: stgit http://zeniv.linux.org.uk/~alan/ttydev/ |
5767 | 5710 | ||
@@ -5834,7 +5777,6 @@ F: fs/udf/ | |||
5834 | UFS FILESYSTEM | 5777 | UFS FILESYSTEM |
5835 | P: Evgeniy Dushistov | 5778 | P: Evgeniy Dushistov |
5836 | M: dushistov@mail.ru | 5779 | M: dushistov@mail.ru |
5837 | L: linux-kernel@vger.kernel.org | ||
5838 | S: Maintained | 5780 | S: Maintained |
5839 | F: Documentation/filesystems/ufs.txt | 5781 | F: Documentation/filesystems/ufs.txt |
5840 | F: fs/ufs/ | 5782 | F: fs/ufs/ |
@@ -5851,7 +5793,6 @@ F: include/linux/uwb/ | |||
5851 | UNIFORM CDROM DRIVER | 5793 | UNIFORM CDROM DRIVER |
5852 | P: Jens Axboe | 5794 | P: Jens Axboe |
5853 | M: axboe@kernel.dk | 5795 | M: axboe@kernel.dk |
5854 | L: linux-kernel@vger.kernel.org | ||
5855 | W: http://www.kernel.dk | 5796 | W: http://www.kernel.dk |
5856 | S: Maintained | 5797 | S: Maintained |
5857 | F: Documentation/cdrom/ | 5798 | F: Documentation/cdrom/ |
@@ -5880,7 +5821,6 @@ F: drivers/usb/class/cdc-acm.* | |||
5880 | USB BLOCK DRIVER (UB ub) | 5821 | USB BLOCK DRIVER (UB ub) |
5881 | P: Pete Zaitcev | 5822 | P: Pete Zaitcev |
5882 | M: zaitcev@redhat.com | 5823 | M: zaitcev@redhat.com |
5883 | L: linux-kernel@vger.kernel.org | ||
5884 | L: linux-usb@vger.kernel.org | 5824 | L: linux-usb@vger.kernel.org |
5885 | S: Supported | 5825 | S: Supported |
5886 | F: drivers/block/ub.c | 5826 | F: drivers/block/ub.c |
@@ -6226,7 +6166,6 @@ P: Hans J. Koch | |||
6226 | M: hjk@linutronix.de | 6166 | M: hjk@linutronix.de |
6227 | P: Greg Kroah-Hartman | 6167 | P: Greg Kroah-Hartman |
6228 | M: gregkh@suse.de | 6168 | M: gregkh@suse.de |
6229 | L: linux-kernel@vger.kernel.org | ||
6230 | S: Maintained | 6169 | S: Maintained |
6231 | F: Documentation/DocBook/uio-howto.tmpl | 6170 | F: Documentation/DocBook/uio-howto.tmpl |
6232 | F: drivers/uio/ | 6171 | F: drivers/uio/ |
@@ -6252,7 +6191,6 @@ F: drivers/video/uvesafb.* | |||
6252 | VFAT/FAT/MSDOS FILESYSTEM | 6191 | VFAT/FAT/MSDOS FILESYSTEM |
6253 | P: OGAWA Hirofumi | 6192 | P: OGAWA Hirofumi |
6254 | M: hirofumi@mail.parknet.co.jp | 6193 | M: hirofumi@mail.parknet.co.jp |
6255 | L: linux-kernel@vger.kernel.org | ||
6256 | S: Maintained | 6194 | S: Maintained |
6257 | F: Documentation/filesystems/vfat.txt | 6195 | F: Documentation/filesystems/vfat.txt |
6258 | F: fs/fat/ | 6196 | F: fs/fat/ |
@@ -6296,6 +6234,14 @@ F: drivers/net/macvlan.c | |||
6296 | F: include/linux/if_*vlan.h | 6234 | F: include/linux/if_*vlan.h |
6297 | F: net/8021q/ | 6235 | F: net/8021q/ |
6298 | 6236 | ||
6237 | VLYNQ BUS | ||
6238 | P: Florian Fainelli | ||
6239 | M: florian@openwrt.org | ||
6240 | L: openwrt-devel@lists.openwrt.org | ||
6241 | S: Maintained | ||
6242 | F: drivers/vlynq/vlynq.c | ||
6243 | F: include/linux/vlynq.h | ||
6244 | |||
6299 | VOLTAGE AND CURRENT REGULATOR FRAMEWORK | 6245 | VOLTAGE AND CURRENT REGULATOR FRAMEWORK |
6300 | P: Liam Girdwood | 6246 | P: Liam Girdwood |
6301 | M: lrg@slimlogic.co.uk | 6247 | M: lrg@slimlogic.co.uk |
@@ -6349,7 +6295,6 @@ F: drivers/hwmon/w83793.c | |||
6349 | W83L51xD SD/MMC CARD INTERFACE DRIVER | 6295 | W83L51xD SD/MMC CARD INTERFACE DRIVER |
6350 | P: Pierre Ossman | 6296 | P: Pierre Ossman |
6351 | M: pierre@ossman.eu | 6297 | M: pierre@ossman.eu |
6352 | L: linux-kernel@vger.kernel.org | ||
6353 | S: Maintained | 6298 | S: Maintained |
6354 | F: drivers/mmc/host/wbsd.* | 6299 | F: drivers/mmc/host/wbsd.* |
6355 | 6300 | ||
@@ -6436,7 +6381,6 @@ M: mingo@redhat.com | |||
6436 | P: H. Peter Anvin | 6381 | P: H. Peter Anvin |
6437 | M: hpa@zytor.com | 6382 | M: hpa@zytor.com |
6438 | M: x86@kernel.org | 6383 | M: x86@kernel.org |
6439 | L: linux-kernel@vger.kernel.org | ||
6440 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86.git | 6384 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86.git |
6441 | S: Maintained | 6385 | S: Maintained |
6442 | F: Documentation/x86/ | 6386 | F: Documentation/x86/ |
@@ -6472,7 +6416,6 @@ XILINX SYSTEMACE DRIVER | |||
6472 | P: Grant Likely | 6416 | P: Grant Likely |
6473 | M: grant.likely@secretlab.ca | 6417 | M: grant.likely@secretlab.ca |
6474 | W: http://www.secretlab.ca/ | 6418 | W: http://www.secretlab.ca/ |
6475 | L: linux-kernel@vger.kernel.org | ||
6476 | S: Maintained | 6419 | S: Maintained |
6477 | F: drivers/block/xsysace.c | 6420 | F: drivers/block/xsysace.c |
6478 | 6421 | ||
@@ -6537,5 +6480,9 @@ F: drivers/serial/zs.* | |||
6537 | 6480 | ||
6538 | THE REST | 6481 | THE REST |
6539 | P: Linus Torvalds | 6482 | P: Linus Torvalds |
6483 | M: torvalds@linux-foundation.org | ||
6484 | L: linux-kernel@vger.kernel.org | ||
6540 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git | 6485 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git |
6541 | S: Buried alive in reporters | 6486 | S: Buried alive in reporters |
6487 | F: * | ||
6488 | F: */ | ||
diff --git a/arch/alpha/include/asm/8253pit.h b/arch/alpha/include/asm/8253pit.h index fef5c1450e47..a71c9c1455a7 100644 --- a/arch/alpha/include/asm/8253pit.h +++ b/arch/alpha/include/asm/8253pit.h | |||
@@ -1,10 +1,3 @@ | |||
1 | /* | 1 | /* |
2 | * 8253/8254 Programmable Interval Timer | 2 | * 8253/8254 Programmable Interval Timer |
3 | */ | 3 | */ |
4 | |||
5 | #ifndef _8253PIT_H | ||
6 | #define _8253PIT_H | ||
7 | |||
8 | #define PIT_TICK_RATE 1193180UL | ||
9 | |||
10 | #endif | ||
diff --git a/arch/alpha/include/asm/kmap_types.h b/arch/alpha/include/asm/kmap_types.h index 3e6735a34c57..a8d4ec8ea4b6 100644 --- a/arch/alpha/include/asm/kmap_types.h +++ b/arch/alpha/include/asm/kmap_types.h | |||
@@ -3,30 +3,12 @@ | |||
3 | 3 | ||
4 | /* Dummy header just to define km_type. */ | 4 | /* Dummy header just to define km_type. */ |
5 | 5 | ||
6 | |||
7 | #ifdef CONFIG_DEBUG_HIGHMEM | 6 | #ifdef CONFIG_DEBUG_HIGHMEM |
8 | # define D(n) __KM_FENCE_##n , | 7 | #define __WITH_KM_FENCE |
9 | #else | ||
10 | # define D(n) | ||
11 | #endif | 8 | #endif |
12 | 9 | ||
13 | enum km_type { | 10 | #include <asm-generic/kmap_types.h> |
14 | D(0) KM_BOUNCE_READ, | ||
15 | D(1) KM_SKB_SUNRPC_DATA, | ||
16 | D(2) KM_SKB_DATA_SOFTIRQ, | ||
17 | D(3) KM_USER0, | ||
18 | D(4) KM_USER1, | ||
19 | D(5) KM_BIO_SRC_IRQ, | ||
20 | D(6) KM_BIO_DST_IRQ, | ||
21 | D(7) KM_PTE0, | ||
22 | D(8) KM_PTE1, | ||
23 | D(9) KM_IRQ0, | ||
24 | D(10) KM_IRQ1, | ||
25 | D(11) KM_SOFTIRQ0, | ||
26 | D(12) KM_SOFTIRQ1, | ||
27 | D(13) KM_TYPE_NR | ||
28 | }; | ||
29 | 11 | ||
30 | #undef D | 12 | #undef __WITH_KM_FENCE |
31 | 13 | ||
32 | #endif | 14 | #endif |
diff --git a/arch/alpha/kernel/init_task.c b/arch/alpha/kernel/init_task.c index c2938e574a40..19b86328ffd7 100644 --- a/arch/alpha/kernel/init_task.c +++ b/arch/alpha/kernel/init_task.c | |||
@@ -10,10 +10,7 @@ | |||
10 | 10 | ||
11 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); | 11 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); |
12 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); | 12 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); |
13 | struct mm_struct init_mm = INIT_MM(init_mm); | ||
14 | struct task_struct init_task = INIT_TASK(init_task); | 13 | struct task_struct init_task = INIT_TASK(init_task); |
15 | |||
16 | EXPORT_SYMBOL(init_mm); | ||
17 | EXPORT_SYMBOL(init_task); | 14 | EXPORT_SYMBOL(init_task); |
18 | 15 | ||
19 | union thread_union init_thread_union | 16 | union thread_union init_thread_union |
diff --git a/arch/alpha/kernel/irq_alpha.c b/arch/alpha/kernel/irq_alpha.c index 67c19f8a9944..38c805dfc544 100644 --- a/arch/alpha/kernel/irq_alpha.c +++ b/arch/alpha/kernel/irq_alpha.c | |||
@@ -227,7 +227,7 @@ struct irqaction timer_irqaction = { | |||
227 | .name = "timer", | 227 | .name = "timer", |
228 | }; | 228 | }; |
229 | 229 | ||
230 | static struct hw_interrupt_type rtc_irq_type = { | 230 | static struct irq_chip rtc_irq_type = { |
231 | .typename = "RTC", | 231 | .typename = "RTC", |
232 | .startup = rtc_startup, | 232 | .startup = rtc_startup, |
233 | .shutdown = rtc_enable_disable, | 233 | .shutdown = rtc_enable_disable, |
diff --git a/arch/alpha/kernel/irq_i8259.c b/arch/alpha/kernel/irq_i8259.c index 9405bee9894e..50bfec9b588f 100644 --- a/arch/alpha/kernel/irq_i8259.c +++ b/arch/alpha/kernel/irq_i8259.c | |||
@@ -83,7 +83,7 @@ i8259a_end_irq(unsigned int irq) | |||
83 | i8259a_enable_irq(irq); | 83 | i8259a_enable_irq(irq); |
84 | } | 84 | } |
85 | 85 | ||
86 | struct hw_interrupt_type i8259a_irq_type = { | 86 | struct irq_chip i8259a_irq_type = { |
87 | .typename = "XT-PIC", | 87 | .typename = "XT-PIC", |
88 | .startup = i8259a_startup_irq, | 88 | .startup = i8259a_startup_irq, |
89 | .shutdown = i8259a_disable_irq, | 89 | .shutdown = i8259a_disable_irq, |
diff --git a/arch/alpha/kernel/irq_impl.h b/arch/alpha/kernel/irq_impl.h index cc9a8a7aa279..b63ccd7386f1 100644 --- a/arch/alpha/kernel/irq_impl.h +++ b/arch/alpha/kernel/irq_impl.h | |||
@@ -36,7 +36,7 @@ extern void i8259a_disable_irq(unsigned int); | |||
36 | extern void i8259a_mask_and_ack_irq(unsigned int); | 36 | extern void i8259a_mask_and_ack_irq(unsigned int); |
37 | extern unsigned int i8259a_startup_irq(unsigned int); | 37 | extern unsigned int i8259a_startup_irq(unsigned int); |
38 | extern void i8259a_end_irq(unsigned int); | 38 | extern void i8259a_end_irq(unsigned int); |
39 | extern struct hw_interrupt_type i8259a_irq_type; | 39 | extern struct irq_chip i8259a_irq_type; |
40 | extern void init_i8259a_irqs(void); | 40 | extern void init_i8259a_irqs(void); |
41 | 41 | ||
42 | extern void handle_irq(int irq); | 42 | extern void handle_irq(int irq); |
diff --git a/arch/alpha/kernel/irq_pyxis.c b/arch/alpha/kernel/irq_pyxis.c index d53edbccbfe5..69199a76ec4a 100644 --- a/arch/alpha/kernel/irq_pyxis.c +++ b/arch/alpha/kernel/irq_pyxis.c | |||
@@ -70,7 +70,7 @@ pyxis_mask_and_ack_irq(unsigned int irq) | |||
70 | *(vulp)PYXIS_INT_MASK; | 70 | *(vulp)PYXIS_INT_MASK; |
71 | } | 71 | } |
72 | 72 | ||
73 | static struct hw_interrupt_type pyxis_irq_type = { | 73 | static struct irq_chip pyxis_irq_type = { |
74 | .typename = "PYXIS", | 74 | .typename = "PYXIS", |
75 | .startup = pyxis_startup_irq, | 75 | .startup = pyxis_startup_irq, |
76 | .shutdown = pyxis_disable_irq, | 76 | .shutdown = pyxis_disable_irq, |
diff --git a/arch/alpha/kernel/irq_srm.c b/arch/alpha/kernel/irq_srm.c index a03fbca4940e..85229369a1f8 100644 --- a/arch/alpha/kernel/irq_srm.c +++ b/arch/alpha/kernel/irq_srm.c | |||
@@ -48,7 +48,7 @@ srm_end_irq(unsigned int irq) | |||
48 | } | 48 | } |
49 | 49 | ||
50 | /* Handle interrupts from the SRM, assuming no additional weirdness. */ | 50 | /* Handle interrupts from the SRM, assuming no additional weirdness. */ |
51 | static struct hw_interrupt_type srm_irq_type = { | 51 | static struct irq_chip srm_irq_type = { |
52 | .typename = "SRM", | 52 | .typename = "SRM", |
53 | .startup = srm_startup_irq, | 53 | .startup = srm_startup_irq, |
54 | .shutdown = srm_disable_irq, | 54 | .shutdown = srm_disable_irq, |
diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c index 80df86cd746b..d2634e4476b4 100644 --- a/arch/alpha/kernel/setup.c +++ b/arch/alpha/kernel/setup.c | |||
@@ -252,9 +252,9 @@ reserve_std_resources(void) | |||
252 | } | 252 | } |
253 | 253 | ||
254 | #define PFN_MAX PFN_DOWN(0x80000000) | 254 | #define PFN_MAX PFN_DOWN(0x80000000) |
255 | #define for_each_mem_cluster(memdesc, cluster, i) \ | 255 | #define for_each_mem_cluster(memdesc, _cluster, i) \ |
256 | for ((cluster) = (memdesc)->cluster, (i) = 0; \ | 256 | for ((_cluster) = (memdesc)->cluster, (i) = 0; \ |
257 | (i) < (memdesc)->numclusters; (i)++, (cluster)++) | 257 | (i) < (memdesc)->numclusters; (i)++, (_cluster)++) |
258 | 258 | ||
259 | static unsigned long __init | 259 | static unsigned long __init |
260 | get_mem_size_limit(char *s) | 260 | get_mem_size_limit(char *s) |
diff --git a/arch/alpha/kernel/sys_alcor.c b/arch/alpha/kernel/sys_alcor.c index e53a1e1c2f21..382035ef7394 100644 --- a/arch/alpha/kernel/sys_alcor.c +++ b/arch/alpha/kernel/sys_alcor.c | |||
@@ -89,7 +89,7 @@ alcor_end_irq(unsigned int irq) | |||
89 | alcor_enable_irq(irq); | 89 | alcor_enable_irq(irq); |
90 | } | 90 | } |
91 | 91 | ||
92 | static struct hw_interrupt_type alcor_irq_type = { | 92 | static struct irq_chip alcor_irq_type = { |
93 | .typename = "ALCOR", | 93 | .typename = "ALCOR", |
94 | .startup = alcor_startup_irq, | 94 | .startup = alcor_startup_irq, |
95 | .shutdown = alcor_disable_irq, | 95 | .shutdown = alcor_disable_irq, |
diff --git a/arch/alpha/kernel/sys_cabriolet.c b/arch/alpha/kernel/sys_cabriolet.c index ace475c124f6..ed349436732b 100644 --- a/arch/alpha/kernel/sys_cabriolet.c +++ b/arch/alpha/kernel/sys_cabriolet.c | |||
@@ -71,7 +71,7 @@ cabriolet_end_irq(unsigned int irq) | |||
71 | cabriolet_enable_irq(irq); | 71 | cabriolet_enable_irq(irq); |
72 | } | 72 | } |
73 | 73 | ||
74 | static struct hw_interrupt_type cabriolet_irq_type = { | 74 | static struct irq_chip cabriolet_irq_type = { |
75 | .typename = "CABRIOLET", | 75 | .typename = "CABRIOLET", |
76 | .startup = cabriolet_startup_irq, | 76 | .startup = cabriolet_startup_irq, |
77 | .shutdown = cabriolet_disable_irq, | 77 | .shutdown = cabriolet_disable_irq, |
diff --git a/arch/alpha/kernel/sys_dp264.c b/arch/alpha/kernel/sys_dp264.c index 5bd5259324b7..46e70ece5176 100644 --- a/arch/alpha/kernel/sys_dp264.c +++ b/arch/alpha/kernel/sys_dp264.c | |||
@@ -198,7 +198,7 @@ clipper_set_affinity(unsigned int irq, const struct cpumask *affinity) | |||
198 | return 0; | 198 | return 0; |
199 | } | 199 | } |
200 | 200 | ||
201 | static struct hw_interrupt_type dp264_irq_type = { | 201 | static struct irq_chip dp264_irq_type = { |
202 | .typename = "DP264", | 202 | .typename = "DP264", |
203 | .startup = dp264_startup_irq, | 203 | .startup = dp264_startup_irq, |
204 | .shutdown = dp264_disable_irq, | 204 | .shutdown = dp264_disable_irq, |
@@ -209,7 +209,7 @@ static struct hw_interrupt_type dp264_irq_type = { | |||
209 | .set_affinity = dp264_set_affinity, | 209 | .set_affinity = dp264_set_affinity, |
210 | }; | 210 | }; |
211 | 211 | ||
212 | static struct hw_interrupt_type clipper_irq_type = { | 212 | static struct irq_chip clipper_irq_type = { |
213 | .typename = "CLIPPER", | 213 | .typename = "CLIPPER", |
214 | .startup = clipper_startup_irq, | 214 | .startup = clipper_startup_irq, |
215 | .shutdown = clipper_disable_irq, | 215 | .shutdown = clipper_disable_irq, |
@@ -298,7 +298,7 @@ clipper_srm_device_interrupt(unsigned long vector) | |||
298 | } | 298 | } |
299 | 299 | ||
300 | static void __init | 300 | static void __init |
301 | init_tsunami_irqs(struct hw_interrupt_type * ops, int imin, int imax) | 301 | init_tsunami_irqs(struct irq_chip * ops, int imin, int imax) |
302 | { | 302 | { |
303 | long i; | 303 | long i; |
304 | for (i = imin; i <= imax; ++i) { | 304 | for (i = imin; i <= imax; ++i) { |
diff --git a/arch/alpha/kernel/sys_eb64p.c b/arch/alpha/kernel/sys_eb64p.c index 9c5a306dc0ee..660c23ef661f 100644 --- a/arch/alpha/kernel/sys_eb64p.c +++ b/arch/alpha/kernel/sys_eb64p.c | |||
@@ -69,7 +69,7 @@ eb64p_end_irq(unsigned int irq) | |||
69 | eb64p_enable_irq(irq); | 69 | eb64p_enable_irq(irq); |
70 | } | 70 | } |
71 | 71 | ||
72 | static struct hw_interrupt_type eb64p_irq_type = { | 72 | static struct irq_chip eb64p_irq_type = { |
73 | .typename = "EB64P", | 73 | .typename = "EB64P", |
74 | .startup = eb64p_startup_irq, | 74 | .startup = eb64p_startup_irq, |
75 | .shutdown = eb64p_disable_irq, | 75 | .shutdown = eb64p_disable_irq, |
diff --git a/arch/alpha/kernel/sys_eiger.c b/arch/alpha/kernel/sys_eiger.c index baf60f36cbd7..b99ea488d844 100644 --- a/arch/alpha/kernel/sys_eiger.c +++ b/arch/alpha/kernel/sys_eiger.c | |||
@@ -80,7 +80,7 @@ eiger_end_irq(unsigned int irq) | |||
80 | eiger_enable_irq(irq); | 80 | eiger_enable_irq(irq); |
81 | } | 81 | } |
82 | 82 | ||
83 | static struct hw_interrupt_type eiger_irq_type = { | 83 | static struct irq_chip eiger_irq_type = { |
84 | .typename = "EIGER", | 84 | .typename = "EIGER", |
85 | .startup = eiger_startup_irq, | 85 | .startup = eiger_startup_irq, |
86 | .shutdown = eiger_disable_irq, | 86 | .shutdown = eiger_disable_irq, |
diff --git a/arch/alpha/kernel/sys_jensen.c b/arch/alpha/kernel/sys_jensen.c index 2b5caf3d9b15..ef0b83a070ac 100644 --- a/arch/alpha/kernel/sys_jensen.c +++ b/arch/alpha/kernel/sys_jensen.c | |||
@@ -118,7 +118,7 @@ jensen_local_end(unsigned int irq) | |||
118 | i8259a_end_irq(1); | 118 | i8259a_end_irq(1); |
119 | } | 119 | } |
120 | 120 | ||
121 | static struct hw_interrupt_type jensen_local_irq_type = { | 121 | static struct irq_chip jensen_local_irq_type = { |
122 | .typename = "LOCAL", | 122 | .typename = "LOCAL", |
123 | .startup = jensen_local_startup, | 123 | .startup = jensen_local_startup, |
124 | .shutdown = jensen_local_shutdown, | 124 | .shutdown = jensen_local_shutdown, |
diff --git a/arch/alpha/kernel/sys_marvel.c b/arch/alpha/kernel/sys_marvel.c index c5a1a2438c67..bbfc4f20ca72 100644 --- a/arch/alpha/kernel/sys_marvel.c +++ b/arch/alpha/kernel/sys_marvel.c | |||
@@ -169,7 +169,7 @@ marvel_irq_noop_return(unsigned int irq) | |||
169 | return 0; | 169 | return 0; |
170 | } | 170 | } |
171 | 171 | ||
172 | static struct hw_interrupt_type marvel_legacy_irq_type = { | 172 | static struct irq_chip marvel_legacy_irq_type = { |
173 | .typename = "LEGACY", | 173 | .typename = "LEGACY", |
174 | .startup = marvel_irq_noop_return, | 174 | .startup = marvel_irq_noop_return, |
175 | .shutdown = marvel_irq_noop, | 175 | .shutdown = marvel_irq_noop, |
@@ -179,7 +179,7 @@ static struct hw_interrupt_type marvel_legacy_irq_type = { | |||
179 | .end = marvel_irq_noop, | 179 | .end = marvel_irq_noop, |
180 | }; | 180 | }; |
181 | 181 | ||
182 | static struct hw_interrupt_type io7_lsi_irq_type = { | 182 | static struct irq_chip io7_lsi_irq_type = { |
183 | .typename = "LSI", | 183 | .typename = "LSI", |
184 | .startup = io7_startup_irq, | 184 | .startup = io7_startup_irq, |
185 | .shutdown = io7_disable_irq, | 185 | .shutdown = io7_disable_irq, |
@@ -189,7 +189,7 @@ static struct hw_interrupt_type io7_lsi_irq_type = { | |||
189 | .end = io7_end_irq, | 189 | .end = io7_end_irq, |
190 | }; | 190 | }; |
191 | 191 | ||
192 | static struct hw_interrupt_type io7_msi_irq_type = { | 192 | static struct irq_chip io7_msi_irq_type = { |
193 | .typename = "MSI", | 193 | .typename = "MSI", |
194 | .startup = io7_startup_irq, | 194 | .startup = io7_startup_irq, |
195 | .shutdown = io7_disable_irq, | 195 | .shutdown = io7_disable_irq, |
@@ -273,8 +273,8 @@ init_one_io7_msi(struct io7 *io7, unsigned int which, unsigned int where) | |||
273 | 273 | ||
274 | static void __init | 274 | static void __init |
275 | init_io7_irqs(struct io7 *io7, | 275 | init_io7_irqs(struct io7 *io7, |
276 | struct hw_interrupt_type *lsi_ops, | 276 | struct irq_chip *lsi_ops, |
277 | struct hw_interrupt_type *msi_ops) | 277 | struct irq_chip *msi_ops) |
278 | { | 278 | { |
279 | long base = (io7->pe << MARVEL_IRQ_VEC_PE_SHIFT) + 16; | 279 | long base = (io7->pe << MARVEL_IRQ_VEC_PE_SHIFT) + 16; |
280 | long i; | 280 | long i; |
diff --git a/arch/alpha/kernel/sys_mikasa.c b/arch/alpha/kernel/sys_mikasa.c index 8d3e9429c5ee..4e366641a08e 100644 --- a/arch/alpha/kernel/sys_mikasa.c +++ b/arch/alpha/kernel/sys_mikasa.c | |||
@@ -68,7 +68,7 @@ mikasa_end_irq(unsigned int irq) | |||
68 | mikasa_enable_irq(irq); | 68 | mikasa_enable_irq(irq); |
69 | } | 69 | } |
70 | 70 | ||
71 | static struct hw_interrupt_type mikasa_irq_type = { | 71 | static struct irq_chip mikasa_irq_type = { |
72 | .typename = "MIKASA", | 72 | .typename = "MIKASA", |
73 | .startup = mikasa_startup_irq, | 73 | .startup = mikasa_startup_irq, |
74 | .shutdown = mikasa_disable_irq, | 74 | .shutdown = mikasa_disable_irq, |
diff --git a/arch/alpha/kernel/sys_noritake.c b/arch/alpha/kernel/sys_noritake.c index 538876b62449..35753a173bac 100644 --- a/arch/alpha/kernel/sys_noritake.c +++ b/arch/alpha/kernel/sys_noritake.c | |||
@@ -73,7 +73,7 @@ noritake_end_irq(unsigned int irq) | |||
73 | noritake_enable_irq(irq); | 73 | noritake_enable_irq(irq); |
74 | } | 74 | } |
75 | 75 | ||
76 | static struct hw_interrupt_type noritake_irq_type = { | 76 | static struct irq_chip noritake_irq_type = { |
77 | .typename = "NORITAKE", | 77 | .typename = "NORITAKE", |
78 | .startup = noritake_startup_irq, | 78 | .startup = noritake_startup_irq, |
79 | .shutdown = noritake_disable_irq, | 79 | .shutdown = noritake_disable_irq, |
diff --git a/arch/alpha/kernel/sys_rawhide.c b/arch/alpha/kernel/sys_rawhide.c index 672cb2df53df..f3aec7e085c8 100644 --- a/arch/alpha/kernel/sys_rawhide.c +++ b/arch/alpha/kernel/sys_rawhide.c | |||
@@ -135,7 +135,7 @@ rawhide_end_irq(unsigned int irq) | |||
135 | rawhide_enable_irq(irq); | 135 | rawhide_enable_irq(irq); |
136 | } | 136 | } |
137 | 137 | ||
138 | static struct hw_interrupt_type rawhide_irq_type = { | 138 | static struct irq_chip rawhide_irq_type = { |
139 | .typename = "RAWHIDE", | 139 | .typename = "RAWHIDE", |
140 | .startup = rawhide_startup_irq, | 140 | .startup = rawhide_startup_irq, |
141 | .shutdown = rawhide_disable_irq, | 141 | .shutdown = rawhide_disable_irq, |
diff --git a/arch/alpha/kernel/sys_ruffian.c b/arch/alpha/kernel/sys_ruffian.c index f15a329b6011..d9f9cfeb9931 100644 --- a/arch/alpha/kernel/sys_ruffian.c +++ b/arch/alpha/kernel/sys_ruffian.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/sched.h> | 14 | #include <linux/sched.h> |
15 | #include <linux/pci.h> | 15 | #include <linux/pci.h> |
16 | #include <linux/ioport.h> | 16 | #include <linux/ioport.h> |
17 | #include <linux/timex.h> | ||
17 | #include <linux/init.h> | 18 | #include <linux/init.h> |
18 | 19 | ||
19 | #include <asm/ptrace.h> | 20 | #include <asm/ptrace.h> |
diff --git a/arch/alpha/kernel/sys_rx164.c b/arch/alpha/kernel/sys_rx164.c index ce1faa6f1df1..fc9246373452 100644 --- a/arch/alpha/kernel/sys_rx164.c +++ b/arch/alpha/kernel/sys_rx164.c | |||
@@ -72,7 +72,7 @@ rx164_end_irq(unsigned int irq) | |||
72 | rx164_enable_irq(irq); | 72 | rx164_enable_irq(irq); |
73 | } | 73 | } |
74 | 74 | ||
75 | static struct hw_interrupt_type rx164_irq_type = { | 75 | static struct irq_chip rx164_irq_type = { |
76 | .typename = "RX164", | 76 | .typename = "RX164", |
77 | .startup = rx164_startup_irq, | 77 | .startup = rx164_startup_irq, |
78 | .shutdown = rx164_disable_irq, | 78 | .shutdown = rx164_disable_irq, |
diff --git a/arch/alpha/kernel/sys_sable.c b/arch/alpha/kernel/sys_sable.c index 9e263256a42d..426eb6906d01 100644 --- a/arch/alpha/kernel/sys_sable.c +++ b/arch/alpha/kernel/sys_sable.c | |||
@@ -501,7 +501,7 @@ sable_lynx_mask_and_ack_irq(unsigned int irq) | |||
501 | spin_unlock(&sable_lynx_irq_lock); | 501 | spin_unlock(&sable_lynx_irq_lock); |
502 | } | 502 | } |
503 | 503 | ||
504 | static struct hw_interrupt_type sable_lynx_irq_type = { | 504 | static struct irq_chip sable_lynx_irq_type = { |
505 | .typename = "SABLE/LYNX", | 505 | .typename = "SABLE/LYNX", |
506 | .startup = sable_lynx_startup_irq, | 506 | .startup = sable_lynx_startup_irq, |
507 | .shutdown = sable_lynx_disable_irq, | 507 | .shutdown = sable_lynx_disable_irq, |
diff --git a/arch/alpha/kernel/sys_takara.c b/arch/alpha/kernel/sys_takara.c index 9bd9a31450c6..830318c21661 100644 --- a/arch/alpha/kernel/sys_takara.c +++ b/arch/alpha/kernel/sys_takara.c | |||
@@ -74,7 +74,7 @@ takara_end_irq(unsigned int irq) | |||
74 | takara_enable_irq(irq); | 74 | takara_enable_irq(irq); |
75 | } | 75 | } |
76 | 76 | ||
77 | static struct hw_interrupt_type takara_irq_type = { | 77 | static struct irq_chip takara_irq_type = { |
78 | .typename = "TAKARA", | 78 | .typename = "TAKARA", |
79 | .startup = takara_startup_irq, | 79 | .startup = takara_startup_irq, |
80 | .shutdown = takara_disable_irq, | 80 | .shutdown = takara_disable_irq, |
diff --git a/arch/alpha/kernel/sys_titan.c b/arch/alpha/kernel/sys_titan.c index 8dd239ebdb9e..88978fc60f83 100644 --- a/arch/alpha/kernel/sys_titan.c +++ b/arch/alpha/kernel/sys_titan.c | |||
@@ -185,7 +185,7 @@ titan_srm_device_interrupt(unsigned long vector) | |||
185 | 185 | ||
186 | 186 | ||
187 | static void __init | 187 | static void __init |
188 | init_titan_irqs(struct hw_interrupt_type * ops, int imin, int imax) | 188 | init_titan_irqs(struct irq_chip * ops, int imin, int imax) |
189 | { | 189 | { |
190 | long i; | 190 | long i; |
191 | for (i = imin; i <= imax; ++i) { | 191 | for (i = imin; i <= imax; ++i) { |
@@ -194,7 +194,7 @@ init_titan_irqs(struct hw_interrupt_type * ops, int imin, int imax) | |||
194 | } | 194 | } |
195 | } | 195 | } |
196 | 196 | ||
197 | static struct hw_interrupt_type titan_irq_type = { | 197 | static struct irq_chip titan_irq_type = { |
198 | .typename = "TITAN", | 198 | .typename = "TITAN", |
199 | .startup = titan_startup_irq, | 199 | .startup = titan_startup_irq, |
200 | .shutdown = titan_disable_irq, | 200 | .shutdown = titan_disable_irq, |
diff --git a/arch/alpha/kernel/sys_wildfire.c b/arch/alpha/kernel/sys_wildfire.c index 42c3eede4d09..e91b4c3838a8 100644 --- a/arch/alpha/kernel/sys_wildfire.c +++ b/arch/alpha/kernel/sys_wildfire.c | |||
@@ -157,7 +157,7 @@ wildfire_end_irq(unsigned int irq) | |||
157 | wildfire_enable_irq(irq); | 157 | wildfire_enable_irq(irq); |
158 | } | 158 | } |
159 | 159 | ||
160 | static struct hw_interrupt_type wildfire_irq_type = { | 160 | static struct irq_chip wildfire_irq_type = { |
161 | .typename = "WILDFIRE", | 161 | .typename = "WILDFIRE", |
162 | .startup = wildfire_startup_irq, | 162 | .startup = wildfire_startup_irq, |
163 | .shutdown = wildfire_disable_irq, | 163 | .shutdown = wildfire_disable_irq, |
diff --git a/arch/alpha/mm/numa.c b/arch/alpha/mm/numa.c index a13de49d1265..0eab55749423 100644 --- a/arch/alpha/mm/numa.c +++ b/arch/alpha/mm/numa.c | |||
@@ -28,9 +28,9 @@ EXPORT_SYMBOL(node_data); | |||
28 | #define DBGDCONT(args...) | 28 | #define DBGDCONT(args...) |
29 | #endif | 29 | #endif |
30 | 30 | ||
31 | #define for_each_mem_cluster(memdesc, cluster, i) \ | 31 | #define for_each_mem_cluster(memdesc, _cluster, i) \ |
32 | for ((cluster) = (memdesc)->cluster, (i) = 0; \ | 32 | for ((_cluster) = (memdesc)->cluster, (i) = 0; \ |
33 | (i) < (memdesc)->numclusters; (i)++, (cluster)++) | 33 | (i) < (memdesc)->numclusters; (i)++, (_cluster)++) |
34 | 34 | ||
35 | static void __init show_mem_layout(void) | 35 | static void __init show_mem_layout(void) |
36 | { | 36 | { |
diff --git a/arch/arm/kernel/init_task.c b/arch/arm/kernel/init_task.c index e859af349467..3f470866bb89 100644 --- a/arch/arm/kernel/init_task.c +++ b/arch/arm/kernel/init_task.c | |||
@@ -14,10 +14,6 @@ | |||
14 | 14 | ||
15 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); | 15 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); |
16 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); | 16 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); |
17 | struct mm_struct init_mm = INIT_MM(init_mm); | ||
18 | |||
19 | EXPORT_SYMBOL(init_mm); | ||
20 | |||
21 | /* | 17 | /* |
22 | * Initial thread structure. | 18 | * Initial thread structure. |
23 | * | 19 | * |
diff --git a/arch/avr32/kernel/init_task.c b/arch/avr32/kernel/init_task.c index 993d56ee3cf3..57ec9f2dcd95 100644 --- a/arch/avr32/kernel/init_task.c +++ b/arch/avr32/kernel/init_task.c | |||
@@ -15,10 +15,6 @@ | |||
15 | 15 | ||
16 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); | 16 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); |
17 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); | 17 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); |
18 | struct mm_struct init_mm = INIT_MM(init_mm); | ||
19 | |||
20 | EXPORT_SYMBOL(init_mm); | ||
21 | |||
22 | /* | 18 | /* |
23 | * Initial thread structure. Must be aligned on an 8192-byte boundary. | 19 | * Initial thread structure. Must be aligned on an 8192-byte boundary. |
24 | */ | 20 | */ |
diff --git a/arch/blackfin/include/asm/kmap_types.h b/arch/blackfin/include/asm/kmap_types.h index e215f7104974..0a88622339ee 100644 --- a/arch/blackfin/include/asm/kmap_types.h +++ b/arch/blackfin/include/asm/kmap_types.h | |||
@@ -1,21 +1,6 @@ | |||
1 | #ifndef _ASM_KMAP_TYPES_H | 1 | #ifndef _ASM_KMAP_TYPES_H |
2 | #define _ASM_KMAP_TYPES_H | 2 | #define _ASM_KMAP_TYPES_H |
3 | 3 | ||
4 | enum km_type { | 4 | #include <asm-generic/kmap_types.h> |
5 | KM_BOUNCE_READ, | ||
6 | KM_SKB_SUNRPC_DATA, | ||
7 | KM_SKB_DATA_SOFTIRQ, | ||
8 | KM_USER0, | ||
9 | KM_USER1, | ||
10 | KM_BIO_SRC_IRQ, | ||
11 | KM_BIO_DST_IRQ, | ||
12 | KM_PTE0, | ||
13 | KM_PTE1, | ||
14 | KM_IRQ0, | ||
15 | KM_IRQ1, | ||
16 | KM_SOFTIRQ0, | ||
17 | KM_SOFTIRQ1, | ||
18 | KM_TYPE_NR | ||
19 | }; | ||
20 | 5 | ||
21 | #endif | 6 | #endif |
diff --git a/arch/blackfin/kernel/init_task.c b/arch/blackfin/kernel/init_task.c index 2c228c020978..c26c34de9f3c 100644 --- a/arch/blackfin/kernel/init_task.c +++ b/arch/blackfin/kernel/init_task.c | |||
@@ -35,10 +35,6 @@ | |||
35 | 35 | ||
36 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); | 36 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); |
37 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); | 37 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); |
38 | |||
39 | struct mm_struct init_mm = INIT_MM(init_mm); | ||
40 | EXPORT_SYMBOL(init_mm); | ||
41 | |||
42 | /* | 38 | /* |
43 | * Initial task structure. | 39 | * Initial task structure. |
44 | * | 40 | * |
diff --git a/arch/cris/include/asm/kmap_types.h b/arch/cris/include/asm/kmap_types.h index 492988cb9077..d2d643c4ea59 100644 --- a/arch/cris/include/asm/kmap_types.h +++ b/arch/cris/include/asm/kmap_types.h | |||
@@ -5,21 +5,6 @@ | |||
5 | * is actually used on cris. | 5 | * is actually used on cris. |
6 | */ | 6 | */ |
7 | 7 | ||
8 | enum km_type { | 8 | #include <asm-generic/kmap_types.h> |
9 | KM_BOUNCE_READ, | ||
10 | KM_SKB_SUNRPC_DATA, | ||
11 | KM_SKB_DATA_SOFTIRQ, | ||
12 | KM_USER0, | ||
13 | KM_USER1, | ||
14 | KM_BIO_SRC_IRQ, | ||
15 | KM_BIO_DST_IRQ, | ||
16 | KM_PTE0, | ||
17 | KM_PTE1, | ||
18 | KM_IRQ0, | ||
19 | KM_IRQ1, | ||
20 | KM_SOFTIRQ0, | ||
21 | KM_SOFTIRQ1, | ||
22 | KM_TYPE_NR | ||
23 | }; | ||
24 | 9 | ||
25 | #endif | 10 | #endif |
diff --git a/arch/cris/kernel/process.c b/arch/cris/kernel/process.c index 4df0b320d524..51dcd04d2777 100644 --- a/arch/cris/kernel/process.c +++ b/arch/cris/kernel/process.c | |||
@@ -38,10 +38,6 @@ | |||
38 | 38 | ||
39 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); | 39 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); |
40 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); | 40 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); |
41 | struct mm_struct init_mm = INIT_MM(init_mm); | ||
42 | |||
43 | EXPORT_SYMBOL(init_mm); | ||
44 | |||
45 | /* | 41 | /* |
46 | * Initial thread structure. | 42 | * Initial thread structure. |
47 | * | 43 | * |
diff --git a/arch/frv/kernel/init_task.c b/arch/frv/kernel/init_task.c index 29429a8b7f6a..1d3df1d9495c 100644 --- a/arch/frv/kernel/init_task.c +++ b/arch/frv/kernel/init_task.c | |||
@@ -12,10 +12,6 @@ | |||
12 | 12 | ||
13 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); | 13 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); |
14 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); | 14 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); |
15 | struct mm_struct init_mm = INIT_MM(init_mm); | ||
16 | |||
17 | EXPORT_SYMBOL(init_mm); | ||
18 | |||
19 | /* | 15 | /* |
20 | * Initial thread structure. | 16 | * Initial thread structure. |
21 | * | 17 | * |
diff --git a/arch/h8300/include/asm/kmap_types.h b/arch/h8300/include/asm/kmap_types.h index 1ec8a3427120..be12a7160116 100644 --- a/arch/h8300/include/asm/kmap_types.h +++ b/arch/h8300/include/asm/kmap_types.h | |||
@@ -1,21 +1,6 @@ | |||
1 | #ifndef _ASM_H8300_KMAP_TYPES_H | 1 | #ifndef _ASM_H8300_KMAP_TYPES_H |
2 | #define _ASM_H8300_KMAP_TYPES_H | 2 | #define _ASM_H8300_KMAP_TYPES_H |
3 | 3 | ||
4 | enum km_type { | 4 | #include <asm-generic/kmap_types.h> |
5 | KM_BOUNCE_READ, | ||
6 | KM_SKB_SUNRPC_DATA, | ||
7 | KM_SKB_DATA_SOFTIRQ, | ||
8 | KM_USER0, | ||
9 | KM_USER1, | ||
10 | KM_BIO_SRC_IRQ, | ||
11 | KM_BIO_DST_IRQ, | ||
12 | KM_PTE0, | ||
13 | KM_PTE1, | ||
14 | KM_IRQ0, | ||
15 | KM_IRQ1, | ||
16 | KM_SOFTIRQ0, | ||
17 | KM_SOFTIRQ1, | ||
18 | KM_TYPE_NR | ||
19 | }; | ||
20 | 5 | ||
21 | #endif | 6 | #endif |
diff --git a/arch/h8300/kernel/init_task.c b/arch/h8300/kernel/init_task.c index cb5dc552da97..089c65ed6eb3 100644 --- a/arch/h8300/kernel/init_task.c +++ b/arch/h8300/kernel/init_task.c | |||
@@ -14,10 +14,6 @@ | |||
14 | 14 | ||
15 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); | 15 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); |
16 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); | 16 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); |
17 | struct mm_struct init_mm = INIT_MM(init_mm); | ||
18 | |||
19 | EXPORT_SYMBOL(init_mm); | ||
20 | |||
21 | /* | 17 | /* |
22 | * Initial task structure. | 18 | * Initial task structure. |
23 | * | 19 | * |
diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c index 56ceb68eb99d..fe63b2dc9d07 100644 --- a/arch/ia64/hp/common/sba_iommu.c +++ b/arch/ia64/hp/common/sba_iommu.c | |||
@@ -1131,7 +1131,7 @@ sba_alloc_coherent (struct device *dev, size_t size, dma_addr_t *dma_handle, gfp | |||
1131 | #ifdef CONFIG_NUMA | 1131 | #ifdef CONFIG_NUMA |
1132 | { | 1132 | { |
1133 | struct page *page; | 1133 | struct page *page; |
1134 | page = alloc_pages_node(ioc->node == MAX_NUMNODES ? | 1134 | page = alloc_pages_exact_node(ioc->node == MAX_NUMNODES ? |
1135 | numa_node_id() : ioc->node, flags, | 1135 | numa_node_id() : ioc->node, flags, |
1136 | get_order(size)); | 1136 | get_order(size)); |
1137 | 1137 | ||
diff --git a/arch/ia64/include/asm/kmap_types.h b/arch/ia64/include/asm/kmap_types.h index 5d1658aa2b3b..05d5f9996105 100644 --- a/arch/ia64/include/asm/kmap_types.h +++ b/arch/ia64/include/asm/kmap_types.h | |||
@@ -1,30 +1,12 @@ | |||
1 | #ifndef _ASM_IA64_KMAP_TYPES_H | 1 | #ifndef _ASM_IA64_KMAP_TYPES_H |
2 | #define _ASM_IA64_KMAP_TYPES_H | 2 | #define _ASM_IA64_KMAP_TYPES_H |
3 | 3 | ||
4 | |||
5 | #ifdef CONFIG_DEBUG_HIGHMEM | 4 | #ifdef CONFIG_DEBUG_HIGHMEM |
6 | # define D(n) __KM_FENCE_##n , | 5 | #define __WITH_KM_FENCE |
7 | #else | ||
8 | # define D(n) | ||
9 | #endif | 6 | #endif |
10 | 7 | ||
11 | enum km_type { | 8 | #include <asm-generic/kmap_types.h> |
12 | D(0) KM_BOUNCE_READ, | ||
13 | D(1) KM_SKB_SUNRPC_DATA, | ||
14 | D(2) KM_SKB_DATA_SOFTIRQ, | ||
15 | D(3) KM_USER0, | ||
16 | D(4) KM_USER1, | ||
17 | D(5) KM_BIO_SRC_IRQ, | ||
18 | D(6) KM_BIO_DST_IRQ, | ||
19 | D(7) KM_PTE0, | ||
20 | D(8) KM_PTE1, | ||
21 | D(9) KM_IRQ0, | ||
22 | D(10) KM_IRQ1, | ||
23 | D(11) KM_SOFTIRQ0, | ||
24 | D(12) KM_SOFTIRQ1, | ||
25 | D(13) KM_TYPE_NR | ||
26 | }; | ||
27 | 9 | ||
28 | #undef D | 10 | #undef __WITH_KM_FENCE |
29 | 11 | ||
30 | #endif /* _ASM_IA64_KMAP_TYPES_H */ | 12 | #endif /* _ASM_IA64_KMAP_TYPES_H */ |
diff --git a/arch/ia64/kernel/init_task.c b/arch/ia64/kernel/init_task.c index 5b0e830c6f33..c475fc281be7 100644 --- a/arch/ia64/kernel/init_task.c +++ b/arch/ia64/kernel/init_task.c | |||
@@ -19,10 +19,6 @@ | |||
19 | 19 | ||
20 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); | 20 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); |
21 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); | 21 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); |
22 | struct mm_struct init_mm = INIT_MM(init_mm); | ||
23 | |||
24 | EXPORT_SYMBOL(init_mm); | ||
25 | |||
26 | /* | 22 | /* |
27 | * Initial task structure. | 23 | * Initial task structure. |
28 | * | 24 | * |
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c index 8f33a8840422..5b17bd402275 100644 --- a/arch/ia64/kernel/mca.c +++ b/arch/ia64/kernel/mca.c | |||
@@ -1829,8 +1829,7 @@ ia64_mca_cpu_init(void *cpu_data) | |||
1829 | data = mca_bootmem(); | 1829 | data = mca_bootmem(); |
1830 | first_time = 0; | 1830 | first_time = 0; |
1831 | } else | 1831 | } else |
1832 | data = page_address(alloc_pages_node(numa_node_id(), | 1832 | data = __get_free_pages(GFP_KERNEL, get_order(sz)); |
1833 | GFP_KERNEL, get_order(sz))); | ||
1834 | if (!data) | 1833 | if (!data) |
1835 | panic("Could not allocate MCA memory for cpu %d\n", | 1834 | panic("Could not allocate MCA memory for cpu %d\n", |
1836 | cpu); | 1835 | cpu); |
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index 8a06dc480594..bdc176cb5e85 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c | |||
@@ -5595,7 +5595,7 @@ pfm_interrupt_handler(int irq, void *arg) | |||
5595 | (*pfm_alt_intr_handler->handler)(irq, arg, regs); | 5595 | (*pfm_alt_intr_handler->handler)(irq, arg, regs); |
5596 | } | 5596 | } |
5597 | 5597 | ||
5598 | put_cpu_no_resched(); | 5598 | put_cpu(); |
5599 | return IRQ_HANDLED; | 5599 | return IRQ_HANDLED; |
5600 | } | 5600 | } |
5601 | 5601 | ||
diff --git a/arch/ia64/kernel/uncached.c b/arch/ia64/kernel/uncached.c index 8eff8c1d40a6..6ba72ab42fcc 100644 --- a/arch/ia64/kernel/uncached.c +++ b/arch/ia64/kernel/uncached.c | |||
@@ -98,7 +98,8 @@ static int uncached_add_chunk(struct uncached_pool *uc_pool, int nid) | |||
98 | 98 | ||
99 | /* attempt to allocate a granule's worth of cached memory pages */ | 99 | /* attempt to allocate a granule's worth of cached memory pages */ |
100 | 100 | ||
101 | page = alloc_pages_node(nid, GFP_KERNEL | __GFP_ZERO | GFP_THISNODE, | 101 | page = alloc_pages_exact_node(nid, |
102 | GFP_KERNEL | __GFP_ZERO | GFP_THISNODE, | ||
102 | IA64_GRANULE_SHIFT-PAGE_SHIFT); | 103 | IA64_GRANULE_SHIFT-PAGE_SHIFT); |
103 | if (!page) { | 104 | if (!page) { |
104 | mutex_unlock(&uc_pool->add_chunk_mutex); | 105 | mutex_unlock(&uc_pool->add_chunk_mutex); |
diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c index d876423e4e75..98b684928e12 100644 --- a/arch/ia64/sn/pci/pci_dma.c +++ b/arch/ia64/sn/pci/pci_dma.c | |||
@@ -90,7 +90,8 @@ static void *sn_dma_alloc_coherent(struct device *dev, size_t size, | |||
90 | */ | 90 | */ |
91 | node = pcibus_to_node(pdev->bus); | 91 | node = pcibus_to_node(pdev->bus); |
92 | if (likely(node >=0)) { | 92 | if (likely(node >=0)) { |
93 | struct page *p = alloc_pages_node(node, flags, get_order(size)); | 93 | struct page *p = alloc_pages_exact_node(node, |
94 | flags, get_order(size)); | ||
94 | 95 | ||
95 | if (likely(p)) | 96 | if (likely(p)) |
96 | cpuaddr = page_address(p); | 97 | cpuaddr = page_address(p); |
diff --git a/arch/m32r/include/asm/kmap_types.h b/arch/m32r/include/asm/kmap_types.h index fa94dc6410ea..4cdb5e3a06bf 100644 --- a/arch/m32r/include/asm/kmap_types.h +++ b/arch/m32r/include/asm/kmap_types.h | |||
@@ -2,28 +2,11 @@ | |||
2 | #define __M32R_KMAP_TYPES_H | 2 | #define __M32R_KMAP_TYPES_H |
3 | 3 | ||
4 | #ifdef CONFIG_DEBUG_HIGHMEM | 4 | #ifdef CONFIG_DEBUG_HIGHMEM |
5 | # define D(n) __KM_FENCE_##n , | 5 | #define __WITH_KM_FENCE |
6 | #else | ||
7 | # define D(n) | ||
8 | #endif | 6 | #endif |
9 | 7 | ||
10 | enum km_type { | 8 | #include <asm-generic/kmap_types.h> |
11 | D(0) KM_BOUNCE_READ, | ||
12 | D(1) KM_SKB_SUNRPC_DATA, | ||
13 | D(2) KM_SKB_DATA_SOFTIRQ, | ||
14 | D(3) KM_USER0, | ||
15 | D(4) KM_USER1, | ||
16 | D(5) KM_BIO_SRC_IRQ, | ||
17 | D(6) KM_BIO_DST_IRQ, | ||
18 | D(7) KM_PTE0, | ||
19 | D(8) KM_PTE1, | ||
20 | D(9) KM_IRQ0, | ||
21 | D(10) KM_IRQ1, | ||
22 | D(11) KM_SOFTIRQ0, | ||
23 | D(12) KM_SOFTIRQ1, | ||
24 | D(13) KM_TYPE_NR | ||
25 | }; | ||
26 | 9 | ||
27 | #undef D | 10 | #undef __WITH_KM_FENCE |
28 | 11 | ||
29 | #endif /* __M32R_KMAP_TYPES_H */ | 12 | #endif /* __M32R_KMAP_TYPES_H */ |
diff --git a/arch/m32r/kernel/init_task.c b/arch/m32r/kernel/init_task.c index 016885c6f260..fce57e5d3f91 100644 --- a/arch/m32r/kernel/init_task.c +++ b/arch/m32r/kernel/init_task.c | |||
@@ -13,10 +13,6 @@ | |||
13 | 13 | ||
14 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); | 14 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); |
15 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); | 15 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); |
16 | struct mm_struct init_mm = INIT_MM(init_mm); | ||
17 | |||
18 | EXPORT_SYMBOL(init_mm); | ||
19 | |||
20 | /* | 16 | /* |
21 | * Initial thread structure. | 17 | * Initial thread structure. |
22 | * | 18 | * |
diff --git a/arch/m32r/mm/discontig.c b/arch/m32r/mm/discontig.c index 7daf897292cf..b7a78ad429b7 100644 --- a/arch/m32r/mm/discontig.c +++ b/arch/m32r/mm/discontig.c | |||
@@ -154,9 +154,9 @@ unsigned long __init zone_sizes_init(void) | |||
154 | * Use all area of internal RAM. | 154 | * Use all area of internal RAM. |
155 | * see __alloc_pages() | 155 | * see __alloc_pages() |
156 | */ | 156 | */ |
157 | NODE_DATA(1)->node_zones->pages_min = 0; | 157 | NODE_DATA(1)->node_zones->watermark[WMARK_MIN] = 0; |
158 | NODE_DATA(1)->node_zones->pages_low = 0; | 158 | NODE_DATA(1)->node_zones->watermark[WMARK_LOW] = 0; |
159 | NODE_DATA(1)->node_zones->pages_high = 0; | 159 | NODE_DATA(1)->node_zones->watermark[WMARK_HIGH] = 0; |
160 | 160 | ||
161 | return holes; | 161 | return holes; |
162 | } | 162 | } |
diff --git a/arch/m32r/platforms/m32104ut/setup.c b/arch/m32r/platforms/m32104ut/setup.c index 98138b4e9220..922fdfdadeaa 100644 --- a/arch/m32r/platforms/m32104ut/setup.c +++ b/arch/m32r/platforms/m32104ut/setup.c | |||
@@ -63,7 +63,7 @@ static void shutdown_m32104ut_irq(unsigned int irq) | |||
63 | outl(M32R_ICUCR_ILEVEL7, port); | 63 | outl(M32R_ICUCR_ILEVEL7, port); |
64 | } | 64 | } |
65 | 65 | ||
66 | static struct hw_interrupt_type m32104ut_irq_type = | 66 | static struct irq_chip m32104ut_irq_type = |
67 | { | 67 | { |
68 | .typename = "M32104UT-IRQ", | 68 | .typename = "M32104UT-IRQ", |
69 | .startup = startup_m32104ut_irq, | 69 | .startup = startup_m32104ut_irq, |
diff --git a/arch/m32r/platforms/m32700ut/setup.c b/arch/m32r/platforms/m32700ut/setup.c index 77b0ae9379e9..9c1bc7487c1e 100644 --- a/arch/m32r/platforms/m32700ut/setup.c +++ b/arch/m32r/platforms/m32700ut/setup.c | |||
@@ -69,7 +69,7 @@ static void shutdown_m32700ut_irq(unsigned int irq) | |||
69 | outl(M32R_ICUCR_ILEVEL7, port); | 69 | outl(M32R_ICUCR_ILEVEL7, port); |
70 | } | 70 | } |
71 | 71 | ||
72 | static struct hw_interrupt_type m32700ut_irq_type = | 72 | static struct irq_chip m32700ut_irq_type = |
73 | { | 73 | { |
74 | .typename = "M32700UT-IRQ", | 74 | .typename = "M32700UT-IRQ", |
75 | .startup = startup_m32700ut_irq, | 75 | .startup = startup_m32700ut_irq, |
@@ -146,7 +146,7 @@ static void shutdown_m32700ut_pld_irq(unsigned int irq) | |||
146 | outw(PLD_ICUCR_ILEVEL7, port); | 146 | outw(PLD_ICUCR_ILEVEL7, port); |
147 | } | 147 | } |
148 | 148 | ||
149 | static struct hw_interrupt_type m32700ut_pld_irq_type = | 149 | static struct irq_chip m32700ut_pld_irq_type = |
150 | { | 150 | { |
151 | .typename = "M32700UT-PLD-IRQ", | 151 | .typename = "M32700UT-PLD-IRQ", |
152 | .startup = startup_m32700ut_pld_irq, | 152 | .startup = startup_m32700ut_pld_irq, |
@@ -215,7 +215,7 @@ static void shutdown_m32700ut_lanpld_irq(unsigned int irq) | |||
215 | outw(PLD_ICUCR_ILEVEL7, port); | 215 | outw(PLD_ICUCR_ILEVEL7, port); |
216 | } | 216 | } |
217 | 217 | ||
218 | static struct hw_interrupt_type m32700ut_lanpld_irq_type = | 218 | static struct irq_chip m32700ut_lanpld_irq_type = |
219 | { | 219 | { |
220 | .typename = "M32700UT-PLD-LAN-IRQ", | 220 | .typename = "M32700UT-PLD-LAN-IRQ", |
221 | .startup = startup_m32700ut_lanpld_irq, | 221 | .startup = startup_m32700ut_lanpld_irq, |
@@ -284,7 +284,7 @@ static void shutdown_m32700ut_lcdpld_irq(unsigned int irq) | |||
284 | outw(PLD_ICUCR_ILEVEL7, port); | 284 | outw(PLD_ICUCR_ILEVEL7, port); |
285 | } | 285 | } |
286 | 286 | ||
287 | static struct hw_interrupt_type m32700ut_lcdpld_irq_type = | 287 | static struct irq_chip m32700ut_lcdpld_irq_type = |
288 | { | 288 | { |
289 | .typename = "M32700UT-PLD-LCD-IRQ", | 289 | .typename = "M32700UT-PLD-LCD-IRQ", |
290 | .startup = startup_m32700ut_lcdpld_irq, | 290 | .startup = startup_m32700ut_lcdpld_irq, |
diff --git a/arch/m32r/platforms/mappi/setup.c b/arch/m32r/platforms/mappi/setup.c index 3ec087ff2214..fb4b17799b66 100644 --- a/arch/m32r/platforms/mappi/setup.c +++ b/arch/m32r/platforms/mappi/setup.c | |||
@@ -63,7 +63,7 @@ static void shutdown_mappi_irq(unsigned int irq) | |||
63 | outl(M32R_ICUCR_ILEVEL7, port); | 63 | outl(M32R_ICUCR_ILEVEL7, port); |
64 | } | 64 | } |
65 | 65 | ||
66 | static struct hw_interrupt_type mappi_irq_type = | 66 | static struct irq_chip mappi_irq_type = |
67 | { | 67 | { |
68 | .typename = "MAPPI-IRQ", | 68 | .typename = "MAPPI-IRQ", |
69 | .startup = startup_mappi_irq, | 69 | .startup = startup_mappi_irq, |
diff --git a/arch/m32r/platforms/mappi2/setup.c b/arch/m32r/platforms/mappi2/setup.c index d87969c6356e..6a65eda0a056 100644 --- a/arch/m32r/platforms/mappi2/setup.c +++ b/arch/m32r/platforms/mappi2/setup.c | |||
@@ -70,7 +70,7 @@ static void shutdown_mappi2_irq(unsigned int irq) | |||
70 | outl(M32R_ICUCR_ILEVEL7, port); | 70 | outl(M32R_ICUCR_ILEVEL7, port); |
71 | } | 71 | } |
72 | 72 | ||
73 | static struct hw_interrupt_type mappi2_irq_type = | 73 | static struct irq_chip mappi2_irq_type = |
74 | { | 74 | { |
75 | .typename = "MAPPI2-IRQ", | 75 | .typename = "MAPPI2-IRQ", |
76 | .startup = startup_mappi2_irq, | 76 | .startup = startup_mappi2_irq, |
diff --git a/arch/m32r/platforms/mappi3/setup.c b/arch/m32r/platforms/mappi3/setup.c index 785b4bd6d9fd..9c337aeac94b 100644 --- a/arch/m32r/platforms/mappi3/setup.c +++ b/arch/m32r/platforms/mappi3/setup.c | |||
@@ -70,7 +70,7 @@ static void shutdown_mappi3_irq(unsigned int irq) | |||
70 | outl(M32R_ICUCR_ILEVEL7, port); | 70 | outl(M32R_ICUCR_ILEVEL7, port); |
71 | } | 71 | } |
72 | 72 | ||
73 | static struct hw_interrupt_type mappi3_irq_type = | 73 | static struct irq_chip mappi3_irq_type = |
74 | { | 74 | { |
75 | .typename = "MAPPI3-IRQ", | 75 | .typename = "MAPPI3-IRQ", |
76 | .startup = startup_mappi3_irq, | 76 | .startup = startup_mappi3_irq, |
diff --git a/arch/m32r/platforms/oaks32r/setup.c b/arch/m32r/platforms/oaks32r/setup.c index 6faa5db68e95..ed865741c38d 100644 --- a/arch/m32r/platforms/oaks32r/setup.c +++ b/arch/m32r/platforms/oaks32r/setup.c | |||
@@ -61,7 +61,7 @@ static void shutdown_oaks32r_irq(unsigned int irq) | |||
61 | outl(M32R_ICUCR_ILEVEL7, port); | 61 | outl(M32R_ICUCR_ILEVEL7, port); |
62 | } | 62 | } |
63 | 63 | ||
64 | static struct hw_interrupt_type oaks32r_irq_type = | 64 | static struct irq_chip oaks32r_irq_type = |
65 | { | 65 | { |
66 | .typename = "OAKS32R-IRQ", | 66 | .typename = "OAKS32R-IRQ", |
67 | .startup = startup_oaks32r_irq, | 67 | .startup = startup_oaks32r_irq, |
diff --git a/arch/m32r/platforms/opsput/setup.c b/arch/m32r/platforms/opsput/setup.c index fab13fd85422..80d680657019 100644 --- a/arch/m32r/platforms/opsput/setup.c +++ b/arch/m32r/platforms/opsput/setup.c | |||
@@ -70,7 +70,7 @@ static void shutdown_opsput_irq(unsigned int irq) | |||
70 | outl(M32R_ICUCR_ILEVEL7, port); | 70 | outl(M32R_ICUCR_ILEVEL7, port); |
71 | } | 71 | } |
72 | 72 | ||
73 | static struct hw_interrupt_type opsput_irq_type = | 73 | static struct irq_chip opsput_irq_type = |
74 | { | 74 | { |
75 | .typename = "OPSPUT-IRQ", | 75 | .typename = "OPSPUT-IRQ", |
76 | .startup = startup_opsput_irq, | 76 | .startup = startup_opsput_irq, |
@@ -147,7 +147,7 @@ static void shutdown_opsput_pld_irq(unsigned int irq) | |||
147 | outw(PLD_ICUCR_ILEVEL7, port); | 147 | outw(PLD_ICUCR_ILEVEL7, port); |
148 | } | 148 | } |
149 | 149 | ||
150 | static struct hw_interrupt_type opsput_pld_irq_type = | 150 | static struct irq_chip opsput_pld_irq_type = |
151 | { | 151 | { |
152 | .typename = "OPSPUT-PLD-IRQ", | 152 | .typename = "OPSPUT-PLD-IRQ", |
153 | .startup = startup_opsput_pld_irq, | 153 | .startup = startup_opsput_pld_irq, |
@@ -216,7 +216,7 @@ static void shutdown_opsput_lanpld_irq(unsigned int irq) | |||
216 | outw(PLD_ICUCR_ILEVEL7, port); | 216 | outw(PLD_ICUCR_ILEVEL7, port); |
217 | } | 217 | } |
218 | 218 | ||
219 | static struct hw_interrupt_type opsput_lanpld_irq_type = | 219 | static struct irq_chip opsput_lanpld_irq_type = |
220 | { | 220 | { |
221 | .typename = "OPSPUT-PLD-LAN-IRQ", | 221 | .typename = "OPSPUT-PLD-LAN-IRQ", |
222 | .startup = startup_opsput_lanpld_irq, | 222 | .startup = startup_opsput_lanpld_irq, |
@@ -285,7 +285,7 @@ static void shutdown_opsput_lcdpld_irq(unsigned int irq) | |||
285 | outw(PLD_ICUCR_ILEVEL7, port); | 285 | outw(PLD_ICUCR_ILEVEL7, port); |
286 | } | 286 | } |
287 | 287 | ||
288 | static struct hw_interrupt_type opsput_lcdpld_irq_type = | 288 | static struct irq_chip opsput_lcdpld_irq_type = |
289 | { | 289 | { |
290 | "OPSPUT-PLD-LCD-IRQ", | 290 | "OPSPUT-PLD-LCD-IRQ", |
291 | startup_opsput_lcdpld_irq, | 291 | startup_opsput_lcdpld_irq, |
diff --git a/arch/m32r/platforms/usrv/setup.c b/arch/m32r/platforms/usrv/setup.c index 89588d649eb7..757302660af8 100644 --- a/arch/m32r/platforms/usrv/setup.c +++ b/arch/m32r/platforms/usrv/setup.c | |||
@@ -61,7 +61,7 @@ static void shutdown_mappi_irq(unsigned int irq) | |||
61 | outl(M32R_ICUCR_ILEVEL7, port); | 61 | outl(M32R_ICUCR_ILEVEL7, port); |
62 | } | 62 | } |
63 | 63 | ||
64 | static struct hw_interrupt_type mappi_irq_type = | 64 | static struct irq_chip mappi_irq_type = |
65 | { | 65 | { |
66 | .typename = "M32700-IRQ", | 66 | .typename = "M32700-IRQ", |
67 | .startup = startup_mappi_irq, | 67 | .startup = startup_mappi_irq, |
@@ -134,7 +134,7 @@ static void shutdown_m32700ut_pld_irq(unsigned int irq) | |||
134 | outw(PLD_ICUCR_ILEVEL7, port); | 134 | outw(PLD_ICUCR_ILEVEL7, port); |
135 | } | 135 | } |
136 | 136 | ||
137 | static struct hw_interrupt_type m32700ut_pld_irq_type = | 137 | static struct irq_chip m32700ut_pld_irq_type = |
138 | { | 138 | { |
139 | .typename = "USRV-PLD-IRQ", | 139 | .typename = "USRV-PLD-IRQ", |
140 | .startup = startup_m32700ut_pld_irq, | 140 | .startup = startup_m32700ut_pld_irq, |
diff --git a/arch/m68k/include/asm/kmap_types.h b/arch/m68k/include/asm/kmap_types.h index c843c63d3801..3413cc1390ec 100644 --- a/arch/m68k/include/asm/kmap_types.h +++ b/arch/m68k/include/asm/kmap_types.h | |||
@@ -1,21 +1,6 @@ | |||
1 | #ifndef __ASM_M68K_KMAP_TYPES_H | 1 | #ifndef __ASM_M68K_KMAP_TYPES_H |
2 | #define __ASM_M68K_KMAP_TYPES_H | 2 | #define __ASM_M68K_KMAP_TYPES_H |
3 | 3 | ||
4 | enum km_type { | 4 | #include <asm-generic/kmap_types.h> |
5 | KM_BOUNCE_READ, | ||
6 | KM_SKB_SUNRPC_DATA, | ||
7 | KM_SKB_DATA_SOFTIRQ, | ||
8 | KM_USER0, | ||
9 | KM_USER1, | ||
10 | KM_BIO_SRC_IRQ, | ||
11 | KM_BIO_DST_IRQ, | ||
12 | KM_PTE0, | ||
13 | KM_PTE1, | ||
14 | KM_IRQ0, | ||
15 | KM_IRQ1, | ||
16 | KM_SOFTIRQ0, | ||
17 | KM_SOFTIRQ1, | ||
18 | KM_TYPE_NR | ||
19 | }; | ||
20 | 5 | ||
21 | #endif /* __ASM_M68K_KMAP_TYPES_H */ | 6 | #endif /* __ASM_M68K_KMAP_TYPES_H */ |
diff --git a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c index ec37fb56c127..72bad65dba3a 100644 --- a/arch/m68k/kernel/process.c +++ b/arch/m68k/kernel/process.c | |||
@@ -42,10 +42,6 @@ | |||
42 | */ | 42 | */ |
43 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); | 43 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); |
44 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); | 44 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); |
45 | struct mm_struct init_mm = INIT_MM(init_mm); | ||
46 | |||
47 | EXPORT_SYMBOL(init_mm); | ||
48 | |||
49 | union thread_union init_thread_union | 45 | union thread_union init_thread_union |
50 | __attribute__((section(".data.init_task"), aligned(THREAD_SIZE))) | 46 | __attribute__((section(".data.init_task"), aligned(THREAD_SIZE))) |
51 | = { INIT_THREAD_INFO(init_task) }; | 47 | = { INIT_THREAD_INFO(init_task) }; |
diff --git a/arch/m68knommu/kernel/init_task.c b/arch/m68knommu/kernel/init_task.c index fe282de1d596..45e97a207fed 100644 --- a/arch/m68knommu/kernel/init_task.c +++ b/arch/m68knommu/kernel/init_task.c | |||
@@ -14,10 +14,6 @@ | |||
14 | 14 | ||
15 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); | 15 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); |
16 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); | 16 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); |
17 | struct mm_struct init_mm = INIT_MM(init_mm); | ||
18 | |||
19 | EXPORT_SYMBOL(init_mm); | ||
20 | |||
21 | /* | 17 | /* |
22 | * Initial task structure. | 18 | * Initial task structure. |
23 | * | 19 | * |
diff --git a/arch/microblaze/include/asm/kmap_types.h b/arch/microblaze/include/asm/kmap_types.h index 4d7e222f5dd7..25975252d83d 100644 --- a/arch/microblaze/include/asm/kmap_types.h +++ b/arch/microblaze/include/asm/kmap_types.h | |||
@@ -1,29 +1,6 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
3 | * | ||
4 | * This file is subject to the terms and conditions of the GNU General Public | ||
5 | * License. See the file "COPYING" in the main directory of this archive | ||
6 | * for more details. | ||
7 | */ | ||
8 | |||
9 | #ifndef _ASM_MICROBLAZE_KMAP_TYPES_H | 1 | #ifndef _ASM_MICROBLAZE_KMAP_TYPES_H |
10 | #define _ASM_MICROBLAZE_KMAP_TYPES_H | 2 | #define _ASM_MICROBLAZE_KMAP_TYPES_H |
11 | 3 | ||
12 | enum km_type { | 4 | #include <asm-generic/kmap_types.h> |
13 | KM_BOUNCE_READ, | ||
14 | KM_SKB_SUNRPC_DATA, | ||
15 | KM_SKB_DATA_SOFTIRQ, | ||
16 | KM_USER0, | ||
17 | KM_USER1, | ||
18 | KM_BIO_SRC_IRQ, | ||
19 | KM_BIO_DST_IRQ, | ||
20 | KM_PTE0, | ||
21 | KM_PTE1, | ||
22 | KM_IRQ0, | ||
23 | KM_IRQ1, | ||
24 | KM_SOFTIRQ0, | ||
25 | KM_SOFTIRQ1, | ||
26 | KM_TYPE_NR, | ||
27 | }; | ||
28 | 5 | ||
29 | #endif /* _ASM_MICROBLAZE_KMAP_TYPES_H */ | 6 | #endif /* _ASM_MICROBLAZE_KMAP_TYPES_H */ |
diff --git a/arch/mips/include/asm/i8253.h b/arch/mips/include/asm/i8253.h index 5dabc870b322..032ca73f181b 100644 --- a/arch/mips/include/asm/i8253.h +++ b/arch/mips/include/asm/i8253.h | |||
@@ -12,8 +12,6 @@ | |||
12 | #define PIT_CH0 0x40 | 12 | #define PIT_CH0 0x40 |
13 | #define PIT_CH2 0x42 | 13 | #define PIT_CH2 0x42 |
14 | 14 | ||
15 | #define PIT_TICK_RATE 1193182UL | ||
16 | |||
17 | extern spinlock_t i8253_lock; | 15 | extern spinlock_t i8253_lock; |
18 | 16 | ||
19 | extern void setup_pit_timer(void); | 17 | extern void setup_pit_timer(void); |
diff --git a/arch/mips/include/asm/kmap_types.h b/arch/mips/include/asm/kmap_types.h index 806aae3c5338..58e91ed0388f 100644 --- a/arch/mips/include/asm/kmap_types.h +++ b/arch/mips/include/asm/kmap_types.h | |||
@@ -1,30 +1,12 @@ | |||
1 | #ifndef _ASM_KMAP_TYPES_H | 1 | #ifndef _ASM_KMAP_TYPES_H |
2 | #define _ASM_KMAP_TYPES_H | 2 | #define _ASM_KMAP_TYPES_H |
3 | 3 | ||
4 | |||
5 | #ifdef CONFIG_DEBUG_HIGHMEM | 4 | #ifdef CONFIG_DEBUG_HIGHMEM |
6 | # define D(n) __KM_FENCE_##n , | 5 | #define __WITH_KM_FENCE |
7 | #else | ||
8 | # define D(n) | ||
9 | #endif | 6 | #endif |
10 | 7 | ||
11 | enum km_type { | 8 | #include <asm-generic/kmap_types.h> |
12 | D(0) KM_BOUNCE_READ, | ||
13 | D(1) KM_SKB_SUNRPC_DATA, | ||
14 | D(2) KM_SKB_DATA_SOFTIRQ, | ||
15 | D(3) KM_USER0, | ||
16 | D(4) KM_USER1, | ||
17 | D(5) KM_BIO_SRC_IRQ, | ||
18 | D(6) KM_BIO_DST_IRQ, | ||
19 | D(7) KM_PTE0, | ||
20 | D(8) KM_PTE1, | ||
21 | D(9) KM_IRQ0, | ||
22 | D(10) KM_IRQ1, | ||
23 | D(11) KM_SOFTIRQ0, | ||
24 | D(12) KM_SOFTIRQ1, | ||
25 | D(13) KM_TYPE_NR | ||
26 | }; | ||
27 | 9 | ||
28 | #undef D | 10 | #undef __WITH_KM_FENCE |
29 | 11 | ||
30 | #endif | 12 | #endif |
diff --git a/arch/mips/kernel/init_task.c b/arch/mips/kernel/init_task.c index 149cd914526e..5b457a40c784 100644 --- a/arch/mips/kernel/init_task.c +++ b/arch/mips/kernel/init_task.c | |||
@@ -11,10 +11,6 @@ | |||
11 | 11 | ||
12 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); | 12 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); |
13 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); | 13 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); |
14 | struct mm_struct init_mm = INIT_MM(init_mm); | ||
15 | |||
16 | EXPORT_SYMBOL(init_mm); | ||
17 | |||
18 | /* | 14 | /* |
19 | * Initial thread structure. | 15 | * Initial thread structure. |
20 | * | 16 | * |
diff --git a/arch/mn10300/include/asm/kmap_types.h b/arch/mn10300/include/asm/kmap_types.h index 3398f9f35603..76d093b58d4f 100644 --- a/arch/mn10300/include/asm/kmap_types.h +++ b/arch/mn10300/include/asm/kmap_types.h | |||
@@ -1,31 +1,6 @@ | |||
1 | /* MN10300 kmap_atomic() slot IDs | ||
2 | * | ||
3 | * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public Licence | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the Licence, or (at your option) any later version. | ||
10 | */ | ||
11 | #ifndef _ASM_KMAP_TYPES_H | 1 | #ifndef _ASM_KMAP_TYPES_H |
12 | #define _ASM_KMAP_TYPES_H | 2 | #define _ASM_KMAP_TYPES_H |
13 | 3 | ||
14 | enum km_type { | 4 | #include <asm-generic/kmap_types.h> |
15 | KM_BOUNCE_READ, | ||
16 | KM_SKB_SUNRPC_DATA, | ||
17 | KM_SKB_DATA_SOFTIRQ, | ||
18 | KM_USER0, | ||
19 | KM_USER1, | ||
20 | KM_BIO_SRC_IRQ, | ||
21 | KM_BIO_DST_IRQ, | ||
22 | KM_PTE0, | ||
23 | KM_PTE1, | ||
24 | KM_IRQ0, | ||
25 | KM_IRQ1, | ||
26 | KM_SOFTIRQ0, | ||
27 | KM_SOFTIRQ1, | ||
28 | KM_TYPE_NR | ||
29 | }; | ||
30 | 5 | ||
31 | #endif /* _ASM_KMAP_TYPES_H */ | 6 | #endif /* _ASM_KMAP_TYPES_H */ |
diff --git a/arch/mn10300/kernel/init_task.c b/arch/mn10300/kernel/init_task.c index 5ac3566f8c98..80d423b80af3 100644 --- a/arch/mn10300/kernel/init_task.c +++ b/arch/mn10300/kernel/init_task.c | |||
@@ -20,9 +20,6 @@ | |||
20 | 20 | ||
21 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); | 21 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); |
22 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); | 22 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); |
23 | struct mm_struct init_mm = INIT_MM(init_mm); | ||
24 | EXPORT_SYMBOL(init_mm); | ||
25 | |||
26 | /* | 23 | /* |
27 | * Initial thread structure. | 24 | * Initial thread structure. |
28 | * | 25 | * |
diff --git a/arch/parisc/include/asm/kmap_types.h b/arch/parisc/include/asm/kmap_types.h index 806aae3c5338..58e91ed0388f 100644 --- a/arch/parisc/include/asm/kmap_types.h +++ b/arch/parisc/include/asm/kmap_types.h | |||
@@ -1,30 +1,12 @@ | |||
1 | #ifndef _ASM_KMAP_TYPES_H | 1 | #ifndef _ASM_KMAP_TYPES_H |
2 | #define _ASM_KMAP_TYPES_H | 2 | #define _ASM_KMAP_TYPES_H |
3 | 3 | ||
4 | |||
5 | #ifdef CONFIG_DEBUG_HIGHMEM | 4 | #ifdef CONFIG_DEBUG_HIGHMEM |
6 | # define D(n) __KM_FENCE_##n , | 5 | #define __WITH_KM_FENCE |
7 | #else | ||
8 | # define D(n) | ||
9 | #endif | 6 | #endif |
10 | 7 | ||
11 | enum km_type { | 8 | #include <asm-generic/kmap_types.h> |
12 | D(0) KM_BOUNCE_READ, | ||
13 | D(1) KM_SKB_SUNRPC_DATA, | ||
14 | D(2) KM_SKB_DATA_SOFTIRQ, | ||
15 | D(3) KM_USER0, | ||
16 | D(4) KM_USER1, | ||
17 | D(5) KM_BIO_SRC_IRQ, | ||
18 | D(6) KM_BIO_DST_IRQ, | ||
19 | D(7) KM_PTE0, | ||
20 | D(8) KM_PTE1, | ||
21 | D(9) KM_IRQ0, | ||
22 | D(10) KM_IRQ1, | ||
23 | D(11) KM_SOFTIRQ0, | ||
24 | D(12) KM_SOFTIRQ1, | ||
25 | D(13) KM_TYPE_NR | ||
26 | }; | ||
27 | 9 | ||
28 | #undef D | 10 | #undef __WITH_KM_FENCE |
29 | 11 | ||
30 | #endif | 12 | #endif |
diff --git a/arch/parisc/kernel/init_task.c b/arch/parisc/kernel/init_task.c index 1e25a45d64c1..82974b20fc10 100644 --- a/arch/parisc/kernel/init_task.c +++ b/arch/parisc/kernel/init_task.c | |||
@@ -36,10 +36,6 @@ | |||
36 | 36 | ||
37 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); | 37 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); |
38 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); | 38 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); |
39 | struct mm_struct init_mm = INIT_MM(init_mm); | ||
40 | |||
41 | EXPORT_SYMBOL(init_mm); | ||
42 | |||
43 | /* | 39 | /* |
44 | * Initial task structure. | 40 | * Initial task structure. |
45 | * | 41 | * |
diff --git a/arch/powerpc/include/asm/8253pit.h b/arch/powerpc/include/asm/8253pit.h index b70d6e53b303..a71c9c1455a7 100644 --- a/arch/powerpc/include/asm/8253pit.h +++ b/arch/powerpc/include/asm/8253pit.h | |||
@@ -1,10 +1,3 @@ | |||
1 | #ifndef _ASM_POWERPC_8253PIT_H | ||
2 | #define _ASM_POWERPC_8253PIT_H | ||
3 | |||
4 | /* | 1 | /* |
5 | * 8253/8254 Programmable Interval Timer | 2 | * 8253/8254 Programmable Interval Timer |
6 | */ | 3 | */ |
7 | |||
8 | #define PIT_TICK_RATE 1193182UL | ||
9 | |||
10 | #endif /* _ASM_POWERPC_8253PIT_H */ | ||
diff --git a/arch/powerpc/kernel/init_task.c b/arch/powerpc/kernel/init_task.c index 688b329800bd..ffc4253fef55 100644 --- a/arch/powerpc/kernel/init_task.c +++ b/arch/powerpc/kernel/init_task.c | |||
@@ -9,10 +9,6 @@ | |||
9 | 9 | ||
10 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); | 10 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); |
11 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); | 11 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); |
12 | struct mm_struct init_mm = INIT_MM(init_mm); | ||
13 | |||
14 | EXPORT_SYMBOL(init_mm); | ||
15 | |||
16 | /* | 12 | /* |
17 | * Initial thread structure. | 13 | * Initial thread structure. |
18 | * | 14 | * |
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 2f0e64b53642..ef6f64950e9b 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c | |||
@@ -44,10 +44,7 @@ | |||
44 | #include <asm/sections.h> | 44 | #include <asm/sections.h> |
45 | #include <asm/machdep.h> | 45 | #include <asm/machdep.h> |
46 | 46 | ||
47 | #ifdef CONFIG_LOGO_LINUX_CLUT224 | ||
48 | #include <linux/linux_logo.h> | 47 | #include <linux/linux_logo.h> |
49 | extern const struct linux_logo logo_linux_clut224; | ||
50 | #endif | ||
51 | 48 | ||
52 | /* | 49 | /* |
53 | * Properties whose value is longer than this get excluded from our | 50 | * Properties whose value is longer than this get excluded from our |
diff --git a/arch/powerpc/platforms/cell/ras.c b/arch/powerpc/platforms/cell/ras.c index 296b5268754e..5e0a191764fc 100644 --- a/arch/powerpc/platforms/cell/ras.c +++ b/arch/powerpc/platforms/cell/ras.c | |||
@@ -122,8 +122,8 @@ static int __init cbe_ptcal_enable_on_node(int nid, int order) | |||
122 | 122 | ||
123 | area->nid = nid; | 123 | area->nid = nid; |
124 | area->order = order; | 124 | area->order = order; |
125 | area->pages = alloc_pages_node(area->nid, GFP_KERNEL | GFP_THISNODE, | 125 | area->pages = alloc_pages_exact_node(area->nid, GFP_KERNEL|GFP_THISNODE, |
126 | area->order); | 126 | area->order); |
127 | 127 | ||
128 | if (!area->pages) { | 128 | if (!area->pages) { |
129 | printk(KERN_WARNING "%s: no page on node %d\n", | 129 | printk(KERN_WARNING "%s: no page on node %d\n", |
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index 9abd210d87c1..8547e86bfb42 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c | |||
@@ -752,17 +752,8 @@ static int __init init_spu_base(void) | |||
752 | goto out_unregister_sysdev_class; | 752 | goto out_unregister_sysdev_class; |
753 | } | 753 | } |
754 | 754 | ||
755 | if (ret > 0) { | 755 | if (ret > 0) |
756 | /* | ||
757 | * We cannot put the forward declaration in | ||
758 | * <linux/linux_logo.h> because of conflicting session type | ||
759 | * conflicts for const and __initdata with different compiler | ||
760 | * versions | ||
761 | */ | ||
762 | extern const struct linux_logo logo_spe_clut224; | ||
763 | |||
764 | fb_append_extra_logo(&logo_spe_clut224, ret); | 756 | fb_append_extra_logo(&logo_spe_clut224, ret); |
765 | } | ||
766 | 757 | ||
767 | mutex_lock(&spu_full_list_mutex); | 758 | mutex_lock(&spu_full_list_mutex); |
768 | xmon_register_spus(&spu_full_list); | 759 | xmon_register_spus(&spu_full_list); |
diff --git a/arch/s390/include/asm/kmap_types.h b/arch/s390/include/asm/kmap_types.h index fd1574648223..94ec3ee07983 100644 --- a/arch/s390/include/asm/kmap_types.h +++ b/arch/s390/include/asm/kmap_types.h | |||
@@ -2,22 +2,7 @@ | |||
2 | #ifndef _ASM_KMAP_TYPES_H | 2 | #ifndef _ASM_KMAP_TYPES_H |
3 | #define _ASM_KMAP_TYPES_H | 3 | #define _ASM_KMAP_TYPES_H |
4 | 4 | ||
5 | enum km_type { | 5 | #include <asm-generic/kmap_types.h> |
6 | KM_BOUNCE_READ, | ||
7 | KM_SKB_SUNRPC_DATA, | ||
8 | KM_SKB_DATA_SOFTIRQ, | ||
9 | KM_USER0, | ||
10 | KM_USER1, | ||
11 | KM_BIO_SRC_IRQ, | ||
12 | KM_BIO_DST_IRQ, | ||
13 | KM_PTE0, | ||
14 | KM_PTE1, | ||
15 | KM_IRQ0, | ||
16 | KM_IRQ1, | ||
17 | KM_SOFTIRQ0, | ||
18 | KM_SOFTIRQ1, | ||
19 | KM_TYPE_NR | ||
20 | }; | ||
21 | 6 | ||
22 | #endif | 7 | #endif |
23 | #endif /* __KERNEL__ */ | 8 | #endif /* __KERNEL__ */ |
diff --git a/arch/s390/kernel/init_task.c b/arch/s390/kernel/init_task.c index 7db95c0b8693..fe787f9e5f3f 100644 --- a/arch/s390/kernel/init_task.c +++ b/arch/s390/kernel/init_task.c | |||
@@ -18,10 +18,6 @@ | |||
18 | 18 | ||
19 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); | 19 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); |
20 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); | 20 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); |
21 | struct mm_struct init_mm = INIT_MM(init_mm); | ||
22 | |||
23 | EXPORT_SYMBOL(init_mm); | ||
24 | |||
25 | /* | 21 | /* |
26 | * Initial thread structure. | 22 | * Initial thread structure. |
27 | * | 23 | * |
diff --git a/arch/sh/include/asm/kmap_types.h b/arch/sh/include/asm/kmap_types.h index 84d565c696be..5962b08b6dd8 100644 --- a/arch/sh/include/asm/kmap_types.h +++ b/arch/sh/include/asm/kmap_types.h | |||
@@ -3,30 +3,12 @@ | |||
3 | 3 | ||
4 | /* Dummy header just to define km_type. */ | 4 | /* Dummy header just to define km_type. */ |
5 | 5 | ||
6 | |||
7 | #ifdef CONFIG_DEBUG_HIGHMEM | 6 | #ifdef CONFIG_DEBUG_HIGHMEM |
8 | # define D(n) __KM_FENCE_##n , | 7 | #define __WITH_KM_FENCE |
9 | #else | ||
10 | # define D(n) | ||
11 | #endif | 8 | #endif |
12 | 9 | ||
13 | enum km_type { | 10 | #include <asm-generic/kmap_types.h> |
14 | D(0) KM_BOUNCE_READ, | ||
15 | D(1) KM_SKB_SUNRPC_DATA, | ||
16 | D(2) KM_SKB_DATA_SOFTIRQ, | ||
17 | D(3) KM_USER0, | ||
18 | D(4) KM_USER1, | ||
19 | D(5) KM_BIO_SRC_IRQ, | ||
20 | D(6) KM_BIO_DST_IRQ, | ||
21 | D(7) KM_PTE0, | ||
22 | D(8) KM_PTE1, | ||
23 | D(9) KM_IRQ0, | ||
24 | D(10) KM_IRQ1, | ||
25 | D(11) KM_SOFTIRQ0, | ||
26 | D(12) KM_SOFTIRQ1, | ||
27 | D(13) KM_TYPE_NR | ||
28 | }; | ||
29 | 11 | ||
30 | #undef D | 12 | #undef __WITH_KM_FENCE |
31 | 13 | ||
32 | #endif | 14 | #endif |
diff --git a/arch/sh/kernel/init_task.c b/arch/sh/kernel/init_task.c index 80c35ff71d56..1719957c0a69 100644 --- a/arch/sh/kernel/init_task.c +++ b/arch/sh/kernel/init_task.c | |||
@@ -10,9 +10,6 @@ | |||
10 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); | 10 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); |
11 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); | 11 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); |
12 | struct pt_regs fake_swapper_regs; | 12 | struct pt_regs fake_swapper_regs; |
13 | struct mm_struct init_mm = INIT_MM(init_mm); | ||
14 | EXPORT_SYMBOL(init_mm); | ||
15 | |||
16 | /* | 13 | /* |
17 | * Initial thread structure. | 14 | * Initial thread structure. |
18 | * | 15 | * |
diff --git a/arch/sparc/include/asm/kmap_types.h b/arch/sparc/include/asm/kmap_types.h index 602f5e034f7a..aad21745fbb9 100644 --- a/arch/sparc/include/asm/kmap_types.h +++ b/arch/sparc/include/asm/kmap_types.h | |||
@@ -5,21 +5,6 @@ | |||
5 | * is actually used on sparc. -DaveM | 5 | * is actually used on sparc. -DaveM |
6 | */ | 6 | */ |
7 | 7 | ||
8 | enum km_type { | 8 | #include <asm-generic/kmap_types.h> |
9 | KM_BOUNCE_READ, | ||
10 | KM_SKB_SUNRPC_DATA, | ||
11 | KM_SKB_DATA_SOFTIRQ, | ||
12 | KM_USER0, | ||
13 | KM_USER1, | ||
14 | KM_BIO_SRC_IRQ, | ||
15 | KM_BIO_DST_IRQ, | ||
16 | KM_PTE0, | ||
17 | KM_PTE1, | ||
18 | KM_IRQ0, | ||
19 | KM_IRQ1, | ||
20 | KM_SOFTIRQ0, | ||
21 | KM_SOFTIRQ1, | ||
22 | KM_TYPE_NR | ||
23 | }; | ||
24 | 9 | ||
25 | #endif | 10 | #endif |
diff --git a/arch/sparc/kernel/init_task.c b/arch/sparc/kernel/init_task.c index f28cb8278e98..28125c5b3d3c 100644 --- a/arch/sparc/kernel/init_task.c +++ b/arch/sparc/kernel/init_task.c | |||
@@ -10,10 +10,7 @@ | |||
10 | 10 | ||
11 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); | 11 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); |
12 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); | 12 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); |
13 | struct mm_struct init_mm = INIT_MM(init_mm); | ||
14 | struct task_struct init_task = INIT_TASK(init_task); | 13 | struct task_struct init_task = INIT_TASK(init_task); |
15 | |||
16 | EXPORT_SYMBOL(init_mm); | ||
17 | EXPORT_SYMBOL(init_task); | 14 | EXPORT_SYMBOL(init_task); |
18 | 15 | ||
19 | /* .text section in head.S is aligned at 8k boundary and this gets linked | 16 | /* .text section in head.S is aligned at 8k boundary and this gets linked |
diff --git a/arch/um/include/shared/init.h b/arch/um/include/shared/init.h index 37dd097c16c0..b3906f860a87 100644 --- a/arch/um/include/shared/init.h +++ b/arch/um/include/shared/init.h | |||
@@ -27,7 +27,7 @@ | |||
27 | * sign followed by value, e.g.: | 27 | * sign followed by value, e.g.: |
28 | * | 28 | * |
29 | * static int init_variable __initdata = 0; | 29 | * static int init_variable __initdata = 0; |
30 | * static char linux_logo[] __initdata = { 0x32, 0x36, ... }; | 30 | * static const char linux_logo[] __initconst = { 0x32, 0x36, ... }; |
31 | * | 31 | * |
32 | * Don't forget to initialize data not at file scope, i.e. within a function, | 32 | * Don't forget to initialize data not at file scope, i.e. within a function, |
33 | * as gcc otherwise puts the data into the bss section and not into the init | 33 | * as gcc otherwise puts the data into the bss section and not into the init |
diff --git a/arch/um/include/shared/net_user.h b/arch/um/include/shared/net_user.h index 63bee158cd8e..3dabbe128e40 100644 --- a/arch/um/include/shared/net_user.h +++ b/arch/um/include/shared/net_user.h | |||
@@ -8,7 +8,7 @@ | |||
8 | 8 | ||
9 | #define ETH_ADDR_LEN (6) | 9 | #define ETH_ADDR_LEN (6) |
10 | #define ETH_HEADER_ETHERTAP (16) | 10 | #define ETH_HEADER_ETHERTAP (16) |
11 | #define ETH_HEADER_OTHER (14) | 11 | #define ETH_HEADER_OTHER (26) /* 14 for ethernet + VLAN + MPLS for crazy people */ |
12 | #define ETH_MAX_PACKET (1500) | 12 | #define ETH_MAX_PACKET (1500) |
13 | 13 | ||
14 | #define UML_NET_VERSION (4) | 14 | #define UML_NET_VERSION (4) |
diff --git a/arch/um/kernel/init_task.c b/arch/um/kernel/init_task.c index 806d381947bf..b25121b537d8 100644 --- a/arch/um/kernel/init_task.c +++ b/arch/um/kernel/init_task.c | |||
@@ -10,11 +10,8 @@ | |||
10 | #include "linux/mqueue.h" | 10 | #include "linux/mqueue.h" |
11 | #include "asm/uaccess.h" | 11 | #include "asm/uaccess.h" |
12 | 12 | ||
13 | struct mm_struct init_mm = INIT_MM(init_mm); | ||
14 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); | 13 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); |
15 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); | 14 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); |
16 | EXPORT_SYMBOL(init_mm); | ||
17 | |||
18 | /* | 15 | /* |
19 | * Initial task structure. | 16 | * Initial task structure. |
20 | * | 17 | * |
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index 336b61569072..454cdb43e351 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c | |||
@@ -358,7 +358,7 @@ EXPORT_SYMBOL(um_request_irq); | |||
358 | EXPORT_SYMBOL(reactivate_fd); | 358 | EXPORT_SYMBOL(reactivate_fd); |
359 | 359 | ||
360 | /* | 360 | /* |
361 | * hw_interrupt_type must define (startup || enable) && | 361 | * irq_chip must define (startup || enable) && |
362 | * (shutdown || disable) && end | 362 | * (shutdown || disable) && end |
363 | */ | 363 | */ |
364 | static void dummy(unsigned int irq) | 364 | static void dummy(unsigned int irq) |
@@ -366,7 +366,7 @@ static void dummy(unsigned int irq) | |||
366 | } | 366 | } |
367 | 367 | ||
368 | /* This is used for everything else than the timer. */ | 368 | /* This is used for everything else than the timer. */ |
369 | static struct hw_interrupt_type normal_irq_type = { | 369 | static struct irq_chip normal_irq_type = { |
370 | .typename = "SIGIO", | 370 | .typename = "SIGIO", |
371 | .release = free_irq_by_irq_and_dev, | 371 | .release = free_irq_by_irq_and_dev, |
372 | .disable = dummy, | 372 | .disable = dummy, |
@@ -375,7 +375,7 @@ static struct hw_interrupt_type normal_irq_type = { | |||
375 | .end = dummy | 375 | .end = dummy |
376 | }; | 376 | }; |
377 | 377 | ||
378 | static struct hw_interrupt_type SIGVTALRM_irq_type = { | 378 | static struct irq_chip SIGVTALRM_irq_type = { |
379 | .typename = "SIGVTALRM", | 379 | .typename = "SIGVTALRM", |
380 | .release = free_irq_by_irq_and_dev, | 380 | .release = free_irq_by_irq_and_dev, |
381 | .shutdown = dummy, /* never called */ | 381 | .shutdown = dummy, /* never called */ |
diff --git a/arch/um/sys-i386/stub.S b/arch/um/sys-i386/stub.S index c41b04bf5fa0..54a36ec20cb7 100644 --- a/arch/um/sys-i386/stub.S +++ b/arch/um/sys-i386/stub.S | |||
@@ -1,7 +1,7 @@ | |||
1 | #include "as-layout.h" | 1 | #include "as-layout.h" |
2 | 2 | ||
3 | .globl syscall_stub | 3 | .globl syscall_stub |
4 | .section .__syscall_stub, "x" | 4 | .section .__syscall_stub, "ax" |
5 | 5 | ||
6 | .globl batch_syscall_stub | 6 | .globl batch_syscall_stub |
7 | batch_syscall_stub: | 7 | batch_syscall_stub: |
diff --git a/arch/um/sys-x86_64/asm/elf.h b/arch/um/sys-x86_64/asm/elf.h index 6e8a9195e952..04b9e87c8dad 100644 --- a/arch/um/sys-x86_64/asm/elf.h +++ b/arch/um/sys-x86_64/asm/elf.h | |||
@@ -66,28 +66,28 @@ typedef struct user_i387_struct elf_fpregset_t; | |||
66 | PT_REGS_R15(regs) = 0; \ | 66 | PT_REGS_R15(regs) = 0; \ |
67 | } while (0) | 67 | } while (0) |
68 | 68 | ||
69 | #define ELF_CORE_COPY_REGS(pr_reg, regs) \ | 69 | #define ELF_CORE_COPY_REGS(pr_reg, _regs) \ |
70 | (pr_reg)[0] = (regs)->regs.gp[0]; \ | 70 | (pr_reg)[0] = (_regs)->regs.gp[0]; \ |
71 | (pr_reg)[1] = (regs)->regs.gp[1]; \ | 71 | (pr_reg)[1] = (_regs)->regs.gp[1]; \ |
72 | (pr_reg)[2] = (regs)->regs.gp[2]; \ | 72 | (pr_reg)[2] = (_regs)->regs.gp[2]; \ |
73 | (pr_reg)[3] = (regs)->regs.gp[3]; \ | 73 | (pr_reg)[3] = (_regs)->regs.gp[3]; \ |
74 | (pr_reg)[4] = (regs)->regs.gp[4]; \ | 74 | (pr_reg)[4] = (_regs)->regs.gp[4]; \ |
75 | (pr_reg)[5] = (regs)->regs.gp[5]; \ | 75 | (pr_reg)[5] = (_regs)->regs.gp[5]; \ |
76 | (pr_reg)[6] = (regs)->regs.gp[6]; \ | 76 | (pr_reg)[6] = (_regs)->regs.gp[6]; \ |
77 | (pr_reg)[7] = (regs)->regs.gp[7]; \ | 77 | (pr_reg)[7] = (_regs)->regs.gp[7]; \ |
78 | (pr_reg)[8] = (regs)->regs.gp[8]; \ | 78 | (pr_reg)[8] = (_regs)->regs.gp[8]; \ |
79 | (pr_reg)[9] = (regs)->regs.gp[9]; \ | 79 | (pr_reg)[9] = (_regs)->regs.gp[9]; \ |
80 | (pr_reg)[10] = (regs)->regs.gp[10]; \ | 80 | (pr_reg)[10] = (_regs)->regs.gp[10]; \ |
81 | (pr_reg)[11] = (regs)->regs.gp[11]; \ | 81 | (pr_reg)[11] = (_regs)->regs.gp[11]; \ |
82 | (pr_reg)[12] = (regs)->regs.gp[12]; \ | 82 | (pr_reg)[12] = (_regs)->regs.gp[12]; \ |
83 | (pr_reg)[13] = (regs)->regs.gp[13]; \ | 83 | (pr_reg)[13] = (_regs)->regs.gp[13]; \ |
84 | (pr_reg)[14] = (regs)->regs.gp[14]; \ | 84 | (pr_reg)[14] = (_regs)->regs.gp[14]; \ |
85 | (pr_reg)[15] = (regs)->regs.gp[15]; \ | 85 | (pr_reg)[15] = (_regs)->regs.gp[15]; \ |
86 | (pr_reg)[16] = (regs)->regs.gp[16]; \ | 86 | (pr_reg)[16] = (_regs)->regs.gp[16]; \ |
87 | (pr_reg)[17] = (regs)->regs.gp[17]; \ | 87 | (pr_reg)[17] = (_regs)->regs.gp[17]; \ |
88 | (pr_reg)[18] = (regs)->regs.gp[18]; \ | 88 | (pr_reg)[18] = (_regs)->regs.gp[18]; \ |
89 | (pr_reg)[19] = (regs)->regs.gp[19]; \ | 89 | (pr_reg)[19] = (_regs)->regs.gp[19]; \ |
90 | (pr_reg)[20] = (regs)->regs.gp[20]; \ | 90 | (pr_reg)[20] = (_regs)->regs.gp[20]; \ |
91 | (pr_reg)[21] = current->thread.arch.fs; \ | 91 | (pr_reg)[21] = current->thread.arch.fs; \ |
92 | (pr_reg)[22] = 0; \ | 92 | (pr_reg)[22] = 0; \ |
93 | (pr_reg)[23] = 0; \ | 93 | (pr_reg)[23] = 0; \ |
diff --git a/arch/um/sys-x86_64/stub.S b/arch/um/sys-x86_64/stub.S index 6d9edf9fabce..20e4a96a6dcb 100644 --- a/arch/um/sys-x86_64/stub.S +++ b/arch/um/sys-x86_64/stub.S | |||
@@ -1,7 +1,7 @@ | |||
1 | #include "as-layout.h" | 1 | #include "as-layout.h" |
2 | 2 | ||
3 | .globl syscall_stub | 3 | .globl syscall_stub |
4 | .section .__syscall_stub, "x" | 4 | .section .__syscall_stub, "ax" |
5 | syscall_stub: | 5 | syscall_stub: |
6 | syscall | 6 | syscall |
7 | /* We don't have 64-bit constants, so this constructs the address | 7 | /* We don't have 64-bit constants, so this constructs the address |
diff --git a/arch/x86/include/asm/kmap_types.h b/arch/x86/include/asm/kmap_types.h index 5759c165a5cf..9e00a731a7fb 100644 --- a/arch/x86/include/asm/kmap_types.h +++ b/arch/x86/include/asm/kmap_types.h | |||
@@ -2,28 +2,11 @@ | |||
2 | #define _ASM_X86_KMAP_TYPES_H | 2 | #define _ASM_X86_KMAP_TYPES_H |
3 | 3 | ||
4 | #if defined(CONFIG_X86_32) && defined(CONFIG_DEBUG_HIGHMEM) | 4 | #if defined(CONFIG_X86_32) && defined(CONFIG_DEBUG_HIGHMEM) |
5 | # define D(n) __KM_FENCE_##n , | 5 | #define __WITH_KM_FENCE |
6 | #else | ||
7 | # define D(n) | ||
8 | #endif | 6 | #endif |
9 | 7 | ||
10 | enum km_type { | 8 | #include <asm-generic/kmap_types.h> |
11 | D(0) KM_BOUNCE_READ, | ||
12 | D(1) KM_SKB_SUNRPC_DATA, | ||
13 | D(2) KM_SKB_DATA_SOFTIRQ, | ||
14 | D(3) KM_USER0, | ||
15 | D(4) KM_USER1, | ||
16 | D(5) KM_BIO_SRC_IRQ, | ||
17 | D(6) KM_BIO_DST_IRQ, | ||
18 | D(7) KM_PTE0, | ||
19 | D(8) KM_PTE1, | ||
20 | D(9) KM_IRQ0, | ||
21 | D(10) KM_IRQ1, | ||
22 | D(11) KM_SOFTIRQ0, | ||
23 | D(12) KM_SOFTIRQ1, | ||
24 | D(13) KM_TYPE_NR | ||
25 | }; | ||
26 | 9 | ||
27 | #undef D | 10 | #undef __WITH_KM_FENCE |
28 | 11 | ||
29 | #endif /* _ASM_X86_KMAP_TYPES_H */ | 12 | #endif /* _ASM_X86_KMAP_TYPES_H */ |
diff --git a/arch/x86/include/asm/timex.h b/arch/x86/include/asm/timex.h index b5c9d45c981f..1375cfc93960 100644 --- a/arch/x86/include/asm/timex.h +++ b/arch/x86/include/asm/timex.h | |||
@@ -4,9 +4,7 @@ | |||
4 | #include <asm/processor.h> | 4 | #include <asm/processor.h> |
5 | #include <asm/tsc.h> | 5 | #include <asm/tsc.h> |
6 | 6 | ||
7 | /* The PIT ticks at this frequency (in HZ): */ | 7 | /* Assume we use the PIT time source for the clock tick */ |
8 | #define PIT_TICK_RATE 1193182 | ||
9 | |||
10 | #define CLOCK_TICK_RATE PIT_TICK_RATE | 8 | #define CLOCK_TICK_RATE PIT_TICK_RATE |
11 | 9 | ||
12 | #define ARCH_HAS_READ_CURRENT_TIMER | 10 | #define ARCH_HAS_READ_CURRENT_TIMER |
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 3ffdcfa9abdf..9fa33886c0d7 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
@@ -487,7 +487,6 @@ out: | |||
487 | static void __cpuinit get_cpu_vendor(struct cpuinfo_x86 *c) | 487 | static void __cpuinit get_cpu_vendor(struct cpuinfo_x86 *c) |
488 | { | 488 | { |
489 | char *v = c->x86_vendor_id; | 489 | char *v = c->x86_vendor_id; |
490 | static int printed; | ||
491 | int i; | 490 | int i; |
492 | 491 | ||
493 | for (i = 0; i < X86_VENDOR_NUM; i++) { | 492 | for (i = 0; i < X86_VENDOR_NUM; i++) { |
@@ -504,13 +503,9 @@ static void __cpuinit get_cpu_vendor(struct cpuinfo_x86 *c) | |||
504 | } | 503 | } |
505 | } | 504 | } |
506 | 505 | ||
507 | if (!printed) { | 506 | printk_once(KERN_ERR |
508 | printed++; | 507 | "CPU: vendor_id '%s' unknown, using generic init.\n" \ |
509 | printk(KERN_ERR | 508 | "CPU: Your system may be unstable.\n", v); |
510 | "CPU: vendor_id '%s' unknown, using generic init.\n", v); | ||
511 | |||
512 | printk(KERN_ERR "CPU: Your system may be unstable.\n"); | ||
513 | } | ||
514 | 509 | ||
515 | c->x86_vendor = X86_VENDOR_UNKNOWN; | 510 | c->x86_vendor = X86_VENDOR_UNKNOWN; |
516 | this_cpu = &default_cpu; | 511 | this_cpu = &default_cpu; |
diff --git a/arch/x86/kernel/i8253.c b/arch/x86/kernel/i8253.c index c2e0bb0890d4..5cf36c053ac4 100644 --- a/arch/x86/kernel/i8253.c +++ b/arch/x86/kernel/i8253.c | |||
@@ -7,6 +7,7 @@ | |||
7 | #include <linux/spinlock.h> | 7 | #include <linux/spinlock.h> |
8 | #include <linux/jiffies.h> | 8 | #include <linux/jiffies.h> |
9 | #include <linux/module.h> | 9 | #include <linux/module.h> |
10 | #include <linux/timex.h> | ||
10 | #include <linux/delay.h> | 11 | #include <linux/delay.h> |
11 | #include <linux/init.h> | 12 | #include <linux/init.h> |
12 | #include <linux/io.h> | 13 | #include <linux/io.h> |
diff --git a/arch/x86/kernel/init_task.c b/arch/x86/kernel/init_task.c index df3bf269beab..270ff83efc11 100644 --- a/arch/x86/kernel/init_task.c +++ b/arch/x86/kernel/init_task.c | |||
@@ -12,7 +12,6 @@ | |||
12 | 12 | ||
13 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); | 13 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); |
14 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); | 14 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); |
15 | struct mm_struct init_mm = INIT_MM(init_mm); | ||
16 | 15 | ||
17 | /* | 16 | /* |
18 | * Initial thread structure. | 17 | * Initial thread structure. |
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index 3e1c057e98fe..ae3180c506a6 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/delay.h> | 9 | #include <linux/delay.h> |
10 | #include <linux/clocksource.h> | 10 | #include <linux/clocksource.h> |
11 | #include <linux/percpu.h> | 11 | #include <linux/percpu.h> |
12 | #include <linux/timex.h> | ||
12 | 13 | ||
13 | #include <asm/hpet.h> | 14 | #include <asm/hpet.h> |
14 | #include <asm/timer.h> | 15 | #include <asm/timer.h> |
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 32d6ae8fb60e..e770bf349ec4 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -1277,7 +1277,7 @@ static struct vmcs *alloc_vmcs_cpu(int cpu) | |||
1277 | struct page *pages; | 1277 | struct page *pages; |
1278 | struct vmcs *vmcs; | 1278 | struct vmcs *vmcs; |
1279 | 1279 | ||
1280 | pages = alloc_pages_node(node, GFP_KERNEL, vmcs_config.order); | 1280 | pages = alloc_pages_exact_node(node, GFP_KERNEL, vmcs_config.order); |
1281 | if (!pages) | 1281 | if (!pages) |
1282 | return NULL; | 1282 | return NULL; |
1283 | vmcs = page_address(pages); | 1283 | vmcs = page_address(pages); |
diff --git a/arch/xtensa/include/asm/kmap_types.h b/arch/xtensa/include/asm/kmap_types.h index 9e822d2e3bce..11c687e527f1 100644 --- a/arch/xtensa/include/asm/kmap_types.h +++ b/arch/xtensa/include/asm/kmap_types.h | |||
@@ -1,31 +1,6 @@ | |||
1 | /* | ||
2 | * include/asm-xtensa/kmap_types.h | ||
3 | * | ||
4 | * This file is subject to the terms and conditions of the GNU General Public | ||
5 | * License. See the file "COPYING" in the main directory of this archive | ||
6 | * for more details. | ||
7 | * | ||
8 | * Copyright (C) 2001 - 2005 Tensilica Inc. | ||
9 | */ | ||
10 | |||
11 | #ifndef _XTENSA_KMAP_TYPES_H | 1 | #ifndef _XTENSA_KMAP_TYPES_H |
12 | #define _XTENSA_KMAP_TYPES_H | 2 | #define _XTENSA_KMAP_TYPES_H |
13 | 3 | ||
14 | enum km_type { | 4 | #include <asm-generic/kmap_types.h> |
15 | KM_BOUNCE_READ, | ||
16 | KM_SKB_SUNRPC_DATA, | ||
17 | KM_SKB_DATA_SOFTIRQ, | ||
18 | KM_USER0, | ||
19 | KM_USER1, | ||
20 | KM_BIO_SRC_IRQ, | ||
21 | KM_BIO_DST_IRQ, | ||
22 | KM_PTE0, | ||
23 | KM_PTE1, | ||
24 | KM_IRQ0, | ||
25 | KM_IRQ1, | ||
26 | KM_SOFTIRQ0, | ||
27 | KM_SOFTIRQ1, | ||
28 | KM_TYPE_NR | ||
29 | }; | ||
30 | 5 | ||
31 | #endif /* _XTENSA_KMAP_TYPES_H */ | 6 | #endif /* _XTENSA_KMAP_TYPES_H */ |
diff --git a/arch/xtensa/kernel/init_task.c b/arch/xtensa/kernel/init_task.c index e07f5c9fcd35..c4302f0e4ba0 100644 --- a/arch/xtensa/kernel/init_task.c +++ b/arch/xtensa/kernel/init_task.c | |||
@@ -23,10 +23,6 @@ | |||
23 | 23 | ||
24 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); | 24 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); |
25 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); | 25 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); |
26 | struct mm_struct init_mm = INIT_MM(init_mm); | ||
27 | |||
28 | EXPORT_SYMBOL(init_mm); | ||
29 | |||
30 | union thread_union init_thread_union | 26 | union thread_union init_thread_union |
31 | __attribute__((__section__(".data.init_task"))) = | 27 | __attribute__((__section__(".data.init_task"))) = |
32 | { INIT_THREAD_INFO(init_task) }; | 28 | { INIT_THREAD_INFO(init_task) }; |
diff --git a/drivers/Kconfig b/drivers/Kconfig index 00cf9553f740..a442c8f29fc1 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig | |||
@@ -104,6 +104,8 @@ source "drivers/auxdisplay/Kconfig" | |||
104 | 104 | ||
105 | source "drivers/uio/Kconfig" | 105 | source "drivers/uio/Kconfig" |
106 | 106 | ||
107 | source "drivers/vlynq/Kconfig" | ||
108 | |||
107 | source "drivers/xen/Kconfig" | 109 | source "drivers/xen/Kconfig" |
108 | 110 | ||
109 | source "drivers/staging/Kconfig" | 111 | source "drivers/staging/Kconfig" |
diff --git a/drivers/Makefile b/drivers/Makefile index 9e7d4e56c85b..00b44f4ccf03 100644 --- a/drivers/Makefile +++ b/drivers/Makefile | |||
@@ -105,6 +105,7 @@ obj-$(CONFIG_PPC_PS3) += ps3/ | |||
105 | obj-$(CONFIG_OF) += of/ | 105 | obj-$(CONFIG_OF) += of/ |
106 | obj-$(CONFIG_SSB) += ssb/ | 106 | obj-$(CONFIG_SSB) += ssb/ |
107 | obj-$(CONFIG_VIRTIO) += virtio/ | 107 | obj-$(CONFIG_VIRTIO) += virtio/ |
108 | obj-$(CONFIG_VLYNQ) += vlynq/ | ||
108 | obj-$(CONFIG_STAGING) += staging/ | 109 | obj-$(CONFIG_STAGING) += staging/ |
109 | obj-y += platform/ | 110 | obj-y += platform/ |
110 | obj-y += ieee802154/ | 111 | obj-y += ieee802154/ |
diff --git a/drivers/base/node.c b/drivers/base/node.c index 40b809742a1c..91d4087b4039 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c | |||
@@ -72,10 +72,8 @@ static ssize_t node_read_meminfo(struct sys_device * dev, | |||
72 | "Node %d Inactive(anon): %8lu kB\n" | 72 | "Node %d Inactive(anon): %8lu kB\n" |
73 | "Node %d Active(file): %8lu kB\n" | 73 | "Node %d Active(file): %8lu kB\n" |
74 | "Node %d Inactive(file): %8lu kB\n" | 74 | "Node %d Inactive(file): %8lu kB\n" |
75 | #ifdef CONFIG_UNEVICTABLE_LRU | ||
76 | "Node %d Unevictable: %8lu kB\n" | 75 | "Node %d Unevictable: %8lu kB\n" |
77 | "Node %d Mlocked: %8lu kB\n" | 76 | "Node %d Mlocked: %8lu kB\n" |
78 | #endif | ||
79 | #ifdef CONFIG_HIGHMEM | 77 | #ifdef CONFIG_HIGHMEM |
80 | "Node %d HighTotal: %8lu kB\n" | 78 | "Node %d HighTotal: %8lu kB\n" |
81 | "Node %d HighFree: %8lu kB\n" | 79 | "Node %d HighFree: %8lu kB\n" |
@@ -105,10 +103,8 @@ static ssize_t node_read_meminfo(struct sys_device * dev, | |||
105 | nid, K(node_page_state(nid, NR_INACTIVE_ANON)), | 103 | nid, K(node_page_state(nid, NR_INACTIVE_ANON)), |
106 | nid, K(node_page_state(nid, NR_ACTIVE_FILE)), | 104 | nid, K(node_page_state(nid, NR_ACTIVE_FILE)), |
107 | nid, K(node_page_state(nid, NR_INACTIVE_FILE)), | 105 | nid, K(node_page_state(nid, NR_INACTIVE_FILE)), |
108 | #ifdef CONFIG_UNEVICTABLE_LRU | ||
109 | nid, K(node_page_state(nid, NR_UNEVICTABLE)), | 106 | nid, K(node_page_state(nid, NR_UNEVICTABLE)), |
110 | nid, K(node_page_state(nid, NR_MLOCK)), | 107 | nid, K(node_page_state(nid, NR_MLOCK)), |
111 | #endif | ||
112 | #ifdef CONFIG_HIGHMEM | 108 | #ifdef CONFIG_HIGHMEM |
113 | nid, K(i.totalhigh), | 109 | nid, K(i.totalhigh), |
114 | nid, K(i.freehigh), | 110 | nid, K(i.freehigh), |
diff --git a/drivers/char/vt.c b/drivers/char/vt.c index c796a86ab7f3..d9113b4c76e3 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c | |||
@@ -171,8 +171,9 @@ int do_poke_blanked_console; | |||
171 | int console_blanked; | 171 | int console_blanked; |
172 | 172 | ||
173 | static int vesa_blank_mode; /* 0:none 1:suspendV 2:suspendH 3:powerdown */ | 173 | static int vesa_blank_mode; /* 0:none 1:suspendV 2:suspendH 3:powerdown */ |
174 | static int blankinterval = 10*60*HZ; | ||
175 | static int vesa_off_interval; | 174 | static int vesa_off_interval; |
175 | static int blankinterval = 10*60; | ||
176 | core_param(consoleblank, blankinterval, int, 0444); | ||
176 | 177 | ||
177 | static DECLARE_WORK(console_work, console_callback); | 178 | static DECLARE_WORK(console_work, console_callback); |
178 | 179 | ||
@@ -1485,7 +1486,7 @@ static void setterm_command(struct vc_data *vc) | |||
1485 | update_attr(vc); | 1486 | update_attr(vc); |
1486 | break; | 1487 | break; |
1487 | case 9: /* set blanking interval */ | 1488 | case 9: /* set blanking interval */ |
1488 | blankinterval = ((vc->vc_par[1] < 60) ? vc->vc_par[1] : 60) * 60 * HZ; | 1489 | blankinterval = ((vc->vc_par[1] < 60) ? vc->vc_par[1] : 60) * 60; |
1489 | poke_blanked_console(); | 1490 | poke_blanked_console(); |
1490 | break; | 1491 | break; |
1491 | case 10: /* set bell frequency in Hz */ | 1492 | case 10: /* set bell frequency in Hz */ |
@@ -2871,7 +2872,7 @@ static int __init con_init(void) | |||
2871 | 2872 | ||
2872 | if (blankinterval) { | 2873 | if (blankinterval) { |
2873 | blank_state = blank_normal_wait; | 2874 | blank_state = blank_normal_wait; |
2874 | mod_timer(&console_timer, jiffies + blankinterval); | 2875 | mod_timer(&console_timer, jiffies + (blankinterval * HZ)); |
2875 | } | 2876 | } |
2876 | 2877 | ||
2877 | for (currcons = 0; currcons < MIN_NR_CONSOLES; currcons++) { | 2878 | for (currcons = 0; currcons < MIN_NR_CONSOLES; currcons++) { |
@@ -3677,7 +3678,7 @@ void do_unblank_screen(int leaving_gfx) | |||
3677 | return; /* but leave console_blanked != 0 */ | 3678 | return; /* but leave console_blanked != 0 */ |
3678 | 3679 | ||
3679 | if (blankinterval) { | 3680 | if (blankinterval) { |
3680 | mod_timer(&console_timer, jiffies + blankinterval); | 3681 | mod_timer(&console_timer, jiffies + (blankinterval * HZ)); |
3681 | blank_state = blank_normal_wait; | 3682 | blank_state = blank_normal_wait; |
3682 | } | 3683 | } |
3683 | 3684 | ||
@@ -3711,7 +3712,7 @@ void unblank_screen(void) | |||
3711 | static void blank_screen_t(unsigned long dummy) | 3712 | static void blank_screen_t(unsigned long dummy) |
3712 | { | 3713 | { |
3713 | if (unlikely(!keventd_up())) { | 3714 | if (unlikely(!keventd_up())) { |
3714 | mod_timer(&console_timer, jiffies + blankinterval); | 3715 | mod_timer(&console_timer, jiffies + (blankinterval * HZ)); |
3715 | return; | 3716 | return; |
3716 | } | 3717 | } |
3717 | blank_timer_expired = 1; | 3718 | blank_timer_expired = 1; |
@@ -3741,7 +3742,7 @@ void poke_blanked_console(void) | |||
3741 | if (console_blanked) | 3742 | if (console_blanked) |
3742 | unblank_screen(); | 3743 | unblank_screen(); |
3743 | else if (blankinterval) { | 3744 | else if (blankinterval) { |
3744 | mod_timer(&console_timer, jiffies + blankinterval); | 3745 | mod_timer(&console_timer, jiffies + (blankinterval * HZ)); |
3745 | blank_state = blank_normal_wait; | 3746 | blank_state = blank_normal_wait; |
3746 | } | 3747 | } |
3747 | } | 3748 | } |
diff --git a/drivers/clocksource/acpi_pm.c b/drivers/clocksource/acpi_pm.c index 40bd8c61c7d7..72a633a6ec98 100644 --- a/drivers/clocksource/acpi_pm.c +++ b/drivers/clocksource/acpi_pm.c | |||
@@ -18,6 +18,7 @@ | |||
18 | 18 | ||
19 | #include <linux/acpi_pmtmr.h> | 19 | #include <linux/acpi_pmtmr.h> |
20 | #include <linux/clocksource.h> | 20 | #include <linux/clocksource.h> |
21 | #include <linux/timex.h> | ||
21 | #include <linux/errno.h> | 22 | #include <linux/errno.h> |
22 | #include <linux/init.h> | 23 | #include <linux/init.h> |
23 | #include <linux/pci.h> | 24 | #include <linux/pci.h> |
diff --git a/drivers/eisa/eisa.ids b/drivers/eisa/eisa.ids index ed69837d8b74..6cbb7a514436 100644 --- a/drivers/eisa/eisa.ids +++ b/drivers/eisa/eisa.ids | |||
@@ -1140,6 +1140,11 @@ NON0301 "c't Universale Graphic Adapter" | |||
1140 | NON0401 "c't Universal Ethernet Adapter" | 1140 | NON0401 "c't Universal Ethernet Adapter" |
1141 | NON0501 "c't Universal 16-Bit Sound Adapter" | 1141 | NON0501 "c't Universal 16-Bit Sound Adapter" |
1142 | NON0601 "c't Universal 8-Bit Adapter" | 1142 | NON0601 "c't Universal 8-Bit Adapter" |
1143 | NPI0120 "Network Peripherals NP-EISA-1 FDDI Interface" | ||
1144 | NPI0221 "Network Peripherals NP-EISA-2 FDDI Interface" | ||
1145 | NPI0223 "Network Peripherals NP-EISA-2E Enhanced FDDI Interface" | ||
1146 | NPI0301 "Network Peripherals NP-EISA-3 FDDI Interface" | ||
1147 | NPI0303 "Network Peripherals NP-EISA-3E Enhanced FDDI Interface" | ||
1143 | NSS0011 "Newport Systems Solutions WNIC Adapter" | 1148 | NSS0011 "Newport Systems Solutions WNIC Adapter" |
1144 | NVL0701 "Novell NE3200 Bus Master Ethernet" | 1149 | NVL0701 "Novell NE3200 Bus Master Ethernet" |
1145 | NVL0702 "Novell NE3200T Bus Master Ethernet" | 1150 | NVL0702 "Novell NE3200T Bus Master Ethernet" |
diff --git a/drivers/firmware/memmap.c b/drivers/firmware/memmap.c index 05aa2d406ac6..d5ea8a68d338 100644 --- a/drivers/firmware/memmap.c +++ b/drivers/firmware/memmap.c | |||
@@ -31,8 +31,12 @@ | |||
31 | * information is necessary as for the resource tree. | 31 | * information is necessary as for the resource tree. |
32 | */ | 32 | */ |
33 | struct firmware_map_entry { | 33 | struct firmware_map_entry { |
34 | resource_size_t start; /* start of the memory range */ | 34 | /* |
35 | resource_size_t end; /* end of the memory range (incl.) */ | 35 | * start and end must be u64 rather than resource_size_t, because e820 |
36 | * resources can lie at addresses above 4G. | ||
37 | */ | ||
38 | u64 start; /* start of the memory range */ | ||
39 | u64 end; /* end of the memory range (incl.) */ | ||
36 | const char *type; /* type of the memory range */ | 40 | const char *type; /* type of the memory range */ |
37 | struct list_head list; /* entry for the linked list */ | 41 | struct list_head list; /* entry for the linked list */ |
38 | struct kobject kobj; /* kobject for each entry */ | 42 | struct kobject kobj; /* kobject for each entry */ |
@@ -101,7 +105,7 @@ static LIST_HEAD(map_entries); | |||
101 | * Common implementation of firmware_map_add() and firmware_map_add_early() | 105 | * Common implementation of firmware_map_add() and firmware_map_add_early() |
102 | * which expects a pre-allocated struct firmware_map_entry. | 106 | * which expects a pre-allocated struct firmware_map_entry. |
103 | **/ | 107 | **/ |
104 | static int firmware_map_add_entry(resource_size_t start, resource_size_t end, | 108 | static int firmware_map_add_entry(u64 start, u64 end, |
105 | const char *type, | 109 | const char *type, |
106 | struct firmware_map_entry *entry) | 110 | struct firmware_map_entry *entry) |
107 | { | 111 | { |
@@ -132,8 +136,7 @@ static int firmware_map_add_entry(resource_size_t start, resource_size_t end, | |||
132 | * | 136 | * |
133 | * Returns 0 on success, or -ENOMEM if no memory could be allocated. | 137 | * Returns 0 on success, or -ENOMEM if no memory could be allocated. |
134 | **/ | 138 | **/ |
135 | int firmware_map_add(resource_size_t start, resource_size_t end, | 139 | int firmware_map_add(u64 start, u64 end, const char *type) |
136 | const char *type) | ||
137 | { | 140 | { |
138 | struct firmware_map_entry *entry; | 141 | struct firmware_map_entry *entry; |
139 | 142 | ||
@@ -157,8 +160,7 @@ int firmware_map_add(resource_size_t start, resource_size_t end, | |||
157 | * | 160 | * |
158 | * Returns 0 on success, or -ENOMEM if no memory could be allocated. | 161 | * Returns 0 on success, or -ENOMEM if no memory could be allocated. |
159 | **/ | 162 | **/ |
160 | int __init firmware_map_add_early(resource_size_t start, resource_size_t end, | 163 | int __init firmware_map_add_early(u64 start, u64 end, const char *type) |
161 | const char *type) | ||
162 | { | 164 | { |
163 | struct firmware_map_entry *entry; | 165 | struct firmware_map_entry *entry; |
164 | 166 | ||
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index 0ecf6b76a401..8e28e5993df5 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c | |||
@@ -504,6 +504,14 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width, | |||
504 | info->fbops = &intelfb_ops; | 504 | info->fbops = &intelfb_ops; |
505 | 505 | ||
506 | info->fix.line_length = fb->pitch; | 506 | info->fix.line_length = fb->pitch; |
507 | |||
508 | /* setup aperture base/size for vesafb takeover */ | ||
509 | info->aperture_base = dev->mode_config.fb_base; | ||
510 | if (IS_I9XX(dev)) | ||
511 | info->aperture_size = pci_resource_len(dev->pdev, 2); | ||
512 | else | ||
513 | info->aperture_size = pci_resource_len(dev->pdev, 0); | ||
514 | |||
507 | info->fix.smem_start = dev->mode_config.fb_base + obj_priv->gtt_offset; | 515 | info->fix.smem_start = dev->mode_config.fb_base + obj_priv->gtt_offset; |
508 | info->fix.smem_len = size; | 516 | info->fix.smem_len = size; |
509 | 517 | ||
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index f8090e137fef..2d5016691d40 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -950,6 +950,7 @@ config SENSORS_HDAPS | |||
950 | config SENSORS_LIS3LV02D | 950 | config SENSORS_LIS3LV02D |
951 | tristate "STMicroeletronics LIS3LV02Dx three-axis digital accelerometer" | 951 | tristate "STMicroeletronics LIS3LV02Dx three-axis digital accelerometer" |
952 | depends on ACPI && INPUT | 952 | depends on ACPI && INPUT |
953 | select INPUT_POLLDEV | ||
953 | select NEW_LEDS | 954 | select NEW_LEDS |
954 | select LEDS_CLASS | 955 | select LEDS_CLASS |
955 | default n | 956 | default n |
@@ -977,6 +978,7 @@ config SENSORS_LIS3LV02D | |||
977 | config SENSORS_LIS3_SPI | 978 | config SENSORS_LIS3_SPI |
978 | tristate "STMicroeletronics LIS3LV02Dx three-axis digital accelerometer (SPI)" | 979 | tristate "STMicroeletronics LIS3LV02Dx three-axis digital accelerometer (SPI)" |
979 | depends on !ACPI && SPI_MASTER && INPUT | 980 | depends on !ACPI && SPI_MASTER && INPUT |
981 | select INPUT_POLLDEV | ||
980 | default n | 982 | default n |
981 | help | 983 | help |
982 | This driver provides support for the LIS3LV02Dx accelerometer connected | 984 | This driver provides support for the LIS3LV02Dx accelerometer connected |
diff --git a/drivers/hwmon/hp_accel.c b/drivers/hwmon/hp_accel.c index abca7e9f953b..6679854c85b0 100644 --- a/drivers/hwmon/hp_accel.c +++ b/drivers/hwmon/hp_accel.c | |||
@@ -27,9 +27,6 @@ | |||
27 | #include <linux/types.h> | 27 | #include <linux/types.h> |
28 | #include <linux/platform_device.h> | 28 | #include <linux/platform_device.h> |
29 | #include <linux/interrupt.h> | 29 | #include <linux/interrupt.h> |
30 | #include <linux/input.h> | ||
31 | #include <linux/kthread.h> | ||
32 | #include <linux/semaphore.h> | ||
33 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
34 | #include <linux/wait.h> | 31 | #include <linux/wait.h> |
35 | #include <linux/poll.h> | 32 | #include <linux/poll.h> |
@@ -161,6 +158,7 @@ static struct axis_conversion lis3lv02d_axis_normal = {1, 2, 3}; | |||
161 | static struct axis_conversion lis3lv02d_axis_y_inverted = {1, -2, 3}; | 158 | static struct axis_conversion lis3lv02d_axis_y_inverted = {1, -2, 3}; |
162 | static struct axis_conversion lis3lv02d_axis_x_inverted = {-1, 2, 3}; | 159 | static struct axis_conversion lis3lv02d_axis_x_inverted = {-1, 2, 3}; |
163 | static struct axis_conversion lis3lv02d_axis_z_inverted = {1, 2, -3}; | 160 | static struct axis_conversion lis3lv02d_axis_z_inverted = {1, 2, -3}; |
161 | static struct axis_conversion lis3lv02d_axis_xy_swap = {2, 1, 3}; | ||
164 | static struct axis_conversion lis3lv02d_axis_xy_rotated_left = {-2, 1, 3}; | 162 | static struct axis_conversion lis3lv02d_axis_xy_rotated_left = {-2, 1, 3}; |
165 | static struct axis_conversion lis3lv02d_axis_xy_rotated_left_usd = {-2, 1, -3}; | 163 | static struct axis_conversion lis3lv02d_axis_xy_rotated_left_usd = {-2, 1, -3}; |
166 | static struct axis_conversion lis3lv02d_axis_xy_swap_inverted = {-2, -1, 3}; | 164 | static struct axis_conversion lis3lv02d_axis_xy_swap_inverted = {-2, -1, 3}; |
@@ -194,13 +192,16 @@ static struct dmi_system_id lis3lv02d_dmi_ids[] = { | |||
194 | AXIS_DMI_MATCH("NX9420", "HP Compaq nx9420", x_inverted), | 192 | AXIS_DMI_MATCH("NX9420", "HP Compaq nx9420", x_inverted), |
195 | AXIS_DMI_MATCH("NW9440", "HP Compaq nw9440", x_inverted), | 193 | AXIS_DMI_MATCH("NW9440", "HP Compaq nw9440", x_inverted), |
196 | AXIS_DMI_MATCH("NC2510", "HP Compaq 2510", y_inverted), | 194 | AXIS_DMI_MATCH("NC2510", "HP Compaq 2510", y_inverted), |
195 | AXIS_DMI_MATCH("NC2710", "HP Compaq 2710", xy_swap), | ||
197 | AXIS_DMI_MATCH("NC8510", "HP Compaq 8510", xy_swap_inverted), | 196 | AXIS_DMI_MATCH("NC8510", "HP Compaq 8510", xy_swap_inverted), |
198 | AXIS_DMI_MATCH("HP2133", "HP 2133", xy_rotated_left), | 197 | AXIS_DMI_MATCH("HP2133", "HP 2133", xy_rotated_left), |
199 | AXIS_DMI_MATCH("HP2140", "HP 2140", xy_swap_inverted), | 198 | AXIS_DMI_MATCH("HP2140", "HP 2140", xy_swap_inverted), |
200 | AXIS_DMI_MATCH("NC653x", "HP Compaq 653", xy_rotated_left_usd), | 199 | AXIS_DMI_MATCH("NC653x", "HP Compaq 653", xy_rotated_left_usd), |
201 | AXIS_DMI_MATCH("NC673x", "HP Compaq 673", xy_rotated_left_usd), | 200 | AXIS_DMI_MATCH("NC673x", "HP Compaq 673", xy_rotated_left_usd), |
202 | AXIS_DMI_MATCH("NC651xx", "HP Compaq 651", xy_rotated_right), | 201 | AXIS_DMI_MATCH("NC651xx", "HP Compaq 651", xy_rotated_right), |
203 | AXIS_DMI_MATCH("NC671xx", "HP Compaq 671", xy_swap_yz_inverted), | 202 | AXIS_DMI_MATCH("NC6710x", "HP Compaq 6710", xy_swap_yz_inverted), |
203 | AXIS_DMI_MATCH("NC6715x", "HP Compaq 6715", y_inverted), | ||
204 | AXIS_DMI_MATCH("NC693xx", "HP EliteBook 693", xy_rotated_right), | ||
204 | /* Intel-based HP Pavilion dv5 */ | 205 | /* Intel-based HP Pavilion dv5 */ |
205 | AXIS_DMI_MATCH2("HPDV5_I", | 206 | AXIS_DMI_MATCH2("HPDV5_I", |
206 | PRODUCT_NAME, "HP Pavilion dv5", | 207 | PRODUCT_NAME, "HP Pavilion dv5", |
@@ -216,7 +217,6 @@ static struct dmi_system_id lis3lv02d_dmi_ids[] = { | |||
216 | { NULL, } | 217 | { NULL, } |
217 | /* Laptop models without axis info (yet): | 218 | /* Laptop models without axis info (yet): |
218 | * "NC6910" "HP Compaq 6910" | 219 | * "NC6910" "HP Compaq 6910" |
219 | * HP Compaq 8710x Notebook PC / Mobile Workstation | ||
220 | * "NC2400" "HP Compaq nc2400" | 220 | * "NC2400" "HP Compaq nc2400" |
221 | * "NX74x0" "HP Compaq nx74" | 221 | * "NX74x0" "HP Compaq nx74" |
222 | * "NX6325" "HP Compaq nx6325" | 222 | * "NX6325" "HP Compaq nx6325" |
@@ -324,7 +324,7 @@ static int lis3lv02d_remove(struct acpi_device *device, int type) | |||
324 | flush_work(&hpled_led.work); | 324 | flush_work(&hpled_led.work); |
325 | led_classdev_unregister(&hpled_led.led_classdev); | 325 | led_classdev_unregister(&hpled_led.led_classdev); |
326 | 326 | ||
327 | return lis3lv02d_remove_fs(); | 327 | return lis3lv02d_remove_fs(&lis3_dev); |
328 | } | 328 | } |
329 | 329 | ||
330 | 330 | ||
@@ -338,13 +338,7 @@ static int lis3lv02d_suspend(struct acpi_device *device, pm_message_t state) | |||
338 | 338 | ||
339 | static int lis3lv02d_resume(struct acpi_device *device) | 339 | static int lis3lv02d_resume(struct acpi_device *device) |
340 | { | 340 | { |
341 | /* put back the device in the right state (ACPI might turn it on) */ | 341 | lis3lv02d_poweron(&lis3_dev); |
342 | mutex_lock(&lis3_dev.lock); | ||
343 | if (lis3_dev.usage > 0) | ||
344 | lis3lv02d_poweron(&lis3_dev); | ||
345 | else | ||
346 | lis3lv02d_poweroff(&lis3_dev); | ||
347 | mutex_unlock(&lis3_dev.lock); | ||
348 | return 0; | 342 | return 0; |
349 | } | 343 | } |
350 | #else | 344 | #else |
diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c index 778eb7795983..271338bdb6be 100644 --- a/drivers/hwmon/lis3lv02d.c +++ b/drivers/hwmon/lis3lv02d.c | |||
@@ -27,9 +27,7 @@ | |||
27 | #include <linux/types.h> | 27 | #include <linux/types.h> |
28 | #include <linux/platform_device.h> | 28 | #include <linux/platform_device.h> |
29 | #include <linux/interrupt.h> | 29 | #include <linux/interrupt.h> |
30 | #include <linux/input.h> | 30 | #include <linux/input-polldev.h> |
31 | #include <linux/kthread.h> | ||
32 | #include <linux/semaphore.h> | ||
33 | #include <linux/delay.h> | 31 | #include <linux/delay.h> |
34 | #include <linux/wait.h> | 32 | #include <linux/wait.h> |
35 | #include <linux/poll.h> | 33 | #include <linux/poll.h> |
@@ -105,56 +103,39 @@ static void lis3lv02d_get_xyz(struct lis3lv02d *lis3, int *x, int *y, int *z) | |||
105 | { | 103 | { |
106 | int position[3]; | 104 | int position[3]; |
107 | 105 | ||
108 | position[0] = lis3_dev.read_data(lis3, OUTX); | 106 | position[0] = lis3->read_data(lis3, OUTX); |
109 | position[1] = lis3_dev.read_data(lis3, OUTY); | 107 | position[1] = lis3->read_data(lis3, OUTY); |
110 | position[2] = lis3_dev.read_data(lis3, OUTZ); | 108 | position[2] = lis3->read_data(lis3, OUTZ); |
111 | 109 | ||
112 | *x = lis3lv02d_get_axis(lis3_dev.ac.x, position); | 110 | *x = lis3lv02d_get_axis(lis3->ac.x, position); |
113 | *y = lis3lv02d_get_axis(lis3_dev.ac.y, position); | 111 | *y = lis3lv02d_get_axis(lis3->ac.y, position); |
114 | *z = lis3lv02d_get_axis(lis3_dev.ac.z, position); | 112 | *z = lis3lv02d_get_axis(lis3->ac.z, position); |
115 | } | 113 | } |
116 | 114 | ||
117 | void lis3lv02d_poweroff(struct lis3lv02d *lis3) | 115 | void lis3lv02d_poweroff(struct lis3lv02d *lis3) |
118 | { | 116 | { |
119 | lis3_dev.is_on = 0; | 117 | /* disable X,Y,Z axis and power down */ |
118 | lis3->write(lis3, CTRL_REG1, 0x00); | ||
120 | } | 119 | } |
121 | EXPORT_SYMBOL_GPL(lis3lv02d_poweroff); | 120 | EXPORT_SYMBOL_GPL(lis3lv02d_poweroff); |
122 | 121 | ||
123 | void lis3lv02d_poweron(struct lis3lv02d *lis3) | 122 | void lis3lv02d_poweron(struct lis3lv02d *lis3) |
124 | { | 123 | { |
125 | lis3_dev.is_on = 1; | 124 | u8 reg; |
126 | lis3_dev.init(lis3); | ||
127 | } | ||
128 | EXPORT_SYMBOL_GPL(lis3lv02d_poweron); | ||
129 | 125 | ||
130 | /* | 126 | lis3->init(lis3); |
131 | * To be called before starting to use the device. It makes sure that the | ||
132 | * device will always be on until a call to lis3lv02d_decrease_use(). Not to be | ||
133 | * used from interrupt context. | ||
134 | */ | ||
135 | static void lis3lv02d_increase_use(struct lis3lv02d *dev) | ||
136 | { | ||
137 | mutex_lock(&dev->lock); | ||
138 | dev->usage++; | ||
139 | if (dev->usage == 1) { | ||
140 | if (!dev->is_on) | ||
141 | lis3lv02d_poweron(dev); | ||
142 | } | ||
143 | mutex_unlock(&dev->lock); | ||
144 | } | ||
145 | 127 | ||
146 | /* | 128 | /* |
147 | * To be called whenever a usage of the device is stopped. | 129 | * Common configuration |
148 | * It will make sure to turn off the device when there is not usage. | 130 | * BDU: LSB and MSB values are not updated until both have been read. |
149 | */ | 131 | * So the value read will always be correct. |
150 | static void lis3lv02d_decrease_use(struct lis3lv02d *dev) | 132 | */ |
151 | { | 133 | lis3->read(lis3, CTRL_REG2, ®); |
152 | mutex_lock(&dev->lock); | 134 | reg |= CTRL2_BDU; |
153 | dev->usage--; | 135 | lis3->write(lis3, CTRL_REG2, reg); |
154 | if (dev->usage == 0) | ||
155 | lis3lv02d_poweroff(dev); | ||
156 | mutex_unlock(&dev->lock); | ||
157 | } | 136 | } |
137 | EXPORT_SYMBOL_GPL(lis3lv02d_poweron); | ||
138 | |||
158 | 139 | ||
159 | static irqreturn_t lis302dl_interrupt(int irq, void *dummy) | 140 | static irqreturn_t lis302dl_interrupt(int irq, void *dummy) |
160 | { | 141 | { |
@@ -198,15 +179,12 @@ static int lis3lv02d_misc_open(struct inode *inode, struct file *file) | |||
198 | printk(KERN_ERR DRIVER_NAME ": IRQ%d allocation failed\n", lis3_dev.irq); | 179 | printk(KERN_ERR DRIVER_NAME ": IRQ%d allocation failed\n", lis3_dev.irq); |
199 | return -EBUSY; | 180 | return -EBUSY; |
200 | } | 181 | } |
201 | lis3lv02d_increase_use(&lis3_dev); | ||
202 | printk("lis3: registered interrupt %d\n", lis3_dev.irq); | ||
203 | return 0; | 182 | return 0; |
204 | } | 183 | } |
205 | 184 | ||
206 | static int lis3lv02d_misc_release(struct inode *inode, struct file *file) | 185 | static int lis3lv02d_misc_release(struct inode *inode, struct file *file) |
207 | { | 186 | { |
208 | fasync_helper(-1, file, 0, &lis3_dev.async_queue); | 187 | fasync_helper(-1, file, 0, &lis3_dev.async_queue); |
209 | lis3lv02d_decrease_use(&lis3_dev); | ||
210 | free_irq(lis3_dev.irq, &lis3_dev); | 188 | free_irq(lis3_dev.irq, &lis3_dev); |
211 | clear_bit(0, &lis3_dev.misc_opened); /* release the device */ | 189 | clear_bit(0, &lis3_dev.misc_opened); /* release the device */ |
212 | return 0; | 190 | return 0; |
@@ -290,46 +268,16 @@ static struct miscdevice lis3lv02d_misc_device = { | |||
290 | .fops = &lis3lv02d_misc_fops, | 268 | .fops = &lis3lv02d_misc_fops, |
291 | }; | 269 | }; |
292 | 270 | ||
293 | /** | 271 | static void lis3lv02d_joystick_poll(struct input_polled_dev *pidev) |
294 | * lis3lv02d_joystick_kthread - Kthread polling function | ||
295 | * @data: unused - here to conform to threadfn prototype | ||
296 | */ | ||
297 | static int lis3lv02d_joystick_kthread(void *data) | ||
298 | { | 272 | { |
299 | int x, y, z; | 273 | int x, y, z; |
300 | 274 | ||
301 | while (!kthread_should_stop()) { | 275 | lis3lv02d_get_xyz(&lis3_dev, &x, &y, &z); |
302 | lis3lv02d_get_xyz(&lis3_dev, &x, &y, &z); | 276 | input_report_abs(pidev->input, ABS_X, x - lis3_dev.xcalib); |
303 | input_report_abs(lis3_dev.idev, ABS_X, x - lis3_dev.xcalib); | 277 | input_report_abs(pidev->input, ABS_Y, y - lis3_dev.ycalib); |
304 | input_report_abs(lis3_dev.idev, ABS_Y, y - lis3_dev.ycalib); | 278 | input_report_abs(pidev->input, ABS_Z, z - lis3_dev.zcalib); |
305 | input_report_abs(lis3_dev.idev, ABS_Z, z - lis3_dev.zcalib); | ||
306 | |||
307 | input_sync(lis3_dev.idev); | ||
308 | |||
309 | try_to_freeze(); | ||
310 | msleep_interruptible(MDPS_POLL_INTERVAL); | ||
311 | } | ||
312 | |||
313 | return 0; | ||
314 | } | ||
315 | |||
316 | static int lis3lv02d_joystick_open(struct input_dev *input) | ||
317 | { | ||
318 | lis3lv02d_increase_use(&lis3_dev); | ||
319 | lis3_dev.kthread = kthread_run(lis3lv02d_joystick_kthread, NULL, "klis3lv02d"); | ||
320 | if (IS_ERR(lis3_dev.kthread)) { | ||
321 | lis3lv02d_decrease_use(&lis3_dev); | ||
322 | return PTR_ERR(lis3_dev.kthread); | ||
323 | } | ||
324 | |||
325 | return 0; | ||
326 | } | 279 | } |
327 | 280 | ||
328 | static void lis3lv02d_joystick_close(struct input_dev *input) | ||
329 | { | ||
330 | kthread_stop(lis3_dev.kthread); | ||
331 | lis3lv02d_decrease_use(&lis3_dev); | ||
332 | } | ||
333 | 281 | ||
334 | static inline void lis3lv02d_calibrate_joystick(void) | 282 | static inline void lis3lv02d_calibrate_joystick(void) |
335 | { | 283 | { |
@@ -339,33 +287,36 @@ static inline void lis3lv02d_calibrate_joystick(void) | |||
339 | 287 | ||
340 | int lis3lv02d_joystick_enable(void) | 288 | int lis3lv02d_joystick_enable(void) |
341 | { | 289 | { |
290 | struct input_dev *input_dev; | ||
342 | int err; | 291 | int err; |
343 | 292 | ||
344 | if (lis3_dev.idev) | 293 | if (lis3_dev.idev) |
345 | return -EINVAL; | 294 | return -EINVAL; |
346 | 295 | ||
347 | lis3_dev.idev = input_allocate_device(); | 296 | lis3_dev.idev = input_allocate_polled_device(); |
348 | if (!lis3_dev.idev) | 297 | if (!lis3_dev.idev) |
349 | return -ENOMEM; | 298 | return -ENOMEM; |
350 | 299 | ||
300 | lis3_dev.idev->poll = lis3lv02d_joystick_poll; | ||
301 | lis3_dev.idev->poll_interval = MDPS_POLL_INTERVAL; | ||
302 | input_dev = lis3_dev.idev->input; | ||
303 | |||
351 | lis3lv02d_calibrate_joystick(); | 304 | lis3lv02d_calibrate_joystick(); |
352 | 305 | ||
353 | lis3_dev.idev->name = "ST LIS3LV02DL Accelerometer"; | 306 | input_dev->name = "ST LIS3LV02DL Accelerometer"; |
354 | lis3_dev.idev->phys = DRIVER_NAME "/input0"; | 307 | input_dev->phys = DRIVER_NAME "/input0"; |
355 | lis3_dev.idev->id.bustype = BUS_HOST; | 308 | input_dev->id.bustype = BUS_HOST; |
356 | lis3_dev.idev->id.vendor = 0; | 309 | input_dev->id.vendor = 0; |
357 | lis3_dev.idev->dev.parent = &lis3_dev.pdev->dev; | 310 | input_dev->dev.parent = &lis3_dev.pdev->dev; |
358 | lis3_dev.idev->open = lis3lv02d_joystick_open; | ||
359 | lis3_dev.idev->close = lis3lv02d_joystick_close; | ||
360 | 311 | ||
361 | set_bit(EV_ABS, lis3_dev.idev->evbit); | 312 | set_bit(EV_ABS, input_dev->evbit); |
362 | input_set_abs_params(lis3_dev.idev, ABS_X, -lis3_dev.mdps_max_val, lis3_dev.mdps_max_val, 3, 3); | 313 | input_set_abs_params(input_dev, ABS_X, -lis3_dev.mdps_max_val, lis3_dev.mdps_max_val, 3, 3); |
363 | input_set_abs_params(lis3_dev.idev, ABS_Y, -lis3_dev.mdps_max_val, lis3_dev.mdps_max_val, 3, 3); | 314 | input_set_abs_params(input_dev, ABS_Y, -lis3_dev.mdps_max_val, lis3_dev.mdps_max_val, 3, 3); |
364 | input_set_abs_params(lis3_dev.idev, ABS_Z, -lis3_dev.mdps_max_val, lis3_dev.mdps_max_val, 3, 3); | 315 | input_set_abs_params(input_dev, ABS_Z, -lis3_dev.mdps_max_val, lis3_dev.mdps_max_val, 3, 3); |
365 | 316 | ||
366 | err = input_register_device(lis3_dev.idev); | 317 | err = input_register_polled_device(lis3_dev.idev); |
367 | if (err) { | 318 | if (err) { |
368 | input_free_device(lis3_dev.idev); | 319 | input_free_polled_device(lis3_dev.idev); |
369 | lis3_dev.idev = NULL; | 320 | lis3_dev.idev = NULL; |
370 | } | 321 | } |
371 | 322 | ||
@@ -378,8 +329,9 @@ void lis3lv02d_joystick_disable(void) | |||
378 | if (!lis3_dev.idev) | 329 | if (!lis3_dev.idev) |
379 | return; | 330 | return; |
380 | 331 | ||
381 | misc_deregister(&lis3lv02d_misc_device); | 332 | if (lis3_dev.irq) |
382 | input_unregister_device(lis3_dev.idev); | 333 | misc_deregister(&lis3lv02d_misc_device); |
334 | input_unregister_polled_device(lis3_dev.idev); | ||
383 | lis3_dev.idev = NULL; | 335 | lis3_dev.idev = NULL; |
384 | } | 336 | } |
385 | EXPORT_SYMBOL_GPL(lis3lv02d_joystick_disable); | 337 | EXPORT_SYMBOL_GPL(lis3lv02d_joystick_disable); |
@@ -390,9 +342,7 @@ static ssize_t lis3lv02d_position_show(struct device *dev, | |||
390 | { | 342 | { |
391 | int x, y, z; | 343 | int x, y, z; |
392 | 344 | ||
393 | lis3lv02d_increase_use(&lis3_dev); | ||
394 | lis3lv02d_get_xyz(&lis3_dev, &x, &y, &z); | 345 | lis3lv02d_get_xyz(&lis3_dev, &x, &y, &z); |
395 | lis3lv02d_decrease_use(&lis3_dev); | ||
396 | return sprintf(buf, "(%d,%d,%d)\n", x, y, z); | 346 | return sprintf(buf, "(%d,%d,%d)\n", x, y, z); |
397 | } | 347 | } |
398 | 348 | ||
@@ -406,9 +356,7 @@ static ssize_t lis3lv02d_calibrate_store(struct device *dev, | |||
406 | struct device_attribute *attr, | 356 | struct device_attribute *attr, |
407 | const char *buf, size_t count) | 357 | const char *buf, size_t count) |
408 | { | 358 | { |
409 | lis3lv02d_increase_use(&lis3_dev); | ||
410 | lis3lv02d_calibrate_joystick(); | 359 | lis3lv02d_calibrate_joystick(); |
411 | lis3lv02d_decrease_use(&lis3_dev); | ||
412 | return count; | 360 | return count; |
413 | } | 361 | } |
414 | 362 | ||
@@ -420,9 +368,7 @@ static ssize_t lis3lv02d_rate_show(struct device *dev, | |||
420 | u8 ctrl; | 368 | u8 ctrl; |
421 | int val; | 369 | int val; |
422 | 370 | ||
423 | lis3lv02d_increase_use(&lis3_dev); | ||
424 | lis3_dev.read(&lis3_dev, CTRL_REG1, &ctrl); | 371 | lis3_dev.read(&lis3_dev, CTRL_REG1, &ctrl); |
425 | lis3lv02d_decrease_use(&lis3_dev); | ||
426 | val = (ctrl & (CTRL1_DF0 | CTRL1_DF1)) >> 4; | 372 | val = (ctrl & (CTRL1_DF0 | CTRL1_DF1)) >> 4; |
427 | return sprintf(buf, "%d\n", lis3lv02dl_df_val[val]); | 373 | return sprintf(buf, "%d\n", lis3lv02dl_df_val[val]); |
428 | } | 374 | } |
@@ -446,17 +392,17 @@ static struct attribute_group lis3lv02d_attribute_group = { | |||
446 | 392 | ||
447 | static int lis3lv02d_add_fs(struct lis3lv02d *lis3) | 393 | static int lis3lv02d_add_fs(struct lis3lv02d *lis3) |
448 | { | 394 | { |
449 | lis3_dev.pdev = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0); | 395 | lis3->pdev = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0); |
450 | if (IS_ERR(lis3_dev.pdev)) | 396 | if (IS_ERR(lis3->pdev)) |
451 | return PTR_ERR(lis3_dev.pdev); | 397 | return PTR_ERR(lis3->pdev); |
452 | 398 | ||
453 | return sysfs_create_group(&lis3_dev.pdev->dev.kobj, &lis3lv02d_attribute_group); | 399 | return sysfs_create_group(&lis3->pdev->dev.kobj, &lis3lv02d_attribute_group); |
454 | } | 400 | } |
455 | 401 | ||
456 | int lis3lv02d_remove_fs(void) | 402 | int lis3lv02d_remove_fs(struct lis3lv02d *lis3) |
457 | { | 403 | { |
458 | sysfs_remove_group(&lis3_dev.pdev->dev.kobj, &lis3lv02d_attribute_group); | 404 | sysfs_remove_group(&lis3->pdev->dev.kobj, &lis3lv02d_attribute_group); |
459 | platform_device_unregister(lis3_dev.pdev); | 405 | platform_device_unregister(lis3->pdev); |
460 | return 0; | 406 | return 0; |
461 | } | 407 | } |
462 | EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs); | 408 | EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs); |
@@ -482,18 +428,35 @@ int lis3lv02d_init_device(struct lis3lv02d *dev) | |||
482 | break; | 428 | break; |
483 | default: | 429 | default: |
484 | printk(KERN_ERR DRIVER_NAME | 430 | printk(KERN_ERR DRIVER_NAME |
485 | ": unknown sensor type 0x%X\n", lis3_dev.whoami); | 431 | ": unknown sensor type 0x%X\n", dev->whoami); |
486 | return -EINVAL; | 432 | return -EINVAL; |
487 | } | 433 | } |
488 | 434 | ||
489 | mutex_init(&dev->lock); | ||
490 | lis3lv02d_add_fs(dev); | 435 | lis3lv02d_add_fs(dev); |
491 | lis3lv02d_increase_use(dev); | 436 | lis3lv02d_poweron(dev); |
492 | 437 | ||
493 | if (lis3lv02d_joystick_enable()) | 438 | if (lis3lv02d_joystick_enable()) |
494 | printk(KERN_ERR DRIVER_NAME ": joystick initialization failed\n"); | 439 | printk(KERN_ERR DRIVER_NAME ": joystick initialization failed\n"); |
495 | 440 | ||
496 | printk("lis3_init_device: irq %d\n", dev->irq); | 441 | /* passing in platform specific data is purely optional and only |
442 | * used by the SPI transport layer at the moment */ | ||
443 | if (dev->pdata) { | ||
444 | struct lis3lv02d_platform_data *p = dev->pdata; | ||
445 | |||
446 | if (p->click_flags && (dev->whoami == LIS_SINGLE_ID)) { | ||
447 | dev->write(dev, CLICK_CFG, p->click_flags); | ||
448 | dev->write(dev, CLICK_TIMELIMIT, p->click_time_limit); | ||
449 | dev->write(dev, CLICK_LATENCY, p->click_latency); | ||
450 | dev->write(dev, CLICK_WINDOW, p->click_window); | ||
451 | dev->write(dev, CLICK_THSZ, p->click_thresh_z & 0xf); | ||
452 | dev->write(dev, CLICK_THSY_X, | ||
453 | (p->click_thresh_x & 0xf) | | ||
454 | (p->click_thresh_y << 4)); | ||
455 | } | ||
456 | |||
457 | if (p->irq_cfg) | ||
458 | dev->write(dev, CTRL_REG3, p->irq_cfg); | ||
459 | } | ||
497 | 460 | ||
498 | /* bail if we did not get an IRQ from the bus layer */ | 461 | /* bail if we did not get an IRQ from the bus layer */ |
499 | if (!dev->irq) { | 462 | if (!dev->irq) { |
@@ -502,11 +465,9 @@ int lis3lv02d_init_device(struct lis3lv02d *dev) | |||
502 | goto out; | 465 | goto out; |
503 | } | 466 | } |
504 | 467 | ||
505 | printk("lis3: registering device\n"); | ||
506 | if (misc_register(&lis3lv02d_misc_device)) | 468 | if (misc_register(&lis3lv02d_misc_device)) |
507 | printk(KERN_ERR DRIVER_NAME ": misc_register failed\n"); | 469 | printk(KERN_ERR DRIVER_NAME ": misc_register failed\n"); |
508 | out: | 470 | out: |
509 | lis3lv02d_decrease_use(dev); | ||
510 | return 0; | 471 | return 0; |
511 | } | 472 | } |
512 | EXPORT_SYMBOL_GPL(lis3lv02d_init_device); | 473 | EXPORT_SYMBOL_GPL(lis3lv02d_init_device); |
diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h index 745ec96806d4..e320e2f511f1 100644 --- a/drivers/hwmon/lis3lv02d.h +++ b/drivers/hwmon/lis3lv02d.h | |||
@@ -18,6 +18,8 @@ | |||
18 | * along with this program; if not, write to the Free Software | 18 | * along with this program; if not, write to the Free Software |
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
20 | */ | 20 | */ |
21 | #include <linux/platform_device.h> | ||
22 | #include <linux/input-polldev.h> | ||
21 | 23 | ||
22 | /* | 24 | /* |
23 | * The actual chip is STMicroelectronics LIS3LV02DL or LIS3LV02DQ that seems to | 25 | * The actual chip is STMicroelectronics LIS3LV02DL or LIS3LV02DQ that seems to |
@@ -27,12 +29,14 @@ | |||
27 | * They can also be connected via I²C. | 29 | * They can also be connected via I²C. |
28 | */ | 30 | */ |
29 | 31 | ||
32 | #include <linux/lis3lv02d.h> | ||
33 | |||
30 | /* 2-byte registers */ | 34 | /* 2-byte registers */ |
31 | #define LIS_DOUBLE_ID 0x3A /* LIS3LV02D[LQ] */ | 35 | #define LIS_DOUBLE_ID 0x3A /* LIS3LV02D[LQ] */ |
32 | /* 1-byte registers */ | 36 | /* 1-byte registers */ |
33 | #define LIS_SINGLE_ID 0x3B /* LIS[32]02DL and others */ | 37 | #define LIS_SINGLE_ID 0x3B /* LIS[32]02DL and others */ |
34 | 38 | ||
35 | enum lis3lv02d_reg { | 39 | enum lis3_reg { |
36 | WHO_AM_I = 0x0F, | 40 | WHO_AM_I = 0x0F, |
37 | OFFSET_X = 0x16, | 41 | OFFSET_X = 0x16, |
38 | OFFSET_Y = 0x17, | 42 | OFFSET_Y = 0x17, |
@@ -60,6 +64,19 @@ enum lis3lv02d_reg { | |||
60 | FF_WU_THS_L = 0x34, | 64 | FF_WU_THS_L = 0x34, |
61 | FF_WU_THS_H = 0x35, | 65 | FF_WU_THS_H = 0x35, |
62 | FF_WU_DURATION = 0x36, | 66 | FF_WU_DURATION = 0x36, |
67 | }; | ||
68 | |||
69 | enum lis302d_reg { | ||
70 | CLICK_CFG = 0x38, | ||
71 | CLICK_SRC = 0x39, | ||
72 | CLICK_THSY_X = 0x3B, | ||
73 | CLICK_THSZ = 0x3C, | ||
74 | CLICK_TIMELIMIT = 0x3D, | ||
75 | CLICK_LATENCY = 0x3E, | ||
76 | CLICK_WINDOW = 0x3F, | ||
77 | }; | ||
78 | |||
79 | enum lis3lv02d_reg { | ||
63 | DD_CFG = 0x38, | 80 | DD_CFG = 0x38, |
64 | DD_SRC = 0x39, | 81 | DD_SRC = 0x39, |
65 | DD_ACK = 0x3A, | 82 | DD_ACK = 0x3A, |
@@ -169,22 +186,20 @@ struct lis3lv02d { | |||
169 | s16 (*read_data) (struct lis3lv02d *lis3, int reg); | 186 | s16 (*read_data) (struct lis3lv02d *lis3, int reg); |
170 | int mdps_max_val; | 187 | int mdps_max_val; |
171 | 188 | ||
172 | struct input_dev *idev; /* input device */ | 189 | struct input_polled_dev *idev; /* input device */ |
173 | struct task_struct *kthread; /* kthread for input */ | ||
174 | struct mutex lock; | ||
175 | struct platform_device *pdev; /* platform device */ | 190 | struct platform_device *pdev; /* platform device */ |
176 | atomic_t count; /* interrupt count after last read */ | 191 | atomic_t count; /* interrupt count after last read */ |
177 | int xcalib; /* calibrated null value for x */ | 192 | int xcalib; /* calibrated null value for x */ |
178 | int ycalib; /* calibrated null value for y */ | 193 | int ycalib; /* calibrated null value for y */ |
179 | int zcalib; /* calibrated null value for z */ | 194 | int zcalib; /* calibrated null value for z */ |
180 | unsigned char is_on; /* whether the device is on or off */ | ||
181 | unsigned char usage; /* usage counter */ | ||
182 | struct axis_conversion ac; /* hw -> logical axis */ | 195 | struct axis_conversion ac; /* hw -> logical axis */ |
183 | 196 | ||
184 | u32 irq; /* IRQ number */ | 197 | u32 irq; /* IRQ number */ |
185 | struct fasync_struct *async_queue; /* queue for the misc device */ | 198 | struct fasync_struct *async_queue; /* queue for the misc device */ |
186 | wait_queue_head_t misc_wait; /* Wait queue for the misc device */ | 199 | wait_queue_head_t misc_wait; /* Wait queue for the misc device */ |
187 | unsigned long misc_opened; /* bit0: whether the device is open */ | 200 | unsigned long misc_opened; /* bit0: whether the device is open */ |
201 | |||
202 | struct lis3lv02d_platform_data *pdata; /* for passing board config */ | ||
188 | }; | 203 | }; |
189 | 204 | ||
190 | int lis3lv02d_init_device(struct lis3lv02d *lis3); | 205 | int lis3lv02d_init_device(struct lis3lv02d *lis3); |
@@ -192,6 +207,6 @@ int lis3lv02d_joystick_enable(void); | |||
192 | void lis3lv02d_joystick_disable(void); | 207 | void lis3lv02d_joystick_disable(void); |
193 | void lis3lv02d_poweroff(struct lis3lv02d *lis3); | 208 | void lis3lv02d_poweroff(struct lis3lv02d *lis3); |
194 | void lis3lv02d_poweron(struct lis3lv02d *lis3); | 209 | void lis3lv02d_poweron(struct lis3lv02d *lis3); |
195 | int lis3lv02d_remove_fs(void); | 210 | int lis3lv02d_remove_fs(struct lis3lv02d *lis3); |
196 | 211 | ||
197 | extern struct lis3lv02d lis3_dev; | 212 | extern struct lis3lv02d lis3_dev; |
diff --git a/drivers/hwmon/lis3lv02d_spi.c b/drivers/hwmon/lis3lv02d_spi.c index 07ae74b0e191..3827ff04485f 100644 --- a/drivers/hwmon/lis3lv02d_spi.c +++ b/drivers/hwmon/lis3lv02d_spi.c | |||
@@ -72,6 +72,7 @@ static int __devinit lis302dl_spi_probe(struct spi_device *spi) | |||
72 | lis3_dev.write = lis3_spi_write; | 72 | lis3_dev.write = lis3_spi_write; |
73 | lis3_dev.irq = spi->irq; | 73 | lis3_dev.irq = spi->irq; |
74 | lis3_dev.ac = lis3lv02d_axis_normal; | 74 | lis3_dev.ac = lis3lv02d_axis_normal; |
75 | lis3_dev.pdata = spi->dev.platform_data; | ||
75 | spi_set_drvdata(spi, &lis3_dev); | 76 | spi_set_drvdata(spi, &lis3_dev); |
76 | 77 | ||
77 | ret = lis3lv02d_init_device(&lis3_dev); | 78 | ret = lis3lv02d_init_device(&lis3_dev); |
diff --git a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c index 356b3a25efa2..1c0b529c06aa 100644 --- a/drivers/input/joystick/analog.c +++ b/drivers/input/joystick/analog.c | |||
@@ -35,7 +35,7 @@ | |||
35 | #include <linux/input.h> | 35 | #include <linux/input.h> |
36 | #include <linux/gameport.h> | 36 | #include <linux/gameport.h> |
37 | #include <linux/jiffies.h> | 37 | #include <linux/jiffies.h> |
38 | #include <asm/timex.h> | 38 | #include <linux/timex.h> |
39 | 39 | ||
40 | #define DRIVER_DESC "Analog joystick and gamepad driver" | 40 | #define DRIVER_DESC "Analog joystick and gamepad driver" |
41 | 41 | ||
diff --git a/drivers/input/misc/pcspkr.c b/drivers/input/misc/pcspkr.c index d6a30cee7bc7..6d67af5387ad 100644 --- a/drivers/input/misc/pcspkr.c +++ b/drivers/input/misc/pcspkr.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/input.h> | 18 | #include <linux/input.h> |
19 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
20 | #include <linux/timex.h> | ||
20 | #include <asm/io.h> | 21 | #include <asm/io.h> |
21 | 22 | ||
22 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); | 23 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); |
diff --git a/drivers/media/video/videobuf-dma-contig.c b/drivers/media/video/videobuf-dma-contig.c index 6109fb5f34e2..0c29a019bc89 100644 --- a/drivers/media/video/videobuf-dma-contig.c +++ b/drivers/media/video/videobuf-dma-contig.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/mm.h> | 19 | #include <linux/mm.h> |
20 | #include <linux/pagemap.h> | ||
20 | #include <linux/dma-mapping.h> | 21 | #include <linux/dma-mapping.h> |
21 | #include <media/videobuf-dma-contig.h> | 22 | #include <media/videobuf-dma-contig.h> |
22 | 23 | ||
@@ -25,6 +26,7 @@ struct videobuf_dma_contig_memory { | |||
25 | void *vaddr; | 26 | void *vaddr; |
26 | dma_addr_t dma_handle; | 27 | dma_addr_t dma_handle; |
27 | unsigned long size; | 28 | unsigned long size; |
29 | int is_userptr; | ||
28 | }; | 30 | }; |
29 | 31 | ||
30 | #define MAGIC_DC_MEM 0x0733ac61 | 32 | #define MAGIC_DC_MEM 0x0733ac61 |
@@ -108,6 +110,82 @@ static struct vm_operations_struct videobuf_vm_ops = { | |||
108 | .close = videobuf_vm_close, | 110 | .close = videobuf_vm_close, |
109 | }; | 111 | }; |
110 | 112 | ||
113 | /** | ||
114 | * videobuf_dma_contig_user_put() - reset pointer to user space buffer | ||
115 | * @mem: per-buffer private videobuf-dma-contig data | ||
116 | * | ||
117 | * This function resets the user space pointer | ||
118 | */ | ||
119 | static void videobuf_dma_contig_user_put(struct videobuf_dma_contig_memory *mem) | ||
120 | { | ||
121 | mem->is_userptr = 0; | ||
122 | mem->dma_handle = 0; | ||
123 | mem->size = 0; | ||
124 | } | ||
125 | |||
126 | /** | ||
127 | * videobuf_dma_contig_user_get() - setup user space memory pointer | ||
128 | * @mem: per-buffer private videobuf-dma-contig data | ||
129 | * @vb: video buffer to map | ||
130 | * | ||
131 | * This function validates and sets up a pointer to user space memory. | ||
132 | * Only physically contiguous pfn-mapped memory is accepted. | ||
133 | * | ||
134 | * Returns 0 if successful. | ||
135 | */ | ||
136 | static int videobuf_dma_contig_user_get(struct videobuf_dma_contig_memory *mem, | ||
137 | struct videobuf_buffer *vb) | ||
138 | { | ||
139 | struct mm_struct *mm = current->mm; | ||
140 | struct vm_area_struct *vma; | ||
141 | unsigned long prev_pfn, this_pfn; | ||
142 | unsigned long pages_done, user_address; | ||
143 | int ret; | ||
144 | |||
145 | mem->size = PAGE_ALIGN(vb->size); | ||
146 | mem->is_userptr = 0; | ||
147 | ret = -EINVAL; | ||
148 | |||
149 | down_read(&mm->mmap_sem); | ||
150 | |||
151 | vma = find_vma(mm, vb->baddr); | ||
152 | if (!vma) | ||
153 | goto out_up; | ||
154 | |||
155 | if ((vb->baddr + mem->size) > vma->vm_end) | ||
156 | goto out_up; | ||
157 | |||
158 | pages_done = 0; | ||
159 | prev_pfn = 0; /* kill warning */ | ||
160 | user_address = vb->baddr; | ||
161 | |||
162 | while (pages_done < (mem->size >> PAGE_SHIFT)) { | ||
163 | ret = follow_pfn(vma, user_address, &this_pfn); | ||
164 | if (ret) | ||
165 | break; | ||
166 | |||
167 | if (pages_done == 0) | ||
168 | mem->dma_handle = this_pfn << PAGE_SHIFT; | ||
169 | else if (this_pfn != (prev_pfn + 1)) | ||
170 | ret = -EFAULT; | ||
171 | |||
172 | if (ret) | ||
173 | break; | ||
174 | |||
175 | prev_pfn = this_pfn; | ||
176 | user_address += PAGE_SIZE; | ||
177 | pages_done++; | ||
178 | } | ||
179 | |||
180 | if (!ret) | ||
181 | mem->is_userptr = 1; | ||
182 | |||
183 | out_up: | ||
184 | up_read(¤t->mm->mmap_sem); | ||
185 | |||
186 | return ret; | ||
187 | } | ||
188 | |||
111 | static void *__videobuf_alloc(size_t size) | 189 | static void *__videobuf_alloc(size_t size) |
112 | { | 190 | { |
113 | struct videobuf_dma_contig_memory *mem; | 191 | struct videobuf_dma_contig_memory *mem; |
@@ -154,12 +232,11 @@ static int __videobuf_iolock(struct videobuf_queue *q, | |||
154 | case V4L2_MEMORY_USERPTR: | 232 | case V4L2_MEMORY_USERPTR: |
155 | dev_dbg(q->dev, "%s memory method USERPTR\n", __func__); | 233 | dev_dbg(q->dev, "%s memory method USERPTR\n", __func__); |
156 | 234 | ||
157 | /* The only USERPTR currently supported is the one needed for | 235 | /* handle pointer from user space */ |
158 | read() method. | ||
159 | */ | ||
160 | if (vb->baddr) | 236 | if (vb->baddr) |
161 | return -EINVAL; | 237 | return videobuf_dma_contig_user_get(mem, vb); |
162 | 238 | ||
239 | /* allocate memory for the read() method */ | ||
163 | mem->size = PAGE_ALIGN(vb->size); | 240 | mem->size = PAGE_ALIGN(vb->size); |
164 | mem->vaddr = dma_alloc_coherent(q->dev, mem->size, | 241 | mem->vaddr = dma_alloc_coherent(q->dev, mem->size, |
165 | &mem->dma_handle, GFP_KERNEL); | 242 | &mem->dma_handle, GFP_KERNEL); |
@@ -400,7 +477,7 @@ void videobuf_dma_contig_free(struct videobuf_queue *q, | |||
400 | So, it should free memory only if the memory were allocated for | 477 | So, it should free memory only if the memory were allocated for |
401 | read() operation. | 478 | read() operation. |
402 | */ | 479 | */ |
403 | if ((buf->memory != V4L2_MEMORY_USERPTR) || buf->baddr) | 480 | if (buf->memory != V4L2_MEMORY_USERPTR) |
404 | return; | 481 | return; |
405 | 482 | ||
406 | if (!mem) | 483 | if (!mem) |
@@ -408,6 +485,13 @@ void videobuf_dma_contig_free(struct videobuf_queue *q, | |||
408 | 485 | ||
409 | MAGIC_CHECK(mem->magic, MAGIC_DC_MEM); | 486 | MAGIC_CHECK(mem->magic, MAGIC_DC_MEM); |
410 | 487 | ||
488 | /* handle user space pointer case */ | ||
489 | if (buf->baddr) { | ||
490 | videobuf_dma_contig_user_put(mem); | ||
491 | return; | ||
492 | } | ||
493 | |||
494 | /* read() method */ | ||
411 | dma_free_coherent(q->dev, mem->size, mem->vaddr, mem->dma_handle); | 495 | dma_free_coherent(q->dev, mem->size, mem->vaddr, mem->dma_handle); |
412 | mem->vaddr = NULL; | 496 | mem->vaddr = NULL; |
413 | } | 497 | } |
diff --git a/drivers/misc/sgi-gru/grufile.c b/drivers/misc/sgi-gru/grufile.c index bbefe77c67a9..3ce2920e2bf3 100644 --- a/drivers/misc/sgi-gru/grufile.c +++ b/drivers/misc/sgi-gru/grufile.c | |||
@@ -302,7 +302,7 @@ static int gru_init_tables(unsigned long gru_base_paddr, void *gru_base_vaddr) | |||
302 | pnode = uv_node_to_pnode(nid); | 302 | pnode = uv_node_to_pnode(nid); |
303 | if (bid < 0 || gru_base[bid]) | 303 | if (bid < 0 || gru_base[bid]) |
304 | continue; | 304 | continue; |
305 | page = alloc_pages_node(nid, GFP_KERNEL, order); | 305 | page = alloc_pages_exact_node(nid, GFP_KERNEL, order); |
306 | if (!page) | 306 | if (!page) |
307 | goto fail; | 307 | goto fail; |
308 | gru_base[bid] = page_address(page); | 308 | gru_base[bid] = page_address(page); |
diff --git a/drivers/misc/sgi-xp/xpc_uv.c b/drivers/misc/sgi-xp/xpc_uv.c index 9172fcdee4e2..c76677afda1b 100644 --- a/drivers/misc/sgi-xp/xpc_uv.c +++ b/drivers/misc/sgi-xp/xpc_uv.c | |||
@@ -232,7 +232,7 @@ xpc_create_gru_mq_uv(unsigned int mq_size, int cpu, char *irq_name, | |||
232 | mq->mmr_blade = uv_cpu_to_blade_id(cpu); | 232 | mq->mmr_blade = uv_cpu_to_blade_id(cpu); |
233 | 233 | ||
234 | nid = cpu_to_node(cpu); | 234 | nid = cpu_to_node(cpu); |
235 | page = alloc_pages_node(nid, GFP_KERNEL | __GFP_ZERO | GFP_THISNODE, | 235 | page = alloc_pages_exact_node(nid, GFP_KERNEL | __GFP_ZERO | GFP_THISNODE, |
236 | pg_order); | 236 | pg_order); |
237 | if (page == NULL) { | 237 | if (page == NULL) { |
238 | dev_err(xpc_part, "xpc_create_gru_mq_uv() failed to alloc %d " | 238 | dev_err(xpc_part, "xpc_create_gru_mq_uv() failed to alloc %d " |
diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c index 1703b20cad5d..6095f8daecd7 100644 --- a/drivers/pcmcia/pcmcia_ioctl.c +++ b/drivers/pcmcia/pcmcia_ioctl.c | |||
@@ -915,12 +915,9 @@ static int ds_ioctl(struct inode * inode, struct file * file, | |||
915 | err = -EPERM; | 915 | err = -EPERM; |
916 | goto free_out; | 916 | goto free_out; |
917 | } else { | 917 | } else { |
918 | static int printed = 0; | 918 | printk_once(KERN_WARNING |
919 | if (!printed) { | 919 | "2.6. kernels use pcmciamtd instead of memory_cs.c and do not require special\n"); |
920 | printk(KERN_WARNING "2.6. kernels use pcmciamtd instead of memory_cs.c and do not require special\n"); | 920 | printk_once(KERN_WARNING "MTD handling any more.\n"); |
921 | printk(KERN_WARNING "MTD handling any more.\n"); | ||
922 | printed++; | ||
923 | } | ||
924 | } | 921 | } |
925 | err = -EINVAL; | 922 | err = -EINVAL; |
926 | goto free_out; | 923 | goto free_out; |
diff --git a/drivers/spi/spi_mpc83xx.c b/drivers/spi/spi_mpc83xx.c index f4573a96af24..a32ccb44065e 100644 --- a/drivers/spi/spi_mpc83xx.c +++ b/drivers/spi/spi_mpc83xx.c | |||
@@ -711,12 +711,12 @@ static int of_mpc83xx_spi_get_chipselects(struct device *dev) | |||
711 | return 0; | 711 | return 0; |
712 | } | 712 | } |
713 | 713 | ||
714 | pinfo->gpios = kmalloc(ngpios * sizeof(pinfo->gpios), GFP_KERNEL); | 714 | pinfo->gpios = kmalloc(ngpios * sizeof(*pinfo->gpios), GFP_KERNEL); |
715 | if (!pinfo->gpios) | 715 | if (!pinfo->gpios) |
716 | return -ENOMEM; | 716 | return -ENOMEM; |
717 | memset(pinfo->gpios, -1, ngpios * sizeof(pinfo->gpios)); | 717 | memset(pinfo->gpios, -1, ngpios * sizeof(*pinfo->gpios)); |
718 | 718 | ||
719 | pinfo->alow_flags = kzalloc(ngpios * sizeof(pinfo->alow_flags), | 719 | pinfo->alow_flags = kzalloc(ngpios * sizeof(*pinfo->alow_flags), |
720 | GFP_KERNEL); | 720 | GFP_KERNEL); |
721 | if (!pinfo->alow_flags) { | 721 | if (!pinfo->alow_flags) { |
722 | ret = -ENOMEM; | 722 | ret = -ENOMEM; |
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 2b5a691064b7..932ffdbf86d9 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig | |||
@@ -2104,6 +2104,7 @@ config FB_MB862XX_LIME | |||
2104 | bool "Lime GDC" | 2104 | bool "Lime GDC" |
2105 | depends on FB_MB862XX | 2105 | depends on FB_MB862XX |
2106 | depends on OF && !FB_MB862XX_PCI_GDC | 2106 | depends on OF && !FB_MB862XX_PCI_GDC |
2107 | depends on PPC | ||
2107 | select FB_FOREIGN_ENDIAN | 2108 | select FB_FOREIGN_ENDIAN |
2108 | select FB_LITTLE_ENDIAN | 2109 | select FB_LITTLE_ENDIAN |
2109 | ---help--- | 2110 | ---help--- |
diff --git a/drivers/video/acornfb.c b/drivers/video/acornfb.c index 6995fe1e86d4..0bcc59eb37fa 100644 --- a/drivers/video/acornfb.c +++ b/drivers/video/acornfb.c | |||
@@ -859,43 +859,6 @@ acornfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) | |||
859 | return 0; | 859 | return 0; |
860 | } | 860 | } |
861 | 861 | ||
862 | /* | ||
863 | * Note that we are entered with the kernel locked. | ||
864 | */ | ||
865 | static int | ||
866 | acornfb_mmap(struct fb_info *info, struct vm_area_struct *vma) | ||
867 | { | ||
868 | unsigned long off, start; | ||
869 | u32 len; | ||
870 | |||
871 | off = vma->vm_pgoff << PAGE_SHIFT; | ||
872 | |||
873 | start = info->fix.smem_start; | ||
874 | len = PAGE_ALIGN(start & ~PAGE_MASK) + info->fix.smem_len; | ||
875 | start &= PAGE_MASK; | ||
876 | if ((vma->vm_end - vma->vm_start + off) > len) | ||
877 | return -EINVAL; | ||
878 | off += start; | ||
879 | vma->vm_pgoff = off >> PAGE_SHIFT; | ||
880 | |||
881 | /* This is an IO map - tell maydump to skip this VMA */ | ||
882 | vma->vm_flags |= VM_IO; | ||
883 | |||
884 | vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); | ||
885 | |||
886 | /* | ||
887 | * Don't alter the page protection flags; we want to keep the area | ||
888 | * cached for better performance. This does mean that we may miss | ||
889 | * some updates to the screen occasionally, but process switches | ||
890 | * should cause the caches and buffers to be flushed often enough. | ||
891 | */ | ||
892 | if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, | ||
893 | vma->vm_end - vma->vm_start, | ||
894 | vma->vm_page_prot)) | ||
895 | return -EAGAIN; | ||
896 | return 0; | ||
897 | } | ||
898 | |||
899 | static struct fb_ops acornfb_ops = { | 862 | static struct fb_ops acornfb_ops = { |
900 | .owner = THIS_MODULE, | 863 | .owner = THIS_MODULE, |
901 | .fb_check_var = acornfb_check_var, | 864 | .fb_check_var = acornfb_check_var, |
@@ -905,7 +868,6 @@ static struct fb_ops acornfb_ops = { | |||
905 | .fb_fillrect = cfb_fillrect, | 868 | .fb_fillrect = cfb_fillrect, |
906 | .fb_copyarea = cfb_copyarea, | 869 | .fb_copyarea = cfb_copyarea, |
907 | .fb_imageblit = cfb_imageblit, | 870 | .fb_imageblit = cfb_imageblit, |
908 | .fb_mmap = acornfb_mmap, | ||
909 | }; | 871 | }; |
910 | 872 | ||
911 | /* | 873 | /* |
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index 2fb63f6ea2f1..5afd64482f55 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c | |||
@@ -345,7 +345,7 @@ static int atmel_lcdfb_check_var(struct fb_var_screeninfo *var, | |||
345 | dev_dbg(dev, " bpp: %u\n", var->bits_per_pixel); | 345 | dev_dbg(dev, " bpp: %u\n", var->bits_per_pixel); |
346 | dev_dbg(dev, " clk: %lu KHz\n", clk_value_khz); | 346 | dev_dbg(dev, " clk: %lu KHz\n", clk_value_khz); |
347 | 347 | ||
348 | if ((PICOS2KHZ(var->pixclock) * var->bits_per_pixel / 8) > clk_value_khz) { | 348 | if (PICOS2KHZ(var->pixclock) > clk_value_khz) { |
349 | dev_err(dev, "%lu KHz pixel clock is too fast\n", PICOS2KHZ(var->pixclock)); | 349 | dev_err(dev, "%lu KHz pixel clock is too fast\n", PICOS2KHZ(var->pixclock)); |
350 | return -EINVAL; | 350 | return -EINVAL; |
351 | } | 351 | } |
diff --git a/drivers/video/aty/radeon_pm.c b/drivers/video/aty/radeon_pm.c index 97a1f095f327..515cf1978d19 100644 --- a/drivers/video/aty/radeon_pm.c +++ b/drivers/video/aty/radeon_pm.c | |||
@@ -213,7 +213,6 @@ static void radeon_pm_disable_dynamic_mode(struct radeonfb_info *rinfo) | |||
213 | PIXCLKS_CNTL__R300_PIXCLK_TRANS_ALWAYS_ONb | | 213 | PIXCLKS_CNTL__R300_PIXCLK_TRANS_ALWAYS_ONb | |
214 | PIXCLKS_CNTL__R300_PIXCLK_TVO_ALWAYS_ONb | | 214 | PIXCLKS_CNTL__R300_PIXCLK_TVO_ALWAYS_ONb | |
215 | PIXCLKS_CNTL__R300_P2G2CLK_ALWAYS_ONb | | 215 | PIXCLKS_CNTL__R300_P2G2CLK_ALWAYS_ONb | |
216 | PIXCLKS_CNTL__R300_P2G2CLK_ALWAYS_ONb | | ||
217 | PIXCLKS_CNTL__R300_DISP_DAC_PIXCLK_DAC2_BLANK_OFF); | 216 | PIXCLKS_CNTL__R300_DISP_DAC_PIXCLK_DAC2_BLANK_OFF); |
218 | OUTPLL(pllPIXCLKS_CNTL, tmp); | 217 | OUTPLL(pllPIXCLKS_CNTL, tmp); |
219 | 218 | ||
@@ -395,7 +394,7 @@ static void radeon_pm_enable_dynamic_mode(struct radeonfb_info *rinfo) | |||
395 | PIXCLKS_CNTL__R300_PIXCLK_TRANS_ALWAYS_ONb | | 394 | PIXCLKS_CNTL__R300_PIXCLK_TRANS_ALWAYS_ONb | |
396 | PIXCLKS_CNTL__R300_PIXCLK_TVO_ALWAYS_ONb | | 395 | PIXCLKS_CNTL__R300_PIXCLK_TVO_ALWAYS_ONb | |
397 | PIXCLKS_CNTL__R300_P2G2CLK_ALWAYS_ONb | | 396 | PIXCLKS_CNTL__R300_P2G2CLK_ALWAYS_ONb | |
398 | PIXCLKS_CNTL__R300_P2G2CLK_ALWAYS_ONb); | 397 | PIXCLKS_CNTL__R300_P2G2CLK_DAC_ALWAYS_ONb); |
399 | OUTPLL(pllPIXCLKS_CNTL, tmp); | 398 | OUTPLL(pllPIXCLKS_CNTL, tmp); |
400 | 399 | ||
401 | tmp = INPLL(pllMCLK_MISC); | 400 | tmp = INPLL(pllMCLK_MISC); |
diff --git a/drivers/video/bf54x-lq043fb.c b/drivers/video/bf54x-lq043fb.c index 37e60b1d2ed9..e49ae5edcc00 100644 --- a/drivers/video/bf54x-lq043fb.c +++ b/drivers/video/bf54x-lq043fb.c | |||
@@ -323,7 +323,6 @@ static int bfin_bf54x_fb_release(struct fb_info *info, int user) | |||
323 | bfin_write_EPPI0_CONTROL(0); | 323 | bfin_write_EPPI0_CONTROL(0); |
324 | SSYNC(); | 324 | SSYNC(); |
325 | disable_dma(CH_EPPI0); | 325 | disable_dma(CH_EPPI0); |
326 | memset(fbi->fb_buffer, 0, info->fix.smem_len); | ||
327 | } | 326 | } |
328 | 327 | ||
329 | spin_unlock(&fbi->lock); | 328 | spin_unlock(&fbi->lock); |
@@ -530,7 +529,7 @@ static irqreturn_t bfin_bf54x_irq_error(int irq, void *dev_id) | |||
530 | return IRQ_HANDLED; | 529 | return IRQ_HANDLED; |
531 | } | 530 | } |
532 | 531 | ||
533 | static int __init bfin_bf54x_probe(struct platform_device *pdev) | 532 | static int __devinit bfin_bf54x_probe(struct platform_device *pdev) |
534 | { | 533 | { |
535 | struct bfin_bf54xfb_info *info; | 534 | struct bfin_bf54xfb_info *info; |
536 | struct fb_info *fbinfo; | 535 | struct fb_info *fbinfo; |
@@ -626,14 +625,12 @@ static int __init bfin_bf54x_probe(struct platform_device *pdev) | |||
626 | goto out3; | 625 | goto out3; |
627 | } | 626 | } |
628 | 627 | ||
629 | memset(info->fb_buffer, 0, fbinfo->fix.smem_len); | ||
630 | |||
631 | fbinfo->screen_base = (void *)info->fb_buffer; | 628 | fbinfo->screen_base = (void *)info->fb_buffer; |
632 | fbinfo->fix.smem_start = (int)info->fb_buffer; | 629 | fbinfo->fix.smem_start = (int)info->fb_buffer; |
633 | 630 | ||
634 | fbinfo->fbops = &bfin_bf54x_fb_ops; | 631 | fbinfo->fbops = &bfin_bf54x_fb_ops; |
635 | 632 | ||
636 | fbinfo->pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL); | 633 | fbinfo->pseudo_palette = kzalloc(sizeof(u32) * 16, GFP_KERNEL); |
637 | if (!fbinfo->pseudo_palette) { | 634 | if (!fbinfo->pseudo_palette) { |
638 | printk(KERN_ERR DRIVER_NAME | 635 | printk(KERN_ERR DRIVER_NAME |
639 | "Fail to allocate pseudo_palette\n"); | 636 | "Fail to allocate pseudo_palette\n"); |
@@ -642,8 +639,6 @@ static int __init bfin_bf54x_probe(struct platform_device *pdev) | |||
642 | goto out4; | 639 | goto out4; |
643 | } | 640 | } |
644 | 641 | ||
645 | memset(fbinfo->pseudo_palette, 0, sizeof(u32) * 16); | ||
646 | |||
647 | if (fb_alloc_cmap(&fbinfo->cmap, BFIN_LCD_NBR_PALETTE_ENTRIES, 0) | 642 | if (fb_alloc_cmap(&fbinfo->cmap, BFIN_LCD_NBR_PALETTE_ENTRIES, 0) |
648 | < 0) { | 643 | < 0) { |
649 | printk(KERN_ERR DRIVER_NAME | 644 | printk(KERN_ERR DRIVER_NAME |
@@ -712,7 +707,7 @@ out1: | |||
712 | return ret; | 707 | return ret; |
713 | } | 708 | } |
714 | 709 | ||
715 | static int bfin_bf54x_remove(struct platform_device *pdev) | 710 | static int __devexit bfin_bf54x_remove(struct platform_device *pdev) |
716 | { | 711 | { |
717 | 712 | ||
718 | struct fb_info *fbinfo = platform_get_drvdata(pdev); | 713 | struct fb_info *fbinfo = platform_get_drvdata(pdev); |
@@ -781,7 +776,7 @@ static int bfin_bf54x_resume(struct platform_device *pdev) | |||
781 | 776 | ||
782 | static struct platform_driver bfin_bf54x_driver = { | 777 | static struct platform_driver bfin_bf54x_driver = { |
783 | .probe = bfin_bf54x_probe, | 778 | .probe = bfin_bf54x_probe, |
784 | .remove = bfin_bf54x_remove, | 779 | .remove = __devexit_p(bfin_bf54x_remove), |
785 | .suspend = bfin_bf54x_suspend, | 780 | .suspend = bfin_bf54x_suspend, |
786 | .resume = bfin_bf54x_resume, | 781 | .resume = bfin_bf54x_resume, |
787 | .driver = { | 782 | .driver = { |
@@ -790,7 +785,7 @@ static struct platform_driver bfin_bf54x_driver = { | |||
790 | }, | 785 | }, |
791 | }; | 786 | }; |
792 | 787 | ||
793 | static int __devinit bfin_bf54x_driver_init(void) | 788 | static int __init bfin_bf54x_driver_init(void) |
794 | { | 789 | { |
795 | return platform_driver_register(&bfin_bf54x_driver); | 790 | return platform_driver_register(&bfin_bf54x_driver); |
796 | } | 791 | } |
diff --git a/drivers/video/bfin-t350mcqb-fb.c b/drivers/video/bfin-t350mcqb-fb.c index 90cfddabf1f7..5cc36cfbf07b 100644 --- a/drivers/video/bfin-t350mcqb-fb.c +++ b/drivers/video/bfin-t350mcqb-fb.c | |||
@@ -242,7 +242,6 @@ static int bfin_t350mcqb_fb_release(struct fb_info *info, int user) | |||
242 | SSYNC(); | 242 | SSYNC(); |
243 | disable_dma(CH_PPI); | 243 | disable_dma(CH_PPI); |
244 | bfin_t350mcqb_stop_timers(); | 244 | bfin_t350mcqb_stop_timers(); |
245 | memset(fbi->fb_buffer, 0, info->fix.smem_len); | ||
246 | } | 245 | } |
247 | 246 | ||
248 | spin_unlock(&fbi->lock); | 247 | spin_unlock(&fbi->lock); |
@@ -527,8 +526,6 @@ static int __devinit bfin_t350mcqb_probe(struct platform_device *pdev) | |||
527 | goto out3; | 526 | goto out3; |
528 | } | 527 | } |
529 | 528 | ||
530 | memset(info->fb_buffer, 0, fbinfo->fix.smem_len); | ||
531 | |||
532 | fbinfo->screen_base = (void *)info->fb_buffer + ACTIVE_VIDEO_MEM_OFFSET; | 529 | fbinfo->screen_base = (void *)info->fb_buffer + ACTIVE_VIDEO_MEM_OFFSET; |
533 | fbinfo->fix.smem_start = (int)info->fb_buffer + ACTIVE_VIDEO_MEM_OFFSET; | 530 | fbinfo->fix.smem_start = (int)info->fb_buffer + ACTIVE_VIDEO_MEM_OFFSET; |
534 | 531 | ||
@@ -602,7 +599,7 @@ out1: | |||
602 | return ret; | 599 | return ret; |
603 | } | 600 | } |
604 | 601 | ||
605 | static int bfin_t350mcqb_remove(struct platform_device *pdev) | 602 | static int __devexit bfin_t350mcqb_remove(struct platform_device *pdev) |
606 | { | 603 | { |
607 | 604 | ||
608 | struct fb_info *fbinfo = platform_get_drvdata(pdev); | 605 | struct fb_info *fbinfo = platform_get_drvdata(pdev); |
@@ -637,9 +634,6 @@ static int bfin_t350mcqb_remove(struct platform_device *pdev) | |||
637 | #ifdef CONFIG_PM | 634 | #ifdef CONFIG_PM |
638 | static int bfin_t350mcqb_suspend(struct platform_device *pdev, pm_message_t state) | 635 | static int bfin_t350mcqb_suspend(struct platform_device *pdev, pm_message_t state) |
639 | { | 636 | { |
640 | struct fb_info *fbinfo = platform_get_drvdata(pdev); | ||
641 | struct bfin_t350mcqbfb_info *info = fbinfo->par; | ||
642 | |||
643 | bfin_t350mcqb_disable_ppi(); | 637 | bfin_t350mcqb_disable_ppi(); |
644 | disable_dma(CH_PPI); | 638 | disable_dma(CH_PPI); |
645 | bfin_write_PPI_STATUS(0xFFFF); | 639 | bfin_write_PPI_STATUS(0xFFFF); |
@@ -649,9 +643,6 @@ static int bfin_t350mcqb_suspend(struct platform_device *pdev, pm_message_t stat | |||
649 | 643 | ||
650 | static int bfin_t350mcqb_resume(struct platform_device *pdev) | 644 | static int bfin_t350mcqb_resume(struct platform_device *pdev) |
651 | { | 645 | { |
652 | struct fb_info *fbinfo = platform_get_drvdata(pdev); | ||
653 | struct bfin_t350mcqbfb_info *info = fbinfo->par; | ||
654 | |||
655 | enable_dma(CH_PPI); | 646 | enable_dma(CH_PPI); |
656 | bfin_t350mcqb_enable_ppi(); | 647 | bfin_t350mcqb_enable_ppi(); |
657 | 648 | ||
@@ -664,7 +655,7 @@ static int bfin_t350mcqb_resume(struct platform_device *pdev) | |||
664 | 655 | ||
665 | static struct platform_driver bfin_t350mcqb_driver = { | 656 | static struct platform_driver bfin_t350mcqb_driver = { |
666 | .probe = bfin_t350mcqb_probe, | 657 | .probe = bfin_t350mcqb_probe, |
667 | .remove = bfin_t350mcqb_remove, | 658 | .remove = __devexit_p(bfin_t350mcqb_remove), |
668 | .suspend = bfin_t350mcqb_suspend, | 659 | .suspend = bfin_t350mcqb_suspend, |
669 | .resume = bfin_t350mcqb_resume, | 660 | .resume = bfin_t350mcqb_resume, |
670 | .driver = { | 661 | .driver = { |
@@ -673,7 +664,7 @@ static struct platform_driver bfin_t350mcqb_driver = { | |||
673 | }, | 664 | }, |
674 | }; | 665 | }; |
675 | 666 | ||
676 | static int __devinit bfin_t350mcqb_driver_init(void) | 667 | static int __init bfin_t350mcqb_driver_init(void) |
677 | { | 668 | { |
678 | return platform_driver_register(&bfin_t350mcqb_driver); | 669 | return platform_driver_register(&bfin_t350mcqb_driver); |
679 | } | 670 | } |
diff --git a/drivers/video/carminefb.c b/drivers/video/carminefb.c index c7ff3c1a266a..0c02f8ec4bf3 100644 --- a/drivers/video/carminefb.c +++ b/drivers/video/carminefb.c | |||
@@ -562,7 +562,7 @@ static int __devinit alloc_carmine_fb(void __iomem *regs, void __iomem *smem_bas | |||
562 | if (ret < 0) | 562 | if (ret < 0) |
563 | goto err_free_fb; | 563 | goto err_free_fb; |
564 | 564 | ||
565 | if (fb_mode > ARRAY_SIZE(carmine_modedb)) | 565 | if (fb_mode >= ARRAY_SIZE(carmine_modedb)) |
566 | fb_mode = CARMINEFB_DEFAULT_VIDEO_MODE; | 566 | fb_mode = CARMINEFB_DEFAULT_VIDEO_MODE; |
567 | 567 | ||
568 | par->cur_mode = par->new_mode = ~0; | 568 | par->cur_mode = par->new_mode = ~0; |
diff --git a/drivers/video/chipsfb.c b/drivers/video/chipsfb.c index 777389c40988..57b9d276497e 100644 --- a/drivers/video/chipsfb.c +++ b/drivers/video/chipsfb.c | |||
@@ -414,7 +414,6 @@ chipsfb_pci_init(struct pci_dev *dp, const struct pci_device_id *ent) | |||
414 | } | 414 | } |
415 | 415 | ||
416 | pci_set_drvdata(dp, p); | 416 | pci_set_drvdata(dp, p); |
417 | p->device = &dp->dev; | ||
418 | 417 | ||
419 | init_chips(p, addr); | 418 | init_chips(p, addr); |
420 | 419 | ||
diff --git a/drivers/video/efifb.c b/drivers/video/efifb.c index 8dea2bc92705..eb12182b2059 100644 --- a/drivers/video/efifb.c +++ b/drivers/video/efifb.c | |||
@@ -280,6 +280,9 @@ static int __init efifb_probe(struct platform_device *dev) | |||
280 | info->pseudo_palette = info->par; | 280 | info->pseudo_palette = info->par; |
281 | info->par = NULL; | 281 | info->par = NULL; |
282 | 282 | ||
283 | info->aperture_base = efifb_fix.smem_start; | ||
284 | info->aperture_size = size_total; | ||
285 | |||
283 | info->screen_base = ioremap(efifb_fix.smem_start, efifb_fix.smem_len); | 286 | info->screen_base = ioremap(efifb_fix.smem_start, efifb_fix.smem_len); |
284 | if (!info->screen_base) { | 287 | if (!info->screen_base) { |
285 | printk(KERN_ERR "efifb: abort, cannot ioremap video memory " | 288 | printk(KERN_ERR "efifb: abort, cannot ioremap video memory " |
@@ -337,7 +340,7 @@ static int __init efifb_probe(struct platform_device *dev) | |||
337 | info->fbops = &efifb_ops; | 340 | info->fbops = &efifb_ops; |
338 | info->var = efifb_defined; | 341 | info->var = efifb_defined; |
339 | info->fix = efifb_fix; | 342 | info->fix = efifb_fix; |
340 | info->flags = FBINFO_FLAG_DEFAULT; | 343 | info->flags = FBINFO_FLAG_DEFAULT | FBINFO_MISC_FIRMWARE; |
341 | 344 | ||
342 | if ((err = fb_alloc_cmap(&info->cmap, 256, 0)) < 0) { | 345 | if ((err = fb_alloc_cmap(&info->cmap, 256, 0)) < 0) { |
343 | printk(KERN_ERR "efifb: cannot allocate colormap\n"); | 346 | printk(KERN_ERR "efifb: cannot allocate colormap\n"); |
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index d412a1ddc12f..f8a09bf8d0cd 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c | |||
@@ -1462,6 +1462,16 @@ static int fb_check_foreignness(struct fb_info *fi) | |||
1462 | return 0; | 1462 | return 0; |
1463 | } | 1463 | } |
1464 | 1464 | ||
1465 | static bool fb_do_apertures_overlap(struct fb_info *gen, struct fb_info *hw) | ||
1466 | { | ||
1467 | /* is the generic aperture base the same as the HW one */ | ||
1468 | if (gen->aperture_base == hw->aperture_base) | ||
1469 | return true; | ||
1470 | /* is the generic aperture base inside the hw base->hw base+size */ | ||
1471 | if (gen->aperture_base > hw->aperture_base && gen->aperture_base <= hw->aperture_base + hw->aperture_size) | ||
1472 | return true; | ||
1473 | return false; | ||
1474 | } | ||
1465 | /** | 1475 | /** |
1466 | * register_framebuffer - registers a frame buffer device | 1476 | * register_framebuffer - registers a frame buffer device |
1467 | * @fb_info: frame buffer info structure | 1477 | * @fb_info: frame buffer info structure |
@@ -1485,6 +1495,23 @@ register_framebuffer(struct fb_info *fb_info) | |||
1485 | if (fb_check_foreignness(fb_info)) | 1495 | if (fb_check_foreignness(fb_info)) |
1486 | return -ENOSYS; | 1496 | return -ENOSYS; |
1487 | 1497 | ||
1498 | /* check all firmware fbs and kick off if the base addr overlaps */ | ||
1499 | for (i = 0 ; i < FB_MAX; i++) { | ||
1500 | if (!registered_fb[i]) | ||
1501 | continue; | ||
1502 | |||
1503 | if (registered_fb[i]->flags & FBINFO_MISC_FIRMWARE) { | ||
1504 | if (fb_do_apertures_overlap(registered_fb[i], fb_info)) { | ||
1505 | printk(KERN_ERR "fb: conflicting fb hw usage " | ||
1506 | "%s vs %s - removing generic driver\n", | ||
1507 | fb_info->fix.id, | ||
1508 | registered_fb[i]->fix.id); | ||
1509 | unregister_framebuffer(registered_fb[i]); | ||
1510 | break; | ||
1511 | } | ||
1512 | } | ||
1513 | } | ||
1514 | |||
1488 | num_registered_fb++; | 1515 | num_registered_fb++; |
1489 | for (i = 0 ; i < FB_MAX; i++) | 1516 | for (i = 0 ; i < FB_MAX; i++) |
1490 | if (!registered_fb[i]) | 1517 | if (!registered_fb[i]) |
@@ -1586,6 +1613,10 @@ unregister_framebuffer(struct fb_info *fb_info) | |||
1586 | device_destroy(fb_class, MKDEV(FB_MAJOR, i)); | 1613 | device_destroy(fb_class, MKDEV(FB_MAJOR, i)); |
1587 | event.info = fb_info; | 1614 | event.info = fb_info; |
1588 | fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event); | 1615 | fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event); |
1616 | |||
1617 | /* this may free fb info */ | ||
1618 | if (fb_info->fbops->fb_destroy) | ||
1619 | fb_info->fbops->fb_destroy(fb_info); | ||
1589 | done: | 1620 | done: |
1590 | return ret; | 1621 | return ret; |
1591 | } | 1622 | } |
diff --git a/drivers/video/igafb.c b/drivers/video/igafb.c index 3a81060137a2..15d200109446 100644 --- a/drivers/video/igafb.c +++ b/drivers/video/igafb.c | |||
@@ -395,17 +395,16 @@ int __init igafb_init(void) | |||
395 | /* We leak a reference here but as it cannot be unloaded this is | 395 | /* We leak a reference here but as it cannot be unloaded this is |
396 | fine. If you write unload code remember to free it in unload */ | 396 | fine. If you write unload code remember to free it in unload */ |
397 | 397 | ||
398 | size = sizeof(struct fb_info) + sizeof(struct iga_par) + sizeof(u32)*16; | 398 | size = sizeof(struct iga_par) + sizeof(u32)*16; |
399 | 399 | ||
400 | info = kzalloc(size, GFP_ATOMIC); | 400 | info = framebuffer_alloc(size, &pdev->dev); |
401 | if (!info) { | 401 | if (!info) { |
402 | printk("igafb_init: can't alloc fb_info\n"); | 402 | printk("igafb_init: can't alloc fb_info\n"); |
403 | pci_dev_put(pdev); | 403 | pci_dev_put(pdev); |
404 | return -ENOMEM; | 404 | return -ENOMEM; |
405 | } | 405 | } |
406 | 406 | ||
407 | par = (struct iga_par *) (info + 1); | 407 | par = info->par; |
408 | |||
409 | 408 | ||
410 | if ((addr = pdev->resource[0].start) == 0) { | 409 | if ((addr = pdev->resource[0].start) == 0) { |
411 | printk("igafb_init: no memory start\n"); | 410 | printk("igafb_init: no memory start\n"); |
@@ -526,7 +525,6 @@ int __init igafb_init(void) | |||
526 | info->var = default_var; | 525 | info->var = default_var; |
527 | info->fix = igafb_fix; | 526 | info->fix = igafb_fix; |
528 | info->pseudo_palette = (void *)(par + 1); | 527 | info->pseudo_palette = (void *)(par + 1); |
529 | info->device = &pdev->dev; | ||
530 | 528 | ||
531 | if (!iga_init(info, par)) { | 529 | if (!iga_init(info, par)) { |
532 | iounmap((void *)par->io_base); | 530 | iounmap((void *)par->io_base); |
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c index ace14fe02fc4..0cafd642fbc0 100644 --- a/drivers/video/intelfb/intelfbdrv.c +++ b/drivers/video/intelfb/intelfbdrv.c | |||
@@ -1365,6 +1365,11 @@ static int intelfb_set_par(struct fb_info *info) | |||
1365 | DBG_MSG("intelfb_set_par (%dx%d-%d)\n", info->var.xres, | 1365 | DBG_MSG("intelfb_set_par (%dx%d-%d)\n", info->var.xres, |
1366 | info->var.yres, info->var.bits_per_pixel); | 1366 | info->var.yres, info->var.bits_per_pixel); |
1367 | 1367 | ||
1368 | /* | ||
1369 | * Disable VCO prior to timing register change. | ||
1370 | */ | ||
1371 | OUTREG(DPLL_A, INREG(DPLL_A) & ~DPLL_VCO_ENABLE); | ||
1372 | |||
1368 | intelfb_blank(FB_BLANK_POWERDOWN, info); | 1373 | intelfb_blank(FB_BLANK_POWERDOWN, info); |
1369 | 1374 | ||
1370 | if (ACCEL(dinfo, info)) | 1375 | if (ACCEL(dinfo, info)) |
diff --git a/drivers/video/logo/Makefile b/drivers/video/logo/Makefile index b91251d1fe41..3b437813584c 100644 --- a/drivers/video/logo/Makefile +++ b/drivers/video/logo/Makefile | |||
@@ -37,22 +37,24 @@ extra-y += $(call logo-cfiles,_clut224,ppm) | |||
37 | # Gray 256 | 37 | # Gray 256 |
38 | extra-y += $(call logo-cfiles,_gray256,pgm) | 38 | extra-y += $(call logo-cfiles,_gray256,pgm) |
39 | 39 | ||
40 | pnmtologo := scripts/pnmtologo | ||
41 | |||
40 | # Create commands like "pnmtologo -t mono -n logo_mac_mono -o ..." | 42 | # Create commands like "pnmtologo -t mono -n logo_mac_mono -o ..." |
41 | quiet_cmd_logo = LOGO $@ | 43 | quiet_cmd_logo = LOGO $@ |
42 | cmd_logo = scripts/pnmtologo \ | 44 | cmd_logo = $(pnmtologo) \ |
43 | -t $(patsubst $*_%,%,$(notdir $(basename $<))) \ | 45 | -t $(patsubst $*_%,%,$(notdir $(basename $<))) \ |
44 | -n $(notdir $(basename $<)) -o $@ $< | 46 | -n $(notdir $(basename $<)) -o $@ $< |
45 | 47 | ||
46 | $(obj)/%_mono.c: $(src)/%_mono.pbm FORCE | 48 | $(obj)/%_mono.c: $(src)/%_mono.pbm $(pnmtologo) FORCE |
47 | $(call if_changed,logo) | 49 | $(call if_changed,logo) |
48 | 50 | ||
49 | $(obj)/%_vga16.c: $(src)/%_vga16.ppm FORCE | 51 | $(obj)/%_vga16.c: $(src)/%_vga16.ppm $(pnmtologo) FORCE |
50 | $(call if_changed,logo) | 52 | $(call if_changed,logo) |
51 | 53 | ||
52 | $(obj)/%_clut224.c: $(src)/%_clut224.ppm FORCE | 54 | $(obj)/%_clut224.c: $(src)/%_clut224.ppm $(pnmtologo) FORCE |
53 | $(call if_changed,logo) | 55 | $(call if_changed,logo) |
54 | 56 | ||
55 | $(obj)/%_gray256.c: $(src)/%_gray256.pgm FORCE | 57 | $(obj)/%_gray256.c: $(src)/%_gray256.pgm $(pnmtologo) FORCE |
56 | $(call if_changed,logo) | 58 | $(call if_changed,logo) |
57 | 59 | ||
58 | # Files generated that shall be removed upon make clean | 60 | # Files generated that shall be removed upon make clean |
diff --git a/drivers/video/logo/logo.c b/drivers/video/logo/logo.c index 2e85a2b52d05..ea7a8ccc830c 100644 --- a/drivers/video/logo/logo.c +++ b/drivers/video/logo/logo.c | |||
@@ -21,21 +21,6 @@ | |||
21 | #include <asm/bootinfo.h> | 21 | #include <asm/bootinfo.h> |
22 | #endif | 22 | #endif |
23 | 23 | ||
24 | extern const struct linux_logo logo_linux_mono; | ||
25 | extern const struct linux_logo logo_linux_vga16; | ||
26 | extern const struct linux_logo logo_linux_clut224; | ||
27 | extern const struct linux_logo logo_blackfin_vga16; | ||
28 | extern const struct linux_logo logo_blackfin_clut224; | ||
29 | extern const struct linux_logo logo_dec_clut224; | ||
30 | extern const struct linux_logo logo_mac_clut224; | ||
31 | extern const struct linux_logo logo_parisc_clut224; | ||
32 | extern const struct linux_logo logo_sgi_clut224; | ||
33 | extern const struct linux_logo logo_sun_clut224; | ||
34 | extern const struct linux_logo logo_superh_mono; | ||
35 | extern const struct linux_logo logo_superh_vga16; | ||
36 | extern const struct linux_logo logo_superh_clut224; | ||
37 | extern const struct linux_logo logo_m32r_clut224; | ||
38 | |||
39 | static int nologo; | 24 | static int nologo; |
40 | module_param(nologo, bool, 0); | 25 | module_param(nologo, bool, 0); |
41 | MODULE_PARM_DESC(nologo, "Disables startup logo"); | 26 | MODULE_PARM_DESC(nologo, "Disables startup logo"); |
diff --git a/drivers/video/mb862xx/mb862xxfb.c b/drivers/video/mb862xx/mb862xxfb.c index fb64234a3825..a28e3cfbbf70 100644 --- a/drivers/video/mb862xx/mb862xxfb.c +++ b/drivers/video/mb862xx/mb862xxfb.c | |||
@@ -19,7 +19,7 @@ | |||
19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
20 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
21 | #include <linux/pci.h> | 21 | #include <linux/pci.h> |
22 | #if defined(CONFIG_PPC_OF) | 22 | #if defined(CONFIG_OF) |
23 | #include <linux/of_platform.h> | 23 | #include <linux/of_platform.h> |
24 | #endif | 24 | #endif |
25 | #include "mb862xxfb.h" | 25 | #include "mb862xxfb.h" |
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c index 16186240c5f2..34e4e7995169 100644 --- a/drivers/video/modedb.c +++ b/drivers/video/modedb.c | |||
@@ -264,6 +264,14 @@ static const struct fb_videomode modedb[] = { | |||
264 | /* 1280x800, 60 Hz, 47.403 kHz hsync, WXGA 16:10 aspect ratio */ | 264 | /* 1280x800, 60 Hz, 47.403 kHz hsync, WXGA 16:10 aspect ratio */ |
265 | NULL, 60, 1280, 800, 12048, 200, 64, 24, 1, 136, 3, | 265 | NULL, 60, 1280, 800, 12048, 200, 64, 24, 1, 136, 3, |
266 | 0, FB_VMODE_NONINTERLACED | 266 | 0, FB_VMODE_NONINTERLACED |
267 | }, { | ||
268 | /* 720x576i @ 50 Hz, 15.625 kHz hsync (PAL RGB) */ | ||
269 | NULL, 50, 720, 576, 74074, 64, 16, 39, 5, 64, 5, | ||
270 | 0, FB_VMODE_INTERLACED | ||
271 | }, { | ||
272 | /* 800x520i @ 50 Hz, 15.625 kHz hsync (PAL RGB) */ | ||
273 | NULL, 50, 800, 520, 58823, 144, 64, 72, 28, 80, 5, | ||
274 | 0, FB_VMODE_INTERLACED | ||
267 | }, | 275 | }, |
268 | }; | 276 | }; |
269 | 277 | ||
diff --git a/drivers/video/offb.c b/drivers/video/offb.c index e1d9eeb1aeaf..4d8c54c23dd7 100644 --- a/drivers/video/offb.c +++ b/drivers/video/offb.c | |||
@@ -378,7 +378,6 @@ static void __init offb_init_fb(const char *name, const char *full_name, | |||
378 | struct fb_fix_screeninfo *fix; | 378 | struct fb_fix_screeninfo *fix; |
379 | struct fb_var_screeninfo *var; | 379 | struct fb_var_screeninfo *var; |
380 | struct fb_info *info; | 380 | struct fb_info *info; |
381 | int size; | ||
382 | 381 | ||
383 | if (!request_mem_region(res_start, res_size, "offb")) | 382 | if (!request_mem_region(res_start, res_size, "offb")) |
384 | return; | 383 | return; |
@@ -393,15 +392,12 @@ static void __init offb_init_fb(const char *name, const char *full_name, | |||
393 | return; | 392 | return; |
394 | } | 393 | } |
395 | 394 | ||
396 | size = sizeof(struct fb_info) + sizeof(u32) * 16; | 395 | info = framebuffer_alloc(sizeof(u32) * 16, NULL); |
397 | |||
398 | info = kmalloc(size, GFP_ATOMIC); | ||
399 | 396 | ||
400 | if (info == 0) { | 397 | if (info == 0) { |
401 | release_mem_region(res_start, res_size); | 398 | release_mem_region(res_start, res_size); |
402 | return; | 399 | return; |
403 | } | 400 | } |
404 | memset(info, 0, size); | ||
405 | 401 | ||
406 | fix = &info->fix; | 402 | fix = &info->fix; |
407 | var = &info->var; | 403 | var = &info->var; |
@@ -497,7 +493,7 @@ static void __init offb_init_fb(const char *name, const char *full_name, | |||
497 | iounmap(par->cmap_adr); | 493 | iounmap(par->cmap_adr); |
498 | par->cmap_adr = NULL; | 494 | par->cmap_adr = NULL; |
499 | iounmap(info->screen_base); | 495 | iounmap(info->screen_base); |
500 | kfree(info); | 496 | framebuffer_release(info); |
501 | release_mem_region(res_start, res_size); | 497 | release_mem_region(res_start, res_size); |
502 | return; | 498 | return; |
503 | } | 499 | } |
diff --git a/drivers/video/pm2fb.c b/drivers/video/pm2fb.c index c6dd924976a4..36436ee6c1a4 100644 --- a/drivers/video/pm2fb.c +++ b/drivers/video/pm2fb.c | |||
@@ -1748,7 +1748,7 @@ static void __devexit pm2fb_remove(struct pci_dev *pdev) | |||
1748 | pci_set_drvdata(pdev, NULL); | 1748 | pci_set_drvdata(pdev, NULL); |
1749 | fb_dealloc_cmap(&info->cmap); | 1749 | fb_dealloc_cmap(&info->cmap); |
1750 | kfree(info->pixmap.addr); | 1750 | kfree(info->pixmap.addr); |
1751 | kfree(info); | 1751 | framebuffer_release(info); |
1752 | } | 1752 | } |
1753 | 1753 | ||
1754 | static struct pci_device_id pm2fb_id_table[] = { | 1754 | static struct pci_device_id pm2fb_id_table[] = { |
diff --git a/drivers/video/s1d13xxxfb.c b/drivers/video/s1d13xxxfb.c index 0726aecf3b7e..0deb0a8867b7 100644 --- a/drivers/video/s1d13xxxfb.c +++ b/drivers/video/s1d13xxxfb.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * | 2 | * |
3 | * (c) 2004 Simtec Electronics | 3 | * (c) 2004 Simtec Electronics |
4 | * (c) 2005 Thibaut VARENE <varenet@parisc-linux.org> | 4 | * (c) 2005 Thibaut VARENE <varenet@parisc-linux.org> |
5 | * (c) 2009 Kristoffer Ericson <kristoffer.ericson@gmail.com> | ||
5 | * | 6 | * |
6 | * Driver for Epson S1D13xxx series framebuffer chips | 7 | * Driver for Epson S1D13xxx series framebuffer chips |
7 | * | 8 | * |
@@ -10,18 +11,10 @@ | |||
10 | * linux/drivers/video/epson1355fb.c | 11 | * linux/drivers/video/epson1355fb.c |
11 | * linux/drivers/video/epson/s1d13xxxfb.c (2.4 driver by Epson) | 12 | * linux/drivers/video/epson/s1d13xxxfb.c (2.4 driver by Epson) |
12 | * | 13 | * |
13 | * Note, currently only tested on S1D13806 with 16bit CRT. | ||
14 | * As such, this driver might still contain some hardcoded bits relating to | ||
15 | * S1D13806. | ||
16 | * Making it work on other S1D13XXX chips should merely be a matter of adding | ||
17 | * a few switch()s, some missing glue here and there maybe, and split header | ||
18 | * files. | ||
19 | * | ||
20 | * TODO: - handle dual screen display (CRT and LCD at the same time). | 14 | * TODO: - handle dual screen display (CRT and LCD at the same time). |
21 | * - check_var(), mode change, etc. | 15 | * - check_var(), mode change, etc. |
22 | * - PM untested. | 16 | * - probably not SMP safe :) |
23 | * - Accelerated interfaces. | 17 | * - support all bitblt operations on all cards |
24 | * - Probably not SMP safe :) | ||
25 | * | 18 | * |
26 | * This file is subject to the terms and conditions of the GNU General Public | 19 | * This file is subject to the terms and conditions of the GNU General Public |
27 | * License. See the file COPYING in the main directory of this archive for | 20 | * License. See the file COPYING in the main directory of this archive for |
@@ -31,19 +24,24 @@ | |||
31 | #include <linux/module.h> | 24 | #include <linux/module.h> |
32 | #include <linux/platform_device.h> | 25 | #include <linux/platform_device.h> |
33 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
34 | |||
35 | #include <linux/types.h> | 27 | #include <linux/types.h> |
36 | #include <linux/errno.h> | 28 | #include <linux/errno.h> |
37 | #include <linux/mm.h> | 29 | #include <linux/mm.h> |
38 | #include <linux/mman.h> | 30 | #include <linux/mman.h> |
39 | #include <linux/fb.h> | 31 | #include <linux/fb.h> |
32 | #include <linux/spinlock_types.h> | ||
33 | #include <linux/spinlock.h> | ||
40 | 34 | ||
41 | #include <asm/io.h> | 35 | #include <asm/io.h> |
42 | 36 | ||
43 | #include <video/s1d13xxxfb.h> | 37 | #include <video/s1d13xxxfb.h> |
44 | 38 | ||
45 | #define PFX "s1d13xxxfb: " | 39 | #define PFX "s1d13xxxfb: " |
40 | #define BLIT "s1d13xxxfb_bitblt: " | ||
46 | 41 | ||
42 | /* | ||
43 | * set this to enable debugging on general functions | ||
44 | */ | ||
47 | #if 0 | 45 | #if 0 |
48 | #define dbg(fmt, args...) do { printk(KERN_INFO fmt, ## args); } while(0) | 46 | #define dbg(fmt, args...) do { printk(KERN_INFO fmt, ## args); } while(0) |
49 | #else | 47 | #else |
@@ -51,7 +49,21 @@ | |||
51 | #endif | 49 | #endif |
52 | 50 | ||
53 | /* | 51 | /* |
54 | * List of card production ids | 52 | * set this to enable debugging on 2D acceleration |
53 | */ | ||
54 | #if 0 | ||
55 | #define dbg_blit(fmt, args...) do { printk(KERN_INFO BLIT fmt, ## args); } while (0) | ||
56 | #else | ||
57 | #define dbg_blit(fmt, args...) do { } while (0) | ||
58 | #endif | ||
59 | |||
60 | /* | ||
61 | * we make sure only one bitblt operation is running | ||
62 | */ | ||
63 | static DEFINE_SPINLOCK(s1d13xxxfb_bitblt_lock); | ||
64 | |||
65 | /* | ||
66 | * list of card production ids | ||
55 | */ | 67 | */ |
56 | static const int s1d13xxxfb_prod_ids[] = { | 68 | static const int s1d13xxxfb_prod_ids[] = { |
57 | S1D13505_PROD_ID, | 69 | S1D13505_PROD_ID, |
@@ -69,7 +81,7 @@ static const char *s1d13xxxfb_prod_names[] = { | |||
69 | }; | 81 | }; |
70 | 82 | ||
71 | /* | 83 | /* |
72 | * Here we define the default struct fb_fix_screeninfo | 84 | * here we define the default struct fb_fix_screeninfo |
73 | */ | 85 | */ |
74 | static struct fb_fix_screeninfo __devinitdata s1d13xxxfb_fix = { | 86 | static struct fb_fix_screeninfo __devinitdata s1d13xxxfb_fix = { |
75 | .id = S1D_FBID, | 87 | .id = S1D_FBID, |
@@ -145,8 +157,10 @@ crt_enable(struct s1d13xxxfb_par *par, int enable) | |||
145 | s1d13xxxfb_writereg(par, S1DREG_COM_DISP_MODE, mode); | 157 | s1d13xxxfb_writereg(par, S1DREG_COM_DISP_MODE, mode); |
146 | } | 158 | } |
147 | 159 | ||
148 | /* framebuffer control routines */ | ||
149 | 160 | ||
161 | /************************************************************* | ||
162 | framebuffer control functions | ||
163 | *************************************************************/ | ||
150 | static inline void | 164 | static inline void |
151 | s1d13xxxfb_setup_pseudocolour(struct fb_info *info) | 165 | s1d13xxxfb_setup_pseudocolour(struct fb_info *info) |
152 | { | 166 | { |
@@ -242,13 +256,13 @@ s1d13xxxfb_set_par(struct fb_info *info) | |||
242 | } | 256 | } |
243 | 257 | ||
244 | /** | 258 | /** |
245 | * s1d13xxxfb_setcolreg - sets a color register. | 259 | * s1d13xxxfb_setcolreg - sets a color register. |
246 | * @regno: Which register in the CLUT we are programming | 260 | * @regno: Which register in the CLUT we are programming |
247 | * @red: The red value which can be up to 16 bits wide | 261 | * @red: The red value which can be up to 16 bits wide |
248 | * @green: The green value which can be up to 16 bits wide | 262 | * @green: The green value which can be up to 16 bits wide |
249 | * @blue: The blue value which can be up to 16 bits wide. | 263 | * @blue: The blue value which can be up to 16 bits wide. |
250 | * @transp: If supported the alpha value which can be up to 16 bits wide. | 264 | * @transp: If supported the alpha value which can be up to 16 bits wide. |
251 | * @info: frame buffer info structure | 265 | * @info: frame buffer info structure |
252 | * | 266 | * |
253 | * Returns negative errno on error, or zero on success. | 267 | * Returns negative errno on error, or zero on success. |
254 | */ | 268 | */ |
@@ -351,15 +365,15 @@ s1d13xxxfb_blank(int blank_mode, struct fb_info *info) | |||
351 | } | 365 | } |
352 | 366 | ||
353 | /** | 367 | /** |
354 | * s1d13xxxfb_pan_display - Pans the display. | 368 | * s1d13xxxfb_pan_display - Pans the display. |
355 | * @var: frame buffer variable screen structure | 369 | * @var: frame buffer variable screen structure |
356 | * @info: frame buffer structure that represents a single frame buffer | 370 | * @info: frame buffer structure that represents a single frame buffer |
357 | * | 371 | * |
358 | * Pan (or wrap, depending on the `vmode' field) the display using the | 372 | * Pan (or wrap, depending on the `vmode' field) the display using the |
359 | * `yoffset' field of the `var' structure (`xoffset' not yet supported). | 373 | * `yoffset' field of the `var' structure (`xoffset' not yet supported). |
360 | * If the values don't fit, return -EINVAL. | 374 | * If the values don't fit, return -EINVAL. |
361 | * | 375 | * |
362 | * Returns negative errno on error, or zero on success. | 376 | * Returns negative errno on error, or zero on success. |
363 | */ | 377 | */ |
364 | static int | 378 | static int |
365 | s1d13xxxfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) | 379 | s1d13xxxfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) |
@@ -390,8 +404,259 @@ s1d13xxxfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) | |||
390 | return 0; | 404 | return 0; |
391 | } | 405 | } |
392 | 406 | ||
393 | /* framebuffer information structures */ | 407 | /************************************************************ |
408 | functions to handle bitblt acceleration | ||
409 | ************************************************************/ | ||
410 | |||
411 | /** | ||
412 | * bltbit_wait_bitset - waits for change in register value | ||
413 | * @info : framebuffer structure | ||
414 | * @bit : value expected in register | ||
415 | * @timeout : ... | ||
416 | * | ||
417 | * waits until value changes INTO bit | ||
418 | */ | ||
419 | static u8 | ||
420 | bltbit_wait_bitset(struct fb_info *info, u8 bit, int timeout) | ||
421 | { | ||
422 | while (!(s1d13xxxfb_readreg(info->par, S1DREG_BBLT_CTL0) & bit)) { | ||
423 | udelay(10); | ||
424 | if (!--timeout) { | ||
425 | dbg_blit("wait_bitset timeout\n"); | ||
426 | break; | ||
427 | } | ||
428 | } | ||
429 | |||
430 | return timeout; | ||
431 | } | ||
432 | |||
433 | /** | ||
434 | * bltbit_wait_bitclear - waits for change in register value | ||
435 | * @info : frambuffer structure | ||
436 | * @bit : value currently in register | ||
437 | * @timeout : ... | ||
438 | * | ||
439 | * waits until value changes FROM bit | ||
440 | * | ||
441 | */ | ||
442 | static u8 | ||
443 | bltbit_wait_bitclear(struct fb_info *info, u8 bit, int timeout) | ||
444 | { | ||
445 | while (s1d13xxxfb_readreg(info->par, S1DREG_BBLT_CTL0) & bit) { | ||
446 | udelay(10); | ||
447 | if (!--timeout) { | ||
448 | dbg_blit("wait_bitclear timeout\n"); | ||
449 | break; | ||
450 | } | ||
451 | } | ||
452 | |||
453 | return timeout; | ||
454 | } | ||
455 | |||
456 | /** | ||
457 | * bltbit_fifo_status - checks the current status of the fifo | ||
458 | * @info : framebuffer structure | ||
459 | * | ||
460 | * returns number of free words in buffer | ||
461 | */ | ||
462 | static u8 | ||
463 | bltbit_fifo_status(struct fb_info *info) | ||
464 | { | ||
465 | u8 status; | ||
394 | 466 | ||
467 | status = s1d13xxxfb_readreg(info->par, S1DREG_BBLT_CTL0); | ||
468 | |||
469 | /* its empty so room for 16 words */ | ||
470 | if (status & BBLT_FIFO_EMPTY) | ||
471 | return 16; | ||
472 | |||
473 | /* its full so we dont want to add */ | ||
474 | if (status & BBLT_FIFO_FULL) | ||
475 | return 0; | ||
476 | |||
477 | /* its atleast half full but we can add one atleast */ | ||
478 | if (status & BBLT_FIFO_NOT_FULL) | ||
479 | return 1; | ||
480 | |||
481 | return 0; | ||
482 | } | ||
483 | |||
484 | /* | ||
485 | * s1d13xxxfb_bitblt_copyarea - accelerated copyarea function | ||
486 | * @info : framebuffer structure | ||
487 | * @area : fb_copyarea structure | ||
488 | * | ||
489 | * supports (atleast) S1D13506 | ||
490 | * | ||
491 | */ | ||
492 | static void | ||
493 | s1d13xxxfb_bitblt_copyarea(struct fb_info *info, const struct fb_copyarea *area) | ||
494 | { | ||
495 | u32 dst, src; | ||
496 | u32 stride; | ||
497 | u16 reverse = 0; | ||
498 | u16 sx = area->sx, sy = area->sy; | ||
499 | u16 dx = area->dx, dy = area->dy; | ||
500 | u16 width = area->width, height = area->height; | ||
501 | u16 bpp; | ||
502 | |||
503 | spin_lock(&s1d13xxxfb_bitblt_lock); | ||
504 | |||
505 | /* bytes per xres line */ | ||
506 | bpp = (info->var.bits_per_pixel >> 3); | ||
507 | stride = bpp * info->var.xres; | ||
508 | |||
509 | /* reverse, calculate the last pixel in rectangle */ | ||
510 | if ((dy > sy) || ((dy == sy) && (dx >= sx))) { | ||
511 | dst = (((dy + height - 1) * stride) + (bpp * (dx + width - 1))); | ||
512 | src = (((sy + height - 1) * stride) + (bpp * (sx + width - 1))); | ||
513 | reverse = 1; | ||
514 | /* not reverse, calculate the first pixel in rectangle */ | ||
515 | } else { /* (y * xres) + (bpp * x) */ | ||
516 | dst = (dy * stride) + (bpp * dx); | ||
517 | src = (sy * stride) + (bpp * sx); | ||
518 | } | ||
519 | |||
520 | /* set source adress */ | ||
521 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_SRC_START0, (src & 0xff)); | ||
522 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_SRC_START1, (src >> 8) & 0x00ff); | ||
523 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_SRC_START2, (src >> 16) & 0x00ff); | ||
524 | |||
525 | /* set destination adress */ | ||
526 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_DST_START0, (dst & 0xff)); | ||
527 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_DST_START1, (dst >> 8) & 0x00ff); | ||
528 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_DST_START2, (dst >> 16) & 0x00ff); | ||
529 | |||
530 | /* program height and width */ | ||
531 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_WIDTH0, (width & 0xff) - 1); | ||
532 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_WIDTH1, (width >> 8)); | ||
533 | |||
534 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_HEIGHT0, (height & 0xff) - 1); | ||
535 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_HEIGHT1, (height >> 8)); | ||
536 | |||
537 | /* negative direction ROP */ | ||
538 | if (reverse == 1) { | ||
539 | dbg_blit("(copyarea) negative rop\n"); | ||
540 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_OP, 0x03); | ||
541 | } else /* positive direction ROP */ { | ||
542 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_OP, 0x02); | ||
543 | dbg_blit("(copyarea) positive rop\n"); | ||
544 | } | ||
545 | |||
546 | /* set for rectangel mode and not linear */ | ||
547 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_CTL0, 0x0); | ||
548 | |||
549 | /* setup the bpp 1 = 16bpp, 0 = 8bpp*/ | ||
550 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_CTL1, (bpp >> 1)); | ||
551 | |||
552 | /* set words per xres */ | ||
553 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_MEM_OFF0, (stride >> 1) & 0xff); | ||
554 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_MEM_OFF1, (stride >> 9)); | ||
555 | |||
556 | dbg_blit("(copyarea) dx=%d, dy=%d\n", dx, dy); | ||
557 | dbg_blit("(copyarea) sx=%d, sy=%d\n", sx, sy); | ||
558 | dbg_blit("(copyarea) width=%d, height=%d\n", width - 1, height - 1); | ||
559 | dbg_blit("(copyarea) stride=%d\n", stride); | ||
560 | dbg_blit("(copyarea) bpp=%d=0x0%d, mem_offset1=%d, mem_offset2=%d\n", bpp, (bpp >> 1), | ||
561 | (stride >> 1) & 0xff, stride >> 9); | ||
562 | |||
563 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_CC_EXP, 0x0c); | ||
564 | |||
565 | /* initialize the engine */ | ||
566 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_CTL0, 0x80); | ||
567 | |||
568 | /* wait to complete */ | ||
569 | bltbit_wait_bitclear(info, 0x80, 8000); | ||
570 | |||
571 | spin_unlock(&s1d13xxxfb_bitblt_lock); | ||
572 | } | ||
573 | |||
574 | /** | ||
575 | * | ||
576 | * s1d13xxxfb_bitblt_solidfill - accelerated solidfill function | ||
577 | * @info : framebuffer structure | ||
578 | * @rect : fb_fillrect structure | ||
579 | * | ||
580 | * supports (atleast 13506) | ||
581 | * | ||
582 | **/ | ||
583 | static void | ||
584 | s1d13xxxfb_bitblt_solidfill(struct fb_info *info, const struct fb_fillrect *rect) | ||
585 | { | ||
586 | u32 screen_stride, dest; | ||
587 | u32 fg; | ||
588 | u16 bpp = (info->var.bits_per_pixel >> 3); | ||
589 | |||
590 | /* grab spinlock */ | ||
591 | spin_lock(&s1d13xxxfb_bitblt_lock); | ||
592 | |||
593 | /* bytes per x width */ | ||
594 | screen_stride = (bpp * info->var.xres); | ||
595 | |||
596 | /* bytes to starting point */ | ||
597 | dest = ((rect->dy * screen_stride) + (bpp * rect->dx)); | ||
598 | |||
599 | dbg_blit("(solidfill) dx=%d, dy=%d, stride=%d, dest=%d\n" | ||
600 | "(solidfill) : rect_width=%d, rect_height=%d\n", | ||
601 | rect->dx, rect->dy, screen_stride, dest, | ||
602 | rect->width - 1, rect->height - 1); | ||
603 | |||
604 | dbg_blit("(solidfill) : xres=%d, yres=%d, bpp=%d\n", | ||
605 | info->var.xres, info->var.yres, | ||
606 | info->var.bits_per_pixel); | ||
607 | dbg_blit("(solidfill) : rop=%d\n", rect->rop); | ||
608 | |||
609 | /* We split the destination into the three registers */ | ||
610 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_DST_START0, (dest & 0x00ff)); | ||
611 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_DST_START1, ((dest >> 8) & 0x00ff)); | ||
612 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_DST_START2, ((dest >> 16) & 0x00ff)); | ||
613 | |||
614 | /* give information regarding rectangel width */ | ||
615 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_WIDTH0, ((rect->width) & 0x00ff) - 1); | ||
616 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_WIDTH1, (rect->width >> 8)); | ||
617 | |||
618 | /* give information regarding rectangel height */ | ||
619 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_HEIGHT0, ((rect->height) & 0x00ff) - 1); | ||
620 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_HEIGHT1, (rect->height >> 8)); | ||
621 | |||
622 | if (info->fix.visual == FB_VISUAL_TRUECOLOR || | ||
623 | info->fix.visual == FB_VISUAL_DIRECTCOLOR) { | ||
624 | fg = ((u32 *)info->pseudo_palette)[rect->color]; | ||
625 | dbg_blit("(solidfill) truecolor/directcolor\n"); | ||
626 | dbg_blit("(solidfill) pseudo_palette[%d] = %d\n", rect->color, fg); | ||
627 | } else { | ||
628 | fg = rect->color; | ||
629 | dbg_blit("(solidfill) color = %d\n", rect->color); | ||
630 | } | ||
631 | |||
632 | /* set foreground color */ | ||
633 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_FGC0, (fg & 0xff)); | ||
634 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_FGC1, (fg >> 8) & 0xff); | ||
635 | |||
636 | /* set rectangual region of memory (rectangle and not linear) */ | ||
637 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_CTL0, 0x0); | ||
638 | |||
639 | /* set operation mode SOLID_FILL */ | ||
640 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_OP, BBLT_SOLID_FILL); | ||
641 | |||
642 | /* set bits per pixel (1 = 16bpp, 0 = 8bpp) */ | ||
643 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_CTL1, (info->var.bits_per_pixel >> 4)); | ||
644 | |||
645 | /* set the memory offset for the bblt in word sizes */ | ||
646 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_MEM_OFF0, (screen_stride >> 1) & 0x00ff); | ||
647 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_MEM_OFF1, (screen_stride >> 9)); | ||
648 | |||
649 | /* and away we go.... */ | ||
650 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_CTL0, 0x80); | ||
651 | |||
652 | /* wait until its done */ | ||
653 | bltbit_wait_bitclear(info, 0x80, 8000); | ||
654 | |||
655 | /* let others play */ | ||
656 | spin_unlock(&s1d13xxxfb_bitblt_lock); | ||
657 | } | ||
658 | |||
659 | /* framebuffer information structures */ | ||
395 | static struct fb_ops s1d13xxxfb_fbops = { | 660 | static struct fb_ops s1d13xxxfb_fbops = { |
396 | .owner = THIS_MODULE, | 661 | .owner = THIS_MODULE, |
397 | .fb_set_par = s1d13xxxfb_set_par, | 662 | .fb_set_par = s1d13xxxfb_set_par, |
@@ -400,7 +665,7 @@ static struct fb_ops s1d13xxxfb_fbops = { | |||
400 | 665 | ||
401 | .fb_pan_display = s1d13xxxfb_pan_display, | 666 | .fb_pan_display = s1d13xxxfb_pan_display, |
402 | 667 | ||
403 | /* to be replaced by any acceleration we can */ | 668 | /* gets replaced at chip detection time */ |
404 | .fb_fillrect = cfb_fillrect, | 669 | .fb_fillrect = cfb_fillrect, |
405 | .fb_copyarea = cfb_copyarea, | 670 | .fb_copyarea = cfb_copyarea, |
406 | .fb_imageblit = cfb_imageblit, | 671 | .fb_imageblit = cfb_imageblit, |
@@ -412,9 +677,9 @@ static int s1d13xxxfb_width_tab[2][4] __devinitdata = { | |||
412 | }; | 677 | }; |
413 | 678 | ||
414 | /** | 679 | /** |
415 | * s1d13xxxfb_fetch_hw_state - Configure the framebuffer according to | 680 | * s1d13xxxfb_fetch_hw_state - Configure the framebuffer according to |
416 | * hardware setup. | 681 | * hardware setup. |
417 | * @info: frame buffer structure | 682 | * @info: frame buffer structure |
418 | * | 683 | * |
419 | * We setup the framebuffer structures according to the current | 684 | * We setup the framebuffer structures according to the current |
420 | * hardware setup. On some machines, the BIOS will have filled | 685 | * hardware setup. On some machines, the BIOS will have filled |
@@ -569,7 +834,6 @@ s1d13xxxfb_probe(struct platform_device *pdev) | |||
569 | if (pdata && pdata->platform_init_video) | 834 | if (pdata && pdata->platform_init_video) |
570 | pdata->platform_init_video(); | 835 | pdata->platform_init_video(); |
571 | 836 | ||
572 | |||
573 | if (pdev->num_resources != 2) { | 837 | if (pdev->num_resources != 2) { |
574 | dev_err(&pdev->dev, "invalid num_resources: %i\n", | 838 | dev_err(&pdev->dev, "invalid num_resources: %i\n", |
575 | pdev->num_resources); | 839 | pdev->num_resources); |
@@ -655,16 +919,27 @@ s1d13xxxfb_probe(struct platform_device *pdev) | |||
655 | 919 | ||
656 | info->fix = s1d13xxxfb_fix; | 920 | info->fix = s1d13xxxfb_fix; |
657 | info->fix.mmio_start = pdev->resource[1].start; | 921 | info->fix.mmio_start = pdev->resource[1].start; |
658 | info->fix.mmio_len = pdev->resource[1].end - pdev->resource[1].start +1; | 922 | info->fix.mmio_len = pdev->resource[1].end - pdev->resource[1].start + 1; |
659 | info->fix.smem_start = pdev->resource[0].start; | 923 | info->fix.smem_start = pdev->resource[0].start; |
660 | info->fix.smem_len = pdev->resource[0].end - pdev->resource[0].start +1; | 924 | info->fix.smem_len = pdev->resource[0].end - pdev->resource[0].start + 1; |
661 | 925 | ||
662 | printk(KERN_INFO PFX "regs mapped at 0x%p, fb %d KiB mapped at 0x%p\n", | 926 | printk(KERN_INFO PFX "regs mapped at 0x%p, fb %d KiB mapped at 0x%p\n", |
663 | default_par->regs, info->fix.smem_len / 1024, info->screen_base); | 927 | default_par->regs, info->fix.smem_len / 1024, info->screen_base); |
664 | 928 | ||
665 | info->par = default_par; | 929 | info->par = default_par; |
666 | info->fbops = &s1d13xxxfb_fbops; | ||
667 | info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; | 930 | info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; |
931 | info->fbops = &s1d13xxxfb_fbops; | ||
932 | |||
933 | switch(prod_id) { | ||
934 | case S1D13506_PROD_ID: /* activate acceleration */ | ||
935 | s1d13xxxfb_fbops.fb_fillrect = s1d13xxxfb_bitblt_solidfill; | ||
936 | s1d13xxxfb_fbops.fb_copyarea = s1d13xxxfb_bitblt_copyarea; | ||
937 | info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN | | ||
938 | FBINFO_HWACCEL_FILLRECT | FBINFO_HWACCEL_COPYAREA; | ||
939 | break; | ||
940 | default: | ||
941 | break; | ||
942 | } | ||
668 | 943 | ||
669 | /* perform "manual" chip initialization, if needed */ | 944 | /* perform "manual" chip initialization, if needed */ |
670 | if (pdata && pdata->initregs) | 945 | if (pdata && pdata->initregs) |
diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c index d3a568e6b169..43680e545427 100644 --- a/drivers/video/s3c-fb.c +++ b/drivers/video/s3c-fb.c | |||
@@ -358,9 +358,16 @@ static int s3c_fb_set_par(struct fb_info *info) | |||
358 | writel(data, regs + VIDOSD_B(win_no)); | 358 | writel(data, regs + VIDOSD_B(win_no)); |
359 | 359 | ||
360 | data = var->xres * var->yres; | 360 | data = var->xres * var->yres; |
361 | |||
362 | u32 osdc_data = 0; | ||
363 | |||
364 | osdc_data = VIDISD14C_ALPHA1_R(0xf) | | ||
365 | VIDISD14C_ALPHA1_G(0xf) | | ||
366 | VIDISD14C_ALPHA1_B(0xf); | ||
367 | |||
361 | if (s3c_fb_has_osd_d(win_no)) { | 368 | if (s3c_fb_has_osd_d(win_no)) { |
362 | writel(data, regs + VIDOSD_D(win_no)); | 369 | writel(data, regs + VIDOSD_D(win_no)); |
363 | writel(0, regs + VIDOSD_C(win_no)); | 370 | writel(osdc_data, regs + VIDOSD_C(win_no)); |
364 | } else | 371 | } else |
365 | writel(data, regs + VIDOSD_C(win_no)); | 372 | writel(data, regs + VIDOSD_C(win_no)); |
366 | 373 | ||
@@ -409,8 +416,12 @@ static int s3c_fb_set_par(struct fb_info *info) | |||
409 | data |= WINCON1_BPPMODE_19BPP_A1666; | 416 | data |= WINCON1_BPPMODE_19BPP_A1666; |
410 | else | 417 | else |
411 | data |= WINCON1_BPPMODE_18BPP_666; | 418 | data |= WINCON1_BPPMODE_18BPP_666; |
412 | } else if (var->transp.length != 0) | 419 | } else if (var->transp.length == 1) |
413 | data |= WINCON1_BPPMODE_25BPP_A1888; | 420 | data |= WINCON1_BPPMODE_25BPP_A1888 |
421 | | WINCON1_BLD_PIX; | ||
422 | else if (var->transp.length == 4) | ||
423 | data |= WINCON1_BPPMODE_28BPP_A4888 | ||
424 | | WINCON1_BLD_PIX | WINCON1_ALPHA_SEL; | ||
414 | else | 425 | else |
415 | data |= WINCON0_BPPMODE_24BPP_888; | 426 | data |= WINCON0_BPPMODE_24BPP_888; |
416 | 427 | ||
@@ -418,6 +429,20 @@ static int s3c_fb_set_par(struct fb_info *info) | |||
418 | break; | 429 | break; |
419 | } | 430 | } |
420 | 431 | ||
432 | /* It has no color key control register for window0 */ | ||
433 | if (win_no > 0) { | ||
434 | u32 keycon0_data = 0, keycon1_data = 0; | ||
435 | |||
436 | keycon0_data = ~(WxKEYCON0_KEYBL_EN | | ||
437 | WxKEYCON0_KEYEN_F | | ||
438 | WxKEYCON0_DIRCON) | WxKEYCON0_COMPKEY(0); | ||
439 | |||
440 | keycon1_data = WxKEYCON1_COLVAL(0xffffff); | ||
441 | |||
442 | writel(keycon0_data, regs + WxKEYCONy(win_no-1, 0)); | ||
443 | writel(keycon1_data, regs + WxKEYCONy(win_no-1, 1)); | ||
444 | } | ||
445 | |||
421 | writel(data, regs + WINCON(win_no)); | 446 | writel(data, regs + WINCON(win_no)); |
422 | writel(0x0, regs + WINxMAP(win_no)); | 447 | writel(0x0, regs + WINxMAP(win_no)); |
423 | 448 | ||
@@ -700,9 +725,12 @@ static void s3c_fb_free_memory(struct s3c_fb *sfb, struct s3c_fb_win *win) | |||
700 | */ | 725 | */ |
701 | static void s3c_fb_release_win(struct s3c_fb *sfb, struct s3c_fb_win *win) | 726 | static void s3c_fb_release_win(struct s3c_fb *sfb, struct s3c_fb_win *win) |
702 | { | 727 | { |
703 | fb_dealloc_cmap(&win->fbinfo->cmap); | 728 | if (win->fbinfo) { |
704 | unregister_framebuffer(win->fbinfo); | 729 | unregister_framebuffer(win->fbinfo); |
705 | s3c_fb_free_memory(sfb, win); | 730 | fb_dealloc_cmap(&win->fbinfo->cmap); |
731 | s3c_fb_free_memory(sfb, win); | ||
732 | framebuffer_release(win->fbinfo); | ||
733 | } | ||
706 | } | 734 | } |
707 | 735 | ||
708 | /** | 736 | /** |
@@ -753,7 +781,7 @@ static int __devinit s3c_fb_probe_win(struct s3c_fb *sfb, unsigned int win_no, | |||
753 | ret = s3c_fb_alloc_memory(sfb, win); | 781 | ret = s3c_fb_alloc_memory(sfb, win); |
754 | if (ret) { | 782 | if (ret) { |
755 | dev_err(sfb->dev, "failed to allocate display memory\n"); | 783 | dev_err(sfb->dev, "failed to allocate display memory\n"); |
756 | goto err_framebuffer; | 784 | return ret; |
757 | } | 785 | } |
758 | 786 | ||
759 | /* setup the r/b/g positions for the window's palette */ | 787 | /* setup the r/b/g positions for the window's palette */ |
@@ -776,7 +804,7 @@ static int __devinit s3c_fb_probe_win(struct s3c_fb *sfb, unsigned int win_no, | |||
776 | ret = s3c_fb_check_var(&fbinfo->var, fbinfo); | 804 | ret = s3c_fb_check_var(&fbinfo->var, fbinfo); |
777 | if (ret < 0) { | 805 | if (ret < 0) { |
778 | dev_err(sfb->dev, "check_var failed on initial video params\n"); | 806 | dev_err(sfb->dev, "check_var failed on initial video params\n"); |
779 | goto err_alloc_mem; | 807 | return ret; |
780 | } | 808 | } |
781 | 809 | ||
782 | /* create initial colour map */ | 810 | /* create initial colour map */ |
@@ -796,20 +824,13 @@ static int __devinit s3c_fb_probe_win(struct s3c_fb *sfb, unsigned int win_no, | |||
796 | ret = register_framebuffer(fbinfo); | 824 | ret = register_framebuffer(fbinfo); |
797 | if (ret < 0) { | 825 | if (ret < 0) { |
798 | dev_err(sfb->dev, "failed to register framebuffer\n"); | 826 | dev_err(sfb->dev, "failed to register framebuffer\n"); |
799 | goto err_alloc_mem; | 827 | return ret; |
800 | } | 828 | } |
801 | 829 | ||
802 | *res = win; | 830 | *res = win; |
803 | dev_info(sfb->dev, "window %d: fb %s\n", win_no, fbinfo->fix.id); | 831 | dev_info(sfb->dev, "window %d: fb %s\n", win_no, fbinfo->fix.id); |
804 | 832 | ||
805 | return 0; | 833 | return 0; |
806 | |||
807 | err_alloc_mem: | ||
808 | s3c_fb_free_memory(sfb, win); | ||
809 | |||
810 | err_framebuffer: | ||
811 | unregister_framebuffer(fbinfo); | ||
812 | return ret; | ||
813 | } | 834 | } |
814 | 835 | ||
815 | /** | 836 | /** |
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c index b0b4513ba537..7da0027e2409 100644 --- a/drivers/video/s3c2410fb.c +++ b/drivers/video/s3c2410fb.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
25 | #include <linux/platform_device.h> | 25 | #include <linux/platform_device.h> |
26 | #include <linux/clk.h> | 26 | #include <linux/clk.h> |
27 | #include <linux/cpufreq.h> | ||
27 | 28 | ||
28 | #include <asm/io.h> | 29 | #include <asm/io.h> |
29 | #include <asm/div64.h> | 30 | #include <asm/div64.h> |
@@ -89,7 +90,7 @@ static void s3c2410fb_set_lcdaddr(struct fb_info *info) | |||
89 | static unsigned int s3c2410fb_calc_pixclk(struct s3c2410fb_info *fbi, | 90 | static unsigned int s3c2410fb_calc_pixclk(struct s3c2410fb_info *fbi, |
90 | unsigned long pixclk) | 91 | unsigned long pixclk) |
91 | { | 92 | { |
92 | unsigned long clk = clk_get_rate(fbi->clk); | 93 | unsigned long clk = fbi->clk_rate; |
93 | unsigned long long div; | 94 | unsigned long long div; |
94 | 95 | ||
95 | /* pixclk is in picoseconds, our clock is in Hz | 96 | /* pixclk is in picoseconds, our clock is in Hz |
@@ -758,6 +759,57 @@ static irqreturn_t s3c2410fb_irq(int irq, void *dev_id) | |||
758 | return IRQ_HANDLED; | 759 | return IRQ_HANDLED; |
759 | } | 760 | } |
760 | 761 | ||
762 | #ifdef CONFIG_CPU_FREQ | ||
763 | |||
764 | static int s3c2410fb_cpufreq_transition(struct notifier_block *nb, | ||
765 | unsigned long val, void *data) | ||
766 | { | ||
767 | struct cpufreq_freqs *freqs = data; | ||
768 | struct s3c2410fb_info *info; | ||
769 | struct fb_info *fbinfo; | ||
770 | long delta_f; | ||
771 | |||
772 | info = container_of(nb, struct s3c2410fb_info, freq_transition); | ||
773 | fbinfo = platform_get_drvdata(to_platform_device(info->dev)); | ||
774 | |||
775 | /* work out change, <0 for speed-up */ | ||
776 | delta_f = info->clk_rate - clk_get_rate(info->clk); | ||
777 | |||
778 | if ((val == CPUFREQ_POSTCHANGE && delta_f > 0) || | ||
779 | (val == CPUFREQ_PRECHANGE && delta_f < 0)) { | ||
780 | info->clk_rate = clk_get_rate(info->clk); | ||
781 | s3c2410fb_activate_var(fbinfo); | ||
782 | } | ||
783 | |||
784 | return 0; | ||
785 | } | ||
786 | |||
787 | static inline int s3c2410fb_cpufreq_register(struct s3c2410fb_info *info) | ||
788 | { | ||
789 | info->freq_transition.notifier_call = s3c2410fb_cpufreq_transition; | ||
790 | |||
791 | return cpufreq_register_notifier(&info->freq_transition, | ||
792 | CPUFREQ_TRANSITION_NOTIFIER); | ||
793 | } | ||
794 | |||
795 | static inline void s3c2410fb_cpufreq_deregister(struct s3c2410fb_info *info) | ||
796 | { | ||
797 | cpufreq_unregister_notifier(&info->freq_transition, | ||
798 | CPUFREQ_TRANSITION_NOTIFIER); | ||
799 | } | ||
800 | |||
801 | #else | ||
802 | static inline int s3c2410fb_cpufreq_register(struct s3c2410fb_info *info) | ||
803 | { | ||
804 | return 0; | ||
805 | } | ||
806 | |||
807 | static inline void s3c2410fb_cpufreq_deregister(struct s3c2410fb_info *info) | ||
808 | { | ||
809 | } | ||
810 | #endif | ||
811 | |||
812 | |||
761 | static char driver_name[] = "s3c2410fb"; | 813 | static char driver_name[] = "s3c2410fb"; |
762 | 814 | ||
763 | static int __init s3c24xxfb_probe(struct platform_device *pdev, | 815 | static int __init s3c24xxfb_probe(struct platform_device *pdev, |
@@ -875,6 +927,8 @@ static int __init s3c24xxfb_probe(struct platform_device *pdev, | |||
875 | 927 | ||
876 | msleep(1); | 928 | msleep(1); |
877 | 929 | ||
930 | info->clk_rate = clk_get_rate(info->clk); | ||
931 | |||
878 | /* find maximum required memory size for display */ | 932 | /* find maximum required memory size for display */ |
879 | for (i = 0; i < mach_info->num_displays; i++) { | 933 | for (i = 0; i < mach_info->num_displays; i++) { |
880 | unsigned long smem_len = mach_info->displays[i].xres; | 934 | unsigned long smem_len = mach_info->displays[i].xres; |
@@ -904,11 +958,17 @@ static int __init s3c24xxfb_probe(struct platform_device *pdev, | |||
904 | 958 | ||
905 | s3c2410fb_check_var(&fbinfo->var, fbinfo); | 959 | s3c2410fb_check_var(&fbinfo->var, fbinfo); |
906 | 960 | ||
961 | ret = s3c2410fb_cpufreq_register(info); | ||
962 | if (ret < 0) { | ||
963 | dev_err(&pdev->dev, "Failed to register cpufreq\n"); | ||
964 | goto free_video_memory; | ||
965 | } | ||
966 | |||
907 | ret = register_framebuffer(fbinfo); | 967 | ret = register_framebuffer(fbinfo); |
908 | if (ret < 0) { | 968 | if (ret < 0) { |
909 | printk(KERN_ERR "Failed to register framebuffer device: %d\n", | 969 | printk(KERN_ERR "Failed to register framebuffer device: %d\n", |
910 | ret); | 970 | ret); |
911 | goto free_video_memory; | 971 | goto free_cpufreq; |
912 | } | 972 | } |
913 | 973 | ||
914 | /* create device files */ | 974 | /* create device files */ |
@@ -922,6 +982,8 @@ static int __init s3c24xxfb_probe(struct platform_device *pdev, | |||
922 | 982 | ||
923 | return 0; | 983 | return 0; |
924 | 984 | ||
985 | free_cpufreq: | ||
986 | s3c2410fb_cpufreq_deregister(info); | ||
925 | free_video_memory: | 987 | free_video_memory: |
926 | s3c2410fb_unmap_video_memory(fbinfo); | 988 | s3c2410fb_unmap_video_memory(fbinfo); |
927 | release_clock: | 989 | release_clock: |
@@ -961,6 +1023,7 @@ static int s3c2410fb_remove(struct platform_device *pdev) | |||
961 | int irq; | 1023 | int irq; |
962 | 1024 | ||
963 | unregister_framebuffer(fbinfo); | 1025 | unregister_framebuffer(fbinfo); |
1026 | s3c2410fb_cpufreq_deregister(info); | ||
964 | 1027 | ||
965 | s3c2410fb_lcd_enable(info, 0); | 1028 | s3c2410fb_lcd_enable(info, 0); |
966 | msleep(1); | 1029 | msleep(1); |
diff --git a/drivers/video/s3c2410fb.h b/drivers/video/s3c2410fb.h index 9a6ba3e9d1b8..47a17bd23011 100644 --- a/drivers/video/s3c2410fb.h +++ b/drivers/video/s3c2410fb.h | |||
@@ -29,8 +29,13 @@ struct s3c2410fb_info { | |||
29 | enum s3c_drv_type drv_type; | 29 | enum s3c_drv_type drv_type; |
30 | struct s3c2410fb_hw regs; | 30 | struct s3c2410fb_hw regs; |
31 | 31 | ||
32 | unsigned long clk_rate; | ||
32 | unsigned int palette_ready; | 33 | unsigned int palette_ready; |
33 | 34 | ||
35 | #ifdef CONFIG_CPU_FREQ | ||
36 | struct notifier_block freq_transition; | ||
37 | #endif | ||
38 | |||
34 | /* keep these registers in case we need to re-write palette */ | 39 | /* keep these registers in case we need to re-write palette */ |
35 | u32 palette_buffer[256]; | 40 | u32 palette_buffer[256]; |
36 | u32 pseudo_pal[16]; | 41 | u32 pseudo_pal[16]; |
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c index 7e17ee95a97a..7072d19080d5 100644 --- a/drivers/video/sis/sis_main.c +++ b/drivers/video/sis/sis_main.c | |||
@@ -5928,7 +5928,7 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
5928 | if(pci_enable_device(pdev)) { | 5928 | if(pci_enable_device(pdev)) { |
5929 | if(ivideo->nbridge) pci_dev_put(ivideo->nbridge); | 5929 | if(ivideo->nbridge) pci_dev_put(ivideo->nbridge); |
5930 | pci_set_drvdata(pdev, NULL); | 5930 | pci_set_drvdata(pdev, NULL); |
5931 | kfree(sis_fb_info); | 5931 | framebuffer_release(sis_fb_info); |
5932 | return -EIO; | 5932 | return -EIO; |
5933 | } | 5933 | } |
5934 | } | 5934 | } |
@@ -6134,7 +6134,7 @@ error_3: vfree(ivideo->bios_abase); | |||
6134 | pci_set_drvdata(pdev, NULL); | 6134 | pci_set_drvdata(pdev, NULL); |
6135 | if(!ivideo->sisvga_enabled) | 6135 | if(!ivideo->sisvga_enabled) |
6136 | pci_disable_device(pdev); | 6136 | pci_disable_device(pdev); |
6137 | kfree(sis_fb_info); | 6137 | framebuffer_release(sis_fb_info); |
6138 | return ret; | 6138 | return ret; |
6139 | } | 6139 | } |
6140 | 6140 | ||
diff --git a/drivers/video/stifb.c b/drivers/video/stifb.c index eabaad765aeb..eec9dcb7f599 100644 --- a/drivers/video/stifb.c +++ b/drivers/video/stifb.c | |||
@@ -1380,7 +1380,7 @@ stifb_cleanup(void) | |||
1380 | if (info->screen_base) | 1380 | if (info->screen_base) |
1381 | iounmap(info->screen_base); | 1381 | iounmap(info->screen_base); |
1382 | fb_dealloc_cmap(&info->cmap); | 1382 | fb_dealloc_cmap(&info->cmap); |
1383 | kfree(info); | 1383 | framebuffer_release(info); |
1384 | } | 1384 | } |
1385 | sti->info = NULL; | 1385 | sti->info = NULL; |
1386 | } | 1386 | } |
diff --git a/drivers/video/tcx.c b/drivers/video/tcx.c index 643afbfe8277..45b883598bf0 100644 --- a/drivers/video/tcx.c +++ b/drivers/video/tcx.c | |||
@@ -116,17 +116,16 @@ struct tcx_par { | |||
116 | u32 flags; | 116 | u32 flags; |
117 | #define TCX_FLAG_BLANKED 0x00000001 | 117 | #define TCX_FLAG_BLANKED 0x00000001 |
118 | 118 | ||
119 | unsigned long physbase; | ||
120 | unsigned long which_io; | 119 | unsigned long which_io; |
121 | unsigned long fbsize; | ||
122 | 120 | ||
123 | struct sbus_mmap_map mmap_map[TCX_MMAP_ENTRIES]; | 121 | struct sbus_mmap_map mmap_map[TCX_MMAP_ENTRIES]; |
124 | int lowdepth; | 122 | int lowdepth; |
125 | }; | 123 | }; |
126 | 124 | ||
127 | /* Reset control plane so that WID is 8-bit plane. */ | 125 | /* Reset control plane so that WID is 8-bit plane. */ |
128 | static void __tcx_set_control_plane(struct tcx_par *par) | 126 | static void __tcx_set_control_plane(struct fb_info *info) |
129 | { | 127 | { |
128 | struct tcx_par *par = info->par; | ||
130 | u32 __iomem *p, *pend; | 129 | u32 __iomem *p, *pend; |
131 | 130 | ||
132 | if (par->lowdepth) | 131 | if (par->lowdepth) |
@@ -135,7 +134,7 @@ static void __tcx_set_control_plane(struct tcx_par *par) | |||
135 | p = par->cplane; | 134 | p = par->cplane; |
136 | if (p == NULL) | 135 | if (p == NULL) |
137 | return; | 136 | return; |
138 | for (pend = p + par->fbsize; p < pend; p++) { | 137 | for (pend = p + info->fix.smem_len; p < pend; p++) { |
139 | u32 tmp = sbus_readl(p); | 138 | u32 tmp = sbus_readl(p); |
140 | 139 | ||
141 | tmp &= 0xffffff; | 140 | tmp &= 0xffffff; |
@@ -149,7 +148,7 @@ static void tcx_reset(struct fb_info *info) | |||
149 | unsigned long flags; | 148 | unsigned long flags; |
150 | 149 | ||
151 | spin_lock_irqsave(&par->lock, flags); | 150 | spin_lock_irqsave(&par->lock, flags); |
152 | __tcx_set_control_plane(par); | 151 | __tcx_set_control_plane(info); |
153 | spin_unlock_irqrestore(&par->lock, flags); | 152 | spin_unlock_irqrestore(&par->lock, flags); |
154 | } | 153 | } |
155 | 154 | ||
@@ -304,7 +303,7 @@ static int tcx_mmap(struct fb_info *info, struct vm_area_struct *vma) | |||
304 | struct tcx_par *par = (struct tcx_par *)info->par; | 303 | struct tcx_par *par = (struct tcx_par *)info->par; |
305 | 304 | ||
306 | return sbusfb_mmap_helper(par->mmap_map, | 305 | return sbusfb_mmap_helper(par->mmap_map, |
307 | par->physbase, par->fbsize, | 306 | info->fix.smem_start, info->fix.smem_len, |
308 | par->which_io, vma); | 307 | par->which_io, vma); |
309 | } | 308 | } |
310 | 309 | ||
@@ -316,7 +315,7 @@ static int tcx_ioctl(struct fb_info *info, unsigned int cmd, | |||
316 | return sbusfb_ioctl_helper(cmd, arg, info, | 315 | return sbusfb_ioctl_helper(cmd, arg, info, |
317 | FBTYPE_TCXCOLOR, | 316 | FBTYPE_TCXCOLOR, |
318 | (par->lowdepth ? 8 : 24), | 317 | (par->lowdepth ? 8 : 24), |
319 | par->fbsize); | 318 | info->fix.smem_len); |
320 | } | 319 | } |
321 | 320 | ||
322 | /* | 321 | /* |
@@ -358,10 +357,10 @@ static void tcx_unmap_regs(struct of_device *op, struct fb_info *info, | |||
358 | par->bt, sizeof(struct bt_regs)); | 357 | par->bt, sizeof(struct bt_regs)); |
359 | if (par->cplane) | 358 | if (par->cplane) |
360 | of_iounmap(&op->resource[4], | 359 | of_iounmap(&op->resource[4], |
361 | par->cplane, par->fbsize * sizeof(u32)); | 360 | par->cplane, info->fix.smem_len * sizeof(u32)); |
362 | if (info->screen_base) | 361 | if (info->screen_base) |
363 | of_iounmap(&op->resource[0], | 362 | of_iounmap(&op->resource[0], |
364 | info->screen_base, par->fbsize); | 363 | info->screen_base, info->fix.smem_len); |
365 | } | 364 | } |
366 | 365 | ||
367 | static int __devinit tcx_probe(struct of_device *op, | 366 | static int __devinit tcx_probe(struct of_device *op, |
@@ -391,7 +390,7 @@ static int __devinit tcx_probe(struct of_device *op, | |||
391 | 390 | ||
392 | linebytes = of_getintprop_default(dp, "linebytes", | 391 | linebytes = of_getintprop_default(dp, "linebytes", |
393 | info->var.xres); | 392 | info->var.xres); |
394 | par->fbsize = PAGE_ALIGN(linebytes * info->var.yres); | 393 | info->fix.smem_len = PAGE_ALIGN(linebytes * info->var.yres); |
395 | 394 | ||
396 | par->tec = of_ioremap(&op->resource[7], 0, | 395 | par->tec = of_ioremap(&op->resource[7], 0, |
397 | sizeof(struct tcx_tec), "tcx tec"); | 396 | sizeof(struct tcx_tec), "tcx tec"); |
@@ -400,7 +399,7 @@ static int __devinit tcx_probe(struct of_device *op, | |||
400 | par->bt = of_ioremap(&op->resource[8], 0, | 399 | par->bt = of_ioremap(&op->resource[8], 0, |
401 | sizeof(struct bt_regs), "tcx dac"); | 400 | sizeof(struct bt_regs), "tcx dac"); |
402 | info->screen_base = of_ioremap(&op->resource[0], 0, | 401 | info->screen_base = of_ioremap(&op->resource[0], 0, |
403 | par->fbsize, "tcx ram"); | 402 | info->fix.smem_len, "tcx ram"); |
404 | if (!par->tec || !par->thc || | 403 | if (!par->tec || !par->thc || |
405 | !par->bt || !info->screen_base) | 404 | !par->bt || !info->screen_base) |
406 | goto out_unmap_regs; | 405 | goto out_unmap_regs; |
@@ -408,7 +407,7 @@ static int __devinit tcx_probe(struct of_device *op, | |||
408 | memcpy(&par->mmap_map, &__tcx_mmap_map, sizeof(par->mmap_map)); | 407 | memcpy(&par->mmap_map, &__tcx_mmap_map, sizeof(par->mmap_map)); |
409 | if (!par->lowdepth) { | 408 | if (!par->lowdepth) { |
410 | par->cplane = of_ioremap(&op->resource[4], 0, | 409 | par->cplane = of_ioremap(&op->resource[4], 0, |
411 | par->fbsize * sizeof(u32), | 410 | info->fix.smem_len * sizeof(u32), |
412 | "tcx cplane"); | 411 | "tcx cplane"); |
413 | if (!par->cplane) | 412 | if (!par->cplane) |
414 | goto out_unmap_regs; | 413 | goto out_unmap_regs; |
@@ -419,7 +418,7 @@ static int __devinit tcx_probe(struct of_device *op, | |||
419 | par->mmap_map[6].size = SBUS_MMAP_EMPTY; | 418 | par->mmap_map[6].size = SBUS_MMAP_EMPTY; |
420 | } | 419 | } |
421 | 420 | ||
422 | par->physbase = op->resource[0].start; | 421 | info->fix.smem_start = op->resource[0].start; |
423 | par->which_io = op->resource[0].flags & IORESOURCE_BITS; | 422 | par->which_io = op->resource[0].flags & IORESOURCE_BITS; |
424 | 423 | ||
425 | for (i = 0; i < TCX_MMAP_ENTRIES; i++) { | 424 | for (i = 0; i < TCX_MMAP_ENTRIES; i++) { |
@@ -473,7 +472,7 @@ static int __devinit tcx_probe(struct of_device *op, | |||
473 | printk(KERN_INFO "%s: TCX at %lx:%lx, %s\n", | 472 | printk(KERN_INFO "%s: TCX at %lx:%lx, %s\n", |
474 | dp->full_name, | 473 | dp->full_name, |
475 | par->which_io, | 474 | par->which_io, |
476 | par->physbase, | 475 | info->fix.smem_start, |
477 | par->lowdepth ? "8-bit only" : "24-bit depth"); | 476 | par->lowdepth ? "8-bit only" : "24-bit depth"); |
478 | 477 | ||
479 | return 0; | 478 | return 0; |
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c index d6856f43d241..bd37ee1f6a25 100644 --- a/drivers/video/vesafb.c +++ b/drivers/video/vesafb.c | |||
@@ -174,8 +174,17 @@ static int vesafb_setcolreg(unsigned regno, unsigned red, unsigned green, | |||
174 | return err; | 174 | return err; |
175 | } | 175 | } |
176 | 176 | ||
177 | static void vesafb_destroy(struct fb_info *info) | ||
178 | { | ||
179 | if (info->screen_base) | ||
180 | iounmap(info->screen_base); | ||
181 | release_mem_region(info->aperture_base, info->aperture_size); | ||
182 | framebuffer_release(info); | ||
183 | } | ||
184 | |||
177 | static struct fb_ops vesafb_ops = { | 185 | static struct fb_ops vesafb_ops = { |
178 | .owner = THIS_MODULE, | 186 | .owner = THIS_MODULE, |
187 | .fb_destroy = vesafb_destroy, | ||
179 | .fb_setcolreg = vesafb_setcolreg, | 188 | .fb_setcolreg = vesafb_setcolreg, |
180 | .fb_pan_display = vesafb_pan_display, | 189 | .fb_pan_display = vesafb_pan_display, |
181 | .fb_fillrect = cfb_fillrect, | 190 | .fb_fillrect = cfb_fillrect, |
@@ -286,6 +295,10 @@ static int __init vesafb_probe(struct platform_device *dev) | |||
286 | info->pseudo_palette = info->par; | 295 | info->pseudo_palette = info->par; |
287 | info->par = NULL; | 296 | info->par = NULL; |
288 | 297 | ||
298 | /* set vesafb aperture size for generic probing */ | ||
299 | info->aperture_base = screen_info.lfb_base; | ||
300 | info->aperture_size = size_total; | ||
301 | |||
289 | info->screen_base = ioremap(vesafb_fix.smem_start, vesafb_fix.smem_len); | 302 | info->screen_base = ioremap(vesafb_fix.smem_start, vesafb_fix.smem_len); |
290 | if (!info->screen_base) { | 303 | if (!info->screen_base) { |
291 | printk(KERN_ERR | 304 | printk(KERN_ERR |
@@ -437,7 +450,7 @@ static int __init vesafb_probe(struct platform_device *dev) | |||
437 | info->fbops = &vesafb_ops; | 450 | info->fbops = &vesafb_ops; |
438 | info->var = vesafb_defined; | 451 | info->var = vesafb_defined; |
439 | info->fix = vesafb_fix; | 452 | info->fix = vesafb_fix; |
440 | info->flags = FBINFO_FLAG_DEFAULT | | 453 | info->flags = FBINFO_FLAG_DEFAULT | FBINFO_MISC_FIRMWARE | |
441 | (ypan ? FBINFO_HWACCEL_YPAN : 0); | 454 | (ypan ? FBINFO_HWACCEL_YPAN : 0); |
442 | 455 | ||
443 | if (!ypan) | 456 | if (!ypan) |
diff --git a/drivers/vlynq/Kconfig b/drivers/vlynq/Kconfig new file mode 100644 index 000000000000..f6542211db48 --- /dev/null +++ b/drivers/vlynq/Kconfig | |||
@@ -0,0 +1,20 @@ | |||
1 | menu "TI VLYNQ" | ||
2 | |||
3 | config VLYNQ | ||
4 | bool "TI VLYNQ bus support" | ||
5 | depends on AR7 && EXPERIMENTAL | ||
6 | help | ||
7 | Support for Texas Instruments(R) VLYNQ bus. | ||
8 | The VLYNQ bus is a high-speed, serial and packetized | ||
9 | data bus which allows external peripherals of a SoC | ||
10 | to appear into the system's main memory. | ||
11 | |||
12 | If unsure, say N | ||
13 | |||
14 | config VLYNQ_DEBUG | ||
15 | bool "VLYNQ bus debug" | ||
16 | depends on VLYNQ && KERNEL_DEBUG | ||
17 | help | ||
18 | Turn on VLYNQ bus debugging. | ||
19 | |||
20 | endmenu | ||
diff --git a/drivers/vlynq/Makefile b/drivers/vlynq/Makefile new file mode 100644 index 000000000000..b3f61149b599 --- /dev/null +++ b/drivers/vlynq/Makefile | |||
@@ -0,0 +1,5 @@ | |||
1 | # | ||
2 | # Makefile for kernel vlynq drivers | ||
3 | # | ||
4 | |||
5 | obj-$(CONFIG_VLYNQ) += vlynq.o | ||
diff --git a/drivers/vlynq/vlynq.c b/drivers/vlynq/vlynq.c new file mode 100644 index 000000000000..7335433b067b --- /dev/null +++ b/drivers/vlynq/vlynq.c | |||
@@ -0,0 +1,814 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006, 2007 Eugene Konev <ejka@openwrt.org> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
17 | * | ||
18 | * Parts of the VLYNQ specification can be found here: | ||
19 | * http://www.ti.com/litv/pdf/sprue36a | ||
20 | */ | ||
21 | |||
22 | #include <linux/init.h> | ||
23 | #include <linux/types.h> | ||
24 | #include <linux/kernel.h> | ||
25 | #include <linux/string.h> | ||
26 | #include <linux/device.h> | ||
27 | #include <linux/module.h> | ||
28 | #include <linux/errno.h> | ||
29 | #include <linux/platform_device.h> | ||
30 | #include <linux/interrupt.h> | ||
31 | #include <linux/device.h> | ||
32 | #include <linux/delay.h> | ||
33 | #include <linux/io.h> | ||
34 | |||
35 | #include <linux/vlynq.h> | ||
36 | |||
37 | #define VLYNQ_CTRL_PM_ENABLE 0x80000000 | ||
38 | #define VLYNQ_CTRL_CLOCK_INT 0x00008000 | ||
39 | #define VLYNQ_CTRL_CLOCK_DIV(x) (((x) & 7) << 16) | ||
40 | #define VLYNQ_CTRL_INT_LOCAL 0x00004000 | ||
41 | #define VLYNQ_CTRL_INT_ENABLE 0x00002000 | ||
42 | #define VLYNQ_CTRL_INT_VECTOR(x) (((x) & 0x1f) << 8) | ||
43 | #define VLYNQ_CTRL_INT2CFG 0x00000080 | ||
44 | #define VLYNQ_CTRL_RESET 0x00000001 | ||
45 | |||
46 | #define VLYNQ_CTRL_CLOCK_MASK (0x7 << 16) | ||
47 | |||
48 | #define VLYNQ_INT_OFFSET 0x00000014 | ||
49 | #define VLYNQ_REMOTE_OFFSET 0x00000080 | ||
50 | |||
51 | #define VLYNQ_STATUS_LINK 0x00000001 | ||
52 | #define VLYNQ_STATUS_LERROR 0x00000080 | ||
53 | #define VLYNQ_STATUS_RERROR 0x00000100 | ||
54 | |||
55 | #define VINT_ENABLE 0x00000100 | ||
56 | #define VINT_TYPE_EDGE 0x00000080 | ||
57 | #define VINT_LEVEL_LOW 0x00000040 | ||
58 | #define VINT_VECTOR(x) ((x) & 0x1f) | ||
59 | #define VINT_OFFSET(irq) (8 * ((irq) % 4)) | ||
60 | |||
61 | #define VLYNQ_AUTONEGO_V2 0x00010000 | ||
62 | |||
63 | struct vlynq_regs { | ||
64 | u32 revision; | ||
65 | u32 control; | ||
66 | u32 status; | ||
67 | u32 int_prio; | ||
68 | u32 int_status; | ||
69 | u32 int_pending; | ||
70 | u32 int_ptr; | ||
71 | u32 tx_offset; | ||
72 | struct vlynq_mapping rx_mapping[4]; | ||
73 | u32 chip; | ||
74 | u32 autonego; | ||
75 | u32 unused[6]; | ||
76 | u32 int_device[8]; | ||
77 | }; | ||
78 | |||
79 | #ifdef VLYNQ_DEBUG | ||
80 | static void vlynq_dump_regs(struct vlynq_device *dev) | ||
81 | { | ||
82 | int i; | ||
83 | |||
84 | printk(KERN_DEBUG "VLYNQ local=%p remote=%p\n", | ||
85 | dev->local, dev->remote); | ||
86 | for (i = 0; i < 32; i++) { | ||
87 | printk(KERN_DEBUG "VLYNQ: local %d: %08x\n", | ||
88 | i + 1, ((u32 *)dev->local)[i]); | ||
89 | printk(KERN_DEBUG "VLYNQ: remote %d: %08x\n", | ||
90 | i + 1, ((u32 *)dev->remote)[i]); | ||
91 | } | ||
92 | } | ||
93 | |||
94 | static void vlynq_dump_mem(u32 *base, int count) | ||
95 | { | ||
96 | int i; | ||
97 | |||
98 | for (i = 0; i < (count + 3) / 4; i++) { | ||
99 | if (i % 4 == 0) | ||
100 | printk(KERN_DEBUG "\nMEM[0x%04x]:", i * 4); | ||
101 | printk(KERN_DEBUG " 0x%08x", *(base + i)); | ||
102 | } | ||
103 | printk(KERN_DEBUG "\n"); | ||
104 | } | ||
105 | #endif | ||
106 | |||
107 | /* Check the VLYNQ link status with a given device */ | ||
108 | static int vlynq_linked(struct vlynq_device *dev) | ||
109 | { | ||
110 | int i; | ||
111 | |||
112 | for (i = 0; i < 100; i++) | ||
113 | if (readl(&dev->local->status) & VLYNQ_STATUS_LINK) | ||
114 | return 1; | ||
115 | else | ||
116 | cpu_relax(); | ||
117 | |||
118 | return 0; | ||
119 | } | ||
120 | |||
121 | static void vlynq_reset(struct vlynq_device *dev) | ||
122 | { | ||
123 | writel(readl(&dev->local->control) | VLYNQ_CTRL_RESET, | ||
124 | &dev->local->control); | ||
125 | |||
126 | /* Wait for the devices to finish resetting */ | ||
127 | msleep(5); | ||
128 | |||
129 | /* Remove reset bit */ | ||
130 | writel(readl(&dev->local->control) & ~VLYNQ_CTRL_RESET, | ||
131 | &dev->local->control); | ||
132 | |||
133 | /* Give some time for the devices to settle */ | ||
134 | msleep(5); | ||
135 | } | ||
136 | |||
137 | static void vlynq_irq_unmask(unsigned int irq) | ||
138 | { | ||
139 | u32 val; | ||
140 | struct vlynq_device *dev = get_irq_chip_data(irq); | ||
141 | int virq; | ||
142 | |||
143 | BUG_ON(!dev); | ||
144 | virq = irq - dev->irq_start; | ||
145 | val = readl(&dev->remote->int_device[virq >> 2]); | ||
146 | val |= (VINT_ENABLE | virq) << VINT_OFFSET(virq); | ||
147 | writel(val, &dev->remote->int_device[virq >> 2]); | ||
148 | } | ||
149 | |||
150 | static void vlynq_irq_mask(unsigned int irq) | ||
151 | { | ||
152 | u32 val; | ||
153 | struct vlynq_device *dev = get_irq_chip_data(irq); | ||
154 | int virq; | ||
155 | |||
156 | BUG_ON(!dev); | ||
157 | virq = irq - dev->irq_start; | ||
158 | val = readl(&dev->remote->int_device[virq >> 2]); | ||
159 | val &= ~(VINT_ENABLE << VINT_OFFSET(virq)); | ||
160 | writel(val, &dev->remote->int_device[virq >> 2]); | ||
161 | } | ||
162 | |||
163 | static int vlynq_irq_type(unsigned int irq, unsigned int flow_type) | ||
164 | { | ||
165 | u32 val; | ||
166 | struct vlynq_device *dev = get_irq_chip_data(irq); | ||
167 | int virq; | ||
168 | |||
169 | BUG_ON(!dev); | ||
170 | virq = irq - dev->irq_start; | ||
171 | val = readl(&dev->remote->int_device[virq >> 2]); | ||
172 | switch (flow_type & IRQ_TYPE_SENSE_MASK) { | ||
173 | case IRQ_TYPE_EDGE_RISING: | ||
174 | case IRQ_TYPE_EDGE_FALLING: | ||
175 | case IRQ_TYPE_EDGE_BOTH: | ||
176 | val |= VINT_TYPE_EDGE << VINT_OFFSET(virq); | ||
177 | val &= ~(VINT_LEVEL_LOW << VINT_OFFSET(virq)); | ||
178 | break; | ||
179 | case IRQ_TYPE_LEVEL_HIGH: | ||
180 | val &= ~(VINT_TYPE_EDGE << VINT_OFFSET(virq)); | ||
181 | val &= ~(VINT_LEVEL_LOW << VINT_OFFSET(virq)); | ||
182 | break; | ||
183 | case IRQ_TYPE_LEVEL_LOW: | ||
184 | val &= ~(VINT_TYPE_EDGE << VINT_OFFSET(virq)); | ||
185 | val |= VINT_LEVEL_LOW << VINT_OFFSET(virq); | ||
186 | break; | ||
187 | default: | ||
188 | return -EINVAL; | ||
189 | } | ||
190 | writel(val, &dev->remote->int_device[virq >> 2]); | ||
191 | return 0; | ||
192 | } | ||
193 | |||
194 | static void vlynq_local_ack(unsigned int irq) | ||
195 | { | ||
196 | struct vlynq_device *dev = get_irq_chip_data(irq); | ||
197 | |||
198 | u32 status = readl(&dev->local->status); | ||
199 | |||
200 | pr_debug("%s: local status: 0x%08x\n", | ||
201 | dev_name(&dev->dev), status); | ||
202 | writel(status, &dev->local->status); | ||
203 | } | ||
204 | |||
205 | static void vlynq_remote_ack(unsigned int irq) | ||
206 | { | ||
207 | struct vlynq_device *dev = get_irq_chip_data(irq); | ||
208 | |||
209 | u32 status = readl(&dev->remote->status); | ||
210 | |||
211 | pr_debug("%s: remote status: 0x%08x\n", | ||
212 | dev_name(&dev->dev), status); | ||
213 | writel(status, &dev->remote->status); | ||
214 | } | ||
215 | |||
216 | static irqreturn_t vlynq_irq(int irq, void *dev_id) | ||
217 | { | ||
218 | struct vlynq_device *dev = dev_id; | ||
219 | u32 status; | ||
220 | int virq = 0; | ||
221 | |||
222 | status = readl(&dev->local->int_status); | ||
223 | writel(status, &dev->local->int_status); | ||
224 | |||
225 | if (unlikely(!status)) | ||
226 | spurious_interrupt(); | ||
227 | |||
228 | while (status) { | ||
229 | if (status & 1) | ||
230 | do_IRQ(dev->irq_start + virq); | ||
231 | status >>= 1; | ||
232 | virq++; | ||
233 | } | ||
234 | |||
235 | return IRQ_HANDLED; | ||
236 | } | ||
237 | |||
238 | static struct irq_chip vlynq_irq_chip = { | ||
239 | .name = "vlynq", | ||
240 | .unmask = vlynq_irq_unmask, | ||
241 | .mask = vlynq_irq_mask, | ||
242 | .set_type = vlynq_irq_type, | ||
243 | }; | ||
244 | |||
245 | static struct irq_chip vlynq_local_chip = { | ||
246 | .name = "vlynq local error", | ||
247 | .unmask = vlynq_irq_unmask, | ||
248 | .mask = vlynq_irq_mask, | ||
249 | .ack = vlynq_local_ack, | ||
250 | }; | ||
251 | |||
252 | static struct irq_chip vlynq_remote_chip = { | ||
253 | .name = "vlynq local error", | ||
254 | .unmask = vlynq_irq_unmask, | ||
255 | .mask = vlynq_irq_mask, | ||
256 | .ack = vlynq_remote_ack, | ||
257 | }; | ||
258 | |||
259 | static int vlynq_setup_irq(struct vlynq_device *dev) | ||
260 | { | ||
261 | u32 val; | ||
262 | int i, virq; | ||
263 | |||
264 | if (dev->local_irq == dev->remote_irq) { | ||
265 | printk(KERN_ERR | ||
266 | "%s: local vlynq irq should be different from remote\n", | ||
267 | dev_name(&dev->dev)); | ||
268 | return -EINVAL; | ||
269 | } | ||
270 | |||
271 | /* Clear local and remote error bits */ | ||
272 | writel(readl(&dev->local->status), &dev->local->status); | ||
273 | writel(readl(&dev->remote->status), &dev->remote->status); | ||
274 | |||
275 | /* Now setup interrupts */ | ||
276 | val = VLYNQ_CTRL_INT_VECTOR(dev->local_irq); | ||
277 | val |= VLYNQ_CTRL_INT_ENABLE | VLYNQ_CTRL_INT_LOCAL | | ||
278 | VLYNQ_CTRL_INT2CFG; | ||
279 | val |= readl(&dev->local->control); | ||
280 | writel(VLYNQ_INT_OFFSET, &dev->local->int_ptr); | ||
281 | writel(val, &dev->local->control); | ||
282 | |||
283 | val = VLYNQ_CTRL_INT_VECTOR(dev->remote_irq); | ||
284 | val |= VLYNQ_CTRL_INT_ENABLE; | ||
285 | val |= readl(&dev->remote->control); | ||
286 | writel(VLYNQ_INT_OFFSET, &dev->remote->int_ptr); | ||
287 | writel(val, &dev->remote->int_ptr); | ||
288 | writel(val, &dev->remote->control); | ||
289 | |||
290 | for (i = dev->irq_start; i <= dev->irq_end; i++) { | ||
291 | virq = i - dev->irq_start; | ||
292 | if (virq == dev->local_irq) { | ||
293 | set_irq_chip_and_handler(i, &vlynq_local_chip, | ||
294 | handle_level_irq); | ||
295 | set_irq_chip_data(i, dev); | ||
296 | } else if (virq == dev->remote_irq) { | ||
297 | set_irq_chip_and_handler(i, &vlynq_remote_chip, | ||
298 | handle_level_irq); | ||
299 | set_irq_chip_data(i, dev); | ||
300 | } else { | ||
301 | set_irq_chip_and_handler(i, &vlynq_irq_chip, | ||
302 | handle_simple_irq); | ||
303 | set_irq_chip_data(i, dev); | ||
304 | writel(0, &dev->remote->int_device[virq >> 2]); | ||
305 | } | ||
306 | } | ||
307 | |||
308 | if (request_irq(dev->irq, vlynq_irq, IRQF_SHARED, "vlynq", dev)) { | ||
309 | printk(KERN_ERR "%s: request_irq failed\n", | ||
310 | dev_name(&dev->dev)); | ||
311 | return -EAGAIN; | ||
312 | } | ||
313 | |||
314 | return 0; | ||
315 | } | ||
316 | |||
317 | static void vlynq_device_release(struct device *dev) | ||
318 | { | ||
319 | struct vlynq_device *vdev = to_vlynq_device(dev); | ||
320 | kfree(vdev); | ||
321 | } | ||
322 | |||
323 | static int vlynq_device_match(struct device *dev, | ||
324 | struct device_driver *drv) | ||
325 | { | ||
326 | struct vlynq_device *vdev = to_vlynq_device(dev); | ||
327 | struct vlynq_driver *vdrv = to_vlynq_driver(drv); | ||
328 | struct vlynq_device_id *ids = vdrv->id_table; | ||
329 | |||
330 | while (ids->id) { | ||
331 | if (ids->id == vdev->dev_id) { | ||
332 | vdev->divisor = ids->divisor; | ||
333 | vlynq_set_drvdata(vdev, ids); | ||
334 | printk(KERN_INFO "Driver found for VLYNQ " | ||
335 | "device: %08x\n", vdev->dev_id); | ||
336 | return 1; | ||
337 | } | ||
338 | printk(KERN_DEBUG "Not using the %08x VLYNQ device's driver" | ||
339 | " for VLYNQ device: %08x\n", ids->id, vdev->dev_id); | ||
340 | ids++; | ||
341 | } | ||
342 | return 0; | ||
343 | } | ||
344 | |||
345 | static int vlynq_device_probe(struct device *dev) | ||
346 | { | ||
347 | struct vlynq_device *vdev = to_vlynq_device(dev); | ||
348 | struct vlynq_driver *drv = to_vlynq_driver(dev->driver); | ||
349 | struct vlynq_device_id *id = vlynq_get_drvdata(vdev); | ||
350 | int result = -ENODEV; | ||
351 | |||
352 | if (drv->probe) | ||
353 | result = drv->probe(vdev, id); | ||
354 | if (result) | ||
355 | put_device(dev); | ||
356 | return result; | ||
357 | } | ||
358 | |||
359 | static int vlynq_device_remove(struct device *dev) | ||
360 | { | ||
361 | struct vlynq_driver *drv = to_vlynq_driver(dev->driver); | ||
362 | |||
363 | if (drv->remove) | ||
364 | drv->remove(to_vlynq_device(dev)); | ||
365 | |||
366 | return 0; | ||
367 | } | ||
368 | |||
369 | int __vlynq_register_driver(struct vlynq_driver *driver, struct module *owner) | ||
370 | { | ||
371 | driver->driver.name = driver->name; | ||
372 | driver->driver.bus = &vlynq_bus_type; | ||
373 | return driver_register(&driver->driver); | ||
374 | } | ||
375 | EXPORT_SYMBOL(__vlynq_register_driver); | ||
376 | |||
377 | void vlynq_unregister_driver(struct vlynq_driver *driver) | ||
378 | { | ||
379 | driver_unregister(&driver->driver); | ||
380 | } | ||
381 | EXPORT_SYMBOL(vlynq_unregister_driver); | ||
382 | |||
383 | /* | ||
384 | * A VLYNQ remote device can clock the VLYNQ bus master | ||
385 | * using a dedicated clock line. In that case, both the | ||
386 | * remove device and the bus master should have the same | ||
387 | * serial clock dividers configured. Iterate through the | ||
388 | * 8 possible dividers until we actually link with the | ||
389 | * device. | ||
390 | */ | ||
391 | static int __vlynq_try_remote(struct vlynq_device *dev) | ||
392 | { | ||
393 | int i; | ||
394 | |||
395 | vlynq_reset(dev); | ||
396 | for (i = dev->dev_id ? vlynq_rdiv2 : vlynq_rdiv8; dev->dev_id ? | ||
397 | i <= vlynq_rdiv8 : i >= vlynq_rdiv2; | ||
398 | dev->dev_id ? i++ : i--) { | ||
399 | |||
400 | if (!vlynq_linked(dev)) | ||
401 | break; | ||
402 | |||
403 | writel((readl(&dev->remote->control) & | ||
404 | ~VLYNQ_CTRL_CLOCK_MASK) | | ||
405 | VLYNQ_CTRL_CLOCK_INT | | ||
406 | VLYNQ_CTRL_CLOCK_DIV(i - vlynq_rdiv1), | ||
407 | &dev->remote->control); | ||
408 | writel((readl(&dev->local->control) | ||
409 | & ~(VLYNQ_CTRL_CLOCK_INT | | ||
410 | VLYNQ_CTRL_CLOCK_MASK)) | | ||
411 | VLYNQ_CTRL_CLOCK_DIV(i - vlynq_rdiv1), | ||
412 | &dev->local->control); | ||
413 | |||
414 | if (vlynq_linked(dev)) { | ||
415 | printk(KERN_DEBUG | ||
416 | "%s: using remote clock divisor %d\n", | ||
417 | dev_name(&dev->dev), i - vlynq_rdiv1 + 1); | ||
418 | dev->divisor = i; | ||
419 | return 0; | ||
420 | } else { | ||
421 | vlynq_reset(dev); | ||
422 | } | ||
423 | } | ||
424 | |||
425 | return -ENODEV; | ||
426 | } | ||
427 | |||
428 | /* | ||
429 | * A VLYNQ remote device can be clocked by the VLYNQ bus | ||
430 | * master using a dedicated clock line. In that case, only | ||
431 | * the bus master configures the serial clock divider. | ||
432 | * Iterate through the 8 possible dividers until we | ||
433 | * actually get a link with the device. | ||
434 | */ | ||
435 | static int __vlynq_try_local(struct vlynq_device *dev) | ||
436 | { | ||
437 | int i; | ||
438 | |||
439 | vlynq_reset(dev); | ||
440 | |||
441 | for (i = dev->dev_id ? vlynq_ldiv2 : vlynq_ldiv8; dev->dev_id ? | ||
442 | i <= vlynq_ldiv8 : i >= vlynq_ldiv2; | ||
443 | dev->dev_id ? i++ : i--) { | ||
444 | |||
445 | writel((readl(&dev->local->control) & | ||
446 | ~VLYNQ_CTRL_CLOCK_MASK) | | ||
447 | VLYNQ_CTRL_CLOCK_INT | | ||
448 | VLYNQ_CTRL_CLOCK_DIV(i - vlynq_ldiv1), | ||
449 | &dev->local->control); | ||
450 | |||
451 | if (vlynq_linked(dev)) { | ||
452 | printk(KERN_DEBUG | ||
453 | "%s: using local clock divisor %d\n", | ||
454 | dev_name(&dev->dev), i - vlynq_ldiv1 + 1); | ||
455 | dev->divisor = i; | ||
456 | return 0; | ||
457 | } else { | ||
458 | vlynq_reset(dev); | ||
459 | } | ||
460 | } | ||
461 | |||
462 | return -ENODEV; | ||
463 | } | ||
464 | |||
465 | /* | ||
466 | * When using external clocking method, serial clock | ||
467 | * is supplied by an external oscillator, therefore we | ||
468 | * should mask the local clock bit in the clock control | ||
469 | * register for both the bus master and the remote device. | ||
470 | */ | ||
471 | static int __vlynq_try_external(struct vlynq_device *dev) | ||
472 | { | ||
473 | vlynq_reset(dev); | ||
474 | if (!vlynq_linked(dev)) | ||
475 | return -ENODEV; | ||
476 | |||
477 | writel((readl(&dev->remote->control) & | ||
478 | ~VLYNQ_CTRL_CLOCK_INT), | ||
479 | &dev->remote->control); | ||
480 | |||
481 | writel((readl(&dev->local->control) & | ||
482 | ~VLYNQ_CTRL_CLOCK_INT), | ||
483 | &dev->local->control); | ||
484 | |||
485 | if (vlynq_linked(dev)) { | ||
486 | printk(KERN_DEBUG "%s: using external clock\n", | ||
487 | dev_name(&dev->dev)); | ||
488 | dev->divisor = vlynq_div_external; | ||
489 | return 0; | ||
490 | } | ||
491 | |||
492 | return -ENODEV; | ||
493 | } | ||
494 | |||
495 | static int __vlynq_enable_device(struct vlynq_device *dev) | ||
496 | { | ||
497 | int result; | ||
498 | struct plat_vlynq_ops *ops = dev->dev.platform_data; | ||
499 | |||
500 | result = ops->on(dev); | ||
501 | if (result) | ||
502 | return result; | ||
503 | |||
504 | switch (dev->divisor) { | ||
505 | case vlynq_div_external: | ||
506 | case vlynq_div_auto: | ||
507 | /* When the device is brought from reset it should have clock | ||
508 | * generation negotiated by hardware. | ||
509 | * Check which device is generating clocks and perform setup | ||
510 | * accordingly */ | ||
511 | if (vlynq_linked(dev) && readl(&dev->remote->control) & | ||
512 | VLYNQ_CTRL_CLOCK_INT) { | ||
513 | if (!__vlynq_try_remote(dev) || | ||
514 | !__vlynq_try_local(dev) || | ||
515 | !__vlynq_try_external(dev)) | ||
516 | return 0; | ||
517 | } else { | ||
518 | if (!__vlynq_try_external(dev) || | ||
519 | !__vlynq_try_local(dev) || | ||
520 | !__vlynq_try_remote(dev)) | ||
521 | return 0; | ||
522 | } | ||
523 | break; | ||
524 | case vlynq_ldiv1: | ||
525 | case vlynq_ldiv2: | ||
526 | case vlynq_ldiv3: | ||
527 | case vlynq_ldiv4: | ||
528 | case vlynq_ldiv5: | ||
529 | case vlynq_ldiv6: | ||
530 | case vlynq_ldiv7: | ||
531 | case vlynq_ldiv8: | ||
532 | writel(VLYNQ_CTRL_CLOCK_INT | | ||
533 | VLYNQ_CTRL_CLOCK_DIV(dev->divisor - | ||
534 | vlynq_ldiv1), &dev->local->control); | ||
535 | writel(0, &dev->remote->control); | ||
536 | if (vlynq_linked(dev)) { | ||
537 | printk(KERN_DEBUG | ||
538 | "%s: using local clock divisor %d\n", | ||
539 | dev_name(&dev->dev), | ||
540 | dev->divisor - vlynq_ldiv1 + 1); | ||
541 | return 0; | ||
542 | } | ||
543 | break; | ||
544 | case vlynq_rdiv1: | ||
545 | case vlynq_rdiv2: | ||
546 | case vlynq_rdiv3: | ||
547 | case vlynq_rdiv4: | ||
548 | case vlynq_rdiv5: | ||
549 | case vlynq_rdiv6: | ||
550 | case vlynq_rdiv7: | ||
551 | case vlynq_rdiv8: | ||
552 | writel(0, &dev->local->control); | ||
553 | writel(VLYNQ_CTRL_CLOCK_INT | | ||
554 | VLYNQ_CTRL_CLOCK_DIV(dev->divisor - | ||
555 | vlynq_rdiv1), &dev->remote->control); | ||
556 | if (vlynq_linked(dev)) { | ||
557 | printk(KERN_DEBUG | ||
558 | "%s: using remote clock divisor %d\n", | ||
559 | dev_name(&dev->dev), | ||
560 | dev->divisor - vlynq_rdiv1 + 1); | ||
561 | return 0; | ||
562 | } | ||
563 | break; | ||
564 | } | ||
565 | |||
566 | ops->off(dev); | ||
567 | return -ENODEV; | ||
568 | } | ||
569 | |||
570 | int vlynq_enable_device(struct vlynq_device *dev) | ||
571 | { | ||
572 | struct plat_vlynq_ops *ops = dev->dev.platform_data; | ||
573 | int result = -ENODEV; | ||
574 | |||
575 | result = __vlynq_enable_device(dev); | ||
576 | if (result) | ||
577 | return result; | ||
578 | |||
579 | result = vlynq_setup_irq(dev); | ||
580 | if (result) | ||
581 | ops->off(dev); | ||
582 | |||
583 | dev->enabled = !result; | ||
584 | return result; | ||
585 | } | ||
586 | EXPORT_SYMBOL(vlynq_enable_device); | ||
587 | |||
588 | |||
589 | void vlynq_disable_device(struct vlynq_device *dev) | ||
590 | { | ||
591 | struct plat_vlynq_ops *ops = dev->dev.platform_data; | ||
592 | |||
593 | dev->enabled = 0; | ||
594 | free_irq(dev->irq, dev); | ||
595 | ops->off(dev); | ||
596 | } | ||
597 | EXPORT_SYMBOL(vlynq_disable_device); | ||
598 | |||
599 | int vlynq_set_local_mapping(struct vlynq_device *dev, u32 tx_offset, | ||
600 | struct vlynq_mapping *mapping) | ||
601 | { | ||
602 | int i; | ||
603 | |||
604 | if (!dev->enabled) | ||
605 | return -ENXIO; | ||
606 | |||
607 | writel(tx_offset, &dev->local->tx_offset); | ||
608 | for (i = 0; i < 4; i++) { | ||
609 | writel(mapping[i].offset, &dev->local->rx_mapping[i].offset); | ||
610 | writel(mapping[i].size, &dev->local->rx_mapping[i].size); | ||
611 | } | ||
612 | return 0; | ||
613 | } | ||
614 | EXPORT_SYMBOL(vlynq_set_local_mapping); | ||
615 | |||
616 | int vlynq_set_remote_mapping(struct vlynq_device *dev, u32 tx_offset, | ||
617 | struct vlynq_mapping *mapping) | ||
618 | { | ||
619 | int i; | ||
620 | |||
621 | if (!dev->enabled) | ||
622 | return -ENXIO; | ||
623 | |||
624 | writel(tx_offset, &dev->remote->tx_offset); | ||
625 | for (i = 0; i < 4; i++) { | ||
626 | writel(mapping[i].offset, &dev->remote->rx_mapping[i].offset); | ||
627 | writel(mapping[i].size, &dev->remote->rx_mapping[i].size); | ||
628 | } | ||
629 | return 0; | ||
630 | } | ||
631 | EXPORT_SYMBOL(vlynq_set_remote_mapping); | ||
632 | |||
633 | int vlynq_set_local_irq(struct vlynq_device *dev, int virq) | ||
634 | { | ||
635 | int irq = dev->irq_start + virq; | ||
636 | if (dev->enabled) | ||
637 | return -EBUSY; | ||
638 | |||
639 | if ((irq < dev->irq_start) || (irq > dev->irq_end)) | ||
640 | return -EINVAL; | ||
641 | |||
642 | if (virq == dev->remote_irq) | ||
643 | return -EINVAL; | ||
644 | |||
645 | dev->local_irq = virq; | ||
646 | |||
647 | return 0; | ||
648 | } | ||
649 | EXPORT_SYMBOL(vlynq_set_local_irq); | ||
650 | |||
651 | int vlynq_set_remote_irq(struct vlynq_device *dev, int virq) | ||
652 | { | ||
653 | int irq = dev->irq_start + virq; | ||
654 | if (dev->enabled) | ||
655 | return -EBUSY; | ||
656 | |||
657 | if ((irq < dev->irq_start) || (irq > dev->irq_end)) | ||
658 | return -EINVAL; | ||
659 | |||
660 | if (virq == dev->local_irq) | ||
661 | return -EINVAL; | ||
662 | |||
663 | dev->remote_irq = virq; | ||
664 | |||
665 | return 0; | ||
666 | } | ||
667 | EXPORT_SYMBOL(vlynq_set_remote_irq); | ||
668 | |||
669 | static int vlynq_probe(struct platform_device *pdev) | ||
670 | { | ||
671 | struct vlynq_device *dev; | ||
672 | struct resource *regs_res, *mem_res, *irq_res; | ||
673 | int len, result; | ||
674 | |||
675 | regs_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs"); | ||
676 | if (!regs_res) | ||
677 | return -ENODEV; | ||
678 | |||
679 | mem_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mem"); | ||
680 | if (!mem_res) | ||
681 | return -ENODEV; | ||
682 | |||
683 | irq_res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "devirq"); | ||
684 | if (!irq_res) | ||
685 | return -ENODEV; | ||
686 | |||
687 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | ||
688 | if (!dev) { | ||
689 | printk(KERN_ERR | ||
690 | "vlynq: failed to allocate device structure\n"); | ||
691 | return -ENOMEM; | ||
692 | } | ||
693 | |||
694 | dev->id = pdev->id; | ||
695 | dev->dev.bus = &vlynq_bus_type; | ||
696 | dev->dev.parent = &pdev->dev; | ||
697 | dev_set_name(&dev->dev, "vlynq%d", dev->id); | ||
698 | dev->dev.platform_data = pdev->dev.platform_data; | ||
699 | dev->dev.release = vlynq_device_release; | ||
700 | |||
701 | dev->regs_start = regs_res->start; | ||
702 | dev->regs_end = regs_res->end; | ||
703 | dev->mem_start = mem_res->start; | ||
704 | dev->mem_end = mem_res->end; | ||
705 | |||
706 | len = regs_res->end - regs_res->start; | ||
707 | if (!request_mem_region(regs_res->start, len, dev_name(&dev->dev))) { | ||
708 | printk(KERN_ERR "%s: Can't request vlynq registers\n", | ||
709 | dev_name(&dev->dev)); | ||
710 | result = -ENXIO; | ||
711 | goto fail_request; | ||
712 | } | ||
713 | |||
714 | dev->local = ioremap(regs_res->start, len); | ||
715 | if (!dev->local) { | ||
716 | printk(KERN_ERR "%s: Can't remap vlynq registers\n", | ||
717 | dev_name(&dev->dev)); | ||
718 | result = -ENXIO; | ||
719 | goto fail_remap; | ||
720 | } | ||
721 | |||
722 | dev->remote = (struct vlynq_regs *)((void *)dev->local + | ||
723 | VLYNQ_REMOTE_OFFSET); | ||
724 | |||
725 | dev->irq = platform_get_irq_byname(pdev, "irq"); | ||
726 | dev->irq_start = irq_res->start; | ||
727 | dev->irq_end = irq_res->end; | ||
728 | dev->local_irq = dev->irq_end - dev->irq_start; | ||
729 | dev->remote_irq = dev->local_irq - 1; | ||
730 | |||
731 | if (device_register(&dev->dev)) | ||
732 | goto fail_register; | ||
733 | platform_set_drvdata(pdev, dev); | ||
734 | |||
735 | printk(KERN_INFO "%s: regs 0x%p, irq %d, mem 0x%p\n", | ||
736 | dev_name(&dev->dev), (void *)dev->regs_start, dev->irq, | ||
737 | (void *)dev->mem_start); | ||
738 | |||
739 | dev->dev_id = 0; | ||
740 | dev->divisor = vlynq_div_auto; | ||
741 | result = __vlynq_enable_device(dev); | ||
742 | if (result == 0) { | ||
743 | dev->dev_id = readl(&dev->remote->chip); | ||
744 | ((struct plat_vlynq_ops *)(dev->dev.platform_data))->off(dev); | ||
745 | } | ||
746 | if (dev->dev_id) | ||
747 | printk(KERN_INFO "Found a VLYNQ device: %08x\n", dev->dev_id); | ||
748 | |||
749 | return 0; | ||
750 | |||
751 | fail_register: | ||
752 | iounmap(dev->local); | ||
753 | fail_remap: | ||
754 | fail_request: | ||
755 | release_mem_region(regs_res->start, len); | ||
756 | kfree(dev); | ||
757 | return result; | ||
758 | } | ||
759 | |||
760 | static int vlynq_remove(struct platform_device *pdev) | ||
761 | { | ||
762 | struct vlynq_device *dev = platform_get_drvdata(pdev); | ||
763 | |||
764 | device_unregister(&dev->dev); | ||
765 | iounmap(dev->local); | ||
766 | release_mem_region(dev->regs_start, dev->regs_end - dev->regs_start); | ||
767 | |||
768 | kfree(dev); | ||
769 | |||
770 | return 0; | ||
771 | } | ||
772 | |||
773 | static struct platform_driver vlynq_platform_driver = { | ||
774 | .driver.name = "vlynq", | ||
775 | .probe = vlynq_probe, | ||
776 | .remove = __devexit_p(vlynq_remove), | ||
777 | }; | ||
778 | |||
779 | struct bus_type vlynq_bus_type = { | ||
780 | .name = "vlynq", | ||
781 | .match = vlynq_device_match, | ||
782 | .probe = vlynq_device_probe, | ||
783 | .remove = vlynq_device_remove, | ||
784 | }; | ||
785 | EXPORT_SYMBOL(vlynq_bus_type); | ||
786 | |||
787 | static int __devinit vlynq_init(void) | ||
788 | { | ||
789 | int res = 0; | ||
790 | |||
791 | res = bus_register(&vlynq_bus_type); | ||
792 | if (res) | ||
793 | goto fail_bus; | ||
794 | |||
795 | res = platform_driver_register(&vlynq_platform_driver); | ||
796 | if (res) | ||
797 | goto fail_platform; | ||
798 | |||
799 | return 0; | ||
800 | |||
801 | fail_platform: | ||
802 | bus_unregister(&vlynq_bus_type); | ||
803 | fail_bus: | ||
804 | return res; | ||
805 | } | ||
806 | |||
807 | static void __devexit vlynq_exit(void) | ||
808 | { | ||
809 | platform_driver_unregister(&vlynq_platform_driver); | ||
810 | bus_unregister(&vlynq_bus_type); | ||
811 | } | ||
812 | |||
813 | module_init(vlynq_init); | ||
814 | module_exit(vlynq_exit); | ||
diff --git a/fs/Kconfig b/fs/Kconfig index 525da2e8f73b..4044f163035f 100644 --- a/fs/Kconfig +++ b/fs/Kconfig | |||
@@ -39,6 +39,13 @@ config FS_POSIX_ACL | |||
39 | bool | 39 | bool |
40 | default n | 40 | default n |
41 | 41 | ||
42 | source "fs/xfs/Kconfig" | ||
43 | source "fs/gfs2/Kconfig" | ||
44 | source "fs/ocfs2/Kconfig" | ||
45 | source "fs/btrfs/Kconfig" | ||
46 | |||
47 | endif # BLOCK | ||
48 | |||
42 | config FILE_LOCKING | 49 | config FILE_LOCKING |
43 | bool "Enable POSIX file locking API" if EMBEDDED | 50 | bool "Enable POSIX file locking API" if EMBEDDED |
44 | default y | 51 | default y |
@@ -47,13 +54,6 @@ config FILE_LOCKING | |||
47 | for filesystems like NFS and for the flock() system | 54 | for filesystems like NFS and for the flock() system |
48 | call. Disabling this option saves about 11k. | 55 | call. Disabling this option saves about 11k. |
49 | 56 | ||
50 | source "fs/xfs/Kconfig" | ||
51 | source "fs/gfs2/Kconfig" | ||
52 | source "fs/ocfs2/Kconfig" | ||
53 | source "fs/btrfs/Kconfig" | ||
54 | |||
55 | endif # BLOCK | ||
56 | |||
57 | source "fs/notify/Kconfig" | 57 | source "fs/notify/Kconfig" |
58 | 58 | ||
59 | source "fs/quota/Kconfig" | 59 | source "fs/quota/Kconfig" |
diff --git a/fs/drop_caches.c b/fs/drop_caches.c index b6a719a909f8..a2edb7913447 100644 --- a/fs/drop_caches.c +++ b/fs/drop_caches.c | |||
@@ -24,7 +24,7 @@ static void drop_pagecache_sb(struct super_block *sb) | |||
24 | continue; | 24 | continue; |
25 | __iget(inode); | 25 | __iget(inode); |
26 | spin_unlock(&inode_lock); | 26 | spin_unlock(&inode_lock); |
27 | __invalidate_mapping_pages(inode->i_mapping, 0, -1, true); | 27 | invalidate_mapping_pages(inode->i_mapping, 0, -1); |
28 | iput(toput_inode); | 28 | iput(toput_inode); |
29 | toput_inode = inode; | 29 | toput_inode = inode; |
30 | spin_lock(&inode_lock); | 30 | spin_lock(&inode_lock); |
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 40308e98c6a4..caf049146ca2 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c | |||
@@ -321,7 +321,7 @@ __sync_single_inode(struct inode *inode, struct writeback_control *wbc) | |||
321 | 321 | ||
322 | spin_lock(&inode_lock); | 322 | spin_lock(&inode_lock); |
323 | inode->i_state &= ~I_SYNC; | 323 | inode->i_state &= ~I_SYNC; |
324 | if (!(inode->i_state & I_FREEING)) { | 324 | if (!(inode->i_state & (I_FREEING | I_CLEAR))) { |
325 | if (!(inode->i_state & I_DIRTY) && | 325 | if (!(inode->i_state & I_DIRTY) && |
326 | mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) { | 326 | mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) { |
327 | /* | 327 | /* |
@@ -492,7 +492,7 @@ void generic_sync_sb_inodes(struct super_block *sb, | |||
492 | break; | 492 | break; |
493 | } | 493 | } |
494 | 494 | ||
495 | if (inode->i_state & I_NEW) { | 495 | if (inode->i_state & (I_NEW | I_WILL_FREE)) { |
496 | requeue_io(inode); | 496 | requeue_io(inode); |
497 | continue; | 497 | continue; |
498 | } | 498 | } |
@@ -523,7 +523,7 @@ void generic_sync_sb_inodes(struct super_block *sb, | |||
523 | if (current_is_pdflush() && !writeback_acquire(bdi)) | 523 | if (current_is_pdflush() && !writeback_acquire(bdi)) |
524 | break; | 524 | break; |
525 | 525 | ||
526 | BUG_ON(inode->i_state & I_FREEING); | 526 | BUG_ON(inode->i_state & (I_FREEING | I_CLEAR)); |
527 | __iget(inode); | 527 | __iget(inode); |
528 | pages_skipped = wbc->pages_skipped; | 528 | pages_skipped = wbc->pages_skipped; |
529 | __writeback_single_inode(inode, wbc); | 529 | __writeback_single_inode(inode, wbc); |
diff --git a/fs/nfs/iostat.h b/fs/nfs/iostat.h index a2ab2529b5ca..ceda50aad73c 100644 --- a/fs/nfs/iostat.h +++ b/fs/nfs/iostat.h | |||
@@ -31,7 +31,7 @@ static inline void nfs_inc_server_stats(const struct nfs_server *server, | |||
31 | cpu = get_cpu(); | 31 | cpu = get_cpu(); |
32 | iostats = per_cpu_ptr(server->io_stats, cpu); | 32 | iostats = per_cpu_ptr(server->io_stats, cpu); |
33 | iostats->events[stat]++; | 33 | iostats->events[stat]++; |
34 | put_cpu_no_resched(); | 34 | put_cpu(); |
35 | } | 35 | } |
36 | 36 | ||
37 | static inline void nfs_inc_stats(const struct inode *inode, | 37 | static inline void nfs_inc_stats(const struct inode *inode, |
@@ -50,7 +50,7 @@ static inline void nfs_add_server_stats(const struct nfs_server *server, | |||
50 | cpu = get_cpu(); | 50 | cpu = get_cpu(); |
51 | iostats = per_cpu_ptr(server->io_stats, cpu); | 51 | iostats = per_cpu_ptr(server->io_stats, cpu); |
52 | iostats->bytes[stat] += addend; | 52 | iostats->bytes[stat] += addend; |
53 | put_cpu_no_resched(); | 53 | put_cpu(); |
54 | } | 54 | } |
55 | 55 | ||
56 | static inline void nfs_add_stats(const struct inode *inode, | 56 | static inline void nfs_add_stats(const struct inode *inode, |
@@ -71,7 +71,7 @@ static inline void nfs_add_fscache_stats(struct inode *inode, | |||
71 | cpu = get_cpu(); | 71 | cpu = get_cpu(); |
72 | iostats = per_cpu_ptr(NFS_SERVER(inode)->io_stats, cpu); | 72 | iostats = per_cpu_ptr(NFS_SERVER(inode)->io_stats, cpu); |
73 | iostats->fscache[stat] += addend; | 73 | iostats->fscache[stat] += addend; |
74 | put_cpu_no_resched(); | 74 | put_cpu(); |
75 | } | 75 | } |
76 | #endif | 76 | #endif |
77 | 77 | ||
diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c index 82c5085559c6..9938034762cc 100644 --- a/fs/ntfs/inode.c +++ b/fs/ntfs/inode.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/pagemap.h> | 27 | #include <linux/pagemap.h> |
28 | #include <linux/quotaops.h> | 28 | #include <linux/quotaops.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/log2.h> | ||
30 | 31 | ||
31 | #include "aops.h" | 32 | #include "aops.h" |
32 | #include "attrib.h" | 33 | #include "attrib.h" |
@@ -1570,7 +1571,7 @@ static int ntfs_read_locked_index_inode(struct inode *base_vi, struct inode *vi) | |||
1570 | ntfs_debug("Index collation rule is 0x%x.", | 1571 | ntfs_debug("Index collation rule is 0x%x.", |
1571 | le32_to_cpu(ir->collation_rule)); | 1572 | le32_to_cpu(ir->collation_rule)); |
1572 | ni->itype.index.block_size = le32_to_cpu(ir->index_block_size); | 1573 | ni->itype.index.block_size = le32_to_cpu(ir->index_block_size); |
1573 | if (ni->itype.index.block_size & (ni->itype.index.block_size - 1)) { | 1574 | if (!is_power_of_2(ni->itype.index.block_size)) { |
1574 | ntfs_error(vi->i_sb, "Index block size (%u) is not a power of " | 1575 | ntfs_error(vi->i_sb, "Index block size (%u) is not a power of " |
1575 | "two.", ni->itype.index.block_size); | 1576 | "two.", ni->itype.index.block_size); |
1576 | goto unm_err_out; | 1577 | goto unm_err_out; |
diff --git a/fs/ntfs/logfile.c b/fs/ntfs/logfile.c index d7932e95b1fd..89b02985c054 100644 --- a/fs/ntfs/logfile.c +++ b/fs/ntfs/logfile.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/highmem.h> | 26 | #include <linux/highmem.h> |
27 | #include <linux/buffer_head.h> | 27 | #include <linux/buffer_head.h> |
28 | #include <linux/bitops.h> | 28 | #include <linux/bitops.h> |
29 | #include <linux/log2.h> | ||
29 | 30 | ||
30 | #include "attrib.h" | 31 | #include "attrib.h" |
31 | #include "aops.h" | 32 | #include "aops.h" |
@@ -65,7 +66,7 @@ static bool ntfs_check_restart_page_header(struct inode *vi, | |||
65 | logfile_log_page_size < NTFS_BLOCK_SIZE || | 66 | logfile_log_page_size < NTFS_BLOCK_SIZE || |
66 | logfile_system_page_size & | 67 | logfile_system_page_size & |
67 | (logfile_system_page_size - 1) || | 68 | (logfile_system_page_size - 1) || |
68 | logfile_log_page_size & (logfile_log_page_size - 1)) { | 69 | !is_power_of_2(logfile_log_page_size)) { |
69 | ntfs_error(vi->i_sb, "$LogFile uses unsupported page size."); | 70 | ntfs_error(vi->i_sb, "$LogFile uses unsupported page size."); |
70 | return false; | 71 | return false; |
71 | } | 72 | } |
diff --git a/fs/proc/base.c b/fs/proc/base.c index 1539e630c47d..3ce5ae9e3d2d 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -1006,7 +1006,12 @@ static ssize_t oom_adjust_read(struct file *file, char __user *buf, | |||
1006 | 1006 | ||
1007 | if (!task) | 1007 | if (!task) |
1008 | return -ESRCH; | 1008 | return -ESRCH; |
1009 | oom_adjust = task->oomkilladj; | 1009 | task_lock(task); |
1010 | if (task->mm) | ||
1011 | oom_adjust = task->mm->oom_adj; | ||
1012 | else | ||
1013 | oom_adjust = OOM_DISABLE; | ||
1014 | task_unlock(task); | ||
1010 | put_task_struct(task); | 1015 | put_task_struct(task); |
1011 | 1016 | ||
1012 | len = snprintf(buffer, sizeof(buffer), "%i\n", oom_adjust); | 1017 | len = snprintf(buffer, sizeof(buffer), "%i\n", oom_adjust); |
@@ -1035,11 +1040,19 @@ static ssize_t oom_adjust_write(struct file *file, const char __user *buf, | |||
1035 | task = get_proc_task(file->f_path.dentry->d_inode); | 1040 | task = get_proc_task(file->f_path.dentry->d_inode); |
1036 | if (!task) | 1041 | if (!task) |
1037 | return -ESRCH; | 1042 | return -ESRCH; |
1038 | if (oom_adjust < task->oomkilladj && !capable(CAP_SYS_RESOURCE)) { | 1043 | task_lock(task); |
1044 | if (!task->mm) { | ||
1045 | task_unlock(task); | ||
1046 | put_task_struct(task); | ||
1047 | return -EINVAL; | ||
1048 | } | ||
1049 | if (oom_adjust < task->mm->oom_adj && !capable(CAP_SYS_RESOURCE)) { | ||
1050 | task_unlock(task); | ||
1039 | put_task_struct(task); | 1051 | put_task_struct(task); |
1040 | return -EACCES; | 1052 | return -EACCES; |
1041 | } | 1053 | } |
1042 | task->oomkilladj = oom_adjust; | 1054 | task->mm->oom_adj = oom_adjust; |
1055 | task_unlock(task); | ||
1043 | put_task_struct(task); | 1056 | put_task_struct(task); |
1044 | if (end - buffer == 0) | 1057 | if (end - buffer == 0) |
1045 | return -EIO; | 1058 | return -EIO; |
diff --git a/fs/proc/meminfo.c b/fs/proc/meminfo.c index c6b0302af4c4..d5c410d47fae 100644 --- a/fs/proc/meminfo.c +++ b/fs/proc/meminfo.c | |||
@@ -64,10 +64,8 @@ static int meminfo_proc_show(struct seq_file *m, void *v) | |||
64 | "Inactive(anon): %8lu kB\n" | 64 | "Inactive(anon): %8lu kB\n" |
65 | "Active(file): %8lu kB\n" | 65 | "Active(file): %8lu kB\n" |
66 | "Inactive(file): %8lu kB\n" | 66 | "Inactive(file): %8lu kB\n" |
67 | #ifdef CONFIG_UNEVICTABLE_LRU | ||
68 | "Unevictable: %8lu kB\n" | 67 | "Unevictable: %8lu kB\n" |
69 | "Mlocked: %8lu kB\n" | 68 | "Mlocked: %8lu kB\n" |
70 | #endif | ||
71 | #ifdef CONFIG_HIGHMEM | 69 | #ifdef CONFIG_HIGHMEM |
72 | "HighTotal: %8lu kB\n" | 70 | "HighTotal: %8lu kB\n" |
73 | "HighFree: %8lu kB\n" | 71 | "HighFree: %8lu kB\n" |
@@ -109,10 +107,8 @@ static int meminfo_proc_show(struct seq_file *m, void *v) | |||
109 | K(pages[LRU_INACTIVE_ANON]), | 107 | K(pages[LRU_INACTIVE_ANON]), |
110 | K(pages[LRU_ACTIVE_FILE]), | 108 | K(pages[LRU_ACTIVE_FILE]), |
111 | K(pages[LRU_INACTIVE_FILE]), | 109 | K(pages[LRU_INACTIVE_FILE]), |
112 | #ifdef CONFIG_UNEVICTABLE_LRU | ||
113 | K(pages[LRU_UNEVICTABLE]), | 110 | K(pages[LRU_UNEVICTABLE]), |
114 | K(global_page_state(NR_MLOCK)), | 111 | K(global_page_state(NR_MLOCK)), |
115 | #endif | ||
116 | #ifdef CONFIG_HIGHMEM | 112 | #ifdef CONFIG_HIGHMEM |
117 | K(i.totalhigh), | 113 | K(i.totalhigh), |
118 | K(i.freehigh), | 114 | K(i.freehigh), |
diff --git a/fs/proc/page.c b/fs/proc/page.c index e9983837d08d..2707c6c7a20f 100644 --- a/fs/proc/page.c +++ b/fs/proc/page.c | |||
@@ -6,11 +6,13 @@ | |||
6 | #include <linux/mmzone.h> | 6 | #include <linux/mmzone.h> |
7 | #include <linux/proc_fs.h> | 7 | #include <linux/proc_fs.h> |
8 | #include <linux/seq_file.h> | 8 | #include <linux/seq_file.h> |
9 | #include <linux/hugetlb.h> | ||
9 | #include <asm/uaccess.h> | 10 | #include <asm/uaccess.h> |
10 | #include "internal.h" | 11 | #include "internal.h" |
11 | 12 | ||
12 | #define KPMSIZE sizeof(u64) | 13 | #define KPMSIZE sizeof(u64) |
13 | #define KPMMASK (KPMSIZE - 1) | 14 | #define KPMMASK (KPMSIZE - 1) |
15 | |||
14 | /* /proc/kpagecount - an array exposing page counts | 16 | /* /proc/kpagecount - an array exposing page counts |
15 | * | 17 | * |
16 | * Each entry is a u64 representing the corresponding | 18 | * Each entry is a u64 representing the corresponding |
@@ -32,20 +34,22 @@ static ssize_t kpagecount_read(struct file *file, char __user *buf, | |||
32 | return -EINVAL; | 34 | return -EINVAL; |
33 | 35 | ||
34 | while (count > 0) { | 36 | while (count > 0) { |
35 | ppage = NULL; | ||
36 | if (pfn_valid(pfn)) | 37 | if (pfn_valid(pfn)) |
37 | ppage = pfn_to_page(pfn); | 38 | ppage = pfn_to_page(pfn); |
38 | pfn++; | 39 | else |
40 | ppage = NULL; | ||
39 | if (!ppage) | 41 | if (!ppage) |
40 | pcount = 0; | 42 | pcount = 0; |
41 | else | 43 | else |
42 | pcount = page_mapcount(ppage); | 44 | pcount = page_mapcount(ppage); |
43 | 45 | ||
44 | if (put_user(pcount, out++)) { | 46 | if (put_user(pcount, out)) { |
45 | ret = -EFAULT; | 47 | ret = -EFAULT; |
46 | break; | 48 | break; |
47 | } | 49 | } |
48 | 50 | ||
51 | pfn++; | ||
52 | out++; | ||
49 | count -= KPMSIZE; | 53 | count -= KPMSIZE; |
50 | } | 54 | } |
51 | 55 | ||
@@ -68,19 +72,122 @@ static const struct file_operations proc_kpagecount_operations = { | |||
68 | 72 | ||
69 | /* These macros are used to decouple internal flags from exported ones */ | 73 | /* These macros are used to decouple internal flags from exported ones */ |
70 | 74 | ||
71 | #define KPF_LOCKED 0 | 75 | #define KPF_LOCKED 0 |
72 | #define KPF_ERROR 1 | 76 | #define KPF_ERROR 1 |
73 | #define KPF_REFERENCED 2 | 77 | #define KPF_REFERENCED 2 |
74 | #define KPF_UPTODATE 3 | 78 | #define KPF_UPTODATE 3 |
75 | #define KPF_DIRTY 4 | 79 | #define KPF_DIRTY 4 |
76 | #define KPF_LRU 5 | 80 | #define KPF_LRU 5 |
77 | #define KPF_ACTIVE 6 | 81 | #define KPF_ACTIVE 6 |
78 | #define KPF_SLAB 7 | 82 | #define KPF_SLAB 7 |
79 | #define KPF_WRITEBACK 8 | 83 | #define KPF_WRITEBACK 8 |
80 | #define KPF_RECLAIM 9 | 84 | #define KPF_RECLAIM 9 |
81 | #define KPF_BUDDY 10 | 85 | #define KPF_BUDDY 10 |
86 | |||
87 | /* 11-20: new additions in 2.6.31 */ | ||
88 | #define KPF_MMAP 11 | ||
89 | #define KPF_ANON 12 | ||
90 | #define KPF_SWAPCACHE 13 | ||
91 | #define KPF_SWAPBACKED 14 | ||
92 | #define KPF_COMPOUND_HEAD 15 | ||
93 | #define KPF_COMPOUND_TAIL 16 | ||
94 | #define KPF_HUGE 17 | ||
95 | #define KPF_UNEVICTABLE 18 | ||
96 | #define KPF_NOPAGE 20 | ||
97 | |||
98 | /* kernel hacking assistances | ||
99 | * WARNING: subject to change, never rely on them! | ||
100 | */ | ||
101 | #define KPF_RESERVED 32 | ||
102 | #define KPF_MLOCKED 33 | ||
103 | #define KPF_MAPPEDTODISK 34 | ||
104 | #define KPF_PRIVATE 35 | ||
105 | #define KPF_PRIVATE_2 36 | ||
106 | #define KPF_OWNER_PRIVATE 37 | ||
107 | #define KPF_ARCH 38 | ||
108 | #define KPF_UNCACHED 39 | ||
109 | |||
110 | static inline u64 kpf_copy_bit(u64 kflags, int ubit, int kbit) | ||
111 | { | ||
112 | return ((kflags >> kbit) & 1) << ubit; | ||
113 | } | ||
82 | 114 | ||
83 | #define kpf_copy_bit(flags, dstpos, srcpos) (((flags >> srcpos) & 1) << dstpos) | 115 | static u64 get_uflags(struct page *page) |
116 | { | ||
117 | u64 k; | ||
118 | u64 u; | ||
119 | |||
120 | /* | ||
121 | * pseudo flag: KPF_NOPAGE | ||
122 | * it differentiates a memory hole from a page with no flags | ||
123 | */ | ||
124 | if (!page) | ||
125 | return 1 << KPF_NOPAGE; | ||
126 | |||
127 | k = page->flags; | ||
128 | u = 0; | ||
129 | |||
130 | /* | ||
131 | * pseudo flags for the well known (anonymous) memory mapped pages | ||
132 | * | ||
133 | * Note that page->_mapcount is overloaded in SLOB/SLUB/SLQB, so the | ||
134 | * simple test in page_mapped() is not enough. | ||
135 | */ | ||
136 | if (!PageSlab(page) && page_mapped(page)) | ||
137 | u |= 1 << KPF_MMAP; | ||
138 | if (PageAnon(page)) | ||
139 | u |= 1 << KPF_ANON; | ||
140 | |||
141 | /* | ||
142 | * compound pages: export both head/tail info | ||
143 | * they together define a compound page's start/end pos and order | ||
144 | */ | ||
145 | if (PageHead(page)) | ||
146 | u |= 1 << KPF_COMPOUND_HEAD; | ||
147 | if (PageTail(page)) | ||
148 | u |= 1 << KPF_COMPOUND_TAIL; | ||
149 | if (PageHuge(page)) | ||
150 | u |= 1 << KPF_HUGE; | ||
151 | |||
152 | u |= kpf_copy_bit(k, KPF_LOCKED, PG_locked); | ||
153 | |||
154 | /* | ||
155 | * Caveats on high order pages: | ||
156 | * PG_buddy will only be set on the head page; SLUB/SLQB do the same | ||
157 | * for PG_slab; SLOB won't set PG_slab at all on compound pages. | ||
158 | */ | ||
159 | u |= kpf_copy_bit(k, KPF_SLAB, PG_slab); | ||
160 | u |= kpf_copy_bit(k, KPF_BUDDY, PG_buddy); | ||
161 | |||
162 | u |= kpf_copy_bit(k, KPF_ERROR, PG_error); | ||
163 | u |= kpf_copy_bit(k, KPF_DIRTY, PG_dirty); | ||
164 | u |= kpf_copy_bit(k, KPF_UPTODATE, PG_uptodate); | ||
165 | u |= kpf_copy_bit(k, KPF_WRITEBACK, PG_writeback); | ||
166 | |||
167 | u |= kpf_copy_bit(k, KPF_LRU, PG_lru); | ||
168 | u |= kpf_copy_bit(k, KPF_REFERENCED, PG_referenced); | ||
169 | u |= kpf_copy_bit(k, KPF_ACTIVE, PG_active); | ||
170 | u |= kpf_copy_bit(k, KPF_RECLAIM, PG_reclaim); | ||
171 | |||
172 | u |= kpf_copy_bit(k, KPF_SWAPCACHE, PG_swapcache); | ||
173 | u |= kpf_copy_bit(k, KPF_SWAPBACKED, PG_swapbacked); | ||
174 | |||
175 | u |= kpf_copy_bit(k, KPF_UNEVICTABLE, PG_unevictable); | ||
176 | u |= kpf_copy_bit(k, KPF_MLOCKED, PG_mlocked); | ||
177 | |||
178 | #ifdef CONFIG_IA64_UNCACHED_ALLOCATOR | ||
179 | u |= kpf_copy_bit(k, KPF_UNCACHED, PG_uncached); | ||
180 | #endif | ||
181 | |||
182 | u |= kpf_copy_bit(k, KPF_RESERVED, PG_reserved); | ||
183 | u |= kpf_copy_bit(k, KPF_MAPPEDTODISK, PG_mappedtodisk); | ||
184 | u |= kpf_copy_bit(k, KPF_PRIVATE, PG_private); | ||
185 | u |= kpf_copy_bit(k, KPF_PRIVATE_2, PG_private_2); | ||
186 | u |= kpf_copy_bit(k, KPF_OWNER_PRIVATE, PG_owner_priv_1); | ||
187 | u |= kpf_copy_bit(k, KPF_ARCH, PG_arch_1); | ||
188 | |||
189 | return u; | ||
190 | }; | ||
84 | 191 | ||
85 | static ssize_t kpageflags_read(struct file *file, char __user *buf, | 192 | static ssize_t kpageflags_read(struct file *file, char __user *buf, |
86 | size_t count, loff_t *ppos) | 193 | size_t count, loff_t *ppos) |
@@ -90,7 +197,6 @@ static ssize_t kpageflags_read(struct file *file, char __user *buf, | |||
90 | unsigned long src = *ppos; | 197 | unsigned long src = *ppos; |
91 | unsigned long pfn; | 198 | unsigned long pfn; |
92 | ssize_t ret = 0; | 199 | ssize_t ret = 0; |
93 | u64 kflags, uflags; | ||
94 | 200 | ||
95 | pfn = src / KPMSIZE; | 201 | pfn = src / KPMSIZE; |
96 | count = min_t(unsigned long, count, (max_pfn * KPMSIZE) - src); | 202 | count = min_t(unsigned long, count, (max_pfn * KPMSIZE) - src); |
@@ -98,32 +204,18 @@ static ssize_t kpageflags_read(struct file *file, char __user *buf, | |||
98 | return -EINVAL; | 204 | return -EINVAL; |
99 | 205 | ||
100 | while (count > 0) { | 206 | while (count > 0) { |
101 | ppage = NULL; | ||
102 | if (pfn_valid(pfn)) | 207 | if (pfn_valid(pfn)) |
103 | ppage = pfn_to_page(pfn); | 208 | ppage = pfn_to_page(pfn); |
104 | pfn++; | ||
105 | if (!ppage) | ||
106 | kflags = 0; | ||
107 | else | 209 | else |
108 | kflags = ppage->flags; | 210 | ppage = NULL; |
109 | 211 | ||
110 | uflags = kpf_copy_bit(kflags, KPF_LOCKED, PG_locked) | | 212 | if (put_user(get_uflags(ppage), out)) { |
111 | kpf_copy_bit(kflags, KPF_ERROR, PG_error) | | ||
112 | kpf_copy_bit(kflags, KPF_REFERENCED, PG_referenced) | | ||
113 | kpf_copy_bit(kflags, KPF_UPTODATE, PG_uptodate) | | ||
114 | kpf_copy_bit(kflags, KPF_DIRTY, PG_dirty) | | ||
115 | kpf_copy_bit(kflags, KPF_LRU, PG_lru) | | ||
116 | kpf_copy_bit(kflags, KPF_ACTIVE, PG_active) | | ||
117 | kpf_copy_bit(kflags, KPF_SLAB, PG_slab) | | ||
118 | kpf_copy_bit(kflags, KPF_WRITEBACK, PG_writeback) | | ||
119 | kpf_copy_bit(kflags, KPF_RECLAIM, PG_reclaim) | | ||
120 | kpf_copy_bit(kflags, KPF_BUDDY, PG_buddy); | ||
121 | |||
122 | if (put_user(uflags, out++)) { | ||
123 | ret = -EFAULT; | 213 | ret = -EFAULT; |
124 | break; | 214 | break; |
125 | } | 215 | } |
126 | 216 | ||
217 | pfn++; | ||
218 | out++; | ||
127 | count -= KPMSIZE; | 219 | count -= KPMSIZE; |
128 | } | 220 | } |
129 | 221 | ||
diff --git a/fs/select.c b/fs/select.c index 0fe0e1469df3..d870237e42c7 100644 --- a/fs/select.c +++ b/fs/select.c | |||
@@ -168,7 +168,7 @@ static struct poll_table_entry *poll_get_entry(struct poll_wqueues *p) | |||
168 | return table->entry++; | 168 | return table->entry++; |
169 | } | 169 | } |
170 | 170 | ||
171 | static int pollwake(wait_queue_t *wait, unsigned mode, int sync, void *key) | 171 | static int __pollwake(wait_queue_t *wait, unsigned mode, int sync, void *key) |
172 | { | 172 | { |
173 | struct poll_wqueues *pwq = wait->private; | 173 | struct poll_wqueues *pwq = wait->private; |
174 | DECLARE_WAITQUEUE(dummy_wait, pwq->polling_task); | 174 | DECLARE_WAITQUEUE(dummy_wait, pwq->polling_task); |
@@ -194,6 +194,16 @@ static int pollwake(wait_queue_t *wait, unsigned mode, int sync, void *key) | |||
194 | return default_wake_function(&dummy_wait, mode, sync, key); | 194 | return default_wake_function(&dummy_wait, mode, sync, key); |
195 | } | 195 | } |
196 | 196 | ||
197 | static int pollwake(wait_queue_t *wait, unsigned mode, int sync, void *key) | ||
198 | { | ||
199 | struct poll_table_entry *entry; | ||
200 | |||
201 | entry = container_of(wait, struct poll_table_entry, wait); | ||
202 | if (key && !((unsigned long)key & entry->key)) | ||
203 | return 0; | ||
204 | return __pollwake(wait, mode, sync, key); | ||
205 | } | ||
206 | |||
197 | /* Add a new entry */ | 207 | /* Add a new entry */ |
198 | static void __pollwait(struct file *filp, wait_queue_head_t *wait_address, | 208 | static void __pollwait(struct file *filp, wait_queue_head_t *wait_address, |
199 | poll_table *p) | 209 | poll_table *p) |
@@ -205,6 +215,7 @@ static void __pollwait(struct file *filp, wait_queue_head_t *wait_address, | |||
205 | get_file(filp); | 215 | get_file(filp); |
206 | entry->filp = filp; | 216 | entry->filp = filp; |
207 | entry->wait_address = wait_address; | 217 | entry->wait_address = wait_address; |
218 | entry->key = p->key; | ||
208 | init_waitqueue_func_entry(&entry->wait, pollwake); | 219 | init_waitqueue_func_entry(&entry->wait, pollwake); |
209 | entry->wait.private = pwq; | 220 | entry->wait.private = pwq; |
210 | add_wait_queue(wait_address, &entry->wait); | 221 | add_wait_queue(wait_address, &entry->wait); |
@@ -362,6 +373,18 @@ get_max: | |||
362 | #define POLLOUT_SET (POLLWRBAND | POLLWRNORM | POLLOUT | POLLERR) | 373 | #define POLLOUT_SET (POLLWRBAND | POLLWRNORM | POLLOUT | POLLERR) |
363 | #define POLLEX_SET (POLLPRI) | 374 | #define POLLEX_SET (POLLPRI) |
364 | 375 | ||
376 | static inline void wait_key_set(poll_table *wait, unsigned long in, | ||
377 | unsigned long out, unsigned long bit) | ||
378 | { | ||
379 | if (wait) { | ||
380 | wait->key = POLLEX_SET; | ||
381 | if (in & bit) | ||
382 | wait->key |= POLLIN_SET; | ||
383 | if (out & bit) | ||
384 | wait->key |= POLLOUT_SET; | ||
385 | } | ||
386 | } | ||
387 | |||
365 | int do_select(int n, fd_set_bits *fds, struct timespec *end_time) | 388 | int do_select(int n, fd_set_bits *fds, struct timespec *end_time) |
366 | { | 389 | { |
367 | ktime_t expire, *to = NULL; | 390 | ktime_t expire, *to = NULL; |
@@ -418,20 +441,25 @@ int do_select(int n, fd_set_bits *fds, struct timespec *end_time) | |||
418 | if (file) { | 441 | if (file) { |
419 | f_op = file->f_op; | 442 | f_op = file->f_op; |
420 | mask = DEFAULT_POLLMASK; | 443 | mask = DEFAULT_POLLMASK; |
421 | if (f_op && f_op->poll) | 444 | if (f_op && f_op->poll) { |
422 | mask = (*f_op->poll)(file, retval ? NULL : wait); | 445 | wait_key_set(wait, in, out, bit); |
446 | mask = (*f_op->poll)(file, wait); | ||
447 | } | ||
423 | fput_light(file, fput_needed); | 448 | fput_light(file, fput_needed); |
424 | if ((mask & POLLIN_SET) && (in & bit)) { | 449 | if ((mask & POLLIN_SET) && (in & bit)) { |
425 | res_in |= bit; | 450 | res_in |= bit; |
426 | retval++; | 451 | retval++; |
452 | wait = NULL; | ||
427 | } | 453 | } |
428 | if ((mask & POLLOUT_SET) && (out & bit)) { | 454 | if ((mask & POLLOUT_SET) && (out & bit)) { |
429 | res_out |= bit; | 455 | res_out |= bit; |
430 | retval++; | 456 | retval++; |
457 | wait = NULL; | ||
431 | } | 458 | } |
432 | if ((mask & POLLEX_SET) && (ex & bit)) { | 459 | if ((mask & POLLEX_SET) && (ex & bit)) { |
433 | res_ex |= bit; | 460 | res_ex |= bit; |
434 | retval++; | 461 | retval++; |
462 | wait = NULL; | ||
435 | } | 463 | } |
436 | } | 464 | } |
437 | } | 465 | } |
@@ -685,8 +713,12 @@ static inline unsigned int do_pollfd(struct pollfd *pollfd, poll_table *pwait) | |||
685 | mask = POLLNVAL; | 713 | mask = POLLNVAL; |
686 | if (file != NULL) { | 714 | if (file != NULL) { |
687 | mask = DEFAULT_POLLMASK; | 715 | mask = DEFAULT_POLLMASK; |
688 | if (file->f_op && file->f_op->poll) | 716 | if (file->f_op && file->f_op->poll) { |
717 | if (pwait) | ||
718 | pwait->key = pollfd->events | | ||
719 | POLLERR | POLLHUP; | ||
689 | mask = file->f_op->poll(file, pwait); | 720 | mask = file->f_op->poll(file, pwait); |
721 | } | ||
690 | /* Mask out unneeded events. */ | 722 | /* Mask out unneeded events. */ |
691 | mask &= pollfd->events | POLLERR | POLLHUP; | 723 | mask &= pollfd->events | POLLERR | POLLHUP; |
692 | fput_light(file, fput_needed); | 724 | fput_light(file, fput_needed); |
diff --git a/include/asm-generic/kmap_types.h b/include/asm-generic/kmap_types.h index 58c33055c304..54e8b3d956b7 100644 --- a/include/asm-generic/kmap_types.h +++ b/include/asm-generic/kmap_types.h | |||
@@ -1,7 +1,7 @@ | |||
1 | #ifndef _ASM_GENERIC_KMAP_TYPES_H | 1 | #ifndef _ASM_GENERIC_KMAP_TYPES_H |
2 | #define _ASM_GENERIC_KMAP_TYPES_H | 2 | #define _ASM_GENERIC_KMAP_TYPES_H |
3 | 3 | ||
4 | #ifdef CONFIG_DEBUG_HIGHMEM | 4 | #ifdef __WITH_KM_FENCE |
5 | # define D(n) __KM_FENCE_##n , | 5 | # define D(n) __KM_FENCE_##n , |
6 | #else | 6 | #else |
7 | # define D(n) | 7 | # define D(n) |
diff --git a/include/linux/bug.h b/include/linux/bug.h index 54398d2c6d8d..d276b5510c83 100644 --- a/include/linux/bug.h +++ b/include/linux/bug.h | |||
@@ -1,7 +1,6 @@ | |||
1 | #ifndef _LINUX_BUG_H | 1 | #ifndef _LINUX_BUG_H |
2 | #define _LINUX_BUG_H | 2 | #define _LINUX_BUG_H |
3 | 3 | ||
4 | #include <linux/module.h> | ||
5 | #include <asm/bug.h> | 4 | #include <asm/bug.h> |
6 | 5 | ||
7 | enum bug_trap_type { | 6 | enum bug_trap_type { |
@@ -24,10 +23,6 @@ const struct bug_entry *find_bug(unsigned long bugaddr); | |||
24 | 23 | ||
25 | enum bug_trap_type report_bug(unsigned long bug_addr, struct pt_regs *regs); | 24 | enum bug_trap_type report_bug(unsigned long bug_addr, struct pt_regs *regs); |
26 | 25 | ||
27 | int module_bug_finalize(const Elf_Ehdr *, const Elf_Shdr *, | ||
28 | struct module *); | ||
29 | void module_bug_cleanup(struct module *); | ||
30 | |||
31 | /* These are defined by the architecture */ | 26 | /* These are defined by the architecture */ |
32 | int is_valid_bugaddr(unsigned long addr); | 27 | int is_valid_bugaddr(unsigned long addr); |
33 | 28 | ||
@@ -38,13 +33,6 @@ static inline enum bug_trap_type report_bug(unsigned long bug_addr, | |||
38 | { | 33 | { |
39 | return BUG_TRAP_TYPE_BUG; | 34 | return BUG_TRAP_TYPE_BUG; |
40 | } | 35 | } |
41 | static inline int module_bug_finalize(const Elf_Ehdr *hdr, | ||
42 | const Elf_Shdr *sechdrs, | ||
43 | struct module *mod) | ||
44 | { | ||
45 | return 0; | ||
46 | } | ||
47 | static inline void module_bug_cleanup(struct module *mod) {} | ||
48 | 36 | ||
49 | #endif /* CONFIG_GENERIC_BUG */ | 37 | #endif /* CONFIG_GENERIC_BUG */ |
50 | #endif /* _LINUX_BUG_H */ | 38 | #endif /* _LINUX_BUG_H */ |
diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h index 05ea1dd7d681..a5740fc4d04b 100644 --- a/include/linux/cpuset.h +++ b/include/linux/cpuset.h | |||
@@ -18,7 +18,6 @@ | |||
18 | 18 | ||
19 | extern int number_of_cpusets; /* How many cpusets are defined in system? */ | 19 | extern int number_of_cpusets; /* How many cpusets are defined in system? */ |
20 | 20 | ||
21 | extern int cpuset_init_early(void); | ||
22 | extern int cpuset_init(void); | 21 | extern int cpuset_init(void); |
23 | extern void cpuset_init_smp(void); | 22 | extern void cpuset_init_smp(void); |
24 | extern void cpuset_cpus_allowed(struct task_struct *p, struct cpumask *mask); | 23 | extern void cpuset_cpus_allowed(struct task_struct *p, struct cpumask *mask); |
@@ -27,7 +26,6 @@ extern void cpuset_cpus_allowed_locked(struct task_struct *p, | |||
27 | extern nodemask_t cpuset_mems_allowed(struct task_struct *p); | 26 | extern nodemask_t cpuset_mems_allowed(struct task_struct *p); |
28 | #define cpuset_current_mems_allowed (current->mems_allowed) | 27 | #define cpuset_current_mems_allowed (current->mems_allowed) |
29 | void cpuset_init_current_mems_allowed(void); | 28 | void cpuset_init_current_mems_allowed(void); |
30 | void cpuset_update_task_memory_state(void); | ||
31 | int cpuset_nodemask_valid_mems_allowed(nodemask_t *nodemask); | 29 | int cpuset_nodemask_valid_mems_allowed(nodemask_t *nodemask); |
32 | 30 | ||
33 | extern int __cpuset_node_allowed_softwall(int node, gfp_t gfp_mask); | 31 | extern int __cpuset_node_allowed_softwall(int node, gfp_t gfp_mask); |
@@ -92,9 +90,13 @@ extern void rebuild_sched_domains(void); | |||
92 | 90 | ||
93 | extern void cpuset_print_task_mems_allowed(struct task_struct *p); | 91 | extern void cpuset_print_task_mems_allowed(struct task_struct *p); |
94 | 92 | ||
93 | static inline void set_mems_allowed(nodemask_t nodemask) | ||
94 | { | ||
95 | current->mems_allowed = nodemask; | ||
96 | } | ||
97 | |||
95 | #else /* !CONFIG_CPUSETS */ | 98 | #else /* !CONFIG_CPUSETS */ |
96 | 99 | ||
97 | static inline int cpuset_init_early(void) { return 0; } | ||
98 | static inline int cpuset_init(void) { return 0; } | 100 | static inline int cpuset_init(void) { return 0; } |
99 | static inline void cpuset_init_smp(void) {} | 101 | static inline void cpuset_init_smp(void) {} |
100 | 102 | ||
@@ -116,7 +118,6 @@ static inline nodemask_t cpuset_mems_allowed(struct task_struct *p) | |||
116 | 118 | ||
117 | #define cpuset_current_mems_allowed (node_states[N_HIGH_MEMORY]) | 119 | #define cpuset_current_mems_allowed (node_states[N_HIGH_MEMORY]) |
118 | static inline void cpuset_init_current_mems_allowed(void) {} | 120 | static inline void cpuset_init_current_mems_allowed(void) {} |
119 | static inline void cpuset_update_task_memory_state(void) {} | ||
120 | 121 | ||
121 | static inline int cpuset_nodemask_valid_mems_allowed(nodemask_t *nodemask) | 122 | static inline int cpuset_nodemask_valid_mems_allowed(nodemask_t *nodemask) |
122 | { | 123 | { |
@@ -188,6 +189,10 @@ static inline void cpuset_print_task_mems_allowed(struct task_struct *p) | |||
188 | { | 189 | { |
189 | } | 190 | } |
190 | 191 | ||
192 | static inline void set_mems_allowed(nodemask_t nodemask) | ||
193 | { | ||
194 | } | ||
195 | |||
191 | #endif /* !CONFIG_CPUSETS */ | 196 | #endif /* !CONFIG_CPUSETS */ |
192 | 197 | ||
193 | #endif /* _LINUX_CPUSET_H */ | 198 | #endif /* _LINUX_CPUSET_H */ |
diff --git a/include/linux/fb.h b/include/linux/fb.h index 330c4b1bfcaa..dd68358996b7 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h | |||
@@ -677,6 +677,9 @@ struct fb_ops { | |||
677 | /* get capability given var */ | 677 | /* get capability given var */ |
678 | void (*fb_get_caps)(struct fb_info *info, struct fb_blit_caps *caps, | 678 | void (*fb_get_caps)(struct fb_info *info, struct fb_blit_caps *caps, |
679 | struct fb_var_screeninfo *var); | 679 | struct fb_var_screeninfo *var); |
680 | |||
681 | /* teardown any resources to do with this framebuffer */ | ||
682 | void (*fb_destroy)(struct fb_info *info); | ||
680 | }; | 683 | }; |
681 | 684 | ||
682 | #ifdef CONFIG_FB_TILEBLITTING | 685 | #ifdef CONFIG_FB_TILEBLITTING |
@@ -786,6 +789,8 @@ struct fb_tile_ops { | |||
786 | #define FBINFO_MISC_USEREVENT 0x10000 /* event request | 789 | #define FBINFO_MISC_USEREVENT 0x10000 /* event request |
787 | from userspace */ | 790 | from userspace */ |
788 | #define FBINFO_MISC_TILEBLITTING 0x20000 /* use tile blitting */ | 791 | #define FBINFO_MISC_TILEBLITTING 0x20000 /* use tile blitting */ |
792 | #define FBINFO_MISC_FIRMWARE 0x40000 /* a replaceable firmware | ||
793 | inited framebuffer */ | ||
789 | 794 | ||
790 | /* A driver may set this flag to indicate that it does want a set_par to be | 795 | /* A driver may set this flag to indicate that it does want a set_par to be |
791 | * called every time when fbcon_switch is executed. The advantage is that with | 796 | * called every time when fbcon_switch is executed. The advantage is that with |
@@ -854,7 +859,12 @@ struct fb_info { | |||
854 | u32 state; /* Hardware state i.e suspend */ | 859 | u32 state; /* Hardware state i.e suspend */ |
855 | void *fbcon_par; /* fbcon use-only private area */ | 860 | void *fbcon_par; /* fbcon use-only private area */ |
856 | /* From here on everything is device dependent */ | 861 | /* From here on everything is device dependent */ |
857 | void *par; | 862 | void *par; |
863 | /* we need the PCI or similiar aperture base/size not | ||
864 | smem_start/size as smem_start may just be an object | ||
865 | allocated inside the aperture so may not actually overlap */ | ||
866 | resource_size_t aperture_base; | ||
867 | resource_size_t aperture_size; | ||
858 | }; | 868 | }; |
859 | 869 | ||
860 | #ifdef MODULE | 870 | #ifdef MODULE |
@@ -893,7 +903,7 @@ struct fb_info { | |||
893 | #define fb_writeq sbus_writeq | 903 | #define fb_writeq sbus_writeq |
894 | #define fb_memset sbus_memset_io | 904 | #define fb_memset sbus_memset_io |
895 | 905 | ||
896 | #elif defined(__i386__) || defined(__alpha__) || defined(__x86_64__) || defined(__hppa__) || defined(__sh__) || defined(__powerpc__) || defined(__avr32__) | 906 | #elif defined(__i386__) || defined(__alpha__) || defined(__x86_64__) || defined(__hppa__) || defined(__sh__) || defined(__powerpc__) || defined(__avr32__) || defined(__bfin__) |
897 | 907 | ||
898 | #define fb_readb __raw_readb | 908 | #define fb_readb __raw_readb |
899 | #define fb_readw __raw_readw | 909 | #define fb_readw __raw_readw |
diff --git a/include/linux/firmware-map.h b/include/linux/firmware-map.h index cca686b39123..875451f1373a 100644 --- a/include/linux/firmware-map.h +++ b/include/linux/firmware-map.h | |||
@@ -24,21 +24,17 @@ | |||
24 | */ | 24 | */ |
25 | #ifdef CONFIG_FIRMWARE_MEMMAP | 25 | #ifdef CONFIG_FIRMWARE_MEMMAP |
26 | 26 | ||
27 | int firmware_map_add(resource_size_t start, resource_size_t end, | 27 | int firmware_map_add(u64 start, u64 end, const char *type); |
28 | const char *type); | 28 | int firmware_map_add_early(u64 start, u64 end, const char *type); |
29 | int firmware_map_add_early(resource_size_t start, resource_size_t end, | ||
30 | const char *type); | ||
31 | 29 | ||
32 | #else /* CONFIG_FIRMWARE_MEMMAP */ | 30 | #else /* CONFIG_FIRMWARE_MEMMAP */ |
33 | 31 | ||
34 | static inline int firmware_map_add(resource_size_t start, resource_size_t end, | 32 | static inline int firmware_map_add(u64 start, u64 end, const char *type) |
35 | const char *type) | ||
36 | { | 33 | { |
37 | return 0; | 34 | return 0; |
38 | } | 35 | } |
39 | 36 | ||
40 | static inline int firmware_map_add_early(resource_size_t start, | 37 | static inline int firmware_map_add_early(u64 start, u64 end, const char *type) |
41 | resource_size_t end, const char *type) | ||
42 | { | 38 | { |
43 | return 0; | 39 | return 0; |
44 | } | 40 | } |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 6d12174fbe11..74a57938c880 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -879,7 +879,7 @@ struct file_ra_state { | |||
879 | there are only # of pages ahead */ | 879 | there are only # of pages ahead */ |
880 | 880 | ||
881 | unsigned int ra_pages; /* Maximum readahead window */ | 881 | unsigned int ra_pages; /* Maximum readahead window */ |
882 | int mmap_miss; /* Cache miss stat for mmap accesses */ | 882 | unsigned int mmap_miss; /* Cache miss stat for mmap accesses */ |
883 | loff_t prev_pos; /* Cache last read() position */ | 883 | loff_t prev_pos; /* Cache last read() position */ |
884 | }; | 884 | }; |
885 | 885 | ||
@@ -2037,9 +2037,6 @@ extern int __invalidate_device(struct block_device *); | |||
2037 | extern int invalidate_partition(struct gendisk *, int); | 2037 | extern int invalidate_partition(struct gendisk *, int); |
2038 | #endif | 2038 | #endif |
2039 | extern int invalidate_inodes(struct super_block *); | 2039 | extern int invalidate_inodes(struct super_block *); |
2040 | unsigned long __invalidate_mapping_pages(struct address_space *mapping, | ||
2041 | pgoff_t start, pgoff_t end, | ||
2042 | bool be_atomic); | ||
2043 | unsigned long invalidate_mapping_pages(struct address_space *mapping, | 2040 | unsigned long invalidate_mapping_pages(struct address_space *mapping, |
2044 | pgoff_t start, pgoff_t end); | 2041 | pgoff_t start, pgoff_t end); |
2045 | 2042 | ||
diff --git a/include/linux/gfp.h b/include/linux/gfp.h index 80e14b8c2e78..cfdb35d71bca 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h | |||
@@ -5,6 +5,7 @@ | |||
5 | #include <linux/stddef.h> | 5 | #include <linux/stddef.h> |
6 | #include <linux/linkage.h> | 6 | #include <linux/linkage.h> |
7 | #include <linux/topology.h> | 7 | #include <linux/topology.h> |
8 | #include <linux/mmdebug.h> | ||
8 | 9 | ||
9 | struct vm_area_struct; | 10 | struct vm_area_struct; |
10 | 11 | ||
@@ -20,7 +21,8 @@ struct vm_area_struct; | |||
20 | #define __GFP_DMA ((__force gfp_t)0x01u) | 21 | #define __GFP_DMA ((__force gfp_t)0x01u) |
21 | #define __GFP_HIGHMEM ((__force gfp_t)0x02u) | 22 | #define __GFP_HIGHMEM ((__force gfp_t)0x02u) |
22 | #define __GFP_DMA32 ((__force gfp_t)0x04u) | 23 | #define __GFP_DMA32 ((__force gfp_t)0x04u) |
23 | 24 | #define __GFP_MOVABLE ((__force gfp_t)0x08u) /* Page is movable */ | |
25 | #define GFP_ZONEMASK (__GFP_DMA|__GFP_HIGHMEM|__GFP_DMA32|__GFP_MOVABLE) | ||
24 | /* | 26 | /* |
25 | * Action modifiers - doesn't change the zoning | 27 | * Action modifiers - doesn't change the zoning |
26 | * | 28 | * |
@@ -50,7 +52,6 @@ struct vm_area_struct; | |||
50 | #define __GFP_HARDWALL ((__force gfp_t)0x20000u) /* Enforce hardwall cpuset memory allocs */ | 52 | #define __GFP_HARDWALL ((__force gfp_t)0x20000u) /* Enforce hardwall cpuset memory allocs */ |
51 | #define __GFP_THISNODE ((__force gfp_t)0x40000u)/* No fallback, no policies */ | 53 | #define __GFP_THISNODE ((__force gfp_t)0x40000u)/* No fallback, no policies */ |
52 | #define __GFP_RECLAIMABLE ((__force gfp_t)0x80000u) /* Page is reclaimable */ | 54 | #define __GFP_RECLAIMABLE ((__force gfp_t)0x80000u) /* Page is reclaimable */ |
53 | #define __GFP_MOVABLE ((__force gfp_t)0x100000u) /* Page is movable */ | ||
54 | 55 | ||
55 | #ifdef CONFIG_KMEMCHECK | 56 | #ifdef CONFIG_KMEMCHECK |
56 | #define __GFP_NOTRACK ((__force gfp_t)0x200000u) /* Don't track with kmemcheck */ | 57 | #define __GFP_NOTRACK ((__force gfp_t)0x200000u) /* Don't track with kmemcheck */ |
@@ -127,24 +128,105 @@ static inline int allocflags_to_migratetype(gfp_t gfp_flags) | |||
127 | ((gfp_flags & __GFP_RECLAIMABLE) != 0); | 128 | ((gfp_flags & __GFP_RECLAIMABLE) != 0); |
128 | } | 129 | } |
129 | 130 | ||
130 | static inline enum zone_type gfp_zone(gfp_t flags) | 131 | #ifdef CONFIG_HIGHMEM |
131 | { | 132 | #define OPT_ZONE_HIGHMEM ZONE_HIGHMEM |
133 | #else | ||
134 | #define OPT_ZONE_HIGHMEM ZONE_NORMAL | ||
135 | #endif | ||
136 | |||
132 | #ifdef CONFIG_ZONE_DMA | 137 | #ifdef CONFIG_ZONE_DMA |
133 | if (flags & __GFP_DMA) | 138 | #define OPT_ZONE_DMA ZONE_DMA |
134 | return ZONE_DMA; | 139 | #else |
140 | #define OPT_ZONE_DMA ZONE_NORMAL | ||
135 | #endif | 141 | #endif |
142 | |||
136 | #ifdef CONFIG_ZONE_DMA32 | 143 | #ifdef CONFIG_ZONE_DMA32 |
137 | if (flags & __GFP_DMA32) | 144 | #define OPT_ZONE_DMA32 ZONE_DMA32 |
138 | return ZONE_DMA32; | 145 | #else |
146 | #define OPT_ZONE_DMA32 ZONE_NORMAL | ||
139 | #endif | 147 | #endif |
140 | if ((flags & (__GFP_HIGHMEM | __GFP_MOVABLE)) == | 148 | |
141 | (__GFP_HIGHMEM | __GFP_MOVABLE)) | 149 | /* |
142 | return ZONE_MOVABLE; | 150 | * GFP_ZONE_TABLE is a word size bitstring that is used for looking up the |
143 | #ifdef CONFIG_HIGHMEM | 151 | * zone to use given the lowest 4 bits of gfp_t. Entries are ZONE_SHIFT long |
144 | if (flags & __GFP_HIGHMEM) | 152 | * and there are 16 of them to cover all possible combinations of |
145 | return ZONE_HIGHMEM; | 153 | * __GFP_DMA, __GFP_DMA32, __GFP_MOVABLE and __GFP_HIGHMEM |
154 | * | ||
155 | * The zone fallback order is MOVABLE=>HIGHMEM=>NORMAL=>DMA32=>DMA. | ||
156 | * But GFP_MOVABLE is not only a zone specifier but also an allocation | ||
157 | * policy. Therefore __GFP_MOVABLE plus another zone selector is valid. | ||
158 | * Only 1bit of the lowest 3 bit (DMA,DMA32,HIGHMEM) can be set to "1". | ||
159 | * | ||
160 | * bit result | ||
161 | * ================= | ||
162 | * 0x0 => NORMAL | ||
163 | * 0x1 => DMA or NORMAL | ||
164 | * 0x2 => HIGHMEM or NORMAL | ||
165 | * 0x3 => BAD (DMA+HIGHMEM) | ||
166 | * 0x4 => DMA32 or DMA or NORMAL | ||
167 | * 0x5 => BAD (DMA+DMA32) | ||
168 | * 0x6 => BAD (HIGHMEM+DMA32) | ||
169 | * 0x7 => BAD (HIGHMEM+DMA32+DMA) | ||
170 | * 0x8 => NORMAL (MOVABLE+0) | ||
171 | * 0x9 => DMA or NORMAL (MOVABLE+DMA) | ||
172 | * 0xa => MOVABLE (Movable is valid only if HIGHMEM is set too) | ||
173 | * 0xb => BAD (MOVABLE+HIGHMEM+DMA) | ||
174 | * 0xc => DMA32 (MOVABLE+HIGHMEM+DMA32) | ||
175 | * 0xd => BAD (MOVABLE+DMA32+DMA) | ||
176 | * 0xe => BAD (MOVABLE+DMA32+HIGHMEM) | ||
177 | * 0xf => BAD (MOVABLE+DMA32+HIGHMEM+DMA) | ||
178 | * | ||
179 | * ZONES_SHIFT must be <= 2 on 32 bit platforms. | ||
180 | */ | ||
181 | |||
182 | #if 16 * ZONES_SHIFT > BITS_PER_LONG | ||
183 | #error ZONES_SHIFT too large to create GFP_ZONE_TABLE integer | ||
184 | #endif | ||
185 | |||
186 | #define GFP_ZONE_TABLE ( \ | ||
187 | (ZONE_NORMAL << 0 * ZONES_SHIFT) \ | ||
188 | | (OPT_ZONE_DMA << __GFP_DMA * ZONES_SHIFT) \ | ||
189 | | (OPT_ZONE_HIGHMEM << __GFP_HIGHMEM * ZONES_SHIFT) \ | ||
190 | | (OPT_ZONE_DMA32 << __GFP_DMA32 * ZONES_SHIFT) \ | ||
191 | | (ZONE_NORMAL << __GFP_MOVABLE * ZONES_SHIFT) \ | ||
192 | | (OPT_ZONE_DMA << (__GFP_MOVABLE | __GFP_DMA) * ZONES_SHIFT) \ | ||
193 | | (ZONE_MOVABLE << (__GFP_MOVABLE | __GFP_HIGHMEM) * ZONES_SHIFT)\ | ||
194 | | (OPT_ZONE_DMA32 << (__GFP_MOVABLE | __GFP_DMA32) * ZONES_SHIFT)\ | ||
195 | ) | ||
196 | |||
197 | /* | ||
198 | * GFP_ZONE_BAD is a bitmap for all combination of __GFP_DMA, __GFP_DMA32 | ||
199 | * __GFP_HIGHMEM and __GFP_MOVABLE that are not permitted. One flag per | ||
200 | * entry starting with bit 0. Bit is set if the combination is not | ||
201 | * allowed. | ||
202 | */ | ||
203 | #define GFP_ZONE_BAD ( \ | ||
204 | 1 << (__GFP_DMA | __GFP_HIGHMEM) \ | ||
205 | | 1 << (__GFP_DMA | __GFP_DMA32) \ | ||
206 | | 1 << (__GFP_DMA32 | __GFP_HIGHMEM) \ | ||
207 | | 1 << (__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM) \ | ||
208 | | 1 << (__GFP_MOVABLE | __GFP_HIGHMEM | __GFP_DMA) \ | ||
209 | | 1 << (__GFP_MOVABLE | __GFP_DMA32 | __GFP_DMA) \ | ||
210 | | 1 << (__GFP_MOVABLE | __GFP_DMA32 | __GFP_HIGHMEM) \ | ||
211 | | 1 << (__GFP_MOVABLE | __GFP_DMA32 | __GFP_DMA | __GFP_HIGHMEM)\ | ||
212 | ) | ||
213 | |||
214 | static inline enum zone_type gfp_zone(gfp_t flags) | ||
215 | { | ||
216 | enum zone_type z; | ||
217 | int bit = flags & GFP_ZONEMASK; | ||
218 | |||
219 | z = (GFP_ZONE_TABLE >> (bit * ZONES_SHIFT)) & | ||
220 | ((1 << ZONES_SHIFT) - 1); | ||
221 | |||
222 | if (__builtin_constant_p(bit)) | ||
223 | BUILD_BUG_ON((GFP_ZONE_BAD >> bit) & 1); | ||
224 | else { | ||
225 | #ifdef CONFIG_DEBUG_VM | ||
226 | BUG_ON((GFP_ZONE_BAD >> bit) & 1); | ||
146 | #endif | 227 | #endif |
147 | return ZONE_NORMAL; | 228 | } |
229 | return z; | ||
148 | } | 230 | } |
149 | 231 | ||
150 | /* | 232 | /* |
@@ -184,30 +266,19 @@ static inline void arch_alloc_page(struct page *page, int order) { } | |||
184 | #endif | 266 | #endif |
185 | 267 | ||
186 | struct page * | 268 | struct page * |
187 | __alloc_pages_internal(gfp_t gfp_mask, unsigned int order, | 269 | __alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order, |
188 | struct zonelist *zonelist, nodemask_t *nodemask); | 270 | struct zonelist *zonelist, nodemask_t *nodemask); |
189 | 271 | ||
190 | static inline struct page * | 272 | static inline struct page * |
191 | __alloc_pages(gfp_t gfp_mask, unsigned int order, | 273 | __alloc_pages(gfp_t gfp_mask, unsigned int order, |
192 | struct zonelist *zonelist) | 274 | struct zonelist *zonelist) |
193 | { | 275 | { |
194 | return __alloc_pages_internal(gfp_mask, order, zonelist, NULL); | 276 | return __alloc_pages_nodemask(gfp_mask, order, zonelist, NULL); |
195 | } | 277 | } |
196 | 278 | ||
197 | static inline struct page * | ||
198 | __alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order, | ||
199 | struct zonelist *zonelist, nodemask_t *nodemask) | ||
200 | { | ||
201 | return __alloc_pages_internal(gfp_mask, order, zonelist, nodemask); | ||
202 | } | ||
203 | |||
204 | |||
205 | static inline struct page *alloc_pages_node(int nid, gfp_t gfp_mask, | 279 | static inline struct page *alloc_pages_node(int nid, gfp_t gfp_mask, |
206 | unsigned int order) | 280 | unsigned int order) |
207 | { | 281 | { |
208 | if (unlikely(order >= MAX_ORDER)) | ||
209 | return NULL; | ||
210 | |||
211 | /* Unknown node is current node */ | 282 | /* Unknown node is current node */ |
212 | if (nid < 0) | 283 | if (nid < 0) |
213 | nid = numa_node_id(); | 284 | nid = numa_node_id(); |
@@ -215,15 +286,20 @@ static inline struct page *alloc_pages_node(int nid, gfp_t gfp_mask, | |||
215 | return __alloc_pages(gfp_mask, order, node_zonelist(nid, gfp_mask)); | 286 | return __alloc_pages(gfp_mask, order, node_zonelist(nid, gfp_mask)); |
216 | } | 287 | } |
217 | 288 | ||
289 | static inline struct page *alloc_pages_exact_node(int nid, gfp_t gfp_mask, | ||
290 | unsigned int order) | ||
291 | { | ||
292 | VM_BUG_ON(nid < 0 || nid >= MAX_NUMNODES); | ||
293 | |||
294 | return __alloc_pages(gfp_mask, order, node_zonelist(nid, gfp_mask)); | ||
295 | } | ||
296 | |||
218 | #ifdef CONFIG_NUMA | 297 | #ifdef CONFIG_NUMA |
219 | extern struct page *alloc_pages_current(gfp_t gfp_mask, unsigned order); | 298 | extern struct page *alloc_pages_current(gfp_t gfp_mask, unsigned order); |
220 | 299 | ||
221 | static inline struct page * | 300 | static inline struct page * |
222 | alloc_pages(gfp_t gfp_mask, unsigned int order) | 301 | alloc_pages(gfp_t gfp_mask, unsigned int order) |
223 | { | 302 | { |
224 | if (unlikely(order >= MAX_ORDER)) | ||
225 | return NULL; | ||
226 | |||
227 | return alloc_pages_current(gfp_mask, order); | 303 | return alloc_pages_current(gfp_mask, order); |
228 | } | 304 | } |
229 | extern struct page *alloc_page_vma(gfp_t gfp_mask, | 305 | extern struct page *alloc_page_vma(gfp_t gfp_mask, |
@@ -260,4 +336,16 @@ void drain_zone_pages(struct zone *zone, struct per_cpu_pages *pcp); | |||
260 | void drain_all_pages(void); | 336 | void drain_all_pages(void); |
261 | void drain_local_pages(void *dummy); | 337 | void drain_local_pages(void *dummy); |
262 | 338 | ||
339 | extern bool oom_killer_disabled; | ||
340 | |||
341 | static inline void oom_killer_disable(void) | ||
342 | { | ||
343 | oom_killer_disabled = true; | ||
344 | } | ||
345 | |||
346 | static inline void oom_killer_enable(void) | ||
347 | { | ||
348 | oom_killer_disabled = false; | ||
349 | } | ||
350 | |||
263 | #endif /* __LINUX_GFP_H */ | 351 | #endif /* __LINUX_GFP_H */ |
diff --git a/include/linux/highmem.h b/include/linux/highmem.h index 1fcb7126a01f..211ff4497269 100644 --- a/include/linux/highmem.h +++ b/include/linux/highmem.h | |||
@@ -55,7 +55,9 @@ static inline void *kmap(struct page *page) | |||
55 | return page_address(page); | 55 | return page_address(page); |
56 | } | 56 | } |
57 | 57 | ||
58 | #define kunmap(page) do { (void) (page); } while (0) | 58 | static inline void kunmap(struct page *page) |
59 | { | ||
60 | } | ||
59 | 61 | ||
60 | static inline void *kmap_atomic(struct page *page, enum km_type idx) | 62 | static inline void *kmap_atomic(struct page *page, enum km_type idx) |
61 | { | 63 | { |
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index 03be7f29ca01..a05a5ef33391 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h | |||
@@ -11,6 +11,8 @@ | |||
11 | 11 | ||
12 | struct ctl_table; | 12 | struct ctl_table; |
13 | 13 | ||
14 | int PageHuge(struct page *page); | ||
15 | |||
14 | static inline int is_vm_hugetlb_page(struct vm_area_struct *vma) | 16 | static inline int is_vm_hugetlb_page(struct vm_area_struct *vma) |
15 | { | 17 | { |
16 | return vma->vm_flags & VM_HUGETLB; | 18 | return vma->vm_flags & VM_HUGETLB; |
@@ -61,6 +63,11 @@ void hugetlb_change_protection(struct vm_area_struct *vma, | |||
61 | 63 | ||
62 | #else /* !CONFIG_HUGETLB_PAGE */ | 64 | #else /* !CONFIG_HUGETLB_PAGE */ |
63 | 65 | ||
66 | static inline int PageHuge(struct page *page) | ||
67 | { | ||
68 | return 0; | ||
69 | } | ||
70 | |||
64 | static inline int is_vm_hugetlb_page(struct vm_area_struct *vma) | 71 | static inline int is_vm_hugetlb_page(struct vm_area_struct *vma) |
65 | { | 72 | { |
66 | return 0; | 73 | return 0; |
diff --git a/include/linux/init.h b/include/linux/init.h index b2189803f19a..8c2c9989626d 100644 --- a/include/linux/init.h +++ b/include/linux/init.h | |||
@@ -29,7 +29,7 @@ | |||
29 | * sign followed by value, e.g.: | 29 | * sign followed by value, e.g.: |
30 | * | 30 | * |
31 | * static int init_variable __initdata = 0; | 31 | * static int init_variable __initdata = 0; |
32 | * static char linux_logo[] __initdata = { 0x32, 0x36, ... }; | 32 | * static const char linux_logo[] __initconst = { 0x32, 0x36, ... }; |
33 | * | 33 | * |
34 | * Don't forget to initialize data not at file scope, i.e. within a function, | 34 | * Don't forget to initialize data not at file scope, i.e. within a function, |
35 | * as gcc otherwise puts the data into the bss section and not into the init | 35 | * as gcc otherwise puts the data into the bss section and not into the init |
diff --git a/include/linux/init_task.h b/include/linux/init_task.h index 28b1f30601b5..5368fbdc7801 100644 --- a/include/linux/init_task.h +++ b/include/linux/init_task.h | |||
@@ -15,18 +15,6 @@ | |||
15 | extern struct files_struct init_files; | 15 | extern struct files_struct init_files; |
16 | extern struct fs_struct init_fs; | 16 | extern struct fs_struct init_fs; |
17 | 17 | ||
18 | #define INIT_MM(name) \ | ||
19 | { \ | ||
20 | .mm_rb = RB_ROOT, \ | ||
21 | .pgd = swapper_pg_dir, \ | ||
22 | .mm_users = ATOMIC_INIT(2), \ | ||
23 | .mm_count = ATOMIC_INIT(1), \ | ||
24 | .mmap_sem = __RWSEM_INITIALIZER(name.mmap_sem), \ | ||
25 | .page_table_lock = __SPIN_LOCK_UNLOCKED(name.page_table_lock), \ | ||
26 | .mmlist = LIST_HEAD_INIT(name.mmlist), \ | ||
27 | .cpu_vm_mask = CPU_MASK_ALL, \ | ||
28 | } | ||
29 | |||
30 | #define INIT_SIGNALS(sig) { \ | 18 | #define INIT_SIGNALS(sig) { \ |
31 | .count = ATOMIC_INIT(1), \ | 19 | .count = ATOMIC_INIT(1), \ |
32 | .wait_chldexit = __WAIT_QUEUE_HEAD_INITIALIZER(sig.wait_chldexit),\ | 20 | .wait_chldexit = __WAIT_QUEUE_HEAD_INITIALIZER(sig.wait_chldexit),\ |
diff --git a/include/linux/linux_logo.h b/include/linux/linux_logo.h index 08a92969c76e..ca5bd91d12e1 100644 --- a/include/linux/linux_logo.h +++ b/include/linux/linux_logo.h | |||
@@ -32,6 +32,22 @@ struct linux_logo { | |||
32 | const unsigned char *data; | 32 | const unsigned char *data; |
33 | }; | 33 | }; |
34 | 34 | ||
35 | extern const struct linux_logo logo_linux_mono; | ||
36 | extern const struct linux_logo logo_linux_vga16; | ||
37 | extern const struct linux_logo logo_linux_clut224; | ||
38 | extern const struct linux_logo logo_blackfin_vga16; | ||
39 | extern const struct linux_logo logo_blackfin_clut224; | ||
40 | extern const struct linux_logo logo_dec_clut224; | ||
41 | extern const struct linux_logo logo_mac_clut224; | ||
42 | extern const struct linux_logo logo_parisc_clut224; | ||
43 | extern const struct linux_logo logo_sgi_clut224; | ||
44 | extern const struct linux_logo logo_sun_clut224; | ||
45 | extern const struct linux_logo logo_superh_mono; | ||
46 | extern const struct linux_logo logo_superh_vga16; | ||
47 | extern const struct linux_logo logo_superh_clut224; | ||
48 | extern const struct linux_logo logo_m32r_clut224; | ||
49 | extern const struct linux_logo logo_spe_clut224; | ||
50 | |||
35 | extern const struct linux_logo *fb_find_logo(int depth); | 51 | extern const struct linux_logo *fb_find_logo(int depth); |
36 | #ifdef CONFIG_FB_LOGO_EXTRA | 52 | #ifdef CONFIG_FB_LOGO_EXTRA |
37 | extern void fb_append_extra_logo(const struct linux_logo *logo, | 53 | extern void fb_append_extra_logo(const struct linux_logo *logo, |
diff --git a/include/linux/lis3lv02d.h b/include/linux/lis3lv02d.h new file mode 100644 index 000000000000..ad651f4e45ac --- /dev/null +++ b/include/linux/lis3lv02d.h | |||
@@ -0,0 +1,39 @@ | |||
1 | #ifndef __LIS3LV02D_H_ | ||
2 | #define __LIS3LV02D_H_ | ||
3 | |||
4 | struct lis3lv02d_platform_data { | ||
5 | /* please note: the 'click' feature is only supported for | ||
6 | * LIS[32]02DL variants of the chip and will be ignored for | ||
7 | * others */ | ||
8 | #define LIS3_CLICK_SINGLE_X (1 << 0) | ||
9 | #define LIS3_CLICK_DOUBLE_X (1 << 1) | ||
10 | #define LIS3_CLICK_SINGLE_Y (1 << 2) | ||
11 | #define LIS3_CLICK_DOUBLE_Y (1 << 3) | ||
12 | #define LIS3_CLICK_SINGLE_Z (1 << 4) | ||
13 | #define LIS3_CLICK_DOUBLE_Z (1 << 5) | ||
14 | unsigned char click_flags; | ||
15 | unsigned char click_thresh_x; | ||
16 | unsigned char click_thresh_y; | ||
17 | unsigned char click_thresh_z; | ||
18 | unsigned char click_time_limit; | ||
19 | unsigned char click_latency; | ||
20 | unsigned char click_window; | ||
21 | |||
22 | #define LIS3_IRQ1_DISABLE (0 << 0) | ||
23 | #define LIS3_IRQ1_FF_WU_1 (1 << 0) | ||
24 | #define LIS3_IRQ1_FF_WU_2 (2 << 0) | ||
25 | #define LIS3_IRQ1_FF_WU_12 (3 << 0) | ||
26 | #define LIS3_IRQ1_DATA_READY (4 << 0) | ||
27 | #define LIS3_IRQ1_CLICK (7 << 0) | ||
28 | #define LIS3_IRQ2_DISABLE (0 << 3) | ||
29 | #define LIS3_IRQ2_FF_WU_1 (1 << 3) | ||
30 | #define LIS3_IRQ2_FF_WU_2 (2 << 3) | ||
31 | #define LIS3_IRQ2_FF_WU_12 (3 << 3) | ||
32 | #define LIS3_IRQ2_DATA_READY (4 << 3) | ||
33 | #define LIS3_IRQ2_CLICK (7 << 3) | ||
34 | #define LIS3_IRQ_OPEN_DRAIN (1 << 6) | ||
35 | #define LIS3_IRQ_ACTIVE_HIGH (1 << 7) | ||
36 | unsigned char irq_cfg; | ||
37 | }; | ||
38 | |||
39 | #endif /* __LIS3LV02D_H_ */ | ||
diff --git a/include/linux/major.h b/include/linux/major.h index 058ec15dd060..6a8ca98c9a96 100644 --- a/include/linux/major.h +++ b/include/linux/major.h | |||
@@ -145,6 +145,7 @@ | |||
145 | #define UNIX98_PTY_MAJOR_COUNT 8 | 145 | #define UNIX98_PTY_MAJOR_COUNT 8 |
146 | #define UNIX98_PTY_SLAVE_MAJOR (UNIX98_PTY_MASTER_MAJOR+UNIX98_PTY_MAJOR_COUNT) | 146 | #define UNIX98_PTY_SLAVE_MAJOR (UNIX98_PTY_MASTER_MAJOR+UNIX98_PTY_MAJOR_COUNT) |
147 | 147 | ||
148 | #define DRBD_MAJOR 147 | ||
148 | #define RTF_MAJOR 150 | 149 | #define RTF_MAJOR 150 |
149 | #define RAW_MAJOR 162 | 150 | #define RAW_MAJOR 162 |
150 | 151 | ||
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 25b9ca93d232..45add35dda1b 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h | |||
@@ -94,6 +94,7 @@ extern void mem_cgroup_note_reclaim_priority(struct mem_cgroup *mem, | |||
94 | extern void mem_cgroup_record_reclaim_priority(struct mem_cgroup *mem, | 94 | extern void mem_cgroup_record_reclaim_priority(struct mem_cgroup *mem, |
95 | int priority); | 95 | int priority); |
96 | int mem_cgroup_inactive_anon_is_low(struct mem_cgroup *memcg); | 96 | int mem_cgroup_inactive_anon_is_low(struct mem_cgroup *memcg); |
97 | int mem_cgroup_inactive_file_is_low(struct mem_cgroup *memcg); | ||
97 | unsigned long mem_cgroup_zone_nr_pages(struct mem_cgroup *memcg, | 98 | unsigned long mem_cgroup_zone_nr_pages(struct mem_cgroup *memcg, |
98 | struct zone *zone, | 99 | struct zone *zone, |
99 | enum lru_list lru); | 100 | enum lru_list lru); |
@@ -239,6 +240,12 @@ mem_cgroup_inactive_anon_is_low(struct mem_cgroup *memcg) | |||
239 | return 1; | 240 | return 1; |
240 | } | 241 | } |
241 | 242 | ||
243 | static inline int | ||
244 | mem_cgroup_inactive_file_is_low(struct mem_cgroup *memcg) | ||
245 | { | ||
246 | return 1; | ||
247 | } | ||
248 | |||
242 | static inline unsigned long | 249 | static inline unsigned long |
243 | mem_cgroup_zone_nr_pages(struct mem_cgroup *memcg, struct zone *zone, | 250 | mem_cgroup_zone_nr_pages(struct mem_cgroup *memcg, struct zone *zone, |
244 | enum lru_list lru) | 251 | enum lru_list lru) |
diff --git a/include/linux/mm.h b/include/linux/mm.h index ad613ed66ab0..d88d6fc530ad 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
@@ -7,7 +7,6 @@ | |||
7 | 7 | ||
8 | #include <linux/gfp.h> | 8 | #include <linux/gfp.h> |
9 | #include <linux/list.h> | 9 | #include <linux/list.h> |
10 | #include <linux/mmdebug.h> | ||
11 | #include <linux/mmzone.h> | 10 | #include <linux/mmzone.h> |
12 | #include <linux/rbtree.h> | 11 | #include <linux/rbtree.h> |
13 | #include <linux/prio_tree.h> | 12 | #include <linux/prio_tree.h> |
@@ -725,7 +724,7 @@ static inline int shmem_lock(struct file *file, int lock, | |||
725 | return 0; | 724 | return 0; |
726 | } | 725 | } |
727 | #endif | 726 | #endif |
728 | struct file *shmem_file_setup(char *name, loff_t size, unsigned long flags); | 727 | struct file *shmem_file_setup(const char *name, loff_t size, unsigned long flags); |
729 | 728 | ||
730 | int shmem_zero_setup(struct vm_area_struct *); | 729 | int shmem_zero_setup(struct vm_area_struct *); |
731 | 730 | ||
@@ -793,6 +792,8 @@ int copy_page_range(struct mm_struct *dst, struct mm_struct *src, | |||
793 | struct vm_area_struct *vma); | 792 | struct vm_area_struct *vma); |
794 | void unmap_mapping_range(struct address_space *mapping, | 793 | void unmap_mapping_range(struct address_space *mapping, |
795 | loff_t const holebegin, loff_t const holelen, int even_cows); | 794 | loff_t const holebegin, loff_t const holelen, int even_cows); |
795 | int follow_pfn(struct vm_area_struct *vma, unsigned long address, | ||
796 | unsigned long *pfn); | ||
796 | int follow_phys(struct vm_area_struct *vma, unsigned long address, | 797 | int follow_phys(struct vm_area_struct *vma, unsigned long address, |
797 | unsigned int flags, unsigned long *prot, resource_size_t *phys); | 798 | unsigned int flags, unsigned long *prot, resource_size_t *phys); |
798 | int generic_access_phys(struct vm_area_struct *vma, unsigned long addr, | 799 | int generic_access_phys(struct vm_area_struct *vma, unsigned long addr, |
@@ -824,8 +825,11 @@ static inline int handle_mm_fault(struct mm_struct *mm, | |||
824 | extern int make_pages_present(unsigned long addr, unsigned long end); | 825 | extern int make_pages_present(unsigned long addr, unsigned long end); |
825 | extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write); | 826 | extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write); |
826 | 827 | ||
827 | int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, unsigned long start, | 828 | int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, |
828 | int len, int write, int force, struct page **pages, struct vm_area_struct **vmas); | 829 | unsigned long start, int len, int write, int force, |
830 | struct page **pages, struct vm_area_struct **vmas); | ||
831 | int get_user_pages_fast(unsigned long start, int nr_pages, int write, | ||
832 | struct page **pages); | ||
829 | 833 | ||
830 | extern int try_to_release_page(struct page * page, gfp_t gfp_mask); | 834 | extern int try_to_release_page(struct page * page, gfp_t gfp_mask); |
831 | extern void do_invalidatepage(struct page *page, unsigned long offset); | 835 | extern void do_invalidatepage(struct page *page, unsigned long offset); |
@@ -850,19 +854,6 @@ extern int mprotect_fixup(struct vm_area_struct *vma, | |||
850 | unsigned long end, unsigned long newflags); | 854 | unsigned long end, unsigned long newflags); |
851 | 855 | ||
852 | /* | 856 | /* |
853 | * get_user_pages_fast provides equivalent functionality to get_user_pages, | ||
854 | * operating on current and current->mm (force=0 and doesn't return any vmas). | ||
855 | * | ||
856 | * get_user_pages_fast may take mmap_sem and page tables, so no assumptions | ||
857 | * can be made about locking. get_user_pages_fast is to be implemented in a | ||
858 | * way that is advantageous (vs get_user_pages()) when the user memory area is | ||
859 | * already faulted in and present in ptes. However if the pages have to be | ||
860 | * faulted in, it may turn out to be slightly slower). | ||
861 | */ | ||
862 | int get_user_pages_fast(unsigned long start, int nr_pages, int write, | ||
863 | struct page **pages); | ||
864 | |||
865 | /* | ||
866 | * A callback you can register to apply pressure to ageable caches. | 857 | * A callback you can register to apply pressure to ageable caches. |
867 | * | 858 | * |
868 | * 'shrink' is passed a count 'nr_to_scan' and a 'gfpmask'. It should | 859 | * 'shrink' is passed a count 'nr_to_scan' and a 'gfpmask'. It should |
@@ -1061,7 +1052,8 @@ extern int __meminit __early_pfn_to_nid(unsigned long pfn); | |||
1061 | extern void set_dma_reserve(unsigned long new_dma_reserve); | 1052 | extern void set_dma_reserve(unsigned long new_dma_reserve); |
1062 | extern void memmap_init_zone(unsigned long, int, unsigned long, | 1053 | extern void memmap_init_zone(unsigned long, int, unsigned long, |
1063 | unsigned long, enum memmap_context); | 1054 | unsigned long, enum memmap_context); |
1064 | extern void setup_per_zone_pages_min(void); | 1055 | extern void setup_per_zone_wmarks(void); |
1056 | extern void calculate_zone_inactive_ratio(struct zone *zone); | ||
1065 | extern void mem_init(void); | 1057 | extern void mem_init(void); |
1066 | extern void __init mmap_init(void); | 1058 | extern void __init mmap_init(void); |
1067 | extern void show_mem(void); | 1059 | extern void show_mem(void); |
@@ -1178,8 +1170,6 @@ void task_dirty_inc(struct task_struct *tsk); | |||
1178 | #define VM_MAX_READAHEAD 128 /* kbytes */ | 1170 | #define VM_MAX_READAHEAD 128 /* kbytes */ |
1179 | #define VM_MIN_READAHEAD 16 /* kbytes (includes current page) */ | 1171 | #define VM_MIN_READAHEAD 16 /* kbytes (includes current page) */ |
1180 | 1172 | ||
1181 | int do_page_cache_readahead(struct address_space *mapping, struct file *filp, | ||
1182 | pgoff_t offset, unsigned long nr_to_read); | ||
1183 | int force_page_cache_readahead(struct address_space *mapping, struct file *filp, | 1173 | int force_page_cache_readahead(struct address_space *mapping, struct file *filp, |
1184 | pgoff_t offset, unsigned long nr_to_read); | 1174 | pgoff_t offset, unsigned long nr_to_read); |
1185 | 1175 | ||
@@ -1197,6 +1187,9 @@ void page_cache_async_readahead(struct address_space *mapping, | |||
1197 | unsigned long size); | 1187 | unsigned long size); |
1198 | 1188 | ||
1199 | unsigned long max_sane_readahead(unsigned long nr); | 1189 | unsigned long max_sane_readahead(unsigned long nr); |
1190 | unsigned long ra_submit(struct file_ra_state *ra, | ||
1191 | struct address_space *mapping, | ||
1192 | struct file *filp); | ||
1200 | 1193 | ||
1201 | /* Do stack extension */ | 1194 | /* Do stack extension */ |
1202 | extern int expand_stack(struct vm_area_struct *vma, unsigned long address); | 1195 | extern int expand_stack(struct vm_area_struct *vma, unsigned long address); |
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 0042090a4d70..7acc8439d9b3 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h | |||
@@ -240,6 +240,8 @@ struct mm_struct { | |||
240 | 240 | ||
241 | unsigned long saved_auxv[AT_VECTOR_SIZE]; /* for /proc/PID/auxv */ | 241 | unsigned long saved_auxv[AT_VECTOR_SIZE]; /* for /proc/PID/auxv */ |
242 | 242 | ||
243 | s8 oom_adj; /* OOM kill score adjustment (bit shift) */ | ||
244 | |||
243 | cpumask_t cpu_vm_mask; | 245 | cpumask_t cpu_vm_mask; |
244 | 246 | ||
245 | /* Architecture-specific MM context */ | 247 | /* Architecture-specific MM context */ |
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index a47c879e1304..889598537370 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h | |||
@@ -50,9 +50,6 @@ extern int page_group_by_mobility_disabled; | |||
50 | 50 | ||
51 | static inline int get_pageblock_migratetype(struct page *page) | 51 | static inline int get_pageblock_migratetype(struct page *page) |
52 | { | 52 | { |
53 | if (unlikely(page_group_by_mobility_disabled)) | ||
54 | return MIGRATE_UNMOVABLE; | ||
55 | |||
56 | return get_pageblock_flags_group(page, PB_migrate, PB_migrate_end); | 53 | return get_pageblock_flags_group(page, PB_migrate, PB_migrate_end); |
57 | } | 54 | } |
58 | 55 | ||
@@ -86,13 +83,8 @@ enum zone_stat_item { | |||
86 | NR_ACTIVE_ANON, /* " " " " " */ | 83 | NR_ACTIVE_ANON, /* " " " " " */ |
87 | NR_INACTIVE_FILE, /* " " " " " */ | 84 | NR_INACTIVE_FILE, /* " " " " " */ |
88 | NR_ACTIVE_FILE, /* " " " " " */ | 85 | NR_ACTIVE_FILE, /* " " " " " */ |
89 | #ifdef CONFIG_UNEVICTABLE_LRU | ||
90 | NR_UNEVICTABLE, /* " " " " " */ | 86 | NR_UNEVICTABLE, /* " " " " " */ |
91 | NR_MLOCK, /* mlock()ed pages found and moved off LRU */ | 87 | NR_MLOCK, /* mlock()ed pages found and moved off LRU */ |
92 | #else | ||
93 | NR_UNEVICTABLE = NR_ACTIVE_FILE, /* avoid compiler errors in dead code */ | ||
94 | NR_MLOCK = NR_ACTIVE_FILE, | ||
95 | #endif | ||
96 | NR_ANON_PAGES, /* Mapped anonymous pages */ | 88 | NR_ANON_PAGES, /* Mapped anonymous pages */ |
97 | NR_FILE_MAPPED, /* pagecache pages mapped into pagetables. | 89 | NR_FILE_MAPPED, /* pagecache pages mapped into pagetables. |
98 | only modified from process context */ | 90 | only modified from process context */ |
@@ -135,11 +127,7 @@ enum lru_list { | |||
135 | LRU_ACTIVE_ANON = LRU_BASE + LRU_ACTIVE, | 127 | LRU_ACTIVE_ANON = LRU_BASE + LRU_ACTIVE, |
136 | LRU_INACTIVE_FILE = LRU_BASE + LRU_FILE, | 128 | LRU_INACTIVE_FILE = LRU_BASE + LRU_FILE, |
137 | LRU_ACTIVE_FILE = LRU_BASE + LRU_FILE + LRU_ACTIVE, | 129 | LRU_ACTIVE_FILE = LRU_BASE + LRU_FILE + LRU_ACTIVE, |
138 | #ifdef CONFIG_UNEVICTABLE_LRU | ||
139 | LRU_UNEVICTABLE, | 130 | LRU_UNEVICTABLE, |
140 | #else | ||
141 | LRU_UNEVICTABLE = LRU_ACTIVE_FILE, /* avoid compiler errors in dead code */ | ||
142 | #endif | ||
143 | NR_LRU_LISTS | 131 | NR_LRU_LISTS |
144 | }; | 132 | }; |
145 | 133 | ||
@@ -159,13 +147,20 @@ static inline int is_active_lru(enum lru_list l) | |||
159 | 147 | ||
160 | static inline int is_unevictable_lru(enum lru_list l) | 148 | static inline int is_unevictable_lru(enum lru_list l) |
161 | { | 149 | { |
162 | #ifdef CONFIG_UNEVICTABLE_LRU | ||
163 | return (l == LRU_UNEVICTABLE); | 150 | return (l == LRU_UNEVICTABLE); |
164 | #else | ||
165 | return 0; | ||
166 | #endif | ||
167 | } | 151 | } |
168 | 152 | ||
153 | enum zone_watermarks { | ||
154 | WMARK_MIN, | ||
155 | WMARK_LOW, | ||
156 | WMARK_HIGH, | ||
157 | NR_WMARK | ||
158 | }; | ||
159 | |||
160 | #define min_wmark_pages(z) (z->watermark[WMARK_MIN]) | ||
161 | #define low_wmark_pages(z) (z->watermark[WMARK_LOW]) | ||
162 | #define high_wmark_pages(z) (z->watermark[WMARK_HIGH]) | ||
163 | |||
169 | struct per_cpu_pages { | 164 | struct per_cpu_pages { |
170 | int count; /* number of pages in the list */ | 165 | int count; /* number of pages in the list */ |
171 | int high; /* high watermark, emptying needed */ | 166 | int high; /* high watermark, emptying needed */ |
@@ -278,7 +273,10 @@ struct zone_reclaim_stat { | |||
278 | 273 | ||
279 | struct zone { | 274 | struct zone { |
280 | /* Fields commonly accessed by the page allocator */ | 275 | /* Fields commonly accessed by the page allocator */ |
281 | unsigned long pages_min, pages_low, pages_high; | 276 | |
277 | /* zone watermarks, access with *_wmark_pages(zone) macros */ | ||
278 | unsigned long watermark[NR_WMARK]; | ||
279 | |||
282 | /* | 280 | /* |
283 | * We don't know if the memory that we're going to allocate will be freeable | 281 | * We don't know if the memory that we're going to allocate will be freeable |
284 | * or/and it will be released eventually, so to avoid totally wasting several | 282 | * or/and it will be released eventually, so to avoid totally wasting several |
@@ -323,9 +321,9 @@ struct zone { | |||
323 | 321 | ||
324 | /* Fields commonly accessed by the page reclaim scanner */ | 322 | /* Fields commonly accessed by the page reclaim scanner */ |
325 | spinlock_t lru_lock; | 323 | spinlock_t lru_lock; |
326 | struct { | 324 | struct zone_lru { |
327 | struct list_head list; | 325 | struct list_head list; |
328 | unsigned long nr_scan; | 326 | unsigned long nr_saved_scan; /* accumulated for batching */ |
329 | } lru[NR_LRU_LISTS]; | 327 | } lru[NR_LRU_LISTS]; |
330 | 328 | ||
331 | struct zone_reclaim_stat reclaim_stat; | 329 | struct zone_reclaim_stat reclaim_stat; |
diff --git a/include/linux/module.h b/include/linux/module.h index a7bc6e7b43a7..505f20dcc1c7 100644 --- a/include/linux/module.h +++ b/include/linux/module.h | |||
@@ -697,4 +697,21 @@ static inline void module_remove_modinfo_attrs(struct module *mod) | |||
697 | 697 | ||
698 | #define __MODULE_STRING(x) __stringify(x) | 698 | #define __MODULE_STRING(x) __stringify(x) |
699 | 699 | ||
700 | |||
701 | #ifdef CONFIG_GENERIC_BUG | ||
702 | int module_bug_finalize(const Elf_Ehdr *, const Elf_Shdr *, | ||
703 | struct module *); | ||
704 | void module_bug_cleanup(struct module *); | ||
705 | |||
706 | #else /* !CONFIG_GENERIC_BUG */ | ||
707 | |||
708 | static inline int module_bug_finalize(const Elf_Ehdr *hdr, | ||
709 | const Elf_Shdr *sechdrs, | ||
710 | struct module *mod) | ||
711 | { | ||
712 | return 0; | ||
713 | } | ||
714 | static inline void module_bug_cleanup(struct module *mod) {} | ||
715 | #endif /* CONFIG_GENERIC_BUG */ | ||
716 | |||
700 | #endif /* _LINUX_MODULE_H */ | 717 | #endif /* _LINUX_MODULE_H */ |
diff --git a/include/linux/nodemask.h b/include/linux/nodemask.h index 848025cd7087..829b94b156f2 100644 --- a/include/linux/nodemask.h +++ b/include/linux/nodemask.h | |||
@@ -408,6 +408,19 @@ static inline int num_node_state(enum node_states state) | |||
408 | #define next_online_node(nid) next_node((nid), node_states[N_ONLINE]) | 408 | #define next_online_node(nid) next_node((nid), node_states[N_ONLINE]) |
409 | 409 | ||
410 | extern int nr_node_ids; | 410 | extern int nr_node_ids; |
411 | extern int nr_online_nodes; | ||
412 | |||
413 | static inline void node_set_online(int nid) | ||
414 | { | ||
415 | node_set_state(nid, N_ONLINE); | ||
416 | nr_online_nodes = num_node_state(N_ONLINE); | ||
417 | } | ||
418 | |||
419 | static inline void node_set_offline(int nid) | ||
420 | { | ||
421 | node_clear_state(nid, N_ONLINE); | ||
422 | nr_online_nodes = num_node_state(N_ONLINE); | ||
423 | } | ||
411 | #else | 424 | #else |
412 | 425 | ||
413 | static inline int node_state(int node, enum node_states state) | 426 | static inline int node_state(int node, enum node_states state) |
@@ -434,7 +447,10 @@ static inline int num_node_state(enum node_states state) | |||
434 | #define first_online_node 0 | 447 | #define first_online_node 0 |
435 | #define next_online_node(nid) (MAX_NUMNODES) | 448 | #define next_online_node(nid) (MAX_NUMNODES) |
436 | #define nr_node_ids 1 | 449 | #define nr_node_ids 1 |
450 | #define nr_online_nodes 1 | ||
437 | 451 | ||
452 | #define node_set_online(node) node_set_state((node), N_ONLINE) | ||
453 | #define node_set_offline(node) node_clear_state((node), N_ONLINE) | ||
438 | #endif | 454 | #endif |
439 | 455 | ||
440 | #define node_online_map node_states[N_ONLINE] | 456 | #define node_online_map node_states[N_ONLINE] |
@@ -454,9 +470,6 @@ static inline int num_node_state(enum node_states state) | |||
454 | #define node_online(node) node_state((node), N_ONLINE) | 470 | #define node_online(node) node_state((node), N_ONLINE) |
455 | #define node_possible(node) node_state((node), N_POSSIBLE) | 471 | #define node_possible(node) node_state((node), N_POSSIBLE) |
456 | 472 | ||
457 | #define node_set_online(node) node_set_state((node), N_ONLINE) | ||
458 | #define node_set_offline(node) node_clear_state((node), N_ONLINE) | ||
459 | |||
460 | #define for_each_node(node) for_each_node_state(node, N_POSSIBLE) | 473 | #define for_each_node(node) for_each_node_state(node, N_POSSIBLE) |
461 | #define for_each_online_node(node) for_each_node_state(node, N_ONLINE) | 474 | #define for_each_online_node(node) for_each_node_state(node, N_ONLINE) |
462 | 475 | ||
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h index 62214c7d2d93..d6792f88a176 100644 --- a/include/linux/page-flags.h +++ b/include/linux/page-flags.h | |||
@@ -95,9 +95,7 @@ enum pageflags { | |||
95 | PG_reclaim, /* To be reclaimed asap */ | 95 | PG_reclaim, /* To be reclaimed asap */ |
96 | PG_buddy, /* Page is free, on buddy lists */ | 96 | PG_buddy, /* Page is free, on buddy lists */ |
97 | PG_swapbacked, /* Page is backed by RAM/swap */ | 97 | PG_swapbacked, /* Page is backed by RAM/swap */ |
98 | #ifdef CONFIG_UNEVICTABLE_LRU | ||
99 | PG_unevictable, /* Page is "unevictable" */ | 98 | PG_unevictable, /* Page is "unevictable" */ |
100 | #endif | ||
101 | #ifdef CONFIG_HAVE_MLOCKED_PAGE_BIT | 99 | #ifdef CONFIG_HAVE_MLOCKED_PAGE_BIT |
102 | PG_mlocked, /* Page is vma mlocked */ | 100 | PG_mlocked, /* Page is vma mlocked */ |
103 | #endif | 101 | #endif |
@@ -248,14 +246,8 @@ PAGEFLAG_FALSE(SwapCache) | |||
248 | SETPAGEFLAG_NOOP(SwapCache) CLEARPAGEFLAG_NOOP(SwapCache) | 246 | SETPAGEFLAG_NOOP(SwapCache) CLEARPAGEFLAG_NOOP(SwapCache) |
249 | #endif | 247 | #endif |
250 | 248 | ||
251 | #ifdef CONFIG_UNEVICTABLE_LRU | ||
252 | PAGEFLAG(Unevictable, unevictable) __CLEARPAGEFLAG(Unevictable, unevictable) | 249 | PAGEFLAG(Unevictable, unevictable) __CLEARPAGEFLAG(Unevictable, unevictable) |
253 | TESTCLEARFLAG(Unevictable, unevictable) | 250 | TESTCLEARFLAG(Unevictable, unevictable) |
254 | #else | ||
255 | PAGEFLAG_FALSE(Unevictable) TESTCLEARFLAG_FALSE(Unevictable) | ||
256 | SETPAGEFLAG_NOOP(Unevictable) CLEARPAGEFLAG_NOOP(Unevictable) | ||
257 | __CLEARPAGEFLAG_NOOP(Unevictable) | ||
258 | #endif | ||
259 | 251 | ||
260 | #ifdef CONFIG_HAVE_MLOCKED_PAGE_BIT | 252 | #ifdef CONFIG_HAVE_MLOCKED_PAGE_BIT |
261 | #define MLOCK_PAGES 1 | 253 | #define MLOCK_PAGES 1 |
@@ -382,12 +374,6 @@ static inline void __ClearPageTail(struct page *page) | |||
382 | 374 | ||
383 | #endif /* !PAGEFLAGS_EXTENDED */ | 375 | #endif /* !PAGEFLAGS_EXTENDED */ |
384 | 376 | ||
385 | #ifdef CONFIG_UNEVICTABLE_LRU | ||
386 | #define __PG_UNEVICTABLE (1 << PG_unevictable) | ||
387 | #else | ||
388 | #define __PG_UNEVICTABLE 0 | ||
389 | #endif | ||
390 | |||
391 | #ifdef CONFIG_HAVE_MLOCKED_PAGE_BIT | 377 | #ifdef CONFIG_HAVE_MLOCKED_PAGE_BIT |
392 | #define __PG_MLOCKED (1 << PG_mlocked) | 378 | #define __PG_MLOCKED (1 << PG_mlocked) |
393 | #else | 379 | #else |
@@ -403,7 +389,7 @@ static inline void __ClearPageTail(struct page *page) | |||
403 | 1 << PG_private | 1 << PG_private_2 | \ | 389 | 1 << PG_private | 1 << PG_private_2 | \ |
404 | 1 << PG_buddy | 1 << PG_writeback | 1 << PG_reserved | \ | 390 | 1 << PG_buddy | 1 << PG_writeback | 1 << PG_reserved | \ |
405 | 1 << PG_slab | 1 << PG_swapcache | 1 << PG_active | \ | 391 | 1 << PG_slab | 1 << PG_swapcache | 1 << PG_active | \ |
406 | __PG_UNEVICTABLE | __PG_MLOCKED) | 392 | 1 << PG_unevictable | __PG_MLOCKED) |
407 | 393 | ||
408 | /* | 394 | /* |
409 | * Flags checked when a page is prepped for return by the page allocator. | 395 | * Flags checked when a page is prepped for return by the page allocator. |
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index 34da5230faab..aec3252afcf5 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h | |||
@@ -22,9 +22,7 @@ enum mapping_flags { | |||
22 | AS_EIO = __GFP_BITS_SHIFT + 0, /* IO error on async write */ | 22 | AS_EIO = __GFP_BITS_SHIFT + 0, /* IO error on async write */ |
23 | AS_ENOSPC = __GFP_BITS_SHIFT + 1, /* ENOSPC on async write */ | 23 | AS_ENOSPC = __GFP_BITS_SHIFT + 1, /* ENOSPC on async write */ |
24 | AS_MM_ALL_LOCKS = __GFP_BITS_SHIFT + 2, /* under mm_take_all_locks() */ | 24 | AS_MM_ALL_LOCKS = __GFP_BITS_SHIFT + 2, /* under mm_take_all_locks() */ |
25 | #ifdef CONFIG_UNEVICTABLE_LRU | ||
26 | AS_UNEVICTABLE = __GFP_BITS_SHIFT + 3, /* e.g., ramdisk, SHM_LOCK */ | 25 | AS_UNEVICTABLE = __GFP_BITS_SHIFT + 3, /* e.g., ramdisk, SHM_LOCK */ |
27 | #endif | ||
28 | }; | 26 | }; |
29 | 27 | ||
30 | static inline void mapping_set_error(struct address_space *mapping, int error) | 28 | static inline void mapping_set_error(struct address_space *mapping, int error) |
@@ -37,8 +35,6 @@ static inline void mapping_set_error(struct address_space *mapping, int error) | |||
37 | } | 35 | } |
38 | } | 36 | } |
39 | 37 | ||
40 | #ifdef CONFIG_UNEVICTABLE_LRU | ||
41 | |||
42 | static inline void mapping_set_unevictable(struct address_space *mapping) | 38 | static inline void mapping_set_unevictable(struct address_space *mapping) |
43 | { | 39 | { |
44 | set_bit(AS_UNEVICTABLE, &mapping->flags); | 40 | set_bit(AS_UNEVICTABLE, &mapping->flags); |
@@ -55,14 +51,6 @@ static inline int mapping_unevictable(struct address_space *mapping) | |||
55 | return test_bit(AS_UNEVICTABLE, &mapping->flags); | 51 | return test_bit(AS_UNEVICTABLE, &mapping->flags); |
56 | return !!mapping; | 52 | return !!mapping; |
57 | } | 53 | } |
58 | #else | ||
59 | static inline void mapping_set_unevictable(struct address_space *mapping) { } | ||
60 | static inline void mapping_clear_unevictable(struct address_space *mapping) { } | ||
61 | static inline int mapping_unevictable(struct address_space *mapping) | ||
62 | { | ||
63 | return 0; | ||
64 | } | ||
65 | #endif | ||
66 | 54 | ||
67 | static inline gfp_t mapping_gfp_mask(struct address_space * mapping) | 55 | static inline gfp_t mapping_gfp_mask(struct address_space * mapping) |
68 | { | 56 | { |
diff --git a/include/linux/poll.h b/include/linux/poll.h index 8c24ef8d9976..fa287f25138d 100644 --- a/include/linux/poll.h +++ b/include/linux/poll.h | |||
@@ -32,6 +32,7 @@ typedef void (*poll_queue_proc)(struct file *, wait_queue_head_t *, struct poll_ | |||
32 | 32 | ||
33 | typedef struct poll_table_struct { | 33 | typedef struct poll_table_struct { |
34 | poll_queue_proc qproc; | 34 | poll_queue_proc qproc; |
35 | unsigned long key; | ||
35 | } poll_table; | 36 | } poll_table; |
36 | 37 | ||
37 | static inline void poll_wait(struct file * filp, wait_queue_head_t * wait_address, poll_table *p) | 38 | static inline void poll_wait(struct file * filp, wait_queue_head_t * wait_address, poll_table *p) |
@@ -43,10 +44,12 @@ static inline void poll_wait(struct file * filp, wait_queue_head_t * wait_addres | |||
43 | static inline void init_poll_funcptr(poll_table *pt, poll_queue_proc qproc) | 44 | static inline void init_poll_funcptr(poll_table *pt, poll_queue_proc qproc) |
44 | { | 45 | { |
45 | pt->qproc = qproc; | 46 | pt->qproc = qproc; |
47 | pt->key = ~0UL; /* all events enabled */ | ||
46 | } | 48 | } |
47 | 49 | ||
48 | struct poll_table_entry { | 50 | struct poll_table_entry { |
49 | struct file *filp; | 51 | struct file *filp; |
52 | unsigned long key; | ||
50 | wait_queue_t wait; | 53 | wait_queue_t wait; |
51 | wait_queue_head_t *wait_address; | 54 | wait_queue_head_t *wait_address; |
52 | }; | 55 | }; |
diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h index 355f6e80db0d..c5da74918096 100644 --- a/include/linux/radix-tree.h +++ b/include/linux/radix-tree.h | |||
@@ -167,6 +167,8 @@ radix_tree_gang_lookup_slot(struct radix_tree_root *root, void ***results, | |||
167 | unsigned long first_index, unsigned int max_items); | 167 | unsigned long first_index, unsigned int max_items); |
168 | unsigned long radix_tree_next_hole(struct radix_tree_root *root, | 168 | unsigned long radix_tree_next_hole(struct radix_tree_root *root, |
169 | unsigned long index, unsigned long max_scan); | 169 | unsigned long index, unsigned long max_scan); |
170 | unsigned long radix_tree_prev_hole(struct radix_tree_root *root, | ||
171 | unsigned long index, unsigned long max_scan); | ||
170 | int radix_tree_preload(gfp_t gfp_mask); | 172 | int radix_tree_preload(gfp_t gfp_mask); |
171 | void radix_tree_init(void); | 173 | void radix_tree_init(void); |
172 | void *radix_tree_tag_set(struct radix_tree_root *root, | 174 | void *radix_tree_tag_set(struct radix_tree_root *root, |
diff --git a/include/linux/rmap.h b/include/linux/rmap.h index b35bc0e19cd9..216d024f830d 100644 --- a/include/linux/rmap.h +++ b/include/linux/rmap.h | |||
@@ -83,7 +83,8 @@ static inline void page_dup_rmap(struct page *page, struct vm_area_struct *vma, | |||
83 | /* | 83 | /* |
84 | * Called from mm/vmscan.c to handle paging out | 84 | * Called from mm/vmscan.c to handle paging out |
85 | */ | 85 | */ |
86 | int page_referenced(struct page *, int is_locked, struct mem_cgroup *cnt); | 86 | int page_referenced(struct page *, int is_locked, |
87 | struct mem_cgroup *cnt, unsigned long *vm_flags); | ||
87 | int try_to_unmap(struct page *, int ignore_refs); | 88 | int try_to_unmap(struct page *, int ignore_refs); |
88 | 89 | ||
89 | /* | 90 | /* |
@@ -105,18 +106,11 @@ unsigned long page_address_in_vma(struct page *, struct vm_area_struct *); | |||
105 | */ | 106 | */ |
106 | int page_mkclean(struct page *); | 107 | int page_mkclean(struct page *); |
107 | 108 | ||
108 | #ifdef CONFIG_UNEVICTABLE_LRU | ||
109 | /* | 109 | /* |
110 | * called in munlock()/munmap() path to check for other vmas holding | 110 | * called in munlock()/munmap() path to check for other vmas holding |
111 | * the page mlocked. | 111 | * the page mlocked. |
112 | */ | 112 | */ |
113 | int try_to_munlock(struct page *); | 113 | int try_to_munlock(struct page *); |
114 | #else | ||
115 | static inline int try_to_munlock(struct page *page) | ||
116 | { | ||
117 | return 0; /* a.k.a. SWAP_SUCCESS */ | ||
118 | } | ||
119 | #endif | ||
120 | 114 | ||
121 | #else /* !CONFIG_MMU */ | 115 | #else /* !CONFIG_MMU */ |
122 | 116 | ||
@@ -124,7 +118,7 @@ static inline int try_to_munlock(struct page *page) | |||
124 | #define anon_vma_prepare(vma) (0) | 118 | #define anon_vma_prepare(vma) (0) |
125 | #define anon_vma_link(vma) do {} while (0) | 119 | #define anon_vma_link(vma) do {} while (0) |
126 | 120 | ||
127 | #define page_referenced(page,l,cnt) TestClearPageReferenced(page) | 121 | #define page_referenced(page, locked, cnt, flags) TestClearPageReferenced(page) |
128 | #define try_to_unmap(page, refs) SWAP_FAIL | 122 | #define try_to_unmap(page, refs) SWAP_FAIL |
129 | 123 | ||
130 | static inline int page_mkclean(struct page *page) | 124 | static inline int page_mkclean(struct page *page) |
diff --git a/include/linux/sched.h b/include/linux/sched.h index 7531b1c28201..02042e7f2196 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -1178,7 +1178,6 @@ struct task_struct { | |||
1178 | * a short time | 1178 | * a short time |
1179 | */ | 1179 | */ |
1180 | unsigned char fpu_counter; | 1180 | unsigned char fpu_counter; |
1181 | s8 oomkilladj; /* OOM kill score adjustment (bit shift). */ | ||
1182 | #ifdef CONFIG_BLK_DEV_IO_TRACE | 1181 | #ifdef CONFIG_BLK_DEV_IO_TRACE |
1183 | unsigned int btrace_seq; | 1182 | unsigned int btrace_seq; |
1184 | #endif | 1183 | #endif |
@@ -1318,7 +1317,8 @@ struct task_struct { | |||
1318 | /* Thread group tracking */ | 1317 | /* Thread group tracking */ |
1319 | u32 parent_exec_id; | 1318 | u32 parent_exec_id; |
1320 | u32 self_exec_id; | 1319 | u32 self_exec_id; |
1321 | /* Protection of (de-)allocation: mm, files, fs, tty, keyrings */ | 1320 | /* Protection of (de-)allocation: mm, files, fs, tty, keyrings, mems_allowed, |
1321 | * mempolicy */ | ||
1322 | spinlock_t alloc_lock; | 1322 | spinlock_t alloc_lock; |
1323 | 1323 | ||
1324 | #ifdef CONFIG_GENERIC_HARDIRQS | 1324 | #ifdef CONFIG_GENERIC_HARDIRQS |
@@ -1386,8 +1386,7 @@ struct task_struct { | |||
1386 | cputime_t acct_timexpd; /* stime + utime since last update */ | 1386 | cputime_t acct_timexpd; /* stime + utime since last update */ |
1387 | #endif | 1387 | #endif |
1388 | #ifdef CONFIG_CPUSETS | 1388 | #ifdef CONFIG_CPUSETS |
1389 | nodemask_t mems_allowed; | 1389 | nodemask_t mems_allowed; /* Protected by alloc_lock */ |
1390 | int cpuset_mems_generation; | ||
1391 | int cpuset_mem_spread_rotor; | 1390 | int cpuset_mem_spread_rotor; |
1392 | #endif | 1391 | #endif |
1393 | #ifdef CONFIG_CGROUPS | 1392 | #ifdef CONFIG_CGROUPS |
@@ -1410,7 +1409,7 @@ struct task_struct { | |||
1410 | struct list_head perf_counter_list; | 1409 | struct list_head perf_counter_list; |
1411 | #endif | 1410 | #endif |
1412 | #ifdef CONFIG_NUMA | 1411 | #ifdef CONFIG_NUMA |
1413 | struct mempolicy *mempolicy; | 1412 | struct mempolicy *mempolicy; /* Protected by alloc_lock */ |
1414 | short il_next; | 1413 | short il_next; |
1415 | #endif | 1414 | #endif |
1416 | atomic_t fs_excl; /* holding fs exclusive resources */ | 1415 | atomic_t fs_excl; /* holding fs exclusive resources */ |
diff --git a/include/linux/smp.h b/include/linux/smp.h index a69db820eed6..9e3d8af09207 100644 --- a/include/linux/smp.h +++ b/include/linux/smp.h | |||
@@ -177,7 +177,6 @@ static inline void init_call_single_data(void) | |||
177 | 177 | ||
178 | #define get_cpu() ({ preempt_disable(); smp_processor_id(); }) | 178 | #define get_cpu() ({ preempt_disable(); smp_processor_id(); }) |
179 | #define put_cpu() preempt_enable() | 179 | #define put_cpu() preempt_enable() |
180 | #define put_cpu_no_resched() preempt_enable_no_resched() | ||
181 | 180 | ||
182 | /* | 181 | /* |
183 | * Callback to arch code if there's nosmp or maxcpus=0 on the | 182 | * Callback to arch code if there's nosmp or maxcpus=0 on the |
diff --git a/include/linux/swap.h b/include/linux/swap.h index d476aad3ff57..0cedf31af0b0 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h | |||
@@ -129,9 +129,10 @@ enum { | |||
129 | 129 | ||
130 | #define SWAP_CLUSTER_MAX 32 | 130 | #define SWAP_CLUSTER_MAX 32 |
131 | 131 | ||
132 | #define SWAP_MAP_MAX 0x7fff | 132 | #define SWAP_MAP_MAX 0x7ffe |
133 | #define SWAP_MAP_BAD 0x8000 | 133 | #define SWAP_MAP_BAD 0x7fff |
134 | 134 | #define SWAP_HAS_CACHE 0x8000 /* There is a swap cache of entry. */ | |
135 | #define SWAP_COUNT_MASK (~SWAP_HAS_CACHE) | ||
135 | /* | 136 | /* |
136 | * The in-memory structure used to track swap areas. | 137 | * The in-memory structure used to track swap areas. |
137 | */ | 138 | */ |
@@ -235,7 +236,6 @@ static inline int zone_reclaim(struct zone *z, gfp_t mask, unsigned int order) | |||
235 | } | 236 | } |
236 | #endif | 237 | #endif |
237 | 238 | ||
238 | #ifdef CONFIG_UNEVICTABLE_LRU | ||
239 | extern int page_evictable(struct page *page, struct vm_area_struct *vma); | 239 | extern int page_evictable(struct page *page, struct vm_area_struct *vma); |
240 | extern void scan_mapping_unevictable_pages(struct address_space *); | 240 | extern void scan_mapping_unevictable_pages(struct address_space *); |
241 | 241 | ||
@@ -244,24 +244,6 @@ extern int scan_unevictable_handler(struct ctl_table *, int, struct file *, | |||
244 | void __user *, size_t *, loff_t *); | 244 | void __user *, size_t *, loff_t *); |
245 | extern int scan_unevictable_register_node(struct node *node); | 245 | extern int scan_unevictable_register_node(struct node *node); |
246 | extern void scan_unevictable_unregister_node(struct node *node); | 246 | extern void scan_unevictable_unregister_node(struct node *node); |
247 | #else | ||
248 | static inline int page_evictable(struct page *page, | ||
249 | struct vm_area_struct *vma) | ||
250 | { | ||
251 | return 1; | ||
252 | } | ||
253 | |||
254 | static inline void scan_mapping_unevictable_pages(struct address_space *mapping) | ||
255 | { | ||
256 | } | ||
257 | |||
258 | static inline int scan_unevictable_register_node(struct node *node) | ||
259 | { | ||
260 | return 0; | ||
261 | } | ||
262 | |||
263 | static inline void scan_unevictable_unregister_node(struct node *node) { } | ||
264 | #endif | ||
265 | 247 | ||
266 | extern int kswapd_run(int nid); | 248 | extern int kswapd_run(int nid); |
267 | 249 | ||
@@ -274,7 +256,7 @@ extern void swap_unplug_io_fn(struct backing_dev_info *, struct page *); | |||
274 | 256 | ||
275 | #ifdef CONFIG_SWAP | 257 | #ifdef CONFIG_SWAP |
276 | /* linux/mm/page_io.c */ | 258 | /* linux/mm/page_io.c */ |
277 | extern int swap_readpage(struct file *, struct page *); | 259 | extern int swap_readpage(struct page *); |
278 | extern int swap_writepage(struct page *page, struct writeback_control *wbc); | 260 | extern int swap_writepage(struct page *page, struct writeback_control *wbc); |
279 | extern void end_swap_bio_read(struct bio *bio, int err); | 261 | extern void end_swap_bio_read(struct bio *bio, int err); |
280 | 262 | ||
@@ -300,9 +282,11 @@ extern long total_swap_pages; | |||
300 | extern void si_swapinfo(struct sysinfo *); | 282 | extern void si_swapinfo(struct sysinfo *); |
301 | extern swp_entry_t get_swap_page(void); | 283 | extern swp_entry_t get_swap_page(void); |
302 | extern swp_entry_t get_swap_page_of_type(int); | 284 | extern swp_entry_t get_swap_page_of_type(int); |
303 | extern int swap_duplicate(swp_entry_t); | 285 | extern void swap_duplicate(swp_entry_t); |
286 | extern int swapcache_prepare(swp_entry_t); | ||
304 | extern int valid_swaphandles(swp_entry_t, unsigned long *); | 287 | extern int valid_swaphandles(swp_entry_t, unsigned long *); |
305 | extern void swap_free(swp_entry_t); | 288 | extern void swap_free(swp_entry_t); |
289 | extern void swapcache_free(swp_entry_t, struct page *page); | ||
306 | extern int free_swap_and_cache(swp_entry_t); | 290 | extern int free_swap_and_cache(swp_entry_t); |
307 | extern int swap_type_of(dev_t, sector_t, struct block_device **); | 291 | extern int swap_type_of(dev_t, sector_t, struct block_device **); |
308 | extern unsigned int count_swap_pages(int, int); | 292 | extern unsigned int count_swap_pages(int, int); |
@@ -370,12 +354,20 @@ static inline void show_swap_cache_info(void) | |||
370 | } | 354 | } |
371 | 355 | ||
372 | #define free_swap_and_cache(swp) is_migration_entry(swp) | 356 | #define free_swap_and_cache(swp) is_migration_entry(swp) |
373 | #define swap_duplicate(swp) is_migration_entry(swp) | 357 | #define swapcache_prepare(swp) is_migration_entry(swp) |
358 | |||
359 | static inline void swap_duplicate(swp_entry_t swp) | ||
360 | { | ||
361 | } | ||
374 | 362 | ||
375 | static inline void swap_free(swp_entry_t swp) | 363 | static inline void swap_free(swp_entry_t swp) |
376 | { | 364 | { |
377 | } | 365 | } |
378 | 366 | ||
367 | static inline void swapcache_free(swp_entry_t swp, struct page *page) | ||
368 | { | ||
369 | } | ||
370 | |||
379 | static inline struct page *swapin_readahead(swp_entry_t swp, gfp_t gfp_mask, | 371 | static inline struct page *swapin_readahead(swp_entry_t swp, gfp_t gfp_mask, |
380 | struct vm_area_struct *vma, unsigned long addr) | 372 | struct vm_area_struct *vma, unsigned long addr) |
381 | { | 373 | { |
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 418d90f5effe..fa4242cdade8 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h | |||
@@ -434,6 +434,7 @@ asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg); | |||
434 | asmlinkage long sys_fcntl64(unsigned int fd, | 434 | asmlinkage long sys_fcntl64(unsigned int fd, |
435 | unsigned int cmd, unsigned long arg); | 435 | unsigned int cmd, unsigned long arg); |
436 | #endif | 436 | #endif |
437 | asmlinkage long sys_pipe(int __user *fildes); | ||
437 | asmlinkage long sys_pipe2(int __user *fildes, int flags); | 438 | asmlinkage long sys_pipe2(int __user *fildes, int flags); |
438 | asmlinkage long sys_dup(unsigned int fildes); | 439 | asmlinkage long sys_dup(unsigned int fildes); |
439 | asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd); | 440 | asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd); |
@@ -751,8 +752,6 @@ asmlinkage long sys_pselect6(int, fd_set __user *, fd_set __user *, | |||
751 | asmlinkage long sys_ppoll(struct pollfd __user *, unsigned int, | 752 | asmlinkage long sys_ppoll(struct pollfd __user *, unsigned int, |
752 | struct timespec __user *, const sigset_t __user *, | 753 | struct timespec __user *, const sigset_t __user *, |
753 | size_t); | 754 | size_t); |
754 | asmlinkage long sys_pipe2(int __user *, int); | ||
755 | asmlinkage long sys_pipe(int __user *); | ||
756 | 755 | ||
757 | int kernel_execve(const char *filename, char *const argv[], char *const envp[]); | 756 | int kernel_execve(const char *filename, char *const argv[], char *const envp[]); |
758 | 757 | ||
diff --git a/include/linux/timex.h b/include/linux/timex.h index 9910e3bd5b31..e6967d10d9e5 100644 --- a/include/linux/timex.h +++ b/include/linux/timex.h | |||
@@ -280,6 +280,9 @@ extern int do_adjtimex(struct timex *); | |||
280 | 280 | ||
281 | int read_current_timer(unsigned long *timer_val); | 281 | int read_current_timer(unsigned long *timer_val); |
282 | 282 | ||
283 | /* The clock frequency of the i8253/i8254 PIT */ | ||
284 | #define PIT_TICK_RATE 1193182ul | ||
285 | |||
283 | #endif /* KERNEL */ | 286 | #endif /* KERNEL */ |
284 | 287 | ||
285 | #endif /* LINUX_TIMEX_H */ | 288 | #endif /* LINUX_TIMEX_H */ |
diff --git a/include/linux/utsname.h b/include/linux/utsname.h index 11232676bfff..3656b300de3a 100644 --- a/include/linux/utsname.h +++ b/include/linux/utsname.h | |||
@@ -22,12 +22,12 @@ struct old_utsname { | |||
22 | }; | 22 | }; |
23 | 23 | ||
24 | struct new_utsname { | 24 | struct new_utsname { |
25 | char sysname[65]; | 25 | char sysname[__NEW_UTS_LEN + 1]; |
26 | char nodename[65]; | 26 | char nodename[__NEW_UTS_LEN + 1]; |
27 | char release[65]; | 27 | char release[__NEW_UTS_LEN + 1]; |
28 | char version[65]; | 28 | char version[__NEW_UTS_LEN + 1]; |
29 | char machine[65]; | 29 | char machine[__NEW_UTS_LEN + 1]; |
30 | char domainname[65]; | 30 | char domainname[__NEW_UTS_LEN + 1]; |
31 | }; | 31 | }; |
32 | 32 | ||
33 | #ifdef __KERNEL__ | 33 | #ifdef __KERNEL__ |
diff --git a/include/linux/vlynq.h b/include/linux/vlynq.h new file mode 100644 index 000000000000..8f6a95882b09 --- /dev/null +++ b/include/linux/vlynq.h | |||
@@ -0,0 +1,161 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006, 2007 Eugene Konev <ejka@openwrt.org> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
17 | */ | ||
18 | |||
19 | #ifndef __VLYNQ_H__ | ||
20 | #define __VLYNQ_H__ | ||
21 | |||
22 | #include <linux/device.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/types.h> | ||
25 | |||
26 | #define VLYNQ_NUM_IRQS 32 | ||
27 | |||
28 | struct vlynq_mapping { | ||
29 | u32 size; | ||
30 | u32 offset; | ||
31 | }; | ||
32 | |||
33 | enum vlynq_divisor { | ||
34 | vlynq_div_auto = 0, | ||
35 | vlynq_ldiv1, | ||
36 | vlynq_ldiv2, | ||
37 | vlynq_ldiv3, | ||
38 | vlynq_ldiv4, | ||
39 | vlynq_ldiv5, | ||
40 | vlynq_ldiv6, | ||
41 | vlynq_ldiv7, | ||
42 | vlynq_ldiv8, | ||
43 | vlynq_rdiv1, | ||
44 | vlynq_rdiv2, | ||
45 | vlynq_rdiv3, | ||
46 | vlynq_rdiv4, | ||
47 | vlynq_rdiv5, | ||
48 | vlynq_rdiv6, | ||
49 | vlynq_rdiv7, | ||
50 | vlynq_rdiv8, | ||
51 | vlynq_div_external | ||
52 | }; | ||
53 | |||
54 | struct vlynq_device_id { | ||
55 | u32 id; | ||
56 | enum vlynq_divisor divisor; | ||
57 | unsigned long driver_data; | ||
58 | }; | ||
59 | |||
60 | struct vlynq_regs; | ||
61 | struct vlynq_device { | ||
62 | u32 id, dev_id; | ||
63 | int local_irq; | ||
64 | int remote_irq; | ||
65 | enum vlynq_divisor divisor; | ||
66 | u32 regs_start, regs_end; | ||
67 | u32 mem_start, mem_end; | ||
68 | u32 irq_start, irq_end; | ||
69 | int irq; | ||
70 | int enabled; | ||
71 | struct vlynq_regs *local; | ||
72 | struct vlynq_regs *remote; | ||
73 | struct device dev; | ||
74 | }; | ||
75 | |||
76 | struct vlynq_driver { | ||
77 | char *name; | ||
78 | struct vlynq_device_id *id_table; | ||
79 | int (*probe)(struct vlynq_device *dev, struct vlynq_device_id *id); | ||
80 | void (*remove)(struct vlynq_device *dev); | ||
81 | struct device_driver driver; | ||
82 | }; | ||
83 | |||
84 | struct plat_vlynq_ops { | ||
85 | int (*on)(struct vlynq_device *dev); | ||
86 | void (*off)(struct vlynq_device *dev); | ||
87 | }; | ||
88 | |||
89 | static inline struct vlynq_driver *to_vlynq_driver(struct device_driver *drv) | ||
90 | { | ||
91 | return container_of(drv, struct vlynq_driver, driver); | ||
92 | } | ||
93 | |||
94 | static inline struct vlynq_device *to_vlynq_device(struct device *device) | ||
95 | { | ||
96 | return container_of(device, struct vlynq_device, dev); | ||
97 | } | ||
98 | |||
99 | extern struct bus_type vlynq_bus_type; | ||
100 | |||
101 | extern int __vlynq_register_driver(struct vlynq_driver *driver, | ||
102 | struct module *owner); | ||
103 | |||
104 | static inline int vlynq_register_driver(struct vlynq_driver *driver) | ||
105 | { | ||
106 | return __vlynq_register_driver(driver, THIS_MODULE); | ||
107 | } | ||
108 | |||
109 | static inline void *vlynq_get_drvdata(struct vlynq_device *dev) | ||
110 | { | ||
111 | return dev_get_drvdata(&dev->dev); | ||
112 | } | ||
113 | |||
114 | static inline void vlynq_set_drvdata(struct vlynq_device *dev, void *data) | ||
115 | { | ||
116 | dev_set_drvdata(&dev->dev, data); | ||
117 | } | ||
118 | |||
119 | static inline u32 vlynq_mem_start(struct vlynq_device *dev) | ||
120 | { | ||
121 | return dev->mem_start; | ||
122 | } | ||
123 | |||
124 | static inline u32 vlynq_mem_end(struct vlynq_device *dev) | ||
125 | { | ||
126 | return dev->mem_end; | ||
127 | } | ||
128 | |||
129 | static inline u32 vlynq_mem_len(struct vlynq_device *dev) | ||
130 | { | ||
131 | return dev->mem_end - dev->mem_start + 1; | ||
132 | } | ||
133 | |||
134 | static inline int vlynq_virq_to_irq(struct vlynq_device *dev, int virq) | ||
135 | { | ||
136 | int irq = dev->irq_start + virq; | ||
137 | if ((irq < dev->irq_start) || (irq > dev->irq_end)) | ||
138 | return -EINVAL; | ||
139 | |||
140 | return irq; | ||
141 | } | ||
142 | |||
143 | static inline int vlynq_irq_to_virq(struct vlynq_device *dev, int irq) | ||
144 | { | ||
145 | if ((irq < dev->irq_start) || (irq > dev->irq_end)) | ||
146 | return -EINVAL; | ||
147 | |||
148 | return irq - dev->irq_start; | ||
149 | } | ||
150 | |||
151 | extern void vlynq_unregister_driver(struct vlynq_driver *driver); | ||
152 | extern int vlynq_enable_device(struct vlynq_device *dev); | ||
153 | extern void vlynq_disable_device(struct vlynq_device *dev); | ||
154 | extern int vlynq_set_local_mapping(struct vlynq_device *dev, u32 tx_offset, | ||
155 | struct vlynq_mapping *mapping); | ||
156 | extern int vlynq_set_remote_mapping(struct vlynq_device *dev, u32 tx_offset, | ||
157 | struct vlynq_mapping *mapping); | ||
158 | extern int vlynq_set_local_irq(struct vlynq_device *dev, int virq); | ||
159 | extern int vlynq_set_remote_irq(struct vlynq_device *dev, int virq); | ||
160 | |||
161 | #endif /* __VLYNQ_H__ */ | ||
diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h index 524cd1b28ecb..81a97cf8f0a0 100644 --- a/include/linux/vmstat.h +++ b/include/linux/vmstat.h | |||
@@ -36,12 +36,14 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT, | |||
36 | FOR_ALL_ZONES(PGSTEAL), | 36 | FOR_ALL_ZONES(PGSTEAL), |
37 | FOR_ALL_ZONES(PGSCAN_KSWAPD), | 37 | FOR_ALL_ZONES(PGSCAN_KSWAPD), |
38 | FOR_ALL_ZONES(PGSCAN_DIRECT), | 38 | FOR_ALL_ZONES(PGSCAN_DIRECT), |
39 | #ifdef CONFIG_NUMA | ||
40 | PGSCAN_ZONE_RECLAIM_FAILED, | ||
41 | #endif | ||
39 | PGINODESTEAL, SLABS_SCANNED, KSWAPD_STEAL, KSWAPD_INODESTEAL, | 42 | PGINODESTEAL, SLABS_SCANNED, KSWAPD_STEAL, KSWAPD_INODESTEAL, |
40 | PAGEOUTRUN, ALLOCSTALL, PGROTATED, | 43 | PAGEOUTRUN, ALLOCSTALL, PGROTATED, |
41 | #ifdef CONFIG_HUGETLB_PAGE | 44 | #ifdef CONFIG_HUGETLB_PAGE |
42 | HTLB_BUDDY_PGALLOC, HTLB_BUDDY_PGALLOC_FAIL, | 45 | HTLB_BUDDY_PGALLOC, HTLB_BUDDY_PGALLOC_FAIL, |
43 | #endif | 46 | #endif |
44 | #ifdef CONFIG_UNEVICTABLE_LRU | ||
45 | UNEVICTABLE_PGCULLED, /* culled to noreclaim list */ | 47 | UNEVICTABLE_PGCULLED, /* culled to noreclaim list */ |
46 | UNEVICTABLE_PGSCANNED, /* scanned for reclaimability */ | 48 | UNEVICTABLE_PGSCANNED, /* scanned for reclaimability */ |
47 | UNEVICTABLE_PGRESCUED, /* rescued from noreclaim list */ | 49 | UNEVICTABLE_PGRESCUED, /* rescued from noreclaim list */ |
@@ -50,7 +52,6 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT, | |||
50 | UNEVICTABLE_PGCLEARED, /* on COW, page truncate */ | 52 | UNEVICTABLE_PGCLEARED, /* on COW, page truncate */ |
51 | UNEVICTABLE_PGSTRANDED, /* unable to isolate on unlock */ | 53 | UNEVICTABLE_PGSTRANDED, /* unable to isolate on unlock */ |
52 | UNEVICTABLE_MLOCKFREED, | 54 | UNEVICTABLE_MLOCKFREED, |
53 | #endif | ||
54 | NR_VM_EVENT_ITEMS | 55 | NR_VM_EVENT_ITEMS |
55 | }; | 56 | }; |
56 | 57 | ||
diff --git a/include/video/s1d13xxxfb.h b/include/video/s1d13xxxfb.h index c3b2a2aa7140..f0736cff2ca3 100644 --- a/include/video/s1d13xxxfb.h +++ b/include/video/s1d13xxxfb.h | |||
@@ -136,6 +136,15 @@ | |||
136 | #define S1DREG_DELAYOFF 0xFFFE | 136 | #define S1DREG_DELAYOFF 0xFFFE |
137 | #define S1DREG_DELAYON 0xFFFF | 137 | #define S1DREG_DELAYON 0xFFFF |
138 | 138 | ||
139 | #define BBLT_FIFO_EMPTY 0x00 | ||
140 | #define BBLT_FIFO_NOT_EMPTY 0x40 | ||
141 | #define BBLT_FIFO_NOT_FULL 0x30 | ||
142 | #define BBLT_FIFO_HALF_FULL 0x20 | ||
143 | #define BBLT_FIFO_FULL 0x10 | ||
144 | |||
145 | #define BBLT_SOLID_FILL 0x0c | ||
146 | |||
147 | |||
139 | /* Note: all above defines should go in separate header files | 148 | /* Note: all above defines should go in separate header files |
140 | when implementing other S1D13xxx chip support. */ | 149 | when implementing other S1D13xxx chip support. */ |
141 | 150 | ||
diff --git a/init/main.c b/init/main.c index 7becd8b5c5bf..7756ddad3c85 100644 --- a/init/main.c +++ b/init/main.c | |||
@@ -671,7 +671,6 @@ asmlinkage void __init start_kernel(void) | |||
671 | initrd_start = 0; | 671 | initrd_start = 0; |
672 | } | 672 | } |
673 | #endif | 673 | #endif |
674 | cpuset_init_early(); | ||
675 | page_cgroup_init(); | 674 | page_cgroup_init(); |
676 | enable_debug_pagealloc(); | 675 | enable_debug_pagealloc(); |
677 | cpu_hotplug_init(); | 676 | cpu_hotplug_init(); |
@@ -868,6 +867,11 @@ static noinline int init_post(void) | |||
868 | static int __init kernel_init(void * unused) | 867 | static int __init kernel_init(void * unused) |
869 | { | 868 | { |
870 | lock_kernel(); | 869 | lock_kernel(); |
870 | |||
871 | /* | ||
872 | * init can allocate pages on any node | ||
873 | */ | ||
874 | set_mems_allowed(node_possible_map); | ||
871 | /* | 875 | /* |
872 | * init can run on any cpu. | 876 | * init can run on any cpu. |
873 | */ | 877 | */ |
diff --git a/kernel/Makefile b/kernel/Makefile index 90b53f6dc226..9df4501cb921 100644 --- a/kernel/Makefile +++ b/kernel/Makefile | |||
@@ -11,6 +11,7 @@ obj-y = sched.o fork.o exec_domain.o panic.o printk.o \ | |||
11 | hrtimer.o rwsem.o nsproxy.o srcu.o semaphore.o \ | 11 | hrtimer.o rwsem.o nsproxy.o srcu.o semaphore.o \ |
12 | notifier.o ksysfs.o pm_qos_params.o sched_clock.o cred.o \ | 12 | notifier.o ksysfs.o pm_qos_params.o sched_clock.o cred.o \ |
13 | async.o | 13 | async.o |
14 | obj-y += groups.o | ||
14 | 15 | ||
15 | ifdef CONFIG_FUNCTION_TRACER | 16 | ifdef CONFIG_FUNCTION_TRACER |
16 | # Do not trace debug files and internal ftrace files | 17 | # Do not trace debug files and internal ftrace files |
diff --git a/kernel/cpuset.c b/kernel/cpuset.c index d5a7e17474ee..7e75a41bd508 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c | |||
@@ -97,12 +97,6 @@ struct cpuset { | |||
97 | 97 | ||
98 | struct cpuset *parent; /* my parent */ | 98 | struct cpuset *parent; /* my parent */ |
99 | 99 | ||
100 | /* | ||
101 | * Copy of global cpuset_mems_generation as of the most | ||
102 | * recent time this cpuset changed its mems_allowed. | ||
103 | */ | ||
104 | int mems_generation; | ||
105 | |||
106 | struct fmeter fmeter; /* memory_pressure filter */ | 100 | struct fmeter fmeter; /* memory_pressure filter */ |
107 | 101 | ||
108 | /* partition number for rebuild_sched_domains() */ | 102 | /* partition number for rebuild_sched_domains() */ |
@@ -176,27 +170,6 @@ static inline int is_spread_slab(const struct cpuset *cs) | |||
176 | return test_bit(CS_SPREAD_SLAB, &cs->flags); | 170 | return test_bit(CS_SPREAD_SLAB, &cs->flags); |
177 | } | 171 | } |
178 | 172 | ||
179 | /* | ||
180 | * Increment this integer everytime any cpuset changes its | ||
181 | * mems_allowed value. Users of cpusets can track this generation | ||
182 | * number, and avoid having to lock and reload mems_allowed unless | ||
183 | * the cpuset they're using changes generation. | ||
184 | * | ||
185 | * A single, global generation is needed because cpuset_attach_task() could | ||
186 | * reattach a task to a different cpuset, which must not have its | ||
187 | * generation numbers aliased with those of that tasks previous cpuset. | ||
188 | * | ||
189 | * Generations are needed for mems_allowed because one task cannot | ||
190 | * modify another's memory placement. So we must enable every task, | ||
191 | * on every visit to __alloc_pages(), to efficiently check whether | ||
192 | * its current->cpuset->mems_allowed has changed, requiring an update | ||
193 | * of its current->mems_allowed. | ||
194 | * | ||
195 | * Since writes to cpuset_mems_generation are guarded by the cgroup lock | ||
196 | * there is no need to mark it atomic. | ||
197 | */ | ||
198 | static int cpuset_mems_generation; | ||
199 | |||
200 | static struct cpuset top_cpuset = { | 173 | static struct cpuset top_cpuset = { |
201 | .flags = ((1 << CS_CPU_EXCLUSIVE) | (1 << CS_MEM_EXCLUSIVE)), | 174 | .flags = ((1 << CS_CPU_EXCLUSIVE) | (1 << CS_MEM_EXCLUSIVE)), |
202 | }; | 175 | }; |
@@ -228,8 +201,9 @@ static struct cpuset top_cpuset = { | |||
228 | * If a task is only holding callback_mutex, then it has read-only | 201 | * If a task is only holding callback_mutex, then it has read-only |
229 | * access to cpusets. | 202 | * access to cpusets. |
230 | * | 203 | * |
231 | * The task_struct fields mems_allowed and mems_generation may only | 204 | * Now, the task_struct fields mems_allowed and mempolicy may be changed |
232 | * be accessed in the context of that task, so require no locks. | 205 | * by other task, we use alloc_lock in the task_struct fields to protect |
206 | * them. | ||
233 | * | 207 | * |
234 | * The cpuset_common_file_read() handlers only hold callback_mutex across | 208 | * The cpuset_common_file_read() handlers only hold callback_mutex across |
235 | * small pieces of code, such as when reading out possibly multi-word | 209 | * small pieces of code, such as when reading out possibly multi-word |
@@ -331,75 +305,22 @@ static void guarantee_online_mems(const struct cpuset *cs, nodemask_t *pmask) | |||
331 | BUG_ON(!nodes_intersects(*pmask, node_states[N_HIGH_MEMORY])); | 305 | BUG_ON(!nodes_intersects(*pmask, node_states[N_HIGH_MEMORY])); |
332 | } | 306 | } |
333 | 307 | ||
334 | /** | 308 | /* |
335 | * cpuset_update_task_memory_state - update task memory placement | 309 | * update task's spread flag if cpuset's page/slab spread flag is set |
336 | * | 310 | * |
337 | * If the current tasks cpusets mems_allowed changed behind our | 311 | * Called with callback_mutex/cgroup_mutex held |
338 | * backs, update current->mems_allowed, mems_generation and task NUMA | ||
339 | * mempolicy to the new value. | ||
340 | * | ||
341 | * Task mempolicy is updated by rebinding it relative to the | ||
342 | * current->cpuset if a task has its memory placement changed. | ||
343 | * Do not call this routine if in_interrupt(). | ||
344 | * | ||
345 | * Call without callback_mutex or task_lock() held. May be | ||
346 | * called with or without cgroup_mutex held. Thanks in part to | ||
347 | * 'the_top_cpuset_hack', the task's cpuset pointer will never | ||
348 | * be NULL. This routine also might acquire callback_mutex during | ||
349 | * call. | ||
350 | * | ||
351 | * Reading current->cpuset->mems_generation doesn't need task_lock | ||
352 | * to guard the current->cpuset derefence, because it is guarded | ||
353 | * from concurrent freeing of current->cpuset using RCU. | ||
354 | * | ||
355 | * The rcu_dereference() is technically probably not needed, | ||
356 | * as I don't actually mind if I see a new cpuset pointer but | ||
357 | * an old value of mems_generation. However this really only | ||
358 | * matters on alpha systems using cpusets heavily. If I dropped | ||
359 | * that rcu_dereference(), it would save them a memory barrier. | ||
360 | * For all other arch's, rcu_dereference is a no-op anyway, and for | ||
361 | * alpha systems not using cpusets, another planned optimization, | ||
362 | * avoiding the rcu critical section for tasks in the root cpuset | ||
363 | * which is statically allocated, so can't vanish, will make this | ||
364 | * irrelevant. Better to use RCU as intended, than to engage in | ||
365 | * some cute trick to save a memory barrier that is impossible to | ||
366 | * test, for alpha systems using cpusets heavily, which might not | ||
367 | * even exist. | ||
368 | * | ||
369 | * This routine is needed to update the per-task mems_allowed data, | ||
370 | * within the tasks context, when it is trying to allocate memory | ||
371 | * (in various mm/mempolicy.c routines) and notices that some other | ||
372 | * task has been modifying its cpuset. | ||
373 | */ | 312 | */ |
374 | 313 | static void cpuset_update_task_spread_flag(struct cpuset *cs, | |
375 | void cpuset_update_task_memory_state(void) | 314 | struct task_struct *tsk) |
376 | { | 315 | { |
377 | int my_cpusets_mem_gen; | 316 | if (is_spread_page(cs)) |
378 | struct task_struct *tsk = current; | 317 | tsk->flags |= PF_SPREAD_PAGE; |
379 | struct cpuset *cs; | 318 | else |
380 | 319 | tsk->flags &= ~PF_SPREAD_PAGE; | |
381 | rcu_read_lock(); | 320 | if (is_spread_slab(cs)) |
382 | my_cpusets_mem_gen = task_cs(tsk)->mems_generation; | 321 | tsk->flags |= PF_SPREAD_SLAB; |
383 | rcu_read_unlock(); | 322 | else |
384 | 323 | tsk->flags &= ~PF_SPREAD_SLAB; | |
385 | if (my_cpusets_mem_gen != tsk->cpuset_mems_generation) { | ||
386 | mutex_lock(&callback_mutex); | ||
387 | task_lock(tsk); | ||
388 | cs = task_cs(tsk); /* Maybe changed when task not locked */ | ||
389 | guarantee_online_mems(cs, &tsk->mems_allowed); | ||
390 | tsk->cpuset_mems_generation = cs->mems_generation; | ||
391 | if (is_spread_page(cs)) | ||
392 | tsk->flags |= PF_SPREAD_PAGE; | ||
393 | else | ||
394 | tsk->flags &= ~PF_SPREAD_PAGE; | ||
395 | if (is_spread_slab(cs)) | ||
396 | tsk->flags |= PF_SPREAD_SLAB; | ||
397 | else | ||
398 | tsk->flags &= ~PF_SPREAD_SLAB; | ||
399 | task_unlock(tsk); | ||
400 | mutex_unlock(&callback_mutex); | ||
401 | mpol_rebind_task(tsk, &tsk->mems_allowed); | ||
402 | } | ||
403 | } | 324 | } |
404 | 325 | ||
405 | /* | 326 | /* |
@@ -1007,14 +928,6 @@ static int update_cpumask(struct cpuset *cs, struct cpuset *trialcs, | |||
1007 | * other task, the task_struct mems_allowed that we are hacking | 928 | * other task, the task_struct mems_allowed that we are hacking |
1008 | * is for our current task, which must allocate new pages for that | 929 | * is for our current task, which must allocate new pages for that |
1009 | * migrating memory region. | 930 | * migrating memory region. |
1010 | * | ||
1011 | * We call cpuset_update_task_memory_state() before hacking | ||
1012 | * our tasks mems_allowed, so that we are assured of being in | ||
1013 | * sync with our tasks cpuset, and in particular, callbacks to | ||
1014 | * cpuset_update_task_memory_state() from nested page allocations | ||
1015 | * won't see any mismatch of our cpuset and task mems_generation | ||
1016 | * values, so won't overwrite our hacked tasks mems_allowed | ||
1017 | * nodemask. | ||
1018 | */ | 931 | */ |
1019 | 932 | ||
1020 | static void cpuset_migrate_mm(struct mm_struct *mm, const nodemask_t *from, | 933 | static void cpuset_migrate_mm(struct mm_struct *mm, const nodemask_t *from, |
@@ -1022,22 +935,37 @@ static void cpuset_migrate_mm(struct mm_struct *mm, const nodemask_t *from, | |||
1022 | { | 935 | { |
1023 | struct task_struct *tsk = current; | 936 | struct task_struct *tsk = current; |
1024 | 937 | ||
1025 | cpuset_update_task_memory_state(); | ||
1026 | |||
1027 | mutex_lock(&callback_mutex); | ||
1028 | tsk->mems_allowed = *to; | 938 | tsk->mems_allowed = *to; |
1029 | mutex_unlock(&callback_mutex); | ||
1030 | 939 | ||
1031 | do_migrate_pages(mm, from, to, MPOL_MF_MOVE_ALL); | 940 | do_migrate_pages(mm, from, to, MPOL_MF_MOVE_ALL); |
1032 | 941 | ||
1033 | mutex_lock(&callback_mutex); | ||
1034 | guarantee_online_mems(task_cs(tsk),&tsk->mems_allowed); | 942 | guarantee_online_mems(task_cs(tsk),&tsk->mems_allowed); |
1035 | mutex_unlock(&callback_mutex); | ||
1036 | } | 943 | } |
1037 | 944 | ||
1038 | /* | 945 | /* |
1039 | * Rebind task's vmas to cpuset's new mems_allowed, and migrate pages to new | 946 | * cpuset_change_task_nodemask - change task's mems_allowed and mempolicy |
1040 | * nodes if memory_migrate flag is set. Called with cgroup_mutex held. | 947 | * @tsk: the task to change |
948 | * @newmems: new nodes that the task will be set | ||
949 | * | ||
950 | * In order to avoid seeing no nodes if the old and new nodes are disjoint, | ||
951 | * we structure updates as setting all new allowed nodes, then clearing newly | ||
952 | * disallowed ones. | ||
953 | * | ||
954 | * Called with task's alloc_lock held | ||
955 | */ | ||
956 | static void cpuset_change_task_nodemask(struct task_struct *tsk, | ||
957 | nodemask_t *newmems) | ||
958 | { | ||
959 | nodes_or(tsk->mems_allowed, tsk->mems_allowed, *newmems); | ||
960 | mpol_rebind_task(tsk, &tsk->mems_allowed); | ||
961 | mpol_rebind_task(tsk, newmems); | ||
962 | tsk->mems_allowed = *newmems; | ||
963 | } | ||
964 | |||
965 | /* | ||
966 | * Update task's mems_allowed and rebind its mempolicy and vmas' mempolicy | ||
967 | * of it to cpuset's new mems_allowed, and migrate pages to new nodes if | ||
968 | * memory_migrate flag is set. Called with cgroup_mutex held. | ||
1041 | */ | 969 | */ |
1042 | static void cpuset_change_nodemask(struct task_struct *p, | 970 | static void cpuset_change_nodemask(struct task_struct *p, |
1043 | struct cgroup_scanner *scan) | 971 | struct cgroup_scanner *scan) |
@@ -1046,12 +974,19 @@ static void cpuset_change_nodemask(struct task_struct *p, | |||
1046 | struct cpuset *cs; | 974 | struct cpuset *cs; |
1047 | int migrate; | 975 | int migrate; |
1048 | const nodemask_t *oldmem = scan->data; | 976 | const nodemask_t *oldmem = scan->data; |
977 | nodemask_t newmems; | ||
978 | |||
979 | cs = cgroup_cs(scan->cg); | ||
980 | guarantee_online_mems(cs, &newmems); | ||
981 | |||
982 | task_lock(p); | ||
983 | cpuset_change_task_nodemask(p, &newmems); | ||
984 | task_unlock(p); | ||
1049 | 985 | ||
1050 | mm = get_task_mm(p); | 986 | mm = get_task_mm(p); |
1051 | if (!mm) | 987 | if (!mm) |
1052 | return; | 988 | return; |
1053 | 989 | ||
1054 | cs = cgroup_cs(scan->cg); | ||
1055 | migrate = is_memory_migrate(cs); | 990 | migrate = is_memory_migrate(cs); |
1056 | 991 | ||
1057 | mpol_rebind_mm(mm, &cs->mems_allowed); | 992 | mpol_rebind_mm(mm, &cs->mems_allowed); |
@@ -1104,10 +1039,10 @@ static void update_tasks_nodemask(struct cpuset *cs, const nodemask_t *oldmem, | |||
1104 | /* | 1039 | /* |
1105 | * Handle user request to change the 'mems' memory placement | 1040 | * Handle user request to change the 'mems' memory placement |
1106 | * of a cpuset. Needs to validate the request, update the | 1041 | * of a cpuset. Needs to validate the request, update the |
1107 | * cpusets mems_allowed and mems_generation, and for each | 1042 | * cpusets mems_allowed, and for each task in the cpuset, |
1108 | * task in the cpuset, rebind any vma mempolicies and if | 1043 | * update mems_allowed and rebind task's mempolicy and any vma |
1109 | * the cpuset is marked 'memory_migrate', migrate the tasks | 1044 | * mempolicies and if the cpuset is marked 'memory_migrate', |
1110 | * pages to the new memory. | 1045 | * migrate the tasks pages to the new memory. |
1111 | * | 1046 | * |
1112 | * Call with cgroup_mutex held. May take callback_mutex during call. | 1047 | * Call with cgroup_mutex held. May take callback_mutex during call. |
1113 | * Will take tasklist_lock, scan tasklist for tasks in cpuset cs, | 1048 | * Will take tasklist_lock, scan tasklist for tasks in cpuset cs, |
@@ -1160,7 +1095,6 @@ static int update_nodemask(struct cpuset *cs, struct cpuset *trialcs, | |||
1160 | 1095 | ||
1161 | mutex_lock(&callback_mutex); | 1096 | mutex_lock(&callback_mutex); |
1162 | cs->mems_allowed = trialcs->mems_allowed; | 1097 | cs->mems_allowed = trialcs->mems_allowed; |
1163 | cs->mems_generation = cpuset_mems_generation++; | ||
1164 | mutex_unlock(&callback_mutex); | 1098 | mutex_unlock(&callback_mutex); |
1165 | 1099 | ||
1166 | update_tasks_nodemask(cs, &oldmem, &heap); | 1100 | update_tasks_nodemask(cs, &oldmem, &heap); |
@@ -1193,6 +1127,46 @@ static int update_relax_domain_level(struct cpuset *cs, s64 val) | |||
1193 | } | 1127 | } |
1194 | 1128 | ||
1195 | /* | 1129 | /* |
1130 | * cpuset_change_flag - make a task's spread flags the same as its cpuset's | ||
1131 | * @tsk: task to be updated | ||
1132 | * @scan: struct cgroup_scanner containing the cgroup of the task | ||
1133 | * | ||
1134 | * Called by cgroup_scan_tasks() for each task in a cgroup. | ||
1135 | * | ||
1136 | * We don't need to re-check for the cgroup/cpuset membership, since we're | ||
1137 | * holding cgroup_lock() at this point. | ||
1138 | */ | ||
1139 | static void cpuset_change_flag(struct task_struct *tsk, | ||
1140 | struct cgroup_scanner *scan) | ||
1141 | { | ||
1142 | cpuset_update_task_spread_flag(cgroup_cs(scan->cg), tsk); | ||
1143 | } | ||
1144 | |||
1145 | /* | ||
1146 | * update_tasks_flags - update the spread flags of tasks in the cpuset. | ||
1147 | * @cs: the cpuset in which each task's spread flags needs to be changed | ||
1148 | * @heap: if NULL, defer allocating heap memory to cgroup_scan_tasks() | ||
1149 | * | ||
1150 | * Called with cgroup_mutex held | ||
1151 | * | ||
1152 | * The cgroup_scan_tasks() function will scan all the tasks in a cgroup, | ||
1153 | * calling callback functions for each. | ||
1154 | * | ||
1155 | * No return value. It's guaranteed that cgroup_scan_tasks() always returns 0 | ||
1156 | * if @heap != NULL. | ||
1157 | */ | ||
1158 | static void update_tasks_flags(struct cpuset *cs, struct ptr_heap *heap) | ||
1159 | { | ||
1160 | struct cgroup_scanner scan; | ||
1161 | |||
1162 | scan.cg = cs->css.cgroup; | ||
1163 | scan.test_task = NULL; | ||
1164 | scan.process_task = cpuset_change_flag; | ||
1165 | scan.heap = heap; | ||
1166 | cgroup_scan_tasks(&scan); | ||
1167 | } | ||
1168 | |||
1169 | /* | ||
1196 | * update_flag - read a 0 or a 1 in a file and update associated flag | 1170 | * update_flag - read a 0 or a 1 in a file and update associated flag |
1197 | * bit: the bit to update (see cpuset_flagbits_t) | 1171 | * bit: the bit to update (see cpuset_flagbits_t) |
1198 | * cs: the cpuset to update | 1172 | * cs: the cpuset to update |
@@ -1205,8 +1179,10 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs, | |||
1205 | int turning_on) | 1179 | int turning_on) |
1206 | { | 1180 | { |
1207 | struct cpuset *trialcs; | 1181 | struct cpuset *trialcs; |
1208 | int err; | ||
1209 | int balance_flag_changed; | 1182 | int balance_flag_changed; |
1183 | int spread_flag_changed; | ||
1184 | struct ptr_heap heap; | ||
1185 | int err; | ||
1210 | 1186 | ||
1211 | trialcs = alloc_trial_cpuset(cs); | 1187 | trialcs = alloc_trial_cpuset(cs); |
1212 | if (!trialcs) | 1188 | if (!trialcs) |
@@ -1221,9 +1197,16 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs, | |||
1221 | if (err < 0) | 1197 | if (err < 0) |
1222 | goto out; | 1198 | goto out; |
1223 | 1199 | ||
1200 | err = heap_init(&heap, PAGE_SIZE, GFP_KERNEL, NULL); | ||
1201 | if (err < 0) | ||
1202 | goto out; | ||
1203 | |||
1224 | balance_flag_changed = (is_sched_load_balance(cs) != | 1204 | balance_flag_changed = (is_sched_load_balance(cs) != |
1225 | is_sched_load_balance(trialcs)); | 1205 | is_sched_load_balance(trialcs)); |
1226 | 1206 | ||
1207 | spread_flag_changed = ((is_spread_slab(cs) != is_spread_slab(trialcs)) | ||
1208 | || (is_spread_page(cs) != is_spread_page(trialcs))); | ||
1209 | |||
1227 | mutex_lock(&callback_mutex); | 1210 | mutex_lock(&callback_mutex); |
1228 | cs->flags = trialcs->flags; | 1211 | cs->flags = trialcs->flags; |
1229 | mutex_unlock(&callback_mutex); | 1212 | mutex_unlock(&callback_mutex); |
@@ -1231,6 +1214,9 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs, | |||
1231 | if (!cpumask_empty(trialcs->cpus_allowed) && balance_flag_changed) | 1214 | if (!cpumask_empty(trialcs->cpus_allowed) && balance_flag_changed) |
1232 | async_rebuild_sched_domains(); | 1215 | async_rebuild_sched_domains(); |
1233 | 1216 | ||
1217 | if (spread_flag_changed) | ||
1218 | update_tasks_flags(cs, &heap); | ||
1219 | heap_free(&heap); | ||
1234 | out: | 1220 | out: |
1235 | free_trial_cpuset(trialcs); | 1221 | free_trial_cpuset(trialcs); |
1236 | return err; | 1222 | return err; |
@@ -1372,15 +1358,20 @@ static void cpuset_attach(struct cgroup_subsys *ss, | |||
1372 | 1358 | ||
1373 | if (cs == &top_cpuset) { | 1359 | if (cs == &top_cpuset) { |
1374 | cpumask_copy(cpus_attach, cpu_possible_mask); | 1360 | cpumask_copy(cpus_attach, cpu_possible_mask); |
1361 | to = node_possible_map; | ||
1375 | } else { | 1362 | } else { |
1376 | mutex_lock(&callback_mutex); | ||
1377 | guarantee_online_cpus(cs, cpus_attach); | 1363 | guarantee_online_cpus(cs, cpus_attach); |
1378 | mutex_unlock(&callback_mutex); | 1364 | guarantee_online_mems(cs, &to); |
1379 | } | 1365 | } |
1380 | err = set_cpus_allowed_ptr(tsk, cpus_attach); | 1366 | err = set_cpus_allowed_ptr(tsk, cpus_attach); |
1381 | if (err) | 1367 | if (err) |
1382 | return; | 1368 | return; |
1383 | 1369 | ||
1370 | task_lock(tsk); | ||
1371 | cpuset_change_task_nodemask(tsk, &to); | ||
1372 | task_unlock(tsk); | ||
1373 | cpuset_update_task_spread_flag(cs, tsk); | ||
1374 | |||
1384 | from = oldcs->mems_allowed; | 1375 | from = oldcs->mems_allowed; |
1385 | to = cs->mems_allowed; | 1376 | to = cs->mems_allowed; |
1386 | mm = get_task_mm(tsk); | 1377 | mm = get_task_mm(tsk); |
@@ -1442,11 +1433,9 @@ static int cpuset_write_u64(struct cgroup *cgrp, struct cftype *cft, u64 val) | |||
1442 | break; | 1433 | break; |
1443 | case FILE_SPREAD_PAGE: | 1434 | case FILE_SPREAD_PAGE: |
1444 | retval = update_flag(CS_SPREAD_PAGE, cs, val); | 1435 | retval = update_flag(CS_SPREAD_PAGE, cs, val); |
1445 | cs->mems_generation = cpuset_mems_generation++; | ||
1446 | break; | 1436 | break; |
1447 | case FILE_SPREAD_SLAB: | 1437 | case FILE_SPREAD_SLAB: |
1448 | retval = update_flag(CS_SPREAD_SLAB, cs, val); | 1438 | retval = update_flag(CS_SPREAD_SLAB, cs, val); |
1449 | cs->mems_generation = cpuset_mems_generation++; | ||
1450 | break; | 1439 | break; |
1451 | default: | 1440 | default: |
1452 | retval = -EINVAL; | 1441 | retval = -EINVAL; |
@@ -1786,8 +1775,6 @@ static struct cgroup_subsys_state *cpuset_create( | |||
1786 | struct cpuset *parent; | 1775 | struct cpuset *parent; |
1787 | 1776 | ||
1788 | if (!cont->parent) { | 1777 | if (!cont->parent) { |
1789 | /* This is early initialization for the top cgroup */ | ||
1790 | top_cpuset.mems_generation = cpuset_mems_generation++; | ||
1791 | return &top_cpuset.css; | 1778 | return &top_cpuset.css; |
1792 | } | 1779 | } |
1793 | parent = cgroup_cs(cont->parent); | 1780 | parent = cgroup_cs(cont->parent); |
@@ -1799,7 +1786,6 @@ static struct cgroup_subsys_state *cpuset_create( | |||
1799 | return ERR_PTR(-ENOMEM); | 1786 | return ERR_PTR(-ENOMEM); |
1800 | } | 1787 | } |
1801 | 1788 | ||
1802 | cpuset_update_task_memory_state(); | ||
1803 | cs->flags = 0; | 1789 | cs->flags = 0; |
1804 | if (is_spread_page(parent)) | 1790 | if (is_spread_page(parent)) |
1805 | set_bit(CS_SPREAD_PAGE, &cs->flags); | 1791 | set_bit(CS_SPREAD_PAGE, &cs->flags); |
@@ -1808,7 +1794,6 @@ static struct cgroup_subsys_state *cpuset_create( | |||
1808 | set_bit(CS_SCHED_LOAD_BALANCE, &cs->flags); | 1794 | set_bit(CS_SCHED_LOAD_BALANCE, &cs->flags); |
1809 | cpumask_clear(cs->cpus_allowed); | 1795 | cpumask_clear(cs->cpus_allowed); |
1810 | nodes_clear(cs->mems_allowed); | 1796 | nodes_clear(cs->mems_allowed); |
1811 | cs->mems_generation = cpuset_mems_generation++; | ||
1812 | fmeter_init(&cs->fmeter); | 1797 | fmeter_init(&cs->fmeter); |
1813 | cs->relax_domain_level = -1; | 1798 | cs->relax_domain_level = -1; |
1814 | 1799 | ||
@@ -1827,8 +1812,6 @@ static void cpuset_destroy(struct cgroup_subsys *ss, struct cgroup *cont) | |||
1827 | { | 1812 | { |
1828 | struct cpuset *cs = cgroup_cs(cont); | 1813 | struct cpuset *cs = cgroup_cs(cont); |
1829 | 1814 | ||
1830 | cpuset_update_task_memory_state(); | ||
1831 | |||
1832 | if (is_sched_load_balance(cs)) | 1815 | if (is_sched_load_balance(cs)) |
1833 | update_flag(CS_SCHED_LOAD_BALANCE, cs, 0); | 1816 | update_flag(CS_SCHED_LOAD_BALANCE, cs, 0); |
1834 | 1817 | ||
@@ -1849,21 +1832,6 @@ struct cgroup_subsys cpuset_subsys = { | |||
1849 | .early_init = 1, | 1832 | .early_init = 1, |
1850 | }; | 1833 | }; |
1851 | 1834 | ||
1852 | /* | ||
1853 | * cpuset_init_early - just enough so that the calls to | ||
1854 | * cpuset_update_task_memory_state() in early init code | ||
1855 | * are harmless. | ||
1856 | */ | ||
1857 | |||
1858 | int __init cpuset_init_early(void) | ||
1859 | { | ||
1860 | alloc_cpumask_var(&top_cpuset.cpus_allowed, GFP_NOWAIT); | ||
1861 | |||
1862 | top_cpuset.mems_generation = cpuset_mems_generation++; | ||
1863 | return 0; | ||
1864 | } | ||
1865 | |||
1866 | |||
1867 | /** | 1835 | /** |
1868 | * cpuset_init - initialize cpusets at system boot | 1836 | * cpuset_init - initialize cpusets at system boot |
1869 | * | 1837 | * |
@@ -1874,11 +1842,13 @@ int __init cpuset_init(void) | |||
1874 | { | 1842 | { |
1875 | int err = 0; | 1843 | int err = 0; |
1876 | 1844 | ||
1845 | if (!alloc_cpumask_var(&top_cpuset.cpus_allowed, GFP_KERNEL)) | ||
1846 | BUG(); | ||
1847 | |||
1877 | cpumask_setall(top_cpuset.cpus_allowed); | 1848 | cpumask_setall(top_cpuset.cpus_allowed); |
1878 | nodes_setall(top_cpuset.mems_allowed); | 1849 | nodes_setall(top_cpuset.mems_allowed); |
1879 | 1850 | ||
1880 | fmeter_init(&top_cpuset.fmeter); | 1851 | fmeter_init(&top_cpuset.fmeter); |
1881 | top_cpuset.mems_generation = cpuset_mems_generation++; | ||
1882 | set_bit(CS_SCHED_LOAD_BALANCE, &top_cpuset.flags); | 1852 | set_bit(CS_SCHED_LOAD_BALANCE, &top_cpuset.flags); |
1883 | top_cpuset.relax_domain_level = -1; | 1853 | top_cpuset.relax_domain_level = -1; |
1884 | 1854 | ||
diff --git a/kernel/groups.c b/kernel/groups.c new file mode 100644 index 000000000000..2b45b2ee3964 --- /dev/null +++ b/kernel/groups.c | |||
@@ -0,0 +1,288 @@ | |||
1 | /* | ||
2 | * Supplementary group IDs | ||
3 | */ | ||
4 | #include <linux/cred.h> | ||
5 | #include <linux/module.h> | ||
6 | #include <linux/slab.h> | ||
7 | #include <linux/security.h> | ||
8 | #include <linux/syscalls.h> | ||
9 | #include <asm/uaccess.h> | ||
10 | |||
11 | /* init to 2 - one for init_task, one to ensure it is never freed */ | ||
12 | struct group_info init_groups = { .usage = ATOMIC_INIT(2) }; | ||
13 | |||
14 | struct group_info *groups_alloc(int gidsetsize) | ||
15 | { | ||
16 | struct group_info *group_info; | ||
17 | int nblocks; | ||
18 | int i; | ||
19 | |||
20 | nblocks = (gidsetsize + NGROUPS_PER_BLOCK - 1) / NGROUPS_PER_BLOCK; | ||
21 | /* Make sure we always allocate at least one indirect block pointer */ | ||
22 | nblocks = nblocks ? : 1; | ||
23 | group_info = kmalloc(sizeof(*group_info) + nblocks*sizeof(gid_t *), GFP_USER); | ||
24 | if (!group_info) | ||
25 | return NULL; | ||
26 | group_info->ngroups = gidsetsize; | ||
27 | group_info->nblocks = nblocks; | ||
28 | atomic_set(&group_info->usage, 1); | ||
29 | |||
30 | if (gidsetsize <= NGROUPS_SMALL) | ||
31 | group_info->blocks[0] = group_info->small_block; | ||
32 | else { | ||
33 | for (i = 0; i < nblocks; i++) { | ||
34 | gid_t *b; | ||
35 | b = (void *)__get_free_page(GFP_USER); | ||
36 | if (!b) | ||
37 | goto out_undo_partial_alloc; | ||
38 | group_info->blocks[i] = b; | ||
39 | } | ||
40 | } | ||
41 | return group_info; | ||
42 | |||
43 | out_undo_partial_alloc: | ||
44 | while (--i >= 0) { | ||
45 | free_page((unsigned long)group_info->blocks[i]); | ||
46 | } | ||
47 | kfree(group_info); | ||
48 | return NULL; | ||
49 | } | ||
50 | |||
51 | EXPORT_SYMBOL(groups_alloc); | ||
52 | |||
53 | void groups_free(struct group_info *group_info) | ||
54 | { | ||
55 | if (group_info->blocks[0] != group_info->small_block) { | ||
56 | int i; | ||
57 | for (i = 0; i < group_info->nblocks; i++) | ||
58 | free_page((unsigned long)group_info->blocks[i]); | ||
59 | } | ||
60 | kfree(group_info); | ||
61 | } | ||
62 | |||
63 | EXPORT_SYMBOL(groups_free); | ||
64 | |||
65 | /* export the group_info to a user-space array */ | ||
66 | static int groups_to_user(gid_t __user *grouplist, | ||
67 | const struct group_info *group_info) | ||
68 | { | ||
69 | int i; | ||
70 | unsigned int count = group_info->ngroups; | ||
71 | |||
72 | for (i = 0; i < group_info->nblocks; i++) { | ||
73 | unsigned int cp_count = min(NGROUPS_PER_BLOCK, count); | ||
74 | unsigned int len = cp_count * sizeof(*grouplist); | ||
75 | |||
76 | if (copy_to_user(grouplist, group_info->blocks[i], len)) | ||
77 | return -EFAULT; | ||
78 | |||
79 | grouplist += NGROUPS_PER_BLOCK; | ||
80 | count -= cp_count; | ||
81 | } | ||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | /* fill a group_info from a user-space array - it must be allocated already */ | ||
86 | static int groups_from_user(struct group_info *group_info, | ||
87 | gid_t __user *grouplist) | ||
88 | { | ||
89 | int i; | ||
90 | unsigned int count = group_info->ngroups; | ||
91 | |||
92 | for (i = 0; i < group_info->nblocks; i++) { | ||
93 | unsigned int cp_count = min(NGROUPS_PER_BLOCK, count); | ||
94 | unsigned int len = cp_count * sizeof(*grouplist); | ||
95 | |||
96 | if (copy_from_user(group_info->blocks[i], grouplist, len)) | ||
97 | return -EFAULT; | ||
98 | |||
99 | grouplist += NGROUPS_PER_BLOCK; | ||
100 | count -= cp_count; | ||
101 | } | ||
102 | return 0; | ||
103 | } | ||
104 | |||
105 | /* a simple Shell sort */ | ||
106 | static void groups_sort(struct group_info *group_info) | ||
107 | { | ||
108 | int base, max, stride; | ||
109 | int gidsetsize = group_info->ngroups; | ||
110 | |||
111 | for (stride = 1; stride < gidsetsize; stride = 3 * stride + 1) | ||
112 | ; /* nothing */ | ||
113 | stride /= 3; | ||
114 | |||
115 | while (stride) { | ||
116 | max = gidsetsize - stride; | ||
117 | for (base = 0; base < max; base++) { | ||
118 | int left = base; | ||
119 | int right = left + stride; | ||
120 | gid_t tmp = GROUP_AT(group_info, right); | ||
121 | |||
122 | while (left >= 0 && GROUP_AT(group_info, left) > tmp) { | ||
123 | GROUP_AT(group_info, right) = | ||
124 | GROUP_AT(group_info, left); | ||
125 | right = left; | ||
126 | left -= stride; | ||
127 | } | ||
128 | GROUP_AT(group_info, right) = tmp; | ||
129 | } | ||
130 | stride /= 3; | ||
131 | } | ||
132 | } | ||
133 | |||
134 | /* a simple bsearch */ | ||
135 | int groups_search(const struct group_info *group_info, gid_t grp) | ||
136 | { | ||
137 | unsigned int left, right; | ||
138 | |||
139 | if (!group_info) | ||
140 | return 0; | ||
141 | |||
142 | left = 0; | ||
143 | right = group_info->ngroups; | ||
144 | while (left < right) { | ||
145 | unsigned int mid = (left+right)/2; | ||
146 | int cmp = grp - GROUP_AT(group_info, mid); | ||
147 | if (cmp > 0) | ||
148 | left = mid + 1; | ||
149 | else if (cmp < 0) | ||
150 | right = mid; | ||
151 | else | ||
152 | return 1; | ||
153 | } | ||
154 | return 0; | ||
155 | } | ||
156 | |||
157 | /** | ||
158 | * set_groups - Change a group subscription in a set of credentials | ||
159 | * @new: The newly prepared set of credentials to alter | ||
160 | * @group_info: The group list to install | ||
161 | * | ||
162 | * Validate a group subscription and, if valid, insert it into a set | ||
163 | * of credentials. | ||
164 | */ | ||
165 | int set_groups(struct cred *new, struct group_info *group_info) | ||
166 | { | ||
167 | int retval; | ||
168 | |||
169 | retval = security_task_setgroups(group_info); | ||
170 | if (retval) | ||
171 | return retval; | ||
172 | |||
173 | put_group_info(new->group_info); | ||
174 | groups_sort(group_info); | ||
175 | get_group_info(group_info); | ||
176 | new->group_info = group_info; | ||
177 | return 0; | ||
178 | } | ||
179 | |||
180 | EXPORT_SYMBOL(set_groups); | ||
181 | |||
182 | /** | ||
183 | * set_current_groups - Change current's group subscription | ||
184 | * @group_info: The group list to impose | ||
185 | * | ||
186 | * Validate a group subscription and, if valid, impose it upon current's task | ||
187 | * security record. | ||
188 | */ | ||
189 | int set_current_groups(struct group_info *group_info) | ||
190 | { | ||
191 | struct cred *new; | ||
192 | int ret; | ||
193 | |||
194 | new = prepare_creds(); | ||
195 | if (!new) | ||
196 | return -ENOMEM; | ||
197 | |||
198 | ret = set_groups(new, group_info); | ||
199 | if (ret < 0) { | ||
200 | abort_creds(new); | ||
201 | return ret; | ||
202 | } | ||
203 | |||
204 | return commit_creds(new); | ||
205 | } | ||
206 | |||
207 | EXPORT_SYMBOL(set_current_groups); | ||
208 | |||
209 | SYSCALL_DEFINE2(getgroups, int, gidsetsize, gid_t __user *, grouplist) | ||
210 | { | ||
211 | const struct cred *cred = current_cred(); | ||
212 | int i; | ||
213 | |||
214 | if (gidsetsize < 0) | ||
215 | return -EINVAL; | ||
216 | |||
217 | /* no need to grab task_lock here; it cannot change */ | ||
218 | i = cred->group_info->ngroups; | ||
219 | if (gidsetsize) { | ||
220 | if (i > gidsetsize) { | ||
221 | i = -EINVAL; | ||
222 | goto out; | ||
223 | } | ||
224 | if (groups_to_user(grouplist, cred->group_info)) { | ||
225 | i = -EFAULT; | ||
226 | goto out; | ||
227 | } | ||
228 | } | ||
229 | out: | ||
230 | return i; | ||
231 | } | ||
232 | |||
233 | /* | ||
234 | * SMP: Our groups are copy-on-write. We can set them safely | ||
235 | * without another task interfering. | ||
236 | */ | ||
237 | |||
238 | SYSCALL_DEFINE2(setgroups, int, gidsetsize, gid_t __user *, grouplist) | ||
239 | { | ||
240 | struct group_info *group_info; | ||
241 | int retval; | ||
242 | |||
243 | if (!capable(CAP_SETGID)) | ||
244 | return -EPERM; | ||
245 | if ((unsigned)gidsetsize > NGROUPS_MAX) | ||
246 | return -EINVAL; | ||
247 | |||
248 | group_info = groups_alloc(gidsetsize); | ||
249 | if (!group_info) | ||
250 | return -ENOMEM; | ||
251 | retval = groups_from_user(group_info, grouplist); | ||
252 | if (retval) { | ||
253 | put_group_info(group_info); | ||
254 | return retval; | ||
255 | } | ||
256 | |||
257 | retval = set_current_groups(group_info); | ||
258 | put_group_info(group_info); | ||
259 | |||
260 | return retval; | ||
261 | } | ||
262 | |||
263 | /* | ||
264 | * Check whether we're fsgid/egid or in the supplemental group.. | ||
265 | */ | ||
266 | int in_group_p(gid_t grp) | ||
267 | { | ||
268 | const struct cred *cred = current_cred(); | ||
269 | int retval = 1; | ||
270 | |||
271 | if (grp != cred->fsgid) | ||
272 | retval = groups_search(cred->group_info, grp); | ||
273 | return retval; | ||
274 | } | ||
275 | |||
276 | EXPORT_SYMBOL(in_group_p); | ||
277 | |||
278 | int in_egroup_p(gid_t grp) | ||
279 | { | ||
280 | const struct cred *cred = current_cred(); | ||
281 | int retval = 1; | ||
282 | |||
283 | if (grp != cred->egid) | ||
284 | retval = groups_search(cred->group_info, grp); | ||
285 | return retval; | ||
286 | } | ||
287 | |||
288 | EXPORT_SYMBOL(in_egroup_p); | ||
diff --git a/kernel/kfifo.c b/kernel/kfifo.c index bc41ad0f24f8..26539e3228e5 100644 --- a/kernel/kfifo.c +++ b/kernel/kfifo.c | |||
@@ -72,9 +72,9 @@ struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask, spinlock_t *lock) | |||
72 | 72 | ||
73 | /* | 73 | /* |
74 | * round up to the next power of 2, since our 'let the indices | 74 | * round up to the next power of 2, since our 'let the indices |
75 | * wrap' tachnique works only in this case. | 75 | * wrap' technique works only in this case. |
76 | */ | 76 | */ |
77 | if (size & (size - 1)) { | 77 | if (!is_power_of_2(size)) { |
78 | BUG_ON(size > 0x80000000); | 78 | BUG_ON(size > 0x80000000); |
79 | size = roundup_pow_of_two(size); | 79 | size = roundup_pow_of_two(size); |
80 | } | 80 | } |
diff --git a/kernel/kthread.c b/kernel/kthread.c index 41c88fe40500..7fa441333529 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/kthread.h> | 9 | #include <linux/kthread.h> |
10 | #include <linux/completion.h> | 10 | #include <linux/completion.h> |
11 | #include <linux/err.h> | 11 | #include <linux/err.h> |
12 | #include <linux/cpuset.h> | ||
12 | #include <linux/unistd.h> | 13 | #include <linux/unistd.h> |
13 | #include <linux/file.h> | 14 | #include <linux/file.h> |
14 | #include <linux/module.h> | 15 | #include <linux/module.h> |
@@ -236,6 +237,7 @@ int kthreadd(void *unused) | |||
236 | ignore_signals(tsk); | 237 | ignore_signals(tsk); |
237 | set_user_nice(tsk, KTHREAD_NICE_LEVEL); | 238 | set_user_nice(tsk, KTHREAD_NICE_LEVEL); |
238 | set_cpus_allowed_ptr(tsk, cpu_all_mask); | 239 | set_cpus_allowed_ptr(tsk, cpu_all_mask); |
240 | set_mems_allowed(node_possible_map); | ||
239 | 241 | ||
240 | current->flags |= PF_NOFREEZE | PF_FREEZER_NOSIG; | 242 | current->flags |= PF_NOFREEZE | PF_FREEZER_NOSIG; |
241 | 243 | ||
diff --git a/kernel/power/process.c b/kernel/power/process.c index ca634019497a..da2072d73811 100644 --- a/kernel/power/process.c +++ b/kernel/power/process.c | |||
@@ -117,9 +117,12 @@ int freeze_processes(void) | |||
117 | if (error) | 117 | if (error) |
118 | goto Exit; | 118 | goto Exit; |
119 | printk("done."); | 119 | printk("done."); |
120 | |||
121 | oom_killer_disable(); | ||
120 | Exit: | 122 | Exit: |
121 | BUG_ON(in_atomic()); | 123 | BUG_ON(in_atomic()); |
122 | printk("\n"); | 124 | printk("\n"); |
125 | |||
123 | return error; | 126 | return error; |
124 | } | 127 | } |
125 | 128 | ||
@@ -145,6 +148,8 @@ static void thaw_tasks(bool nosig_only) | |||
145 | 148 | ||
146 | void thaw_processes(void) | 149 | void thaw_processes(void) |
147 | { | 150 | { |
151 | oom_killer_enable(); | ||
152 | |||
148 | printk("Restarting tasks ... "); | 153 | printk("Restarting tasks ... "); |
149 | thaw_tasks(true); | 154 | thaw_tasks(true); |
150 | thaw_tasks(false); | 155 | thaw_tasks(false); |
diff --git a/kernel/profile.c b/kernel/profile.c index 28cf26ad2d24..69911b5745eb 100644 --- a/kernel/profile.c +++ b/kernel/profile.c | |||
@@ -365,7 +365,7 @@ static int __cpuinit profile_cpu_callback(struct notifier_block *info, | |||
365 | node = cpu_to_node(cpu); | 365 | node = cpu_to_node(cpu); |
366 | per_cpu(cpu_profile_flip, cpu) = 0; | 366 | per_cpu(cpu_profile_flip, cpu) = 0; |
367 | if (!per_cpu(cpu_profile_hits, cpu)[1]) { | 367 | if (!per_cpu(cpu_profile_hits, cpu)[1]) { |
368 | page = alloc_pages_node(node, | 368 | page = alloc_pages_exact_node(node, |
369 | GFP_KERNEL | __GFP_ZERO, | 369 | GFP_KERNEL | __GFP_ZERO, |
370 | 0); | 370 | 0); |
371 | if (!page) | 371 | if (!page) |
@@ -373,7 +373,7 @@ static int __cpuinit profile_cpu_callback(struct notifier_block *info, | |||
373 | per_cpu(cpu_profile_hits, cpu)[1] = page_address(page); | 373 | per_cpu(cpu_profile_hits, cpu)[1] = page_address(page); |
374 | } | 374 | } |
375 | if (!per_cpu(cpu_profile_hits, cpu)[0]) { | 375 | if (!per_cpu(cpu_profile_hits, cpu)[0]) { |
376 | page = alloc_pages_node(node, | 376 | page = alloc_pages_exact_node(node, |
377 | GFP_KERNEL | __GFP_ZERO, | 377 | GFP_KERNEL | __GFP_ZERO, |
378 | 0); | 378 | 0); |
379 | if (!page) | 379 | if (!page) |
@@ -564,14 +564,14 @@ static int create_hash_tables(void) | |||
564 | int node = cpu_to_node(cpu); | 564 | int node = cpu_to_node(cpu); |
565 | struct page *page; | 565 | struct page *page; |
566 | 566 | ||
567 | page = alloc_pages_node(node, | 567 | page = alloc_pages_exact_node(node, |
568 | GFP_KERNEL | __GFP_ZERO | GFP_THISNODE, | 568 | GFP_KERNEL | __GFP_ZERO | GFP_THISNODE, |
569 | 0); | 569 | 0); |
570 | if (!page) | 570 | if (!page) |
571 | goto out_cleanup; | 571 | goto out_cleanup; |
572 | per_cpu(cpu_profile_hits, cpu)[1] | 572 | per_cpu(cpu_profile_hits, cpu)[1] |
573 | = (struct profile_hit *)page_address(page); | 573 | = (struct profile_hit *)page_address(page); |
574 | page = alloc_pages_node(node, | 574 | page = alloc_pages_exact_node(node, |
575 | GFP_KERNEL | __GFP_ZERO | GFP_THISNODE, | 575 | GFP_KERNEL | __GFP_ZERO | GFP_THISNODE, |
576 | 0); | 576 | 0); |
577 | if (!page) | 577 | if (!page) |
diff --git a/kernel/slow-work.c b/kernel/slow-work.c index 521ed2004d63..09d7519557d3 100644 --- a/kernel/slow-work.c +++ b/kernel/slow-work.c | |||
@@ -319,6 +319,15 @@ cant_get_ref: | |||
319 | EXPORT_SYMBOL(slow_work_enqueue); | 319 | EXPORT_SYMBOL(slow_work_enqueue); |
320 | 320 | ||
321 | /* | 321 | /* |
322 | * Schedule a cull of the thread pool at some time in the near future | ||
323 | */ | ||
324 | static void slow_work_schedule_cull(void) | ||
325 | { | ||
326 | mod_timer(&slow_work_cull_timer, | ||
327 | round_jiffies(jiffies + SLOW_WORK_CULL_TIMEOUT)); | ||
328 | } | ||
329 | |||
330 | /* | ||
322 | * Worker thread culling algorithm | 331 | * Worker thread culling algorithm |
323 | */ | 332 | */ |
324 | static bool slow_work_cull_thread(void) | 333 | static bool slow_work_cull_thread(void) |
@@ -335,8 +344,7 @@ static bool slow_work_cull_thread(void) | |||
335 | list_empty(&vslow_work_queue) && | 344 | list_empty(&vslow_work_queue) && |
336 | atomic_read(&slow_work_thread_count) > | 345 | atomic_read(&slow_work_thread_count) > |
337 | slow_work_min_threads) { | 346 | slow_work_min_threads) { |
338 | mod_timer(&slow_work_cull_timer, | 347 | slow_work_schedule_cull(); |
339 | jiffies + SLOW_WORK_CULL_TIMEOUT); | ||
340 | do_cull = true; | 348 | do_cull = true; |
341 | } | 349 | } |
342 | } | 350 | } |
@@ -393,8 +401,7 @@ static int slow_work_thread(void *_data) | |||
393 | list_empty(&vslow_work_queue) && | 401 | list_empty(&vslow_work_queue) && |
394 | atomic_read(&slow_work_thread_count) > | 402 | atomic_read(&slow_work_thread_count) > |
395 | slow_work_min_threads) | 403 | slow_work_min_threads) |
396 | mod_timer(&slow_work_cull_timer, | 404 | slow_work_schedule_cull(); |
397 | jiffies + SLOW_WORK_CULL_TIMEOUT); | ||
398 | continue; | 405 | continue; |
399 | } | 406 | } |
400 | 407 | ||
@@ -458,7 +465,7 @@ static void slow_work_new_thread_execute(struct slow_work *work) | |||
458 | if (atomic_dec_and_test(&slow_work_thread_count)) | 465 | if (atomic_dec_and_test(&slow_work_thread_count)) |
459 | BUG(); /* we're running on a slow work thread... */ | 466 | BUG(); /* we're running on a slow work thread... */ |
460 | mod_timer(&slow_work_oom_timer, | 467 | mod_timer(&slow_work_oom_timer, |
461 | jiffies + SLOW_WORK_OOM_TIMEOUT); | 468 | round_jiffies(jiffies + SLOW_WORK_OOM_TIMEOUT)); |
462 | } else { | 469 | } else { |
463 | /* ratelimit the starting of new threads */ | 470 | /* ratelimit the starting of new threads */ |
464 | mod_timer(&slow_work_oom_timer, jiffies + 1); | 471 | mod_timer(&slow_work_oom_timer, jiffies + 1); |
@@ -502,8 +509,7 @@ static int slow_work_min_threads_sysctl(struct ctl_table *table, int write, | |||
502 | if (n < 0 && !slow_work_may_not_start_new_thread) | 509 | if (n < 0 && !slow_work_may_not_start_new_thread) |
503 | slow_work_enqueue(&slow_work_new_thread); | 510 | slow_work_enqueue(&slow_work_new_thread); |
504 | else if (n > 0) | 511 | else if (n > 0) |
505 | mod_timer(&slow_work_cull_timer, | 512 | slow_work_schedule_cull(); |
506 | jiffies + SLOW_WORK_CULL_TIMEOUT); | ||
507 | } | 513 | } |
508 | mutex_unlock(&slow_work_user_lock); | 514 | mutex_unlock(&slow_work_user_lock); |
509 | } | 515 | } |
@@ -529,8 +535,7 @@ static int slow_work_max_threads_sysctl(struct ctl_table *table, int write, | |||
529 | atomic_read(&slow_work_thread_count); | 535 | atomic_read(&slow_work_thread_count); |
530 | 536 | ||
531 | if (n < 0) | 537 | if (n < 0) |
532 | mod_timer(&slow_work_cull_timer, | 538 | slow_work_schedule_cull(); |
533 | jiffies + SLOW_WORK_CULL_TIMEOUT); | ||
534 | } | 539 | } |
535 | mutex_unlock(&slow_work_user_lock); | 540 | mutex_unlock(&slow_work_user_lock); |
536 | } | 541 | } |
diff --git a/kernel/sys.c b/kernel/sys.c index 438d99a38c87..b3f1097c76fa 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
@@ -1113,289 +1113,6 @@ out: | |||
1113 | return err; | 1113 | return err; |
1114 | } | 1114 | } |
1115 | 1115 | ||
1116 | /* | ||
1117 | * Supplementary group IDs | ||
1118 | */ | ||
1119 | |||
1120 | /* init to 2 - one for init_task, one to ensure it is never freed */ | ||
1121 | struct group_info init_groups = { .usage = ATOMIC_INIT(2) }; | ||
1122 | |||
1123 | struct group_info *groups_alloc(int gidsetsize) | ||
1124 | { | ||
1125 | struct group_info *group_info; | ||
1126 | int nblocks; | ||
1127 | int i; | ||
1128 | |||
1129 | nblocks = (gidsetsize + NGROUPS_PER_BLOCK - 1) / NGROUPS_PER_BLOCK; | ||
1130 | /* Make sure we always allocate at least one indirect block pointer */ | ||
1131 | nblocks = nblocks ? : 1; | ||
1132 | group_info = kmalloc(sizeof(*group_info) + nblocks*sizeof(gid_t *), GFP_USER); | ||
1133 | if (!group_info) | ||
1134 | return NULL; | ||
1135 | group_info->ngroups = gidsetsize; | ||
1136 | group_info->nblocks = nblocks; | ||
1137 | atomic_set(&group_info->usage, 1); | ||
1138 | |||
1139 | if (gidsetsize <= NGROUPS_SMALL) | ||
1140 | group_info->blocks[0] = group_info->small_block; | ||
1141 | else { | ||
1142 | for (i = 0; i < nblocks; i++) { | ||
1143 | gid_t *b; | ||
1144 | b = (void *)__get_free_page(GFP_USER); | ||
1145 | if (!b) | ||
1146 | goto out_undo_partial_alloc; | ||
1147 | group_info->blocks[i] = b; | ||
1148 | } | ||
1149 | } | ||
1150 | return group_info; | ||
1151 | |||
1152 | out_undo_partial_alloc: | ||
1153 | while (--i >= 0) { | ||
1154 | free_page((unsigned long)group_info->blocks[i]); | ||
1155 | } | ||
1156 | kfree(group_info); | ||
1157 | return NULL; | ||
1158 | } | ||
1159 | |||
1160 | EXPORT_SYMBOL(groups_alloc); | ||
1161 | |||
1162 | void groups_free(struct group_info *group_info) | ||
1163 | { | ||
1164 | if (group_info->blocks[0] != group_info->small_block) { | ||
1165 | int i; | ||
1166 | for (i = 0; i < group_info->nblocks; i++) | ||
1167 | free_page((unsigned long)group_info->blocks[i]); | ||
1168 | } | ||
1169 | kfree(group_info); | ||
1170 | } | ||
1171 | |||
1172 | EXPORT_SYMBOL(groups_free); | ||
1173 | |||
1174 | /* export the group_info to a user-space array */ | ||
1175 | static int groups_to_user(gid_t __user *grouplist, | ||
1176 | const struct group_info *group_info) | ||
1177 | { | ||
1178 | int i; | ||
1179 | unsigned int count = group_info->ngroups; | ||
1180 | |||
1181 | for (i = 0; i < group_info->nblocks; i++) { | ||
1182 | unsigned int cp_count = min(NGROUPS_PER_BLOCK, count); | ||
1183 | unsigned int len = cp_count * sizeof(*grouplist); | ||
1184 | |||
1185 | if (copy_to_user(grouplist, group_info->blocks[i], len)) | ||
1186 | return -EFAULT; | ||
1187 | |||
1188 | grouplist += NGROUPS_PER_BLOCK; | ||
1189 | count -= cp_count; | ||
1190 | } | ||
1191 | return 0; | ||
1192 | } | ||
1193 | |||
1194 | /* fill a group_info from a user-space array - it must be allocated already */ | ||
1195 | static int groups_from_user(struct group_info *group_info, | ||
1196 | gid_t __user *grouplist) | ||
1197 | { | ||
1198 | int i; | ||
1199 | unsigned int count = group_info->ngroups; | ||
1200 | |||
1201 | for (i = 0; i < group_info->nblocks; i++) { | ||
1202 | unsigned int cp_count = min(NGROUPS_PER_BLOCK, count); | ||
1203 | unsigned int len = cp_count * sizeof(*grouplist); | ||
1204 | |||
1205 | if (copy_from_user(group_info->blocks[i], grouplist, len)) | ||
1206 | return -EFAULT; | ||
1207 | |||
1208 | grouplist += NGROUPS_PER_BLOCK; | ||
1209 | count -= cp_count; | ||
1210 | } | ||
1211 | return 0; | ||
1212 | } | ||
1213 | |||
1214 | /* a simple Shell sort */ | ||
1215 | static void groups_sort(struct group_info *group_info) | ||
1216 | { | ||
1217 | int base, max, stride; | ||
1218 | int gidsetsize = group_info->ngroups; | ||
1219 | |||
1220 | for (stride = 1; stride < gidsetsize; stride = 3 * stride + 1) | ||
1221 | ; /* nothing */ | ||
1222 | stride /= 3; | ||
1223 | |||
1224 | while (stride) { | ||
1225 | max = gidsetsize - stride; | ||
1226 | for (base = 0; base < max; base++) { | ||
1227 | int left = base; | ||
1228 | int right = left + stride; | ||
1229 | gid_t tmp = GROUP_AT(group_info, right); | ||
1230 | |||
1231 | while (left >= 0 && GROUP_AT(group_info, left) > tmp) { | ||
1232 | GROUP_AT(group_info, right) = | ||
1233 | GROUP_AT(group_info, left); | ||
1234 | right = left; | ||
1235 | left -= stride; | ||
1236 | } | ||
1237 | GROUP_AT(group_info, right) = tmp; | ||
1238 | } | ||
1239 | stride /= 3; | ||
1240 | } | ||
1241 | } | ||
1242 | |||
1243 | /* a simple bsearch */ | ||
1244 | int groups_search(const struct group_info *group_info, gid_t grp) | ||
1245 | { | ||
1246 | unsigned int left, right; | ||
1247 | |||
1248 | if (!group_info) | ||
1249 | return 0; | ||
1250 | |||
1251 | left = 0; | ||
1252 | right = group_info->ngroups; | ||
1253 | while (left < right) { | ||
1254 | unsigned int mid = (left+right)/2; | ||
1255 | int cmp = grp - GROUP_AT(group_info, mid); | ||
1256 | if (cmp > 0) | ||
1257 | left = mid + 1; | ||
1258 | else if (cmp < 0) | ||
1259 | right = mid; | ||
1260 | else | ||
1261 | return 1; | ||
1262 | } | ||
1263 | return 0; | ||
1264 | } | ||
1265 | |||
1266 | /** | ||
1267 | * set_groups - Change a group subscription in a set of credentials | ||
1268 | * @new: The newly prepared set of credentials to alter | ||
1269 | * @group_info: The group list to install | ||
1270 | * | ||
1271 | * Validate a group subscription and, if valid, insert it into a set | ||
1272 | * of credentials. | ||
1273 | */ | ||
1274 | int set_groups(struct cred *new, struct group_info *group_info) | ||
1275 | { | ||
1276 | int retval; | ||
1277 | |||
1278 | retval = security_task_setgroups(group_info); | ||
1279 | if (retval) | ||
1280 | return retval; | ||
1281 | |||
1282 | put_group_info(new->group_info); | ||
1283 | groups_sort(group_info); | ||
1284 | get_group_info(group_info); | ||
1285 | new->group_info = group_info; | ||
1286 | return 0; | ||
1287 | } | ||
1288 | |||
1289 | EXPORT_SYMBOL(set_groups); | ||
1290 | |||
1291 | /** | ||
1292 | * set_current_groups - Change current's group subscription | ||
1293 | * @group_info: The group list to impose | ||
1294 | * | ||
1295 | * Validate a group subscription and, if valid, impose it upon current's task | ||
1296 | * security record. | ||
1297 | */ | ||
1298 | int set_current_groups(struct group_info *group_info) | ||
1299 | { | ||
1300 | struct cred *new; | ||
1301 | int ret; | ||
1302 | |||
1303 | new = prepare_creds(); | ||
1304 | if (!new) | ||
1305 | return -ENOMEM; | ||
1306 | |||
1307 | ret = set_groups(new, group_info); | ||
1308 | if (ret < 0) { | ||
1309 | abort_creds(new); | ||
1310 | return ret; | ||
1311 | } | ||
1312 | |||
1313 | return commit_creds(new); | ||
1314 | } | ||
1315 | |||
1316 | EXPORT_SYMBOL(set_current_groups); | ||
1317 | |||
1318 | SYSCALL_DEFINE2(getgroups, int, gidsetsize, gid_t __user *, grouplist) | ||
1319 | { | ||
1320 | const struct cred *cred = current_cred(); | ||
1321 | int i; | ||
1322 | |||
1323 | if (gidsetsize < 0) | ||
1324 | return -EINVAL; | ||
1325 | |||
1326 | /* no need to grab task_lock here; it cannot change */ | ||
1327 | i = cred->group_info->ngroups; | ||
1328 | if (gidsetsize) { | ||
1329 | if (i > gidsetsize) { | ||
1330 | i = -EINVAL; | ||
1331 | goto out; | ||
1332 | } | ||
1333 | if (groups_to_user(grouplist, cred->group_info)) { | ||
1334 | i = -EFAULT; | ||
1335 | goto out; | ||
1336 | } | ||
1337 | } | ||
1338 | out: | ||
1339 | return i; | ||
1340 | } | ||
1341 | |||
1342 | /* | ||
1343 | * SMP: Our groups are copy-on-write. We can set them safely | ||
1344 | * without another task interfering. | ||
1345 | */ | ||
1346 | |||
1347 | SYSCALL_DEFINE2(setgroups, int, gidsetsize, gid_t __user *, grouplist) | ||
1348 | { | ||
1349 | struct group_info *group_info; | ||
1350 | int retval; | ||
1351 | |||
1352 | if (!capable(CAP_SETGID)) | ||
1353 | return -EPERM; | ||
1354 | if ((unsigned)gidsetsize > NGROUPS_MAX) | ||
1355 | return -EINVAL; | ||
1356 | |||
1357 | group_info = groups_alloc(gidsetsize); | ||
1358 | if (!group_info) | ||
1359 | return -ENOMEM; | ||
1360 | retval = groups_from_user(group_info, grouplist); | ||
1361 | if (retval) { | ||
1362 | put_group_info(group_info); | ||
1363 | return retval; | ||
1364 | } | ||
1365 | |||
1366 | retval = set_current_groups(group_info); | ||
1367 | put_group_info(group_info); | ||
1368 | |||
1369 | return retval; | ||
1370 | } | ||
1371 | |||
1372 | /* | ||
1373 | * Check whether we're fsgid/egid or in the supplemental group.. | ||
1374 | */ | ||
1375 | int in_group_p(gid_t grp) | ||
1376 | { | ||
1377 | const struct cred *cred = current_cred(); | ||
1378 | int retval = 1; | ||
1379 | |||
1380 | if (grp != cred->fsgid) | ||
1381 | retval = groups_search(cred->group_info, grp); | ||
1382 | return retval; | ||
1383 | } | ||
1384 | |||
1385 | EXPORT_SYMBOL(in_group_p); | ||
1386 | |||
1387 | int in_egroup_p(gid_t grp) | ||
1388 | { | ||
1389 | const struct cred *cred = current_cred(); | ||
1390 | int retval = 1; | ||
1391 | |||
1392 | if (grp != cred->egid) | ||
1393 | retval = groups_search(cred->group_info, grp); | ||
1394 | return retval; | ||
1395 | } | ||
1396 | |||
1397 | EXPORT_SYMBOL(in_egroup_p); | ||
1398 | |||
1399 | DECLARE_RWSEM(uts_sem); | 1116 | DECLARE_RWSEM(uts_sem); |
1400 | 1117 | ||
1401 | SYSCALL_DEFINE1(newuname, struct new_utsname __user *, name) | 1118 | SYSCALL_DEFINE1(newuname, struct new_utsname __user *, name) |
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index f5c76b6cd616..ab462b9968d5 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
@@ -1337,7 +1337,6 @@ static struct ctl_table vm_table[] = { | |||
1337 | .extra2 = &one, | 1337 | .extra2 = &one, |
1338 | }, | 1338 | }, |
1339 | #endif | 1339 | #endif |
1340 | #ifdef CONFIG_UNEVICTABLE_LRU | ||
1341 | { | 1340 | { |
1342 | .ctl_name = CTL_UNNUMBERED, | 1341 | .ctl_name = CTL_UNNUMBERED, |
1343 | .procname = "scan_unevictable_pages", | 1342 | .procname = "scan_unevictable_pages", |
@@ -1346,7 +1345,6 @@ static struct ctl_table vm_table[] = { | |||
1346 | .mode = 0644, | 1345 | .mode = 0644, |
1347 | .proc_handler = &scan_unevictable_handler, | 1346 | .proc_handler = &scan_unevictable_handler, |
1348 | }, | 1347 | }, |
1349 | #endif | ||
1350 | /* | 1348 | /* |
1351 | * NOTE: do not add new entries to this table unless you have read | 1349 | * NOTE: do not add new entries to this table unless you have read |
1352 | * Documentation/sysctl/ctl_unnumbered.txt | 1350 | * Documentation/sysctl/ctl_unnumbered.txt |
diff --git a/lib/dec_and_lock.c b/lib/dec_and_lock.c index a65c31455541..e73822aa6e9a 100644 --- a/lib/dec_and_lock.c +++ b/lib/dec_and_lock.c | |||
@@ -19,11 +19,10 @@ | |||
19 | */ | 19 | */ |
20 | int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock) | 20 | int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock) |
21 | { | 21 | { |
22 | #ifdef CONFIG_SMP | ||
23 | /* Subtract 1 from counter unless that drops it to 0 (ie. it was 1) */ | 22 | /* Subtract 1 from counter unless that drops it to 0 (ie. it was 1) */ |
24 | if (atomic_add_unless(atomic, -1, 1)) | 23 | if (atomic_add_unless(atomic, -1, 1)) |
25 | return 0; | 24 | return 0; |
26 | #endif | 25 | |
27 | /* Otherwise do it the slow way */ | 26 | /* Otherwise do it the slow way */ |
28 | spin_lock(lock); | 27 | spin_lock(lock); |
29 | if (atomic_dec_and_test(atomic)) | 28 | if (atomic_dec_and_test(atomic)) |
diff --git a/lib/genalloc.c b/lib/genalloc.c index f6d276db2d58..eed2bdb865e7 100644 --- a/lib/genalloc.c +++ b/lib/genalloc.c | |||
@@ -85,7 +85,6 @@ void gen_pool_destroy(struct gen_pool *pool) | |||
85 | int bit, end_bit; | 85 | int bit, end_bit; |
86 | 86 | ||
87 | 87 | ||
88 | write_lock(&pool->lock); | ||
89 | list_for_each_safe(_chunk, _next_chunk, &pool->chunks) { | 88 | list_for_each_safe(_chunk, _next_chunk, &pool->chunks) { |
90 | chunk = list_entry(_chunk, struct gen_pool_chunk, next_chunk); | 89 | chunk = list_entry(_chunk, struct gen_pool_chunk, next_chunk); |
91 | list_del(&chunk->next_chunk); | 90 | list_del(&chunk->next_chunk); |
diff --git a/lib/hexdump.c b/lib/hexdump.c index f07c0db81d26..39af2560f765 100644 --- a/lib/hexdump.c +++ b/lib/hexdump.c | |||
@@ -65,7 +65,8 @@ void hex_dump_to_buffer(const void *buf, size_t len, int rowsize, | |||
65 | 65 | ||
66 | for (j = 0; j < ngroups; j++) | 66 | for (j = 0; j < ngroups; j++) |
67 | lx += scnprintf(linebuf + lx, linebuflen - lx, | 67 | lx += scnprintf(linebuf + lx, linebuflen - lx, |
68 | "%16.16llx ", (unsigned long long)*(ptr8 + j)); | 68 | "%s%16.16llx", j ? " " : "", |
69 | (unsigned long long)*(ptr8 + j)); | ||
69 | ascii_column = 17 * ngroups + 2; | 70 | ascii_column = 17 * ngroups + 2; |
70 | break; | 71 | break; |
71 | } | 72 | } |
@@ -76,7 +77,7 @@ void hex_dump_to_buffer(const void *buf, size_t len, int rowsize, | |||
76 | 77 | ||
77 | for (j = 0; j < ngroups; j++) | 78 | for (j = 0; j < ngroups; j++) |
78 | lx += scnprintf(linebuf + lx, linebuflen - lx, | 79 | lx += scnprintf(linebuf + lx, linebuflen - lx, |
79 | "%8.8x ", *(ptr4 + j)); | 80 | "%s%8.8x", j ? " " : "", *(ptr4 + j)); |
80 | ascii_column = 9 * ngroups + 2; | 81 | ascii_column = 9 * ngroups + 2; |
81 | break; | 82 | break; |
82 | } | 83 | } |
@@ -87,19 +88,21 @@ void hex_dump_to_buffer(const void *buf, size_t len, int rowsize, | |||
87 | 88 | ||
88 | for (j = 0; j < ngroups; j++) | 89 | for (j = 0; j < ngroups; j++) |
89 | lx += scnprintf(linebuf + lx, linebuflen - lx, | 90 | lx += scnprintf(linebuf + lx, linebuflen - lx, |
90 | "%4.4x ", *(ptr2 + j)); | 91 | "%s%4.4x", j ? " " : "", *(ptr2 + j)); |
91 | ascii_column = 5 * ngroups + 2; | 92 | ascii_column = 5 * ngroups + 2; |
92 | break; | 93 | break; |
93 | } | 94 | } |
94 | 95 | ||
95 | default: | 96 | default: |
96 | for (j = 0; (j < rowsize) && (j < len) && (lx + 4) < linebuflen; | 97 | for (j = 0; (j < len) && (lx + 3) <= linebuflen; j++) { |
97 | j++) { | ||
98 | ch = ptr[j]; | 98 | ch = ptr[j]; |
99 | linebuf[lx++] = hex_asc_hi(ch); | 99 | linebuf[lx++] = hex_asc_hi(ch); |
100 | linebuf[lx++] = hex_asc_lo(ch); | 100 | linebuf[lx++] = hex_asc_lo(ch); |
101 | linebuf[lx++] = ' '; | 101 | linebuf[lx++] = ' '; |
102 | } | 102 | } |
103 | if (j) | ||
104 | lx--; | ||
105 | |||
103 | ascii_column = 3 * rowsize + 2; | 106 | ascii_column = 3 * rowsize + 2; |
104 | break; | 107 | break; |
105 | } | 108 | } |
@@ -108,7 +111,7 @@ void hex_dump_to_buffer(const void *buf, size_t len, int rowsize, | |||
108 | 111 | ||
109 | while (lx < (linebuflen - 1) && lx < (ascii_column - 1)) | 112 | while (lx < (linebuflen - 1) && lx < (ascii_column - 1)) |
110 | linebuf[lx++] = ' '; | 113 | linebuf[lx++] = ' '; |
111 | for (j = 0; (j < rowsize) && (j < len) && (lx + 2) < linebuflen; j++) | 114 | for (j = 0; (j < len) && (lx + 2) < linebuflen; j++) |
112 | linebuf[lx++] = (isascii(ptr[j]) && isprint(ptr[j])) ? ptr[j] | 115 | linebuf[lx++] = (isascii(ptr[j]) && isprint(ptr[j])) ? ptr[j] |
113 | : '.'; | 116 | : '.'; |
114 | nil: | 117 | nil: |
diff --git a/lib/radix-tree.c b/lib/radix-tree.c index 4bb42a0344ec..23abbd93cae1 100644 --- a/lib/radix-tree.c +++ b/lib/radix-tree.c | |||
@@ -351,20 +351,12 @@ int radix_tree_insert(struct radix_tree_root *root, | |||
351 | } | 351 | } |
352 | EXPORT_SYMBOL(radix_tree_insert); | 352 | EXPORT_SYMBOL(radix_tree_insert); |
353 | 353 | ||
354 | /** | 354 | /* |
355 | * radix_tree_lookup_slot - lookup a slot in a radix tree | 355 | * is_slot == 1 : search for the slot. |
356 | * @root: radix tree root | 356 | * is_slot == 0 : search for the node. |
357 | * @index: index key | ||
358 | * | ||
359 | * Returns: the slot corresponding to the position @index in the | ||
360 | * radix tree @root. This is useful for update-if-exists operations. | ||
361 | * | ||
362 | * This function can be called under rcu_read_lock iff the slot is not | ||
363 | * modified by radix_tree_replace_slot, otherwise it must be called | ||
364 | * exclusive from other writers. Any dereference of the slot must be done | ||
365 | * using radix_tree_deref_slot. | ||
366 | */ | 357 | */ |
367 | void **radix_tree_lookup_slot(struct radix_tree_root *root, unsigned long index) | 358 | static void *radix_tree_lookup_element(struct radix_tree_root *root, |
359 | unsigned long index, int is_slot) | ||
368 | { | 360 | { |
369 | unsigned int height, shift; | 361 | unsigned int height, shift; |
370 | struct radix_tree_node *node, **slot; | 362 | struct radix_tree_node *node, **slot; |
@@ -376,7 +368,7 @@ void **radix_tree_lookup_slot(struct radix_tree_root *root, unsigned long index) | |||
376 | if (!radix_tree_is_indirect_ptr(node)) { | 368 | if (!radix_tree_is_indirect_ptr(node)) { |
377 | if (index > 0) | 369 | if (index > 0) |
378 | return NULL; | 370 | return NULL; |
379 | return (void **)&root->rnode; | 371 | return is_slot ? (void *)&root->rnode : node; |
380 | } | 372 | } |
381 | node = radix_tree_indirect_to_ptr(node); | 373 | node = radix_tree_indirect_to_ptr(node); |
382 | 374 | ||
@@ -397,7 +389,25 @@ void **radix_tree_lookup_slot(struct radix_tree_root *root, unsigned long index) | |||
397 | height--; | 389 | height--; |
398 | } while (height > 0); | 390 | } while (height > 0); |
399 | 391 | ||
400 | return (void **)slot; | 392 | return is_slot ? (void *)slot:node; |
393 | } | ||
394 | |||
395 | /** | ||
396 | * radix_tree_lookup_slot - lookup a slot in a radix tree | ||
397 | * @root: radix tree root | ||
398 | * @index: index key | ||
399 | * | ||
400 | * Returns: the slot corresponding to the position @index in the | ||
401 | * radix tree @root. This is useful for update-if-exists operations. | ||
402 | * | ||
403 | * This function can be called under rcu_read_lock iff the slot is not | ||
404 | * modified by radix_tree_replace_slot, otherwise it must be called | ||
405 | * exclusive from other writers. Any dereference of the slot must be done | ||
406 | * using radix_tree_deref_slot. | ||
407 | */ | ||
408 | void **radix_tree_lookup_slot(struct radix_tree_root *root, unsigned long index) | ||
409 | { | ||
410 | return (void **)radix_tree_lookup_element(root, index, 1); | ||
401 | } | 411 | } |
402 | EXPORT_SYMBOL(radix_tree_lookup_slot); | 412 | EXPORT_SYMBOL(radix_tree_lookup_slot); |
403 | 413 | ||
@@ -415,38 +425,7 @@ EXPORT_SYMBOL(radix_tree_lookup_slot); | |||
415 | */ | 425 | */ |
416 | void *radix_tree_lookup(struct radix_tree_root *root, unsigned long index) | 426 | void *radix_tree_lookup(struct radix_tree_root *root, unsigned long index) |
417 | { | 427 | { |
418 | unsigned int height, shift; | 428 | return radix_tree_lookup_element(root, index, 0); |
419 | struct radix_tree_node *node, **slot; | ||
420 | |||
421 | node = rcu_dereference(root->rnode); | ||
422 | if (node == NULL) | ||
423 | return NULL; | ||
424 | |||
425 | if (!radix_tree_is_indirect_ptr(node)) { | ||
426 | if (index > 0) | ||
427 | return NULL; | ||
428 | return node; | ||
429 | } | ||
430 | node = radix_tree_indirect_to_ptr(node); | ||
431 | |||
432 | height = node->height; | ||
433 | if (index > radix_tree_maxindex(height)) | ||
434 | return NULL; | ||
435 | |||
436 | shift = (height-1) * RADIX_TREE_MAP_SHIFT; | ||
437 | |||
438 | do { | ||
439 | slot = (struct radix_tree_node **) | ||
440 | (node->slots + ((index>>shift) & RADIX_TREE_MAP_MASK)); | ||
441 | node = rcu_dereference(*slot); | ||
442 | if (node == NULL) | ||
443 | return NULL; | ||
444 | |||
445 | shift -= RADIX_TREE_MAP_SHIFT; | ||
446 | height--; | ||
447 | } while (height > 0); | ||
448 | |||
449 | return node; | ||
450 | } | 429 | } |
451 | EXPORT_SYMBOL(radix_tree_lookup); | 430 | EXPORT_SYMBOL(radix_tree_lookup); |
452 | 431 | ||
@@ -666,6 +645,43 @@ unsigned long radix_tree_next_hole(struct radix_tree_root *root, | |||
666 | } | 645 | } |
667 | EXPORT_SYMBOL(radix_tree_next_hole); | 646 | EXPORT_SYMBOL(radix_tree_next_hole); |
668 | 647 | ||
648 | /** | ||
649 | * radix_tree_prev_hole - find the prev hole (not-present entry) | ||
650 | * @root: tree root | ||
651 | * @index: index key | ||
652 | * @max_scan: maximum range to search | ||
653 | * | ||
654 | * Search backwards in the range [max(index-max_scan+1, 0), index] | ||
655 | * for the first hole. | ||
656 | * | ||
657 | * Returns: the index of the hole if found, otherwise returns an index | ||
658 | * outside of the set specified (in which case 'index - return >= max_scan' | ||
659 | * will be true). In rare cases of wrap-around, LONG_MAX will be returned. | ||
660 | * | ||
661 | * radix_tree_next_hole may be called under rcu_read_lock. However, like | ||
662 | * radix_tree_gang_lookup, this will not atomically search a snapshot of | ||
663 | * the tree at a single point in time. For example, if a hole is created | ||
664 | * at index 10, then subsequently a hole is created at index 5, | ||
665 | * radix_tree_prev_hole covering both indexes may return 5 if called under | ||
666 | * rcu_read_lock. | ||
667 | */ | ||
668 | unsigned long radix_tree_prev_hole(struct radix_tree_root *root, | ||
669 | unsigned long index, unsigned long max_scan) | ||
670 | { | ||
671 | unsigned long i; | ||
672 | |||
673 | for (i = 0; i < max_scan; i++) { | ||
674 | if (!radix_tree_lookup(root, index)) | ||
675 | break; | ||
676 | index--; | ||
677 | if (index == LONG_MAX) | ||
678 | break; | ||
679 | } | ||
680 | |||
681 | return index; | ||
682 | } | ||
683 | EXPORT_SYMBOL(radix_tree_prev_hole); | ||
684 | |||
669 | static unsigned int | 685 | static unsigned int |
670 | __lookup(struct radix_tree_node *slot, void ***results, unsigned long index, | 686 | __lookup(struct radix_tree_node *slot, void ***results, unsigned long index, |
671 | unsigned int max_items, unsigned long *next_index) | 687 | unsigned int max_items, unsigned long *next_index) |
diff --git a/lib/rbtree.c b/lib/rbtree.c index f653659e0bc1..e2aa3be29858 100644 --- a/lib/rbtree.c +++ b/lib/rbtree.c | |||
@@ -231,34 +231,34 @@ void rb_erase(struct rb_node *node, struct rb_root *root) | |||
231 | node = node->rb_right; | 231 | node = node->rb_right; |
232 | while ((left = node->rb_left) != NULL) | 232 | while ((left = node->rb_left) != NULL) |
233 | node = left; | 233 | node = left; |
234 | |||
235 | if (rb_parent(old)) { | ||
236 | if (rb_parent(old)->rb_left == old) | ||
237 | rb_parent(old)->rb_left = node; | ||
238 | else | ||
239 | rb_parent(old)->rb_right = node; | ||
240 | } else | ||
241 | root->rb_node = node; | ||
242 | |||
234 | child = node->rb_right; | 243 | child = node->rb_right; |
235 | parent = rb_parent(node); | 244 | parent = rb_parent(node); |
236 | color = rb_color(node); | 245 | color = rb_color(node); |
237 | 246 | ||
238 | if (child) | ||
239 | rb_set_parent(child, parent); | ||
240 | if (parent == old) { | 247 | if (parent == old) { |
241 | parent->rb_right = child; | ||
242 | parent = node; | 248 | parent = node; |
243 | } else | 249 | } else { |
250 | if (child) | ||
251 | rb_set_parent(child, parent); | ||
244 | parent->rb_left = child; | 252 | parent->rb_left = child; |
245 | 253 | ||
254 | node->rb_right = old->rb_right; | ||
255 | rb_set_parent(old->rb_right, node); | ||
256 | } | ||
257 | |||
246 | node->rb_parent_color = old->rb_parent_color; | 258 | node->rb_parent_color = old->rb_parent_color; |
247 | node->rb_right = old->rb_right; | ||
248 | node->rb_left = old->rb_left; | 259 | node->rb_left = old->rb_left; |
249 | |||
250 | if (rb_parent(old)) | ||
251 | { | ||
252 | if (rb_parent(old)->rb_left == old) | ||
253 | rb_parent(old)->rb_left = node; | ||
254 | else | ||
255 | rb_parent(old)->rb_right = node; | ||
256 | } else | ||
257 | root->rb_node = node; | ||
258 | |||
259 | rb_set_parent(old->rb_left, node); | 260 | rb_set_parent(old->rb_left, node); |
260 | if (old->rb_right) | 261 | |
261 | rb_set_parent(old->rb_right, node); | ||
262 | goto color; | 262 | goto color; |
263 | } | 263 | } |
264 | 264 | ||
diff --git a/mm/Kconfig b/mm/Kconfig index 6f4610a9ce55..c948d4ca8bde 100644 --- a/mm/Kconfig +++ b/mm/Kconfig | |||
@@ -203,25 +203,13 @@ config VIRT_TO_BUS | |||
203 | def_bool y | 203 | def_bool y |
204 | depends on !ARCH_NO_VIRT_TO_BUS | 204 | depends on !ARCH_NO_VIRT_TO_BUS |
205 | 205 | ||
206 | config UNEVICTABLE_LRU | ||
207 | bool "Add LRU list to track non-evictable pages" | ||
208 | default y | ||
209 | help | ||
210 | Keeps unevictable pages off of the active and inactive pageout | ||
211 | lists, so kswapd will not waste CPU time or have its balancing | ||
212 | algorithms thrown off by scanning these pages. Selecting this | ||
213 | will use one page flag and increase the code size a little, | ||
214 | say Y unless you know what you are doing. | ||
215 | |||
216 | See Documentation/vm/unevictable-lru.txt for more information. | ||
217 | |||
218 | config HAVE_MLOCK | 206 | config HAVE_MLOCK |
219 | bool | 207 | bool |
220 | default y if MMU=y | 208 | default y if MMU=y |
221 | 209 | ||
222 | config HAVE_MLOCKED_PAGE_BIT | 210 | config HAVE_MLOCKED_PAGE_BIT |
223 | bool | 211 | bool |
224 | default y if HAVE_MLOCK=y && UNEVICTABLE_LRU=y | 212 | default y if HAVE_MLOCK=y |
225 | 213 | ||
226 | config MMU_NOTIFIER | 214 | config MMU_NOTIFIER |
227 | bool | 215 | bool |
diff --git a/mm/Makefile b/mm/Makefile index c379ce08354a..5e0bd6426693 100644 --- a/mm/Makefile +++ b/mm/Makefile | |||
@@ -12,6 +12,7 @@ obj-y := bootmem.o filemap.o mempool.o oom_kill.o fadvise.o \ | |||
12 | readahead.o swap.o truncate.o vmscan.o shmem.o \ | 12 | readahead.o swap.o truncate.o vmscan.o shmem.o \ |
13 | prio_tree.o util.o mmzone.o vmstat.o backing-dev.o \ | 13 | prio_tree.o util.o mmzone.o vmstat.o backing-dev.o \ |
14 | page_isolation.o mm_init.o $(mmu-y) | 14 | page_isolation.o mm_init.o $(mmu-y) |
15 | obj-y += init-mm.o | ||
15 | 16 | ||
16 | obj-$(CONFIG_PROC_PAGE_MONITOR) += pagewalk.o | 17 | obj-$(CONFIG_PROC_PAGE_MONITOR) += pagewalk.o |
17 | obj-$(CONFIG_BOUNCE) += bounce.o | 18 | obj-$(CONFIG_BOUNCE) += bounce.o |
diff --git a/mm/fadvise.c b/mm/fadvise.c index 54a0f8040afa..e43359214f6f 100644 --- a/mm/fadvise.c +++ b/mm/fadvise.c | |||
@@ -101,7 +101,7 @@ SYSCALL_DEFINE(fadvise64_64)(int fd, loff_t offset, loff_t len, int advice) | |||
101 | 101 | ||
102 | ret = force_page_cache_readahead(mapping, file, | 102 | ret = force_page_cache_readahead(mapping, file, |
103 | start_index, | 103 | start_index, |
104 | max_sane_readahead(nrpages)); | 104 | nrpages); |
105 | if (ret > 0) | 105 | if (ret > 0) |
106 | ret = 0; | 106 | ret = 0; |
107 | break; | 107 | break; |
diff --git a/mm/filemap.c b/mm/filemap.c index 1b60f30cebfa..22396713feb9 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
@@ -521,7 +521,7 @@ struct page *__page_cache_alloc(gfp_t gfp) | |||
521 | { | 521 | { |
522 | if (cpuset_do_page_mem_spread()) { | 522 | if (cpuset_do_page_mem_spread()) { |
523 | int n = cpuset_mem_spread_node(); | 523 | int n = cpuset_mem_spread_node(); |
524 | return alloc_pages_node(n, gfp, 0); | 524 | return alloc_pages_exact_node(n, gfp, 0); |
525 | } | 525 | } |
526 | return alloc_pages(gfp, 0); | 526 | return alloc_pages(gfp, 0); |
527 | } | 527 | } |
@@ -1004,9 +1004,6 @@ EXPORT_SYMBOL(grab_cache_page_nowait); | |||
1004 | static void shrink_readahead_size_eio(struct file *filp, | 1004 | static void shrink_readahead_size_eio(struct file *filp, |
1005 | struct file_ra_state *ra) | 1005 | struct file_ra_state *ra) |
1006 | { | 1006 | { |
1007 | if (!ra->ra_pages) | ||
1008 | return; | ||
1009 | |||
1010 | ra->ra_pages /= 4; | 1007 | ra->ra_pages /= 4; |
1011 | } | 1008 | } |
1012 | 1009 | ||
@@ -1390,8 +1387,7 @@ do_readahead(struct address_space *mapping, struct file *filp, | |||
1390 | if (!mapping || !mapping->a_ops || !mapping->a_ops->readpage) | 1387 | if (!mapping || !mapping->a_ops || !mapping->a_ops->readpage) |
1391 | return -EINVAL; | 1388 | return -EINVAL; |
1392 | 1389 | ||
1393 | force_page_cache_readahead(mapping, filp, index, | 1390 | force_page_cache_readahead(mapping, filp, index, nr); |
1394 | max_sane_readahead(nr)); | ||
1395 | return 0; | 1391 | return 0; |
1396 | } | 1392 | } |
1397 | 1393 | ||
@@ -1457,6 +1453,73 @@ static int page_cache_read(struct file *file, pgoff_t offset) | |||
1457 | 1453 | ||
1458 | #define MMAP_LOTSAMISS (100) | 1454 | #define MMAP_LOTSAMISS (100) |
1459 | 1455 | ||
1456 | /* | ||
1457 | * Synchronous readahead happens when we don't even find | ||
1458 | * a page in the page cache at all. | ||
1459 | */ | ||
1460 | static void do_sync_mmap_readahead(struct vm_area_struct *vma, | ||
1461 | struct file_ra_state *ra, | ||
1462 | struct file *file, | ||
1463 | pgoff_t offset) | ||
1464 | { | ||
1465 | unsigned long ra_pages; | ||
1466 | struct address_space *mapping = file->f_mapping; | ||
1467 | |||
1468 | /* If we don't want any read-ahead, don't bother */ | ||
1469 | if (VM_RandomReadHint(vma)) | ||
1470 | return; | ||
1471 | |||
1472 | if (VM_SequentialReadHint(vma) || | ||
1473 | offset - 1 == (ra->prev_pos >> PAGE_CACHE_SHIFT)) { | ||
1474 | page_cache_sync_readahead(mapping, ra, file, offset, | ||
1475 | ra->ra_pages); | ||
1476 | return; | ||
1477 | } | ||
1478 | |||
1479 | if (ra->mmap_miss < INT_MAX) | ||
1480 | ra->mmap_miss++; | ||
1481 | |||
1482 | /* | ||
1483 | * Do we miss much more than hit in this file? If so, | ||
1484 | * stop bothering with read-ahead. It will only hurt. | ||
1485 | */ | ||
1486 | if (ra->mmap_miss > MMAP_LOTSAMISS) | ||
1487 | return; | ||
1488 | |||
1489 | /* | ||
1490 | * mmap read-around | ||
1491 | */ | ||
1492 | ra_pages = max_sane_readahead(ra->ra_pages); | ||
1493 | if (ra_pages) { | ||
1494 | ra->start = max_t(long, 0, offset - ra_pages/2); | ||
1495 | ra->size = ra_pages; | ||
1496 | ra->async_size = 0; | ||
1497 | ra_submit(ra, mapping, file); | ||
1498 | } | ||
1499 | } | ||
1500 | |||
1501 | /* | ||
1502 | * Asynchronous readahead happens when we find the page and PG_readahead, | ||
1503 | * so we want to possibly extend the readahead further.. | ||
1504 | */ | ||
1505 | static void do_async_mmap_readahead(struct vm_area_struct *vma, | ||
1506 | struct file_ra_state *ra, | ||
1507 | struct file *file, | ||
1508 | struct page *page, | ||
1509 | pgoff_t offset) | ||
1510 | { | ||
1511 | struct address_space *mapping = file->f_mapping; | ||
1512 | |||
1513 | /* If we don't want any read-ahead, don't bother */ | ||
1514 | if (VM_RandomReadHint(vma)) | ||
1515 | return; | ||
1516 | if (ra->mmap_miss > 0) | ||
1517 | ra->mmap_miss--; | ||
1518 | if (PageReadahead(page)) | ||
1519 | page_cache_async_readahead(mapping, ra, file, | ||
1520 | page, offset, ra->ra_pages); | ||
1521 | } | ||
1522 | |||
1460 | /** | 1523 | /** |
1461 | * filemap_fault - read in file data for page fault handling | 1524 | * filemap_fault - read in file data for page fault handling |
1462 | * @vma: vma in which the fault was taken | 1525 | * @vma: vma in which the fault was taken |
@@ -1476,78 +1539,44 @@ int filemap_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
1476 | struct address_space *mapping = file->f_mapping; | 1539 | struct address_space *mapping = file->f_mapping; |
1477 | struct file_ra_state *ra = &file->f_ra; | 1540 | struct file_ra_state *ra = &file->f_ra; |
1478 | struct inode *inode = mapping->host; | 1541 | struct inode *inode = mapping->host; |
1542 | pgoff_t offset = vmf->pgoff; | ||
1479 | struct page *page; | 1543 | struct page *page; |
1480 | pgoff_t size; | 1544 | pgoff_t size; |
1481 | int did_readaround = 0; | ||
1482 | int ret = 0; | 1545 | int ret = 0; |
1483 | 1546 | ||
1484 | size = (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; | 1547 | size = (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; |
1485 | if (vmf->pgoff >= size) | 1548 | if (offset >= size) |
1486 | return VM_FAULT_SIGBUS; | 1549 | return VM_FAULT_SIGBUS; |
1487 | 1550 | ||
1488 | /* If we don't want any read-ahead, don't bother */ | ||
1489 | if (VM_RandomReadHint(vma)) | ||
1490 | goto no_cached_page; | ||
1491 | |||
1492 | /* | 1551 | /* |
1493 | * Do we have something in the page cache already? | 1552 | * Do we have something in the page cache already? |
1494 | */ | 1553 | */ |
1495 | retry_find: | 1554 | page = find_get_page(mapping, offset); |
1496 | page = find_lock_page(mapping, vmf->pgoff); | 1555 | if (likely(page)) { |
1497 | /* | ||
1498 | * For sequential accesses, we use the generic readahead logic. | ||
1499 | */ | ||
1500 | if (VM_SequentialReadHint(vma)) { | ||
1501 | if (!page) { | ||
1502 | page_cache_sync_readahead(mapping, ra, file, | ||
1503 | vmf->pgoff, 1); | ||
1504 | page = find_lock_page(mapping, vmf->pgoff); | ||
1505 | if (!page) | ||
1506 | goto no_cached_page; | ||
1507 | } | ||
1508 | if (PageReadahead(page)) { | ||
1509 | page_cache_async_readahead(mapping, ra, file, page, | ||
1510 | vmf->pgoff, 1); | ||
1511 | } | ||
1512 | } | ||
1513 | |||
1514 | if (!page) { | ||
1515 | unsigned long ra_pages; | ||
1516 | |||
1517 | ra->mmap_miss++; | ||
1518 | |||
1519 | /* | 1556 | /* |
1520 | * Do we miss much more than hit in this file? If so, | 1557 | * We found the page, so try async readahead before |
1521 | * stop bothering with read-ahead. It will only hurt. | 1558 | * waiting for the lock. |
1522 | */ | 1559 | */ |
1523 | if (ra->mmap_miss > MMAP_LOTSAMISS) | 1560 | do_async_mmap_readahead(vma, ra, file, page, offset); |
1524 | goto no_cached_page; | 1561 | lock_page(page); |
1525 | 1562 | ||
1526 | /* | 1563 | /* Did it get truncated? */ |
1527 | * To keep the pgmajfault counter straight, we need to | 1564 | if (unlikely(page->mapping != mapping)) { |
1528 | * check did_readaround, as this is an inner loop. | 1565 | unlock_page(page); |
1529 | */ | 1566 | put_page(page); |
1530 | if (!did_readaround) { | 1567 | goto no_cached_page; |
1531 | ret = VM_FAULT_MAJOR; | ||
1532 | count_vm_event(PGMAJFAULT); | ||
1533 | } | ||
1534 | did_readaround = 1; | ||
1535 | ra_pages = max_sane_readahead(file->f_ra.ra_pages); | ||
1536 | if (ra_pages) { | ||
1537 | pgoff_t start = 0; | ||
1538 | |||
1539 | if (vmf->pgoff > ra_pages / 2) | ||
1540 | start = vmf->pgoff - ra_pages / 2; | ||
1541 | do_page_cache_readahead(mapping, file, start, ra_pages); | ||
1542 | } | 1568 | } |
1543 | page = find_lock_page(mapping, vmf->pgoff); | 1569 | } else { |
1570 | /* No page in the page cache at all */ | ||
1571 | do_sync_mmap_readahead(vma, ra, file, offset); | ||
1572 | count_vm_event(PGMAJFAULT); | ||
1573 | ret = VM_FAULT_MAJOR; | ||
1574 | retry_find: | ||
1575 | page = find_lock_page(mapping, offset); | ||
1544 | if (!page) | 1576 | if (!page) |
1545 | goto no_cached_page; | 1577 | goto no_cached_page; |
1546 | } | 1578 | } |
1547 | 1579 | ||
1548 | if (!did_readaround) | ||
1549 | ra->mmap_miss--; | ||
1550 | |||
1551 | /* | 1580 | /* |
1552 | * We have a locked page in the page cache, now we need to check | 1581 | * We have a locked page in the page cache, now we need to check |
1553 | * that it's up-to-date. If not, it is going to be due to an error. | 1582 | * that it's up-to-date. If not, it is going to be due to an error. |
@@ -1555,18 +1584,18 @@ retry_find: | |||
1555 | if (unlikely(!PageUptodate(page))) | 1584 | if (unlikely(!PageUptodate(page))) |
1556 | goto page_not_uptodate; | 1585 | goto page_not_uptodate; |
1557 | 1586 | ||
1558 | /* Must recheck i_size under page lock */ | 1587 | /* |
1588 | * Found the page and have a reference on it. | ||
1589 | * We must recheck i_size under page lock. | ||
1590 | */ | ||
1559 | size = (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; | 1591 | size = (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; |
1560 | if (unlikely(vmf->pgoff >= size)) { | 1592 | if (unlikely(offset >= size)) { |
1561 | unlock_page(page); | 1593 | unlock_page(page); |
1562 | page_cache_release(page); | 1594 | page_cache_release(page); |
1563 | return VM_FAULT_SIGBUS; | 1595 | return VM_FAULT_SIGBUS; |
1564 | } | 1596 | } |
1565 | 1597 | ||
1566 | /* | 1598 | ra->prev_pos = (loff_t)offset << PAGE_CACHE_SHIFT; |
1567 | * Found the page and have a reference on it. | ||
1568 | */ | ||
1569 | ra->prev_pos = (loff_t)page->index << PAGE_CACHE_SHIFT; | ||
1570 | vmf->page = page; | 1599 | vmf->page = page; |
1571 | return ret | VM_FAULT_LOCKED; | 1600 | return ret | VM_FAULT_LOCKED; |
1572 | 1601 | ||
@@ -1575,7 +1604,7 @@ no_cached_page: | |||
1575 | * We're only likely to ever get here if MADV_RANDOM is in | 1604 | * We're only likely to ever get here if MADV_RANDOM is in |
1576 | * effect. | 1605 | * effect. |
1577 | */ | 1606 | */ |
1578 | error = page_cache_read(file, vmf->pgoff); | 1607 | error = page_cache_read(file, offset); |
1579 | 1608 | ||
1580 | /* | 1609 | /* |
1581 | * The page we want has now been added to the page cache. | 1610 | * The page we want has now been added to the page cache. |
@@ -1595,12 +1624,6 @@ no_cached_page: | |||
1595 | return VM_FAULT_SIGBUS; | 1624 | return VM_FAULT_SIGBUS; |
1596 | 1625 | ||
1597 | page_not_uptodate: | 1626 | page_not_uptodate: |
1598 | /* IO error path */ | ||
1599 | if (!did_readaround) { | ||
1600 | ret = VM_FAULT_MAJOR; | ||
1601 | count_vm_event(PGMAJFAULT); | ||
1602 | } | ||
1603 | |||
1604 | /* | 1627 | /* |
1605 | * Umm, take care of errors if the page isn't up-to-date. | 1628 | * Umm, take care of errors if the page isn't up-to-date. |
1606 | * Try to re-read it _once_. We do this synchronously, | 1629 | * Try to re-read it _once_. We do this synchronously, |
diff --git a/mm/hugetlb.c b/mm/hugetlb.c index e83ad2c9228c..a56e6f3ce979 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c | |||
@@ -578,41 +578,6 @@ static void free_huge_page(struct page *page) | |||
578 | hugetlb_put_quota(mapping, 1); | 578 | hugetlb_put_quota(mapping, 1); |
579 | } | 579 | } |
580 | 580 | ||
581 | /* | ||
582 | * Increment or decrement surplus_huge_pages. Keep node-specific counters | ||
583 | * balanced by operating on them in a round-robin fashion. | ||
584 | * Returns 1 if an adjustment was made. | ||
585 | */ | ||
586 | static int adjust_pool_surplus(struct hstate *h, int delta) | ||
587 | { | ||
588 | static int prev_nid; | ||
589 | int nid = prev_nid; | ||
590 | int ret = 0; | ||
591 | |||
592 | VM_BUG_ON(delta != -1 && delta != 1); | ||
593 | do { | ||
594 | nid = next_node(nid, node_online_map); | ||
595 | if (nid == MAX_NUMNODES) | ||
596 | nid = first_node(node_online_map); | ||
597 | |||
598 | /* To shrink on this node, there must be a surplus page */ | ||
599 | if (delta < 0 && !h->surplus_huge_pages_node[nid]) | ||
600 | continue; | ||
601 | /* Surplus cannot exceed the total number of pages */ | ||
602 | if (delta > 0 && h->surplus_huge_pages_node[nid] >= | ||
603 | h->nr_huge_pages_node[nid]) | ||
604 | continue; | ||
605 | |||
606 | h->surplus_huge_pages += delta; | ||
607 | h->surplus_huge_pages_node[nid] += delta; | ||
608 | ret = 1; | ||
609 | break; | ||
610 | } while (nid != prev_nid); | ||
611 | |||
612 | prev_nid = nid; | ||
613 | return ret; | ||
614 | } | ||
615 | |||
616 | static void prep_new_huge_page(struct hstate *h, struct page *page, int nid) | 581 | static void prep_new_huge_page(struct hstate *h, struct page *page, int nid) |
617 | { | 582 | { |
618 | set_compound_page_dtor(page, free_huge_page); | 583 | set_compound_page_dtor(page, free_huge_page); |
@@ -623,6 +588,34 @@ static void prep_new_huge_page(struct hstate *h, struct page *page, int nid) | |||
623 | put_page(page); /* free it into the hugepage allocator */ | 588 | put_page(page); /* free it into the hugepage allocator */ |
624 | } | 589 | } |
625 | 590 | ||
591 | static void prep_compound_gigantic_page(struct page *page, unsigned long order) | ||
592 | { | ||
593 | int i; | ||
594 | int nr_pages = 1 << order; | ||
595 | struct page *p = page + 1; | ||
596 | |||
597 | /* we rely on prep_new_huge_page to set the destructor */ | ||
598 | set_compound_order(page, order); | ||
599 | __SetPageHead(page); | ||
600 | for (i = 1; i < nr_pages; i++, p = mem_map_next(p, page, i)) { | ||
601 | __SetPageTail(p); | ||
602 | p->first_page = page; | ||
603 | } | ||
604 | } | ||
605 | |||
606 | int PageHuge(struct page *page) | ||
607 | { | ||
608 | compound_page_dtor *dtor; | ||
609 | |||
610 | if (!PageCompound(page)) | ||
611 | return 0; | ||
612 | |||
613 | page = compound_head(page); | ||
614 | dtor = get_compound_page_dtor(page); | ||
615 | |||
616 | return dtor == free_huge_page; | ||
617 | } | ||
618 | |||
626 | static struct page *alloc_fresh_huge_page_node(struct hstate *h, int nid) | 619 | static struct page *alloc_fresh_huge_page_node(struct hstate *h, int nid) |
627 | { | 620 | { |
628 | struct page *page; | 621 | struct page *page; |
@@ -630,7 +623,7 @@ static struct page *alloc_fresh_huge_page_node(struct hstate *h, int nid) | |||
630 | if (h->order >= MAX_ORDER) | 623 | if (h->order >= MAX_ORDER) |
631 | return NULL; | 624 | return NULL; |
632 | 625 | ||
633 | page = alloc_pages_node(nid, | 626 | page = alloc_pages_exact_node(nid, |
634 | htlb_alloc_mask|__GFP_COMP|__GFP_THISNODE| | 627 | htlb_alloc_mask|__GFP_COMP|__GFP_THISNODE| |
635 | __GFP_REPEAT|__GFP_NOWARN, | 628 | __GFP_REPEAT|__GFP_NOWARN, |
636 | huge_page_order(h)); | 629 | huge_page_order(h)); |
@@ -649,7 +642,7 @@ static struct page *alloc_fresh_huge_page_node(struct hstate *h, int nid) | |||
649 | * Use a helper variable to find the next node and then | 642 | * Use a helper variable to find the next node and then |
650 | * copy it back to hugetlb_next_nid afterwards: | 643 | * copy it back to hugetlb_next_nid afterwards: |
651 | * otherwise there's a window in which a racer might | 644 | * otherwise there's a window in which a racer might |
652 | * pass invalid nid MAX_NUMNODES to alloc_pages_node. | 645 | * pass invalid nid MAX_NUMNODES to alloc_pages_exact_node. |
653 | * But we don't need to use a spin_lock here: it really | 646 | * But we don't need to use a spin_lock here: it really |
654 | * doesn't matter if occasionally a racer chooses the | 647 | * doesn't matter if occasionally a racer chooses the |
655 | * same nid as we do. Move nid forward in the mask even | 648 | * same nid as we do. Move nid forward in the mask even |
@@ -875,7 +868,7 @@ static void return_unused_surplus_pages(struct hstate *h, | |||
875 | * can no longer free unreserved surplus pages. This occurs when | 868 | * can no longer free unreserved surplus pages. This occurs when |
876 | * the nodes with surplus pages have no free pages. | 869 | * the nodes with surplus pages have no free pages. |
877 | */ | 870 | */ |
878 | unsigned long remaining_iterations = num_online_nodes(); | 871 | unsigned long remaining_iterations = nr_online_nodes; |
879 | 872 | ||
880 | /* Uncommit the reservation */ | 873 | /* Uncommit the reservation */ |
881 | h->resv_huge_pages -= unused_resv_pages; | 874 | h->resv_huge_pages -= unused_resv_pages; |
@@ -904,7 +897,7 @@ static void return_unused_surplus_pages(struct hstate *h, | |||
904 | h->surplus_huge_pages--; | 897 | h->surplus_huge_pages--; |
905 | h->surplus_huge_pages_node[nid]--; | 898 | h->surplus_huge_pages_node[nid]--; |
906 | nr_pages--; | 899 | nr_pages--; |
907 | remaining_iterations = num_online_nodes(); | 900 | remaining_iterations = nr_online_nodes; |
908 | } | 901 | } |
909 | } | 902 | } |
910 | } | 903 | } |
@@ -1140,6 +1133,41 @@ static inline void try_to_free_low(struct hstate *h, unsigned long count) | |||
1140 | } | 1133 | } |
1141 | #endif | 1134 | #endif |
1142 | 1135 | ||
1136 | /* | ||
1137 | * Increment or decrement surplus_huge_pages. Keep node-specific counters | ||
1138 | * balanced by operating on them in a round-robin fashion. | ||
1139 | * Returns 1 if an adjustment was made. | ||
1140 | */ | ||
1141 | static int adjust_pool_surplus(struct hstate *h, int delta) | ||
1142 | { | ||
1143 | static int prev_nid; | ||
1144 | int nid = prev_nid; | ||
1145 | int ret = 0; | ||
1146 | |||
1147 | VM_BUG_ON(delta != -1 && delta != 1); | ||
1148 | do { | ||
1149 | nid = next_node(nid, node_online_map); | ||
1150 | if (nid == MAX_NUMNODES) | ||
1151 | nid = first_node(node_online_map); | ||
1152 | |||
1153 | /* To shrink on this node, there must be a surplus page */ | ||
1154 | if (delta < 0 && !h->surplus_huge_pages_node[nid]) | ||
1155 | continue; | ||
1156 | /* Surplus cannot exceed the total number of pages */ | ||
1157 | if (delta > 0 && h->surplus_huge_pages_node[nid] >= | ||
1158 | h->nr_huge_pages_node[nid]) | ||
1159 | continue; | ||
1160 | |||
1161 | h->surplus_huge_pages += delta; | ||
1162 | h->surplus_huge_pages_node[nid] += delta; | ||
1163 | ret = 1; | ||
1164 | break; | ||
1165 | } while (nid != prev_nid); | ||
1166 | |||
1167 | prev_nid = nid; | ||
1168 | return ret; | ||
1169 | } | ||
1170 | |||
1143 | #define persistent_huge_pages(h) (h->nr_huge_pages - h->surplus_huge_pages) | 1171 | #define persistent_huge_pages(h) (h->nr_huge_pages - h->surplus_huge_pages) |
1144 | static unsigned long set_max_huge_pages(struct hstate *h, unsigned long count) | 1172 | static unsigned long set_max_huge_pages(struct hstate *h, unsigned long count) |
1145 | { | 1173 | { |
diff --git a/mm/init-mm.c b/mm/init-mm.c new file mode 100644 index 000000000000..57aba0da9668 --- /dev/null +++ b/mm/init-mm.c | |||
@@ -0,0 +1,20 @@ | |||
1 | #include <linux/mm_types.h> | ||
2 | #include <linux/rbtree.h> | ||
3 | #include <linux/rwsem.h> | ||
4 | #include <linux/spinlock.h> | ||
5 | #include <linux/list.h> | ||
6 | #include <linux/cpumask.h> | ||
7 | |||
8 | #include <asm/atomic.h> | ||
9 | #include <asm/pgtable.h> | ||
10 | |||
11 | struct mm_struct init_mm = { | ||
12 | .mm_rb = RB_ROOT, | ||
13 | .pgd = swapper_pg_dir, | ||
14 | .mm_users = ATOMIC_INIT(2), | ||
15 | .mm_count = ATOMIC_INIT(1), | ||
16 | .mmap_sem = __RWSEM_INITIALIZER(init_mm.mmap_sem), | ||
17 | .page_table_lock = __SPIN_LOCK_UNLOCKED(init_mm.page_table_lock), | ||
18 | .mmlist = LIST_HEAD_INIT(init_mm.mmlist), | ||
19 | .cpu_vm_mask = CPU_MASK_ALL, | ||
20 | }; | ||
diff --git a/mm/internal.h b/mm/internal.h index 987bb03fbdd8..f290c4db528b 100644 --- a/mm/internal.h +++ b/mm/internal.h | |||
@@ -16,9 +16,6 @@ | |||
16 | void free_pgtables(struct mmu_gather *tlb, struct vm_area_struct *start_vma, | 16 | void free_pgtables(struct mmu_gather *tlb, struct vm_area_struct *start_vma, |
17 | unsigned long floor, unsigned long ceiling); | 17 | unsigned long floor, unsigned long ceiling); |
18 | 18 | ||
19 | extern void prep_compound_page(struct page *page, unsigned long order); | ||
20 | extern void prep_compound_gigantic_page(struct page *page, unsigned long order); | ||
21 | |||
22 | static inline void set_page_count(struct page *page, int v) | 19 | static inline void set_page_count(struct page *page, int v) |
23 | { | 20 | { |
24 | atomic_set(&page->_count, v); | 21 | atomic_set(&page->_count, v); |
@@ -51,6 +48,8 @@ extern void putback_lru_page(struct page *page); | |||
51 | */ | 48 | */ |
52 | extern unsigned long highest_memmap_pfn; | 49 | extern unsigned long highest_memmap_pfn; |
53 | extern void __free_pages_bootmem(struct page *page, unsigned int order); | 50 | extern void __free_pages_bootmem(struct page *page, unsigned int order); |
51 | extern void prep_compound_page(struct page *page, unsigned long order); | ||
52 | |||
54 | 53 | ||
55 | /* | 54 | /* |
56 | * function for dealing with page's order in buddy system. | 55 | * function for dealing with page's order in buddy system. |
@@ -74,7 +73,6 @@ static inline void munlock_vma_pages_all(struct vm_area_struct *vma) | |||
74 | } | 73 | } |
75 | #endif | 74 | #endif |
76 | 75 | ||
77 | #ifdef CONFIG_UNEVICTABLE_LRU | ||
78 | /* | 76 | /* |
79 | * unevictable_migrate_page() called only from migrate_page_copy() to | 77 | * unevictable_migrate_page() called only from migrate_page_copy() to |
80 | * migrate unevictable flag to new page. | 78 | * migrate unevictable flag to new page. |
@@ -86,11 +84,6 @@ static inline void unevictable_migrate_page(struct page *new, struct page *old) | |||
86 | if (TestClearPageUnevictable(old)) | 84 | if (TestClearPageUnevictable(old)) |
87 | SetPageUnevictable(new); | 85 | SetPageUnevictable(new); |
88 | } | 86 | } |
89 | #else | ||
90 | static inline void unevictable_migrate_page(struct page *new, struct page *old) | ||
91 | { | ||
92 | } | ||
93 | #endif | ||
94 | 87 | ||
95 | #ifdef CONFIG_HAVE_MLOCKED_PAGE_BIT | 88 | #ifdef CONFIG_HAVE_MLOCKED_PAGE_BIT |
96 | /* | 89 | /* |
@@ -150,23 +143,6 @@ static inline void mlock_migrate_page(struct page *newpage, struct page *page) | |||
150 | } | 143 | } |
151 | } | 144 | } |
152 | 145 | ||
153 | /* | ||
154 | * free_page_mlock() -- clean up attempts to free and mlocked() page. | ||
155 | * Page should not be on lru, so no need to fix that up. | ||
156 | * free_pages_check() will verify... | ||
157 | */ | ||
158 | static inline void free_page_mlock(struct page *page) | ||
159 | { | ||
160 | if (unlikely(TestClearPageMlocked(page))) { | ||
161 | unsigned long flags; | ||
162 | |||
163 | local_irq_save(flags); | ||
164 | __dec_zone_page_state(page, NR_MLOCK); | ||
165 | __count_vm_event(UNEVICTABLE_MLOCKFREED); | ||
166 | local_irq_restore(flags); | ||
167 | } | ||
168 | } | ||
169 | |||
170 | #else /* CONFIG_HAVE_MLOCKED_PAGE_BIT */ | 146 | #else /* CONFIG_HAVE_MLOCKED_PAGE_BIT */ |
171 | static inline int is_mlocked_vma(struct vm_area_struct *v, struct page *p) | 147 | static inline int is_mlocked_vma(struct vm_area_struct *v, struct page *p) |
172 | { | 148 | { |
@@ -175,7 +151,6 @@ static inline int is_mlocked_vma(struct vm_area_struct *v, struct page *p) | |||
175 | static inline void clear_page_mlock(struct page *page) { } | 151 | static inline void clear_page_mlock(struct page *page) { } |
176 | static inline void mlock_vma_page(struct page *page) { } | 152 | static inline void mlock_vma_page(struct page *page) { } |
177 | static inline void mlock_migrate_page(struct page *new, struct page *old) { } | 153 | static inline void mlock_migrate_page(struct page *new, struct page *old) { } |
178 | static inline void free_page_mlock(struct page *page) { } | ||
179 | 154 | ||
180 | #endif /* CONFIG_HAVE_MLOCKED_PAGE_BIT */ | 155 | #endif /* CONFIG_HAVE_MLOCKED_PAGE_BIT */ |
181 | 156 | ||
@@ -284,4 +259,8 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, | |||
284 | unsigned long start, int len, int flags, | 259 | unsigned long start, int len, int flags, |
285 | struct page **pages, struct vm_area_struct **vmas); | 260 | struct page **pages, struct vm_area_struct **vmas); |
286 | 261 | ||
262 | #define ZONE_RECLAIM_NOSCAN -2 | ||
263 | #define ZONE_RECLAIM_FULL -1 | ||
264 | #define ZONE_RECLAIM_SOME 0 | ||
265 | #define ZONE_RECLAIM_SUCCESS 1 | ||
287 | #endif | 266 | #endif |
diff --git a/mm/madvise.c b/mm/madvise.c index b9ce574827c8..76eb4193acdd 100644 --- a/mm/madvise.c +++ b/mm/madvise.c | |||
@@ -123,8 +123,7 @@ static long madvise_willneed(struct vm_area_struct * vma, | |||
123 | end = vma->vm_end; | 123 | end = vma->vm_end; |
124 | end = ((end - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff; | 124 | end = ((end - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff; |
125 | 125 | ||
126 | force_page_cache_readahead(file->f_mapping, | 126 | force_page_cache_readahead(file->f_mapping, file, start, end - start); |
127 | file, start, max_sane_readahead(end - start)); | ||
128 | return 0; | 127 | return 0; |
129 | } | 128 | } |
130 | 129 | ||
@@ -239,12 +238,30 @@ madvise_vma(struct vm_area_struct *vma, struct vm_area_struct **prev, | |||
239 | break; | 238 | break; |
240 | 239 | ||
241 | default: | 240 | default: |
242 | error = -EINVAL; | 241 | BUG(); |
243 | break; | 242 | break; |
244 | } | 243 | } |
245 | return error; | 244 | return error; |
246 | } | 245 | } |
247 | 246 | ||
247 | static int | ||
248 | madvise_behavior_valid(int behavior) | ||
249 | { | ||
250 | switch (behavior) { | ||
251 | case MADV_DOFORK: | ||
252 | case MADV_DONTFORK: | ||
253 | case MADV_NORMAL: | ||
254 | case MADV_SEQUENTIAL: | ||
255 | case MADV_RANDOM: | ||
256 | case MADV_REMOVE: | ||
257 | case MADV_WILLNEED: | ||
258 | case MADV_DONTNEED: | ||
259 | return 1; | ||
260 | |||
261 | default: | ||
262 | return 0; | ||
263 | } | ||
264 | } | ||
248 | /* | 265 | /* |
249 | * The madvise(2) system call. | 266 | * The madvise(2) system call. |
250 | * | 267 | * |
@@ -290,6 +307,9 @@ SYSCALL_DEFINE3(madvise, unsigned long, start, size_t, len_in, int, behavior) | |||
290 | int write; | 307 | int write; |
291 | size_t len; | 308 | size_t len; |
292 | 309 | ||
310 | if (!madvise_behavior_valid(behavior)) | ||
311 | return error; | ||
312 | |||
293 | write = madvise_need_mmap_write(behavior); | 313 | write = madvise_need_mmap_write(behavior); |
294 | if (write) | 314 | if (write) |
295 | down_write(¤t->mm->mmap_sem); | 315 | down_write(¤t->mm->mmap_sem); |
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 78eb8552818b..70db6e0a5eec 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -570,6 +570,17 @@ int mem_cgroup_inactive_anon_is_low(struct mem_cgroup *memcg) | |||
570 | return 0; | 570 | return 0; |
571 | } | 571 | } |
572 | 572 | ||
573 | int mem_cgroup_inactive_file_is_low(struct mem_cgroup *memcg) | ||
574 | { | ||
575 | unsigned long active; | ||
576 | unsigned long inactive; | ||
577 | |||
578 | inactive = mem_cgroup_get_local_zonestat(memcg, LRU_INACTIVE_FILE); | ||
579 | active = mem_cgroup_get_local_zonestat(memcg, LRU_ACTIVE_FILE); | ||
580 | |||
581 | return (active > inactive); | ||
582 | } | ||
583 | |||
573 | unsigned long mem_cgroup_zone_nr_pages(struct mem_cgroup *memcg, | 584 | unsigned long mem_cgroup_zone_nr_pages(struct mem_cgroup *memcg, |
574 | struct zone *zone, | 585 | struct zone *zone, |
575 | enum lru_list lru) | 586 | enum lru_list lru) |
diff --git a/mm/memory.c b/mm/memory.c index 4126dd16778c..d5d1653d60a6 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
@@ -1360,6 +1360,56 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, | |||
1360 | return i; | 1360 | return i; |
1361 | } | 1361 | } |
1362 | 1362 | ||
1363 | /** | ||
1364 | * get_user_pages() - pin user pages in memory | ||
1365 | * @tsk: task_struct of target task | ||
1366 | * @mm: mm_struct of target mm | ||
1367 | * @start: starting user address | ||
1368 | * @len: number of pages from start to pin | ||
1369 | * @write: whether pages will be written to by the caller | ||
1370 | * @force: whether to force write access even if user mapping is | ||
1371 | * readonly. This will result in the page being COWed even | ||
1372 | * in MAP_SHARED mappings. You do not want this. | ||
1373 | * @pages: array that receives pointers to the pages pinned. | ||
1374 | * Should be at least nr_pages long. Or NULL, if caller | ||
1375 | * only intends to ensure the pages are faulted in. | ||
1376 | * @vmas: array of pointers to vmas corresponding to each page. | ||
1377 | * Or NULL if the caller does not require them. | ||
1378 | * | ||
1379 | * Returns number of pages pinned. This may be fewer than the number | ||
1380 | * requested. If len is 0 or negative, returns 0. If no pages | ||
1381 | * were pinned, returns -errno. Each page returned must be released | ||
1382 | * with a put_page() call when it is finished with. vmas will only | ||
1383 | * remain valid while mmap_sem is held. | ||
1384 | * | ||
1385 | * Must be called with mmap_sem held for read or write. | ||
1386 | * | ||
1387 | * get_user_pages walks a process's page tables and takes a reference to | ||
1388 | * each struct page that each user address corresponds to at a given | ||
1389 | * instant. That is, it takes the page that would be accessed if a user | ||
1390 | * thread accesses the given user virtual address at that instant. | ||
1391 | * | ||
1392 | * This does not guarantee that the page exists in the user mappings when | ||
1393 | * get_user_pages returns, and there may even be a completely different | ||
1394 | * page there in some cases (eg. if mmapped pagecache has been invalidated | ||
1395 | * and subsequently re faulted). However it does guarantee that the page | ||
1396 | * won't be freed completely. And mostly callers simply care that the page | ||
1397 | * contains data that was valid *at some point in time*. Typically, an IO | ||
1398 | * or similar operation cannot guarantee anything stronger anyway because | ||
1399 | * locks can't be held over the syscall boundary. | ||
1400 | * | ||
1401 | * If write=0, the page must not be written to. If the page is written to, | ||
1402 | * set_page_dirty (or set_page_dirty_lock, as appropriate) must be called | ||
1403 | * after the page is finished with, and before put_page is called. | ||
1404 | * | ||
1405 | * get_user_pages is typically used for fewer-copy IO operations, to get a | ||
1406 | * handle on the memory by some means other than accesses via the user virtual | ||
1407 | * addresses. The pages may be submitted for DMA to devices or accessed via | ||
1408 | * their kernel linear mapping (via the kmap APIs). Care should be taken to | ||
1409 | * use the correct cache flushing APIs. | ||
1410 | * | ||
1411 | * See also get_user_pages_fast, for performance critical applications. | ||
1412 | */ | ||
1363 | int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, | 1413 | int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, |
1364 | unsigned long start, int len, int write, int force, | 1414 | unsigned long start, int len, int write, int force, |
1365 | struct page **pages, struct vm_area_struct **vmas) | 1415 | struct page **pages, struct vm_area_struct **vmas) |
@@ -3053,22 +3103,13 @@ int in_gate_area_no_task(unsigned long addr) | |||
3053 | 3103 | ||
3054 | #endif /* __HAVE_ARCH_GATE_AREA */ | 3104 | #endif /* __HAVE_ARCH_GATE_AREA */ |
3055 | 3105 | ||
3056 | #ifdef CONFIG_HAVE_IOREMAP_PROT | 3106 | static int follow_pte(struct mm_struct *mm, unsigned long address, |
3057 | int follow_phys(struct vm_area_struct *vma, | 3107 | pte_t **ptepp, spinlock_t **ptlp) |
3058 | unsigned long address, unsigned int flags, | ||
3059 | unsigned long *prot, resource_size_t *phys) | ||
3060 | { | 3108 | { |
3061 | pgd_t *pgd; | 3109 | pgd_t *pgd; |
3062 | pud_t *pud; | 3110 | pud_t *pud; |
3063 | pmd_t *pmd; | 3111 | pmd_t *pmd; |
3064 | pte_t *ptep, pte; | 3112 | pte_t *ptep; |
3065 | spinlock_t *ptl; | ||
3066 | resource_size_t phys_addr = 0; | ||
3067 | struct mm_struct *mm = vma->vm_mm; | ||
3068 | int ret = -EINVAL; | ||
3069 | |||
3070 | if (!(vma->vm_flags & (VM_IO | VM_PFNMAP))) | ||
3071 | goto out; | ||
3072 | 3113 | ||
3073 | pgd = pgd_offset(mm, address); | 3114 | pgd = pgd_offset(mm, address); |
3074 | if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd))) | 3115 | if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd))) |
@@ -3086,22 +3127,71 @@ int follow_phys(struct vm_area_struct *vma, | |||
3086 | if (pmd_huge(*pmd)) | 3127 | if (pmd_huge(*pmd)) |
3087 | goto out; | 3128 | goto out; |
3088 | 3129 | ||
3089 | ptep = pte_offset_map_lock(mm, pmd, address, &ptl); | 3130 | ptep = pte_offset_map_lock(mm, pmd, address, ptlp); |
3090 | if (!ptep) | 3131 | if (!ptep) |
3091 | goto out; | 3132 | goto out; |
3133 | if (!pte_present(*ptep)) | ||
3134 | goto unlock; | ||
3135 | *ptepp = ptep; | ||
3136 | return 0; | ||
3137 | unlock: | ||
3138 | pte_unmap_unlock(ptep, *ptlp); | ||
3139 | out: | ||
3140 | return -EINVAL; | ||
3141 | } | ||
3092 | 3142 | ||
3143 | /** | ||
3144 | * follow_pfn - look up PFN at a user virtual address | ||
3145 | * @vma: memory mapping | ||
3146 | * @address: user virtual address | ||
3147 | * @pfn: location to store found PFN | ||
3148 | * | ||
3149 | * Only IO mappings and raw PFN mappings are allowed. | ||
3150 | * | ||
3151 | * Returns zero and the pfn at @pfn on success, -ve otherwise. | ||
3152 | */ | ||
3153 | int follow_pfn(struct vm_area_struct *vma, unsigned long address, | ||
3154 | unsigned long *pfn) | ||
3155 | { | ||
3156 | int ret = -EINVAL; | ||
3157 | spinlock_t *ptl; | ||
3158 | pte_t *ptep; | ||
3159 | |||
3160 | if (!(vma->vm_flags & (VM_IO | VM_PFNMAP))) | ||
3161 | return ret; | ||
3162 | |||
3163 | ret = follow_pte(vma->vm_mm, address, &ptep, &ptl); | ||
3164 | if (ret) | ||
3165 | return ret; | ||
3166 | *pfn = pte_pfn(*ptep); | ||
3167 | pte_unmap_unlock(ptep, ptl); | ||
3168 | return 0; | ||
3169 | } | ||
3170 | EXPORT_SYMBOL(follow_pfn); | ||
3171 | |||
3172 | #ifdef CONFIG_HAVE_IOREMAP_PROT | ||
3173 | int follow_phys(struct vm_area_struct *vma, | ||
3174 | unsigned long address, unsigned int flags, | ||
3175 | unsigned long *prot, resource_size_t *phys) | ||
3176 | { | ||
3177 | int ret = -EINVAL; | ||
3178 | pte_t *ptep, pte; | ||
3179 | spinlock_t *ptl; | ||
3180 | |||
3181 | if (!(vma->vm_flags & (VM_IO | VM_PFNMAP))) | ||
3182 | goto out; | ||
3183 | |||
3184 | if (follow_pte(vma->vm_mm, address, &ptep, &ptl)) | ||
3185 | goto out; | ||
3093 | pte = *ptep; | 3186 | pte = *ptep; |
3094 | if (!pte_present(pte)) | 3187 | |
3095 | goto unlock; | ||
3096 | if ((flags & FOLL_WRITE) && !pte_write(pte)) | 3188 | if ((flags & FOLL_WRITE) && !pte_write(pte)) |
3097 | goto unlock; | 3189 | goto unlock; |
3098 | phys_addr = pte_pfn(pte); | ||
3099 | phys_addr <<= PAGE_SHIFT; /* Shift here to avoid overflow on PAE */ | ||
3100 | 3190 | ||
3101 | *prot = pgprot_val(pte_pgprot(pte)); | 3191 | *prot = pgprot_val(pte_pgprot(pte)); |
3102 | *phys = phys_addr; | 3192 | *phys = (resource_size_t)pte_pfn(pte) << PAGE_SHIFT; |
3103 | ret = 0; | ||
3104 | 3193 | ||
3194 | ret = 0; | ||
3105 | unlock: | 3195 | unlock: |
3106 | pte_unmap_unlock(ptep, ptl); | 3196 | pte_unmap_unlock(ptep, ptl); |
3107 | out: | 3197 | out: |
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index c083cf5fd6df..e4412a676c88 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c | |||
@@ -422,7 +422,8 @@ int online_pages(unsigned long pfn, unsigned long nr_pages) | |||
422 | zone->present_pages += onlined_pages; | 422 | zone->present_pages += onlined_pages; |
423 | zone->zone_pgdat->node_present_pages += onlined_pages; | 423 | zone->zone_pgdat->node_present_pages += onlined_pages; |
424 | 424 | ||
425 | setup_per_zone_pages_min(); | 425 | setup_per_zone_wmarks(); |
426 | calculate_zone_inactive_ratio(zone); | ||
426 | if (onlined_pages) { | 427 | if (onlined_pages) { |
427 | kswapd_run(zone_to_nid(zone)); | 428 | kswapd_run(zone_to_nid(zone)); |
428 | node_set_state(zone_to_nid(zone), N_HIGH_MEMORY); | 429 | node_set_state(zone_to_nid(zone), N_HIGH_MEMORY); |
@@ -832,6 +833,9 @@ repeat: | |||
832 | totalram_pages -= offlined_pages; | 833 | totalram_pages -= offlined_pages; |
833 | num_physpages -= offlined_pages; | 834 | num_physpages -= offlined_pages; |
834 | 835 | ||
836 | setup_per_zone_wmarks(); | ||
837 | calculate_zone_inactive_ratio(zone); | ||
838 | |||
835 | vm_total_pages = nr_free_pagecache_pages(); | 839 | vm_total_pages = nr_free_pagecache_pages(); |
836 | writeback_set_ratelimit(); | 840 | writeback_set_ratelimit(); |
837 | 841 | ||
diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 3eb4a6fdc043..e08e2c4da63a 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c | |||
@@ -182,13 +182,54 @@ static int mpol_new_bind(struct mempolicy *pol, const nodemask_t *nodes) | |||
182 | return 0; | 182 | return 0; |
183 | } | 183 | } |
184 | 184 | ||
185 | /* Create a new policy */ | 185 | /* |
186 | * mpol_set_nodemask is called after mpol_new() to set up the nodemask, if | ||
187 | * any, for the new policy. mpol_new() has already validated the nodes | ||
188 | * parameter with respect to the policy mode and flags. But, we need to | ||
189 | * handle an empty nodemask with MPOL_PREFERRED here. | ||
190 | * | ||
191 | * Must be called holding task's alloc_lock to protect task's mems_allowed | ||
192 | * and mempolicy. May also be called holding the mmap_semaphore for write. | ||
193 | */ | ||
194 | static int mpol_set_nodemask(struct mempolicy *pol, const nodemask_t *nodes) | ||
195 | { | ||
196 | nodemask_t cpuset_context_nmask; | ||
197 | int ret; | ||
198 | |||
199 | /* if mode is MPOL_DEFAULT, pol is NULL. This is right. */ | ||
200 | if (pol == NULL) | ||
201 | return 0; | ||
202 | |||
203 | VM_BUG_ON(!nodes); | ||
204 | if (pol->mode == MPOL_PREFERRED && nodes_empty(*nodes)) | ||
205 | nodes = NULL; /* explicit local allocation */ | ||
206 | else { | ||
207 | if (pol->flags & MPOL_F_RELATIVE_NODES) | ||
208 | mpol_relative_nodemask(&cpuset_context_nmask, nodes, | ||
209 | &cpuset_current_mems_allowed); | ||
210 | else | ||
211 | nodes_and(cpuset_context_nmask, *nodes, | ||
212 | cpuset_current_mems_allowed); | ||
213 | if (mpol_store_user_nodemask(pol)) | ||
214 | pol->w.user_nodemask = *nodes; | ||
215 | else | ||
216 | pol->w.cpuset_mems_allowed = | ||
217 | cpuset_current_mems_allowed; | ||
218 | } | ||
219 | |||
220 | ret = mpol_ops[pol->mode].create(pol, | ||
221 | nodes ? &cpuset_context_nmask : NULL); | ||
222 | return ret; | ||
223 | } | ||
224 | |||
225 | /* | ||
226 | * This function just creates a new policy, does some check and simple | ||
227 | * initialization. You must invoke mpol_set_nodemask() to set nodes. | ||
228 | */ | ||
186 | static struct mempolicy *mpol_new(unsigned short mode, unsigned short flags, | 229 | static struct mempolicy *mpol_new(unsigned short mode, unsigned short flags, |
187 | nodemask_t *nodes) | 230 | nodemask_t *nodes) |
188 | { | 231 | { |
189 | struct mempolicy *policy; | 232 | struct mempolicy *policy; |
190 | nodemask_t cpuset_context_nmask; | ||
191 | int ret; | ||
192 | 233 | ||
193 | pr_debug("setting mode %d flags %d nodes[0] %lx\n", | 234 | pr_debug("setting mode %d flags %d nodes[0] %lx\n", |
194 | mode, flags, nodes ? nodes_addr(*nodes)[0] : -1); | 235 | mode, flags, nodes ? nodes_addr(*nodes)[0] : -1); |
@@ -210,7 +251,6 @@ static struct mempolicy *mpol_new(unsigned short mode, unsigned short flags, | |||
210 | if (((flags & MPOL_F_STATIC_NODES) || | 251 | if (((flags & MPOL_F_STATIC_NODES) || |
211 | (flags & MPOL_F_RELATIVE_NODES))) | 252 | (flags & MPOL_F_RELATIVE_NODES))) |
212 | return ERR_PTR(-EINVAL); | 253 | return ERR_PTR(-EINVAL); |
213 | nodes = NULL; /* flag local alloc */ | ||
214 | } | 254 | } |
215 | } else if (nodes_empty(*nodes)) | 255 | } else if (nodes_empty(*nodes)) |
216 | return ERR_PTR(-EINVAL); | 256 | return ERR_PTR(-EINVAL); |
@@ -221,30 +261,6 @@ static struct mempolicy *mpol_new(unsigned short mode, unsigned short flags, | |||
221 | policy->mode = mode; | 261 | policy->mode = mode; |
222 | policy->flags = flags; | 262 | policy->flags = flags; |
223 | 263 | ||
224 | if (nodes) { | ||
225 | /* | ||
226 | * cpuset related setup doesn't apply to local allocation | ||
227 | */ | ||
228 | cpuset_update_task_memory_state(); | ||
229 | if (flags & MPOL_F_RELATIVE_NODES) | ||
230 | mpol_relative_nodemask(&cpuset_context_nmask, nodes, | ||
231 | &cpuset_current_mems_allowed); | ||
232 | else | ||
233 | nodes_and(cpuset_context_nmask, *nodes, | ||
234 | cpuset_current_mems_allowed); | ||
235 | if (mpol_store_user_nodemask(policy)) | ||
236 | policy->w.user_nodemask = *nodes; | ||
237 | else | ||
238 | policy->w.cpuset_mems_allowed = | ||
239 | cpuset_mems_allowed(current); | ||
240 | } | ||
241 | |||
242 | ret = mpol_ops[mode].create(policy, | ||
243 | nodes ? &cpuset_context_nmask : NULL); | ||
244 | if (ret < 0) { | ||
245 | kmem_cache_free(policy_cache, policy); | ||
246 | return ERR_PTR(ret); | ||
247 | } | ||
248 | return policy; | 264 | return policy; |
249 | } | 265 | } |
250 | 266 | ||
@@ -324,6 +340,8 @@ static void mpol_rebind_policy(struct mempolicy *pol, | |||
324 | /* | 340 | /* |
325 | * Wrapper for mpol_rebind_policy() that just requires task | 341 | * Wrapper for mpol_rebind_policy() that just requires task |
326 | * pointer, and updates task mempolicy. | 342 | * pointer, and updates task mempolicy. |
343 | * | ||
344 | * Called with task's alloc_lock held. | ||
327 | */ | 345 | */ |
328 | 346 | ||
329 | void mpol_rebind_task(struct task_struct *tsk, const nodemask_t *new) | 347 | void mpol_rebind_task(struct task_struct *tsk, const nodemask_t *new) |
@@ -600,8 +618,9 @@ static void mpol_set_task_struct_flag(void) | |||
600 | static long do_set_mempolicy(unsigned short mode, unsigned short flags, | 618 | static long do_set_mempolicy(unsigned short mode, unsigned short flags, |
601 | nodemask_t *nodes) | 619 | nodemask_t *nodes) |
602 | { | 620 | { |
603 | struct mempolicy *new; | 621 | struct mempolicy *new, *old; |
604 | struct mm_struct *mm = current->mm; | 622 | struct mm_struct *mm = current->mm; |
623 | int ret; | ||
605 | 624 | ||
606 | new = mpol_new(mode, flags, nodes); | 625 | new = mpol_new(mode, flags, nodes); |
607 | if (IS_ERR(new)) | 626 | if (IS_ERR(new)) |
@@ -615,20 +634,33 @@ static long do_set_mempolicy(unsigned short mode, unsigned short flags, | |||
615 | */ | 634 | */ |
616 | if (mm) | 635 | if (mm) |
617 | down_write(&mm->mmap_sem); | 636 | down_write(&mm->mmap_sem); |
618 | mpol_put(current->mempolicy); | 637 | task_lock(current); |
638 | ret = mpol_set_nodemask(new, nodes); | ||
639 | if (ret) { | ||
640 | task_unlock(current); | ||
641 | if (mm) | ||
642 | up_write(&mm->mmap_sem); | ||
643 | mpol_put(new); | ||
644 | return ret; | ||
645 | } | ||
646 | old = current->mempolicy; | ||
619 | current->mempolicy = new; | 647 | current->mempolicy = new; |
620 | mpol_set_task_struct_flag(); | 648 | mpol_set_task_struct_flag(); |
621 | if (new && new->mode == MPOL_INTERLEAVE && | 649 | if (new && new->mode == MPOL_INTERLEAVE && |
622 | nodes_weight(new->v.nodes)) | 650 | nodes_weight(new->v.nodes)) |
623 | current->il_next = first_node(new->v.nodes); | 651 | current->il_next = first_node(new->v.nodes); |
652 | task_unlock(current); | ||
624 | if (mm) | 653 | if (mm) |
625 | up_write(&mm->mmap_sem); | 654 | up_write(&mm->mmap_sem); |
626 | 655 | ||
656 | mpol_put(old); | ||
627 | return 0; | 657 | return 0; |
628 | } | 658 | } |
629 | 659 | ||
630 | /* | 660 | /* |
631 | * Return nodemask for policy for get_mempolicy() query | 661 | * Return nodemask for policy for get_mempolicy() query |
662 | * | ||
663 | * Called with task's alloc_lock held | ||
632 | */ | 664 | */ |
633 | static void get_policy_nodemask(struct mempolicy *p, nodemask_t *nodes) | 665 | static void get_policy_nodemask(struct mempolicy *p, nodemask_t *nodes) |
634 | { | 666 | { |
@@ -674,7 +706,6 @@ static long do_get_mempolicy(int *policy, nodemask_t *nmask, | |||
674 | struct vm_area_struct *vma = NULL; | 706 | struct vm_area_struct *vma = NULL; |
675 | struct mempolicy *pol = current->mempolicy; | 707 | struct mempolicy *pol = current->mempolicy; |
676 | 708 | ||
677 | cpuset_update_task_memory_state(); | ||
678 | if (flags & | 709 | if (flags & |
679 | ~(unsigned long)(MPOL_F_NODE|MPOL_F_ADDR|MPOL_F_MEMS_ALLOWED)) | 710 | ~(unsigned long)(MPOL_F_NODE|MPOL_F_ADDR|MPOL_F_MEMS_ALLOWED)) |
680 | return -EINVAL; | 711 | return -EINVAL; |
@@ -683,7 +714,9 @@ static long do_get_mempolicy(int *policy, nodemask_t *nmask, | |||
683 | if (flags & (MPOL_F_NODE|MPOL_F_ADDR)) | 714 | if (flags & (MPOL_F_NODE|MPOL_F_ADDR)) |
684 | return -EINVAL; | 715 | return -EINVAL; |
685 | *policy = 0; /* just so it's initialized */ | 716 | *policy = 0; /* just so it's initialized */ |
717 | task_lock(current); | ||
686 | *nmask = cpuset_current_mems_allowed; | 718 | *nmask = cpuset_current_mems_allowed; |
719 | task_unlock(current); | ||
687 | return 0; | 720 | return 0; |
688 | } | 721 | } |
689 | 722 | ||
@@ -738,8 +771,11 @@ static long do_get_mempolicy(int *policy, nodemask_t *nmask, | |||
738 | } | 771 | } |
739 | 772 | ||
740 | err = 0; | 773 | err = 0; |
741 | if (nmask) | 774 | if (nmask) { |
775 | task_lock(current); | ||
742 | get_policy_nodemask(pol, nmask); | 776 | get_policy_nodemask(pol, nmask); |
777 | task_unlock(current); | ||
778 | } | ||
743 | 779 | ||
744 | out: | 780 | out: |
745 | mpol_cond_put(pol); | 781 | mpol_cond_put(pol); |
@@ -767,7 +803,7 @@ static void migrate_page_add(struct page *page, struct list_head *pagelist, | |||
767 | 803 | ||
768 | static struct page *new_node_page(struct page *page, unsigned long node, int **x) | 804 | static struct page *new_node_page(struct page *page, unsigned long node, int **x) |
769 | { | 805 | { |
770 | return alloc_pages_node(node, GFP_HIGHUSER_MOVABLE, 0); | 806 | return alloc_pages_exact_node(node, GFP_HIGHUSER_MOVABLE, 0); |
771 | } | 807 | } |
772 | 808 | ||
773 | /* | 809 | /* |
@@ -979,6 +1015,14 @@ static long do_mbind(unsigned long start, unsigned long len, | |||
979 | return err; | 1015 | return err; |
980 | } | 1016 | } |
981 | down_write(&mm->mmap_sem); | 1017 | down_write(&mm->mmap_sem); |
1018 | task_lock(current); | ||
1019 | err = mpol_set_nodemask(new, nmask); | ||
1020 | task_unlock(current); | ||
1021 | if (err) { | ||
1022 | up_write(&mm->mmap_sem); | ||
1023 | mpol_put(new); | ||
1024 | return err; | ||
1025 | } | ||
982 | vma = check_range(mm, start, end, nmask, | 1026 | vma = check_range(mm, start, end, nmask, |
983 | flags | MPOL_MF_INVERT, &pagelist); | 1027 | flags | MPOL_MF_INVERT, &pagelist); |
984 | 1028 | ||
@@ -1545,8 +1589,6 @@ alloc_page_vma(gfp_t gfp, struct vm_area_struct *vma, unsigned long addr) | |||
1545 | struct mempolicy *pol = get_vma_policy(current, vma, addr); | 1589 | struct mempolicy *pol = get_vma_policy(current, vma, addr); |
1546 | struct zonelist *zl; | 1590 | struct zonelist *zl; |
1547 | 1591 | ||
1548 | cpuset_update_task_memory_state(); | ||
1549 | |||
1550 | if (unlikely(pol->mode == MPOL_INTERLEAVE)) { | 1592 | if (unlikely(pol->mode == MPOL_INTERLEAVE)) { |
1551 | unsigned nid; | 1593 | unsigned nid; |
1552 | 1594 | ||
@@ -1593,8 +1635,6 @@ struct page *alloc_pages_current(gfp_t gfp, unsigned order) | |||
1593 | { | 1635 | { |
1594 | struct mempolicy *pol = current->mempolicy; | 1636 | struct mempolicy *pol = current->mempolicy; |
1595 | 1637 | ||
1596 | if ((gfp & __GFP_WAIT) && !in_interrupt()) | ||
1597 | cpuset_update_task_memory_state(); | ||
1598 | if (!pol || in_interrupt() || (gfp & __GFP_THISNODE)) | 1638 | if (!pol || in_interrupt() || (gfp & __GFP_THISNODE)) |
1599 | pol = &default_policy; | 1639 | pol = &default_policy; |
1600 | 1640 | ||
@@ -1854,6 +1894,8 @@ restart: | |||
1854 | */ | 1894 | */ |
1855 | void mpol_shared_policy_init(struct shared_policy *sp, struct mempolicy *mpol) | 1895 | void mpol_shared_policy_init(struct shared_policy *sp, struct mempolicy *mpol) |
1856 | { | 1896 | { |
1897 | int ret; | ||
1898 | |||
1857 | sp->root = RB_ROOT; /* empty tree == default mempolicy */ | 1899 | sp->root = RB_ROOT; /* empty tree == default mempolicy */ |
1858 | spin_lock_init(&sp->lock); | 1900 | spin_lock_init(&sp->lock); |
1859 | 1901 | ||
@@ -1863,9 +1905,19 @@ void mpol_shared_policy_init(struct shared_policy *sp, struct mempolicy *mpol) | |||
1863 | 1905 | ||
1864 | /* contextualize the tmpfs mount point mempolicy */ | 1906 | /* contextualize the tmpfs mount point mempolicy */ |
1865 | new = mpol_new(mpol->mode, mpol->flags, &mpol->w.user_nodemask); | 1907 | new = mpol_new(mpol->mode, mpol->flags, &mpol->w.user_nodemask); |
1866 | mpol_put(mpol); /* drop our ref on sb mpol */ | 1908 | if (IS_ERR(new)) { |
1867 | if (IS_ERR(new)) | 1909 | mpol_put(mpol); /* drop our ref on sb mpol */ |
1868 | return; /* no valid nodemask intersection */ | 1910 | return; /* no valid nodemask intersection */ |
1911 | } | ||
1912 | |||
1913 | task_lock(current); | ||
1914 | ret = mpol_set_nodemask(new, &mpol->w.user_nodemask); | ||
1915 | task_unlock(current); | ||
1916 | mpol_put(mpol); /* drop our ref on sb mpol */ | ||
1917 | if (ret) { | ||
1918 | mpol_put(new); | ||
1919 | return; | ||
1920 | } | ||
1869 | 1921 | ||
1870 | /* Create pseudo-vma that contains just the policy */ | 1922 | /* Create pseudo-vma that contains just the policy */ |
1871 | memset(&pvma, 0, sizeof(struct vm_area_struct)); | 1923 | memset(&pvma, 0, sizeof(struct vm_area_struct)); |
@@ -2086,8 +2138,19 @@ int mpol_parse_str(char *str, struct mempolicy **mpol, int no_context) | |||
2086 | new = mpol_new(mode, mode_flags, &nodes); | 2138 | new = mpol_new(mode, mode_flags, &nodes); |
2087 | if (IS_ERR(new)) | 2139 | if (IS_ERR(new)) |
2088 | err = 1; | 2140 | err = 1; |
2089 | else if (no_context) | 2141 | else { |
2090 | new->w.user_nodemask = nodes; /* save for contextualization */ | 2142 | int ret; |
2143 | |||
2144 | task_lock(current); | ||
2145 | ret = mpol_set_nodemask(new, &nodes); | ||
2146 | task_unlock(current); | ||
2147 | if (ret) | ||
2148 | err = 1; | ||
2149 | else if (no_context) { | ||
2150 | /* save for contextualization */ | ||
2151 | new->w.user_nodemask = nodes; | ||
2152 | } | ||
2153 | } | ||
2091 | 2154 | ||
2092 | out: | 2155 | out: |
2093 | /* Restore string for error message */ | 2156 | /* Restore string for error message */ |
diff --git a/mm/migrate.c b/mm/migrate.c index 068655d8f883..939888f9ddab 100644 --- a/mm/migrate.c +++ b/mm/migrate.c | |||
@@ -802,7 +802,7 @@ static struct page *new_page_node(struct page *p, unsigned long private, | |||
802 | 802 | ||
803 | *result = &pm->status; | 803 | *result = &pm->status; |
804 | 804 | ||
805 | return alloc_pages_node(pm->node, | 805 | return alloc_pages_exact_node(pm->node, |
806 | GFP_HIGHUSER_MOVABLE | GFP_THISNODE, 0); | 806 | GFP_HIGHUSER_MOVABLE | GFP_THISNODE, 0); |
807 | } | 807 | } |
808 | 808 | ||
@@ -820,7 +820,6 @@ static int do_move_page_to_node_array(struct mm_struct *mm, | |||
820 | struct page_to_node *pp; | 820 | struct page_to_node *pp; |
821 | LIST_HEAD(pagelist); | 821 | LIST_HEAD(pagelist); |
822 | 822 | ||
823 | migrate_prep(); | ||
824 | down_read(&mm->mmap_sem); | 823 | down_read(&mm->mmap_sem); |
825 | 824 | ||
826 | /* | 825 | /* |
@@ -907,6 +906,9 @@ static int do_pages_move(struct mm_struct *mm, struct task_struct *task, | |||
907 | pm = (struct page_to_node *)__get_free_page(GFP_KERNEL); | 906 | pm = (struct page_to_node *)__get_free_page(GFP_KERNEL); |
908 | if (!pm) | 907 | if (!pm) |
909 | goto out; | 908 | goto out; |
909 | |||
910 | migrate_prep(); | ||
911 | |||
910 | /* | 912 | /* |
911 | * Store a chunk of page_to_node array in a page, | 913 | * Store a chunk of page_to_node array in a page, |
912 | * but keep the last one as a marker | 914 | * but keep the last one as a marker |
diff --git a/mm/mlock.c b/mm/mlock.c index ac130433c7d3..45eb650b9654 100644 --- a/mm/mlock.c +++ b/mm/mlock.c | |||
@@ -31,7 +31,6 @@ int can_do_mlock(void) | |||
31 | } | 31 | } |
32 | EXPORT_SYMBOL(can_do_mlock); | 32 | EXPORT_SYMBOL(can_do_mlock); |
33 | 33 | ||
34 | #ifdef CONFIG_UNEVICTABLE_LRU | ||
35 | /* | 34 | /* |
36 | * Mlocked pages are marked with PageMlocked() flag for efficient testing | 35 | * Mlocked pages are marked with PageMlocked() flag for efficient testing |
37 | * in vmscan and, possibly, the fault path; and to support semi-accurate | 36 | * in vmscan and, possibly, the fault path; and to support semi-accurate |
@@ -261,27 +260,6 @@ static int __mlock_posix_error_return(long retval) | |||
261 | return retval; | 260 | return retval; |
262 | } | 261 | } |
263 | 262 | ||
264 | #else /* CONFIG_UNEVICTABLE_LRU */ | ||
265 | |||
266 | /* | ||
267 | * Just make pages present if VM_LOCKED. No-op if unlocking. | ||
268 | */ | ||
269 | static long __mlock_vma_pages_range(struct vm_area_struct *vma, | ||
270 | unsigned long start, unsigned long end, | ||
271 | int mlock) | ||
272 | { | ||
273 | if (mlock && (vma->vm_flags & VM_LOCKED)) | ||
274 | return make_pages_present(start, end); | ||
275 | return 0; | ||
276 | } | ||
277 | |||
278 | static inline int __mlock_posix_error_return(long retval) | ||
279 | { | ||
280 | return 0; | ||
281 | } | ||
282 | |||
283 | #endif /* CONFIG_UNEVICTABLE_LRU */ | ||
284 | |||
285 | /** | 263 | /** |
286 | * mlock_vma_pages_range() - mlock pages in specified vma range. | 264 | * mlock_vma_pages_range() - mlock pages in specified vma range. |
287 | * @vma - the vma containing the specfied address range | 265 | * @vma - the vma containing the specfied address range |
diff --git a/mm/oom_kill.c b/mm/oom_kill.c index a7b2460e922b..175a67a78a99 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c | |||
@@ -58,6 +58,7 @@ unsigned long badness(struct task_struct *p, unsigned long uptime) | |||
58 | unsigned long points, cpu_time, run_time; | 58 | unsigned long points, cpu_time, run_time; |
59 | struct mm_struct *mm; | 59 | struct mm_struct *mm; |
60 | struct task_struct *child; | 60 | struct task_struct *child; |
61 | int oom_adj; | ||
61 | 62 | ||
62 | task_lock(p); | 63 | task_lock(p); |
63 | mm = p->mm; | 64 | mm = p->mm; |
@@ -65,6 +66,11 @@ unsigned long badness(struct task_struct *p, unsigned long uptime) | |||
65 | task_unlock(p); | 66 | task_unlock(p); |
66 | return 0; | 67 | return 0; |
67 | } | 68 | } |
69 | oom_adj = mm->oom_adj; | ||
70 | if (oom_adj == OOM_DISABLE) { | ||
71 | task_unlock(p); | ||
72 | return 0; | ||
73 | } | ||
68 | 74 | ||
69 | /* | 75 | /* |
70 | * The memory size of the process is the basis for the badness. | 76 | * The memory size of the process is the basis for the badness. |
@@ -148,15 +154,15 @@ unsigned long badness(struct task_struct *p, unsigned long uptime) | |||
148 | points /= 8; | 154 | points /= 8; |
149 | 155 | ||
150 | /* | 156 | /* |
151 | * Adjust the score by oomkilladj. | 157 | * Adjust the score by oom_adj. |
152 | */ | 158 | */ |
153 | if (p->oomkilladj) { | 159 | if (oom_adj) { |
154 | if (p->oomkilladj > 0) { | 160 | if (oom_adj > 0) { |
155 | if (!points) | 161 | if (!points) |
156 | points = 1; | 162 | points = 1; |
157 | points <<= p->oomkilladj; | 163 | points <<= oom_adj; |
158 | } else | 164 | } else |
159 | points >>= -(p->oomkilladj); | 165 | points >>= -(oom_adj); |
160 | } | 166 | } |
161 | 167 | ||
162 | #ifdef DEBUG | 168 | #ifdef DEBUG |
@@ -251,11 +257,8 @@ static struct task_struct *select_bad_process(unsigned long *ppoints, | |||
251 | *ppoints = ULONG_MAX; | 257 | *ppoints = ULONG_MAX; |
252 | } | 258 | } |
253 | 259 | ||
254 | if (p->oomkilladj == OOM_DISABLE) | ||
255 | continue; | ||
256 | |||
257 | points = badness(p, uptime.tv_sec); | 260 | points = badness(p, uptime.tv_sec); |
258 | if (points > *ppoints || !chosen) { | 261 | if (points > *ppoints) { |
259 | chosen = p; | 262 | chosen = p; |
260 | *ppoints = points; | 263 | *ppoints = points; |
261 | } | 264 | } |
@@ -304,8 +307,7 @@ static void dump_tasks(const struct mem_cgroup *mem) | |||
304 | } | 307 | } |
305 | printk(KERN_INFO "[%5d] %5d %5d %8lu %8lu %3d %3d %s\n", | 308 | printk(KERN_INFO "[%5d] %5d %5d %8lu %8lu %3d %3d %s\n", |
306 | p->pid, __task_cred(p)->uid, p->tgid, mm->total_vm, | 309 | p->pid, __task_cred(p)->uid, p->tgid, mm->total_vm, |
307 | get_mm_rss(mm), (int)task_cpu(p), p->oomkilladj, | 310 | get_mm_rss(mm), (int)task_cpu(p), mm->oom_adj, p->comm); |
308 | p->comm); | ||
309 | task_unlock(p); | 311 | task_unlock(p); |
310 | } while_each_thread(g, p); | 312 | } while_each_thread(g, p); |
311 | } | 313 | } |
@@ -323,11 +325,8 @@ static void __oom_kill_task(struct task_struct *p, int verbose) | |||
323 | return; | 325 | return; |
324 | } | 326 | } |
325 | 327 | ||
326 | if (!p->mm) { | 328 | if (!p->mm) |
327 | WARN_ON(1); | ||
328 | printk(KERN_WARNING "tried to kill an mm-less task!\n"); | ||
329 | return; | 329 | return; |
330 | } | ||
331 | 330 | ||
332 | if (verbose) | 331 | if (verbose) |
333 | printk(KERN_ERR "Killed process %d (%s)\n", | 332 | printk(KERN_ERR "Killed process %d (%s)\n", |
@@ -349,28 +348,13 @@ static int oom_kill_task(struct task_struct *p) | |||
349 | struct mm_struct *mm; | 348 | struct mm_struct *mm; |
350 | struct task_struct *g, *q; | 349 | struct task_struct *g, *q; |
351 | 350 | ||
351 | task_lock(p); | ||
352 | mm = p->mm; | 352 | mm = p->mm; |
353 | 353 | if (!mm || mm->oom_adj == OOM_DISABLE) { | |
354 | /* WARNING: mm may not be dereferenced since we did not obtain its | 354 | task_unlock(p); |
355 | * value from get_task_mm(p). This is OK since all we need to do is | ||
356 | * compare mm to q->mm below. | ||
357 | * | ||
358 | * Furthermore, even if mm contains a non-NULL value, p->mm may | ||
359 | * change to NULL at any time since we do not hold task_lock(p). | ||
360 | * However, this is of no concern to us. | ||
361 | */ | ||
362 | |||
363 | if (mm == NULL) | ||
364 | return 1; | 355 | return 1; |
365 | 356 | } | |
366 | /* | 357 | task_unlock(p); |
367 | * Don't kill the process if any threads are set to OOM_DISABLE | ||
368 | */ | ||
369 | do_each_thread(g, q) { | ||
370 | if (q->mm == mm && q->oomkilladj == OOM_DISABLE) | ||
371 | return 1; | ||
372 | } while_each_thread(g, q); | ||
373 | |||
374 | __oom_kill_task(p, 1); | 358 | __oom_kill_task(p, 1); |
375 | 359 | ||
376 | /* | 360 | /* |
@@ -393,10 +377,11 @@ static int oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order, | |||
393 | struct task_struct *c; | 377 | struct task_struct *c; |
394 | 378 | ||
395 | if (printk_ratelimit()) { | 379 | if (printk_ratelimit()) { |
396 | printk(KERN_WARNING "%s invoked oom-killer: " | ||
397 | "gfp_mask=0x%x, order=%d, oomkilladj=%d\n", | ||
398 | current->comm, gfp_mask, order, current->oomkilladj); | ||
399 | task_lock(current); | 380 | task_lock(current); |
381 | printk(KERN_WARNING "%s invoked oom-killer: " | ||
382 | "gfp_mask=0x%x, order=%d, oom_adj=%d\n", | ||
383 | current->comm, gfp_mask, order, | ||
384 | current->mm ? current->mm->oom_adj : OOM_DISABLE); | ||
400 | cpuset_print_task_mems_allowed(current); | 385 | cpuset_print_task_mems_allowed(current); |
401 | task_unlock(current); | 386 | task_unlock(current); |
402 | dump_stack(); | 387 | dump_stack(); |
@@ -409,8 +394,9 @@ static int oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order, | |||
409 | /* | 394 | /* |
410 | * If the task is already exiting, don't alarm the sysadmin or kill | 395 | * If the task is already exiting, don't alarm the sysadmin or kill |
411 | * its children or threads, just set TIF_MEMDIE so it can die quickly | 396 | * its children or threads, just set TIF_MEMDIE so it can die quickly |
397 | * if its mm is still attached. | ||
412 | */ | 398 | */ |
413 | if (p->flags & PF_EXITING) { | 399 | if (p->mm && (p->flags & PF_EXITING)) { |
414 | __oom_kill_task(p, 0); | 400 | __oom_kill_task(p, 0); |
415 | return 0; | 401 | return 0; |
416 | } | 402 | } |
diff --git a/mm/page-writeback.c b/mm/page-writeback.c index bb553c3e955d..7b0dcea4935b 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c | |||
@@ -265,18 +265,19 @@ static void bdi_writeout_fraction(struct backing_dev_info *bdi, | |||
265 | * This avoids exceeding the total dirty_limit when the floating averages | 265 | * This avoids exceeding the total dirty_limit when the floating averages |
266 | * fluctuate too quickly. | 266 | * fluctuate too quickly. |
267 | */ | 267 | */ |
268 | static void | 268 | static void clip_bdi_dirty_limit(struct backing_dev_info *bdi, |
269 | clip_bdi_dirty_limit(struct backing_dev_info *bdi, long dirty, long *pbdi_dirty) | 269 | unsigned long dirty, unsigned long *pbdi_dirty) |
270 | { | 270 | { |
271 | long avail_dirty; | 271 | unsigned long avail_dirty; |
272 | 272 | ||
273 | avail_dirty = dirty - | 273 | avail_dirty = global_page_state(NR_FILE_DIRTY) + |
274 | (global_page_state(NR_FILE_DIRTY) + | ||
275 | global_page_state(NR_WRITEBACK) + | 274 | global_page_state(NR_WRITEBACK) + |
276 | global_page_state(NR_UNSTABLE_NFS) + | 275 | global_page_state(NR_UNSTABLE_NFS) + |
277 | global_page_state(NR_WRITEBACK_TEMP)); | 276 | global_page_state(NR_WRITEBACK_TEMP); |
278 | 277 | ||
279 | if (avail_dirty < 0) | 278 | if (avail_dirty < dirty) |
279 | avail_dirty = dirty - avail_dirty; | ||
280 | else | ||
280 | avail_dirty = 0; | 281 | avail_dirty = 0; |
281 | 282 | ||
282 | avail_dirty += bdi_stat(bdi, BDI_RECLAIMABLE) + | 283 | avail_dirty += bdi_stat(bdi, BDI_RECLAIMABLE) + |
@@ -299,10 +300,10 @@ static inline void task_dirties_fraction(struct task_struct *tsk, | |||
299 | * | 300 | * |
300 | * dirty -= (dirty/8) * p_{t} | 301 | * dirty -= (dirty/8) * p_{t} |
301 | */ | 302 | */ |
302 | static void task_dirty_limit(struct task_struct *tsk, long *pdirty) | 303 | static void task_dirty_limit(struct task_struct *tsk, unsigned long *pdirty) |
303 | { | 304 | { |
304 | long numerator, denominator; | 305 | long numerator, denominator; |
305 | long dirty = *pdirty; | 306 | unsigned long dirty = *pdirty; |
306 | u64 inv = dirty >> 3; | 307 | u64 inv = dirty >> 3; |
307 | 308 | ||
308 | task_dirties_fraction(tsk, &numerator, &denominator); | 309 | task_dirties_fraction(tsk, &numerator, &denominator); |
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 0727896a88ac..a5f3c278c573 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -162,17 +162,25 @@ static unsigned long __meminitdata dma_reserve; | |||
162 | 162 | ||
163 | #if MAX_NUMNODES > 1 | 163 | #if MAX_NUMNODES > 1 |
164 | int nr_node_ids __read_mostly = MAX_NUMNODES; | 164 | int nr_node_ids __read_mostly = MAX_NUMNODES; |
165 | int nr_online_nodes __read_mostly = 1; | ||
165 | EXPORT_SYMBOL(nr_node_ids); | 166 | EXPORT_SYMBOL(nr_node_ids); |
167 | EXPORT_SYMBOL(nr_online_nodes); | ||
166 | #endif | 168 | #endif |
167 | 169 | ||
168 | int page_group_by_mobility_disabled __read_mostly; | 170 | int page_group_by_mobility_disabled __read_mostly; |
169 | 171 | ||
170 | static void set_pageblock_migratetype(struct page *page, int migratetype) | 172 | static void set_pageblock_migratetype(struct page *page, int migratetype) |
171 | { | 173 | { |
174 | |||
175 | if (unlikely(page_group_by_mobility_disabled)) | ||
176 | migratetype = MIGRATE_UNMOVABLE; | ||
177 | |||
172 | set_pageblock_flags_group(page, (unsigned long)migratetype, | 178 | set_pageblock_flags_group(page, (unsigned long)migratetype, |
173 | PB_migrate, PB_migrate_end); | 179 | PB_migrate, PB_migrate_end); |
174 | } | 180 | } |
175 | 181 | ||
182 | bool oom_killer_disabled __read_mostly; | ||
183 | |||
176 | #ifdef CONFIG_DEBUG_VM | 184 | #ifdef CONFIG_DEBUG_VM |
177 | static int page_outside_zone_boundaries(struct zone *zone, struct page *page) | 185 | static int page_outside_zone_boundaries(struct zone *zone, struct page *page) |
178 | { | 186 | { |
@@ -295,23 +303,6 @@ void prep_compound_page(struct page *page, unsigned long order) | |||
295 | } | 303 | } |
296 | } | 304 | } |
297 | 305 | ||
298 | #ifdef CONFIG_HUGETLBFS | ||
299 | void prep_compound_gigantic_page(struct page *page, unsigned long order) | ||
300 | { | ||
301 | int i; | ||
302 | int nr_pages = 1 << order; | ||
303 | struct page *p = page + 1; | ||
304 | |||
305 | set_compound_page_dtor(page, free_compound_page); | ||
306 | set_compound_order(page, order); | ||
307 | __SetPageHead(page); | ||
308 | for (i = 1; i < nr_pages; i++, p = mem_map_next(p, page, i)) { | ||
309 | __SetPageTail(p); | ||
310 | p->first_page = page; | ||
311 | } | ||
312 | } | ||
313 | #endif | ||
314 | |||
315 | static int destroy_compound_page(struct page *page, unsigned long order) | 306 | static int destroy_compound_page(struct page *page, unsigned long order) |
316 | { | 307 | { |
317 | int i; | 308 | int i; |
@@ -418,7 +409,7 @@ static inline int page_is_buddy(struct page *page, struct page *buddy, | |||
418 | return 0; | 409 | return 0; |
419 | 410 | ||
420 | if (PageBuddy(buddy) && page_order(buddy) == order) { | 411 | if (PageBuddy(buddy) && page_order(buddy) == order) { |
421 | BUG_ON(page_count(buddy) != 0); | 412 | VM_BUG_ON(page_count(buddy) != 0); |
422 | return 1; | 413 | return 1; |
423 | } | 414 | } |
424 | return 0; | 415 | return 0; |
@@ -449,22 +440,22 @@ static inline int page_is_buddy(struct page *page, struct page *buddy, | |||
449 | */ | 440 | */ |
450 | 441 | ||
451 | static inline void __free_one_page(struct page *page, | 442 | static inline void __free_one_page(struct page *page, |
452 | struct zone *zone, unsigned int order) | 443 | struct zone *zone, unsigned int order, |
444 | int migratetype) | ||
453 | { | 445 | { |
454 | unsigned long page_idx; | 446 | unsigned long page_idx; |
455 | int order_size = 1 << order; | ||
456 | int migratetype = get_pageblock_migratetype(page); | ||
457 | 447 | ||
458 | if (unlikely(PageCompound(page))) | 448 | if (unlikely(PageCompound(page))) |
459 | if (unlikely(destroy_compound_page(page, order))) | 449 | if (unlikely(destroy_compound_page(page, order))) |
460 | return; | 450 | return; |
461 | 451 | ||
452 | VM_BUG_ON(migratetype == -1); | ||
453 | |||
462 | page_idx = page_to_pfn(page) & ((1 << MAX_ORDER) - 1); | 454 | page_idx = page_to_pfn(page) & ((1 << MAX_ORDER) - 1); |
463 | 455 | ||
464 | VM_BUG_ON(page_idx & (order_size - 1)); | 456 | VM_BUG_ON(page_idx & ((1 << order) - 1)); |
465 | VM_BUG_ON(bad_range(zone, page)); | 457 | VM_BUG_ON(bad_range(zone, page)); |
466 | 458 | ||
467 | __mod_zone_page_state(zone, NR_FREE_PAGES, order_size); | ||
468 | while (order < MAX_ORDER-1) { | 459 | while (order < MAX_ORDER-1) { |
469 | unsigned long combined_idx; | 460 | unsigned long combined_idx; |
470 | struct page *buddy; | 461 | struct page *buddy; |
@@ -488,12 +479,27 @@ static inline void __free_one_page(struct page *page, | |||
488 | zone->free_area[order].nr_free++; | 479 | zone->free_area[order].nr_free++; |
489 | } | 480 | } |
490 | 481 | ||
482 | #ifdef CONFIG_HAVE_MLOCKED_PAGE_BIT | ||
483 | /* | ||
484 | * free_page_mlock() -- clean up attempts to free and mlocked() page. | ||
485 | * Page should not be on lru, so no need to fix that up. | ||
486 | * free_pages_check() will verify... | ||
487 | */ | ||
488 | static inline void free_page_mlock(struct page *page) | ||
489 | { | ||
490 | __ClearPageMlocked(page); | ||
491 | __dec_zone_page_state(page, NR_MLOCK); | ||
492 | __count_vm_event(UNEVICTABLE_MLOCKFREED); | ||
493 | } | ||
494 | #else | ||
495 | static void free_page_mlock(struct page *page) { } | ||
496 | #endif | ||
497 | |||
491 | static inline int free_pages_check(struct page *page) | 498 | static inline int free_pages_check(struct page *page) |
492 | { | 499 | { |
493 | free_page_mlock(page); | ||
494 | if (unlikely(page_mapcount(page) | | 500 | if (unlikely(page_mapcount(page) | |
495 | (page->mapping != NULL) | | 501 | (page->mapping != NULL) | |
496 | (page_count(page) != 0) | | 502 | (atomic_read(&page->_count) != 0) | |
497 | (page->flags & PAGE_FLAGS_CHECK_AT_FREE))) { | 503 | (page->flags & PAGE_FLAGS_CHECK_AT_FREE))) { |
498 | bad_page(page); | 504 | bad_page(page); |
499 | return 1; | 505 | return 1; |
@@ -520,6 +526,8 @@ static void free_pages_bulk(struct zone *zone, int count, | |||
520 | spin_lock(&zone->lock); | 526 | spin_lock(&zone->lock); |
521 | zone_clear_flag(zone, ZONE_ALL_UNRECLAIMABLE); | 527 | zone_clear_flag(zone, ZONE_ALL_UNRECLAIMABLE); |
522 | zone->pages_scanned = 0; | 528 | zone->pages_scanned = 0; |
529 | |||
530 | __mod_zone_page_state(zone, NR_FREE_PAGES, count << order); | ||
523 | while (count--) { | 531 | while (count--) { |
524 | struct page *page; | 532 | struct page *page; |
525 | 533 | ||
@@ -527,17 +535,20 @@ static void free_pages_bulk(struct zone *zone, int count, | |||
527 | page = list_entry(list->prev, struct page, lru); | 535 | page = list_entry(list->prev, struct page, lru); |
528 | /* have to delete it as __free_one_page list manipulates */ | 536 | /* have to delete it as __free_one_page list manipulates */ |
529 | list_del(&page->lru); | 537 | list_del(&page->lru); |
530 | __free_one_page(page, zone, order); | 538 | __free_one_page(page, zone, order, page_private(page)); |
531 | } | 539 | } |
532 | spin_unlock(&zone->lock); | 540 | spin_unlock(&zone->lock); |
533 | } | 541 | } |
534 | 542 | ||
535 | static void free_one_page(struct zone *zone, struct page *page, int order) | 543 | static void free_one_page(struct zone *zone, struct page *page, int order, |
544 | int migratetype) | ||
536 | { | 545 | { |
537 | spin_lock(&zone->lock); | 546 | spin_lock(&zone->lock); |
538 | zone_clear_flag(zone, ZONE_ALL_UNRECLAIMABLE); | 547 | zone_clear_flag(zone, ZONE_ALL_UNRECLAIMABLE); |
539 | zone->pages_scanned = 0; | 548 | zone->pages_scanned = 0; |
540 | __free_one_page(page, zone, order); | 549 | |
550 | __mod_zone_page_state(zone, NR_FREE_PAGES, 1 << order); | ||
551 | __free_one_page(page, zone, order, migratetype); | ||
541 | spin_unlock(&zone->lock); | 552 | spin_unlock(&zone->lock); |
542 | } | 553 | } |
543 | 554 | ||
@@ -546,6 +557,7 @@ static void __free_pages_ok(struct page *page, unsigned int order) | |||
546 | unsigned long flags; | 557 | unsigned long flags; |
547 | int i; | 558 | int i; |
548 | int bad = 0; | 559 | int bad = 0; |
560 | int clearMlocked = PageMlocked(page); | ||
549 | 561 | ||
550 | kmemcheck_free_shadow(page, order); | 562 | kmemcheck_free_shadow(page, order); |
551 | 563 | ||
@@ -563,8 +575,11 @@ static void __free_pages_ok(struct page *page, unsigned int order) | |||
563 | kernel_map_pages(page, 1 << order, 0); | 575 | kernel_map_pages(page, 1 << order, 0); |
564 | 576 | ||
565 | local_irq_save(flags); | 577 | local_irq_save(flags); |
578 | if (unlikely(clearMlocked)) | ||
579 | free_page_mlock(page); | ||
566 | __count_vm_events(PGFREE, 1 << order); | 580 | __count_vm_events(PGFREE, 1 << order); |
567 | free_one_page(page_zone(page), page, order); | 581 | free_one_page(page_zone(page), page, order, |
582 | get_pageblock_migratetype(page)); | ||
568 | local_irq_restore(flags); | 583 | local_irq_restore(flags); |
569 | } | 584 | } |
570 | 585 | ||
@@ -635,7 +650,7 @@ static int prep_new_page(struct page *page, int order, gfp_t gfp_flags) | |||
635 | { | 650 | { |
636 | if (unlikely(page_mapcount(page) | | 651 | if (unlikely(page_mapcount(page) | |
637 | (page->mapping != NULL) | | 652 | (page->mapping != NULL) | |
638 | (page_count(page) != 0) | | 653 | (atomic_read(&page->_count) != 0) | |
639 | (page->flags & PAGE_FLAGS_CHECK_AT_PREP))) { | 654 | (page->flags & PAGE_FLAGS_CHECK_AT_PREP))) { |
640 | bad_page(page); | 655 | bad_page(page); |
641 | return 1; | 656 | return 1; |
@@ -660,7 +675,8 @@ static int prep_new_page(struct page *page, int order, gfp_t gfp_flags) | |||
660 | * Go through the free lists for the given migratetype and remove | 675 | * Go through the free lists for the given migratetype and remove |
661 | * the smallest available page from the freelists | 676 | * the smallest available page from the freelists |
662 | */ | 677 | */ |
663 | static struct page *__rmqueue_smallest(struct zone *zone, unsigned int order, | 678 | static inline |
679 | struct page *__rmqueue_smallest(struct zone *zone, unsigned int order, | ||
664 | int migratetype) | 680 | int migratetype) |
665 | { | 681 | { |
666 | unsigned int current_order; | 682 | unsigned int current_order; |
@@ -678,7 +694,6 @@ static struct page *__rmqueue_smallest(struct zone *zone, unsigned int order, | |||
678 | list_del(&page->lru); | 694 | list_del(&page->lru); |
679 | rmv_page_order(page); | 695 | rmv_page_order(page); |
680 | area->nr_free--; | 696 | area->nr_free--; |
681 | __mod_zone_page_state(zone, NR_FREE_PAGES, - (1UL << order)); | ||
682 | expand(zone, page, order, current_order, area, migratetype); | 697 | expand(zone, page, order, current_order, area, migratetype); |
683 | return page; | 698 | return page; |
684 | } | 699 | } |
@@ -769,8 +784,8 @@ static int move_freepages_block(struct zone *zone, struct page *page, | |||
769 | } | 784 | } |
770 | 785 | ||
771 | /* Remove an element from the buddy allocator from the fallback list */ | 786 | /* Remove an element from the buddy allocator from the fallback list */ |
772 | static struct page *__rmqueue_fallback(struct zone *zone, int order, | 787 | static inline struct page * |
773 | int start_migratetype) | 788 | __rmqueue_fallback(struct zone *zone, int order, int start_migratetype) |
774 | { | 789 | { |
775 | struct free_area * area; | 790 | struct free_area * area; |
776 | int current_order; | 791 | int current_order; |
@@ -818,8 +833,6 @@ static struct page *__rmqueue_fallback(struct zone *zone, int order, | |||
818 | /* Remove the page from the freelists */ | 833 | /* Remove the page from the freelists */ |
819 | list_del(&page->lru); | 834 | list_del(&page->lru); |
820 | rmv_page_order(page); | 835 | rmv_page_order(page); |
821 | __mod_zone_page_state(zone, NR_FREE_PAGES, | ||
822 | -(1UL << order)); | ||
823 | 836 | ||
824 | if (current_order == pageblock_order) | 837 | if (current_order == pageblock_order) |
825 | set_pageblock_migratetype(page, | 838 | set_pageblock_migratetype(page, |
@@ -830,8 +843,7 @@ static struct page *__rmqueue_fallback(struct zone *zone, int order, | |||
830 | } | 843 | } |
831 | } | 844 | } |
832 | 845 | ||
833 | /* Use MIGRATE_RESERVE rather than fail an allocation */ | 846 | return NULL; |
834 | return __rmqueue_smallest(zone, order, MIGRATE_RESERVE); | ||
835 | } | 847 | } |
836 | 848 | ||
837 | /* | 849 | /* |
@@ -843,11 +855,23 @@ static struct page *__rmqueue(struct zone *zone, unsigned int order, | |||
843 | { | 855 | { |
844 | struct page *page; | 856 | struct page *page; |
845 | 857 | ||
858 | retry_reserve: | ||
846 | page = __rmqueue_smallest(zone, order, migratetype); | 859 | page = __rmqueue_smallest(zone, order, migratetype); |
847 | 860 | ||
848 | if (unlikely(!page)) | 861 | if (unlikely(!page) && migratetype != MIGRATE_RESERVE) { |
849 | page = __rmqueue_fallback(zone, order, migratetype); | 862 | page = __rmqueue_fallback(zone, order, migratetype); |
850 | 863 | ||
864 | /* | ||
865 | * Use MIGRATE_RESERVE rather than fail an allocation. goto | ||
866 | * is used because __rmqueue_smallest is an inline function | ||
867 | * and we want just one call site | ||
868 | */ | ||
869 | if (!page) { | ||
870 | migratetype = MIGRATE_RESERVE; | ||
871 | goto retry_reserve; | ||
872 | } | ||
873 | } | ||
874 | |||
851 | return page; | 875 | return page; |
852 | } | 876 | } |
853 | 877 | ||
@@ -881,6 +905,7 @@ static int rmqueue_bulk(struct zone *zone, unsigned int order, | |||
881 | set_page_private(page, migratetype); | 905 | set_page_private(page, migratetype); |
882 | list = &page->lru; | 906 | list = &page->lru; |
883 | } | 907 | } |
908 | __mod_zone_page_state(zone, NR_FREE_PAGES, -(i << order)); | ||
884 | spin_unlock(&zone->lock); | 909 | spin_unlock(&zone->lock); |
885 | return i; | 910 | return i; |
886 | } | 911 | } |
@@ -996,6 +1021,7 @@ static void free_hot_cold_page(struct page *page, int cold) | |||
996 | struct zone *zone = page_zone(page); | 1021 | struct zone *zone = page_zone(page); |
997 | struct per_cpu_pages *pcp; | 1022 | struct per_cpu_pages *pcp; |
998 | unsigned long flags; | 1023 | unsigned long flags; |
1024 | int clearMlocked = PageMlocked(page); | ||
999 | 1025 | ||
1000 | kmemcheck_free_shadow(page, 0); | 1026 | kmemcheck_free_shadow(page, 0); |
1001 | 1027 | ||
@@ -1012,13 +1038,16 @@ static void free_hot_cold_page(struct page *page, int cold) | |||
1012 | kernel_map_pages(page, 1, 0); | 1038 | kernel_map_pages(page, 1, 0); |
1013 | 1039 | ||
1014 | pcp = &zone_pcp(zone, get_cpu())->pcp; | 1040 | pcp = &zone_pcp(zone, get_cpu())->pcp; |
1041 | set_page_private(page, get_pageblock_migratetype(page)); | ||
1015 | local_irq_save(flags); | 1042 | local_irq_save(flags); |
1043 | if (unlikely(clearMlocked)) | ||
1044 | free_page_mlock(page); | ||
1016 | __count_vm_event(PGFREE); | 1045 | __count_vm_event(PGFREE); |
1046 | |||
1017 | if (cold) | 1047 | if (cold) |
1018 | list_add_tail(&page->lru, &pcp->list); | 1048 | list_add_tail(&page->lru, &pcp->list); |
1019 | else | 1049 | else |
1020 | list_add(&page->lru, &pcp->list); | 1050 | list_add(&page->lru, &pcp->list); |
1021 | set_page_private(page, get_pageblock_migratetype(page)); | ||
1022 | pcp->count++; | 1051 | pcp->count++; |
1023 | if (pcp->count >= pcp->high) { | 1052 | if (pcp->count >= pcp->high) { |
1024 | free_pages_bulk(zone, pcp->batch, &pcp->list, 0); | 1053 | free_pages_bulk(zone, pcp->batch, &pcp->list, 0); |
@@ -1071,14 +1100,15 @@ void split_page(struct page *page, unsigned int order) | |||
1071 | * we cheat by calling it from here, in the order > 0 path. Saves a branch | 1100 | * we cheat by calling it from here, in the order > 0 path. Saves a branch |
1072 | * or two. | 1101 | * or two. |
1073 | */ | 1102 | */ |
1074 | static struct page *buffered_rmqueue(struct zone *preferred_zone, | 1103 | static inline |
1075 | struct zone *zone, int order, gfp_t gfp_flags) | 1104 | struct page *buffered_rmqueue(struct zone *preferred_zone, |
1105 | struct zone *zone, int order, gfp_t gfp_flags, | ||
1106 | int migratetype) | ||
1076 | { | 1107 | { |
1077 | unsigned long flags; | 1108 | unsigned long flags; |
1078 | struct page *page; | 1109 | struct page *page; |
1079 | int cold = !!(gfp_flags & __GFP_COLD); | 1110 | int cold = !!(gfp_flags & __GFP_COLD); |
1080 | int cpu; | 1111 | int cpu; |
1081 | int migratetype = allocflags_to_migratetype(gfp_flags); | ||
1082 | 1112 | ||
1083 | again: | 1113 | again: |
1084 | cpu = get_cpu(); | 1114 | cpu = get_cpu(); |
@@ -1115,8 +1145,22 @@ again: | |||
1115 | list_del(&page->lru); | 1145 | list_del(&page->lru); |
1116 | pcp->count--; | 1146 | pcp->count--; |
1117 | } else { | 1147 | } else { |
1148 | if (unlikely(gfp_flags & __GFP_NOFAIL)) { | ||
1149 | /* | ||
1150 | * __GFP_NOFAIL is not to be used in new code. | ||
1151 | * | ||
1152 | * All __GFP_NOFAIL callers should be fixed so that they | ||
1153 | * properly detect and handle allocation failures. | ||
1154 | * | ||
1155 | * We most definitely don't want callers attempting to | ||
1156 | * allocate greater than single-page units with | ||
1157 | * __GFP_NOFAIL. | ||
1158 | */ | ||
1159 | WARN_ON_ONCE(order > 0); | ||
1160 | } | ||
1118 | spin_lock_irqsave(&zone->lock, flags); | 1161 | spin_lock_irqsave(&zone->lock, flags); |
1119 | page = __rmqueue(zone, order, migratetype); | 1162 | page = __rmqueue(zone, order, migratetype); |
1163 | __mod_zone_page_state(zone, NR_FREE_PAGES, -(1 << order)); | ||
1120 | spin_unlock(&zone->lock); | 1164 | spin_unlock(&zone->lock); |
1121 | if (!page) | 1165 | if (!page) |
1122 | goto failed; | 1166 | goto failed; |
@@ -1138,10 +1182,15 @@ failed: | |||
1138 | return NULL; | 1182 | return NULL; |
1139 | } | 1183 | } |
1140 | 1184 | ||
1141 | #define ALLOC_NO_WATERMARKS 0x01 /* don't check watermarks at all */ | 1185 | /* The ALLOC_WMARK bits are used as an index to zone->watermark */ |
1142 | #define ALLOC_WMARK_MIN 0x02 /* use pages_min watermark */ | 1186 | #define ALLOC_WMARK_MIN WMARK_MIN |
1143 | #define ALLOC_WMARK_LOW 0x04 /* use pages_low watermark */ | 1187 | #define ALLOC_WMARK_LOW WMARK_LOW |
1144 | #define ALLOC_WMARK_HIGH 0x08 /* use pages_high watermark */ | 1188 | #define ALLOC_WMARK_HIGH WMARK_HIGH |
1189 | #define ALLOC_NO_WATERMARKS 0x04 /* don't check watermarks at all */ | ||
1190 | |||
1191 | /* Mask to get the watermark bits */ | ||
1192 | #define ALLOC_WMARK_MASK (ALLOC_NO_WATERMARKS-1) | ||
1193 | |||
1145 | #define ALLOC_HARDER 0x10 /* try to alloc harder */ | 1194 | #define ALLOC_HARDER 0x10 /* try to alloc harder */ |
1146 | #define ALLOC_HIGH 0x20 /* __GFP_HIGH set */ | 1195 | #define ALLOC_HIGH 0x20 /* __GFP_HIGH set */ |
1147 | #define ALLOC_CPUSET 0x40 /* check for correct cpuset */ | 1196 | #define ALLOC_CPUSET 0x40 /* check for correct cpuset */ |
@@ -1399,23 +1448,18 @@ static void zlc_mark_zone_full(struct zonelist *zonelist, struct zoneref *z) | |||
1399 | */ | 1448 | */ |
1400 | static struct page * | 1449 | static struct page * |
1401 | get_page_from_freelist(gfp_t gfp_mask, nodemask_t *nodemask, unsigned int order, | 1450 | get_page_from_freelist(gfp_t gfp_mask, nodemask_t *nodemask, unsigned int order, |
1402 | struct zonelist *zonelist, int high_zoneidx, int alloc_flags) | 1451 | struct zonelist *zonelist, int high_zoneidx, int alloc_flags, |
1452 | struct zone *preferred_zone, int migratetype) | ||
1403 | { | 1453 | { |
1404 | struct zoneref *z; | 1454 | struct zoneref *z; |
1405 | struct page *page = NULL; | 1455 | struct page *page = NULL; |
1406 | int classzone_idx; | 1456 | int classzone_idx; |
1407 | struct zone *zone, *preferred_zone; | 1457 | struct zone *zone; |
1408 | nodemask_t *allowednodes = NULL;/* zonelist_cache approximation */ | 1458 | nodemask_t *allowednodes = NULL;/* zonelist_cache approximation */ |
1409 | int zlc_active = 0; /* set if using zonelist_cache */ | 1459 | int zlc_active = 0; /* set if using zonelist_cache */ |
1410 | int did_zlc_setup = 0; /* just call zlc_setup() one time */ | 1460 | int did_zlc_setup = 0; /* just call zlc_setup() one time */ |
1411 | 1461 | ||
1412 | (void)first_zones_zonelist(zonelist, high_zoneidx, nodemask, | ||
1413 | &preferred_zone); | ||
1414 | if (!preferred_zone) | ||
1415 | return NULL; | ||
1416 | |||
1417 | classzone_idx = zone_idx(preferred_zone); | 1462 | classzone_idx = zone_idx(preferred_zone); |
1418 | |||
1419 | zonelist_scan: | 1463 | zonelist_scan: |
1420 | /* | 1464 | /* |
1421 | * Scan zonelist, looking for a zone with enough free. | 1465 | * Scan zonelist, looking for a zone with enough free. |
@@ -1430,31 +1474,49 @@ zonelist_scan: | |||
1430 | !cpuset_zone_allowed_softwall(zone, gfp_mask)) | 1474 | !cpuset_zone_allowed_softwall(zone, gfp_mask)) |
1431 | goto try_next_zone; | 1475 | goto try_next_zone; |
1432 | 1476 | ||
1477 | BUILD_BUG_ON(ALLOC_NO_WATERMARKS < NR_WMARK); | ||
1433 | if (!(alloc_flags & ALLOC_NO_WATERMARKS)) { | 1478 | if (!(alloc_flags & ALLOC_NO_WATERMARKS)) { |
1434 | unsigned long mark; | 1479 | unsigned long mark; |
1435 | if (alloc_flags & ALLOC_WMARK_MIN) | 1480 | int ret; |
1436 | mark = zone->pages_min; | 1481 | |
1437 | else if (alloc_flags & ALLOC_WMARK_LOW) | 1482 | mark = zone->watermark[alloc_flags & ALLOC_WMARK_MASK]; |
1438 | mark = zone->pages_low; | 1483 | if (zone_watermark_ok(zone, order, mark, |
1439 | else | 1484 | classzone_idx, alloc_flags)) |
1440 | mark = zone->pages_high; | 1485 | goto try_this_zone; |
1441 | if (!zone_watermark_ok(zone, order, mark, | 1486 | |
1442 | classzone_idx, alloc_flags)) { | 1487 | if (zone_reclaim_mode == 0) |
1443 | if (!zone_reclaim_mode || | 1488 | goto this_zone_full; |
1444 | !zone_reclaim(zone, gfp_mask, order)) | 1489 | |
1490 | ret = zone_reclaim(zone, gfp_mask, order); | ||
1491 | switch (ret) { | ||
1492 | case ZONE_RECLAIM_NOSCAN: | ||
1493 | /* did not scan */ | ||
1494 | goto try_next_zone; | ||
1495 | case ZONE_RECLAIM_FULL: | ||
1496 | /* scanned but unreclaimable */ | ||
1497 | goto this_zone_full; | ||
1498 | default: | ||
1499 | /* did we reclaim enough */ | ||
1500 | if (!zone_watermark_ok(zone, order, mark, | ||
1501 | classzone_idx, alloc_flags)) | ||
1445 | goto this_zone_full; | 1502 | goto this_zone_full; |
1446 | } | 1503 | } |
1447 | } | 1504 | } |
1448 | 1505 | ||
1449 | page = buffered_rmqueue(preferred_zone, zone, order, gfp_mask); | 1506 | try_this_zone: |
1507 | page = buffered_rmqueue(preferred_zone, zone, order, | ||
1508 | gfp_mask, migratetype); | ||
1450 | if (page) | 1509 | if (page) |
1451 | break; | 1510 | break; |
1452 | this_zone_full: | 1511 | this_zone_full: |
1453 | if (NUMA_BUILD) | 1512 | if (NUMA_BUILD) |
1454 | zlc_mark_zone_full(zonelist, z); | 1513 | zlc_mark_zone_full(zonelist, z); |
1455 | try_next_zone: | 1514 | try_next_zone: |
1456 | if (NUMA_BUILD && !did_zlc_setup) { | 1515 | if (NUMA_BUILD && !did_zlc_setup && nr_online_nodes > 1) { |
1457 | /* we do zlc_setup after the first zone is tried */ | 1516 | /* |
1517 | * we do zlc_setup after the first zone is tried but only | ||
1518 | * if there are multiple nodes make it worthwhile | ||
1519 | */ | ||
1458 | allowednodes = zlc_setup(zonelist, alloc_flags); | 1520 | allowednodes = zlc_setup(zonelist, alloc_flags); |
1459 | zlc_active = 1; | 1521 | zlc_active = 1; |
1460 | did_zlc_setup = 1; | 1522 | did_zlc_setup = 1; |
@@ -1469,47 +1531,217 @@ try_next_zone: | |||
1469 | return page; | 1531 | return page; |
1470 | } | 1532 | } |
1471 | 1533 | ||
1534 | static inline int | ||
1535 | should_alloc_retry(gfp_t gfp_mask, unsigned int order, | ||
1536 | unsigned long pages_reclaimed) | ||
1537 | { | ||
1538 | /* Do not loop if specifically requested */ | ||
1539 | if (gfp_mask & __GFP_NORETRY) | ||
1540 | return 0; | ||
1541 | |||
1542 | /* | ||
1543 | * In this implementation, order <= PAGE_ALLOC_COSTLY_ORDER | ||
1544 | * means __GFP_NOFAIL, but that may not be true in other | ||
1545 | * implementations. | ||
1546 | */ | ||
1547 | if (order <= PAGE_ALLOC_COSTLY_ORDER) | ||
1548 | return 1; | ||
1549 | |||
1550 | /* | ||
1551 | * For order > PAGE_ALLOC_COSTLY_ORDER, if __GFP_REPEAT is | ||
1552 | * specified, then we retry until we no longer reclaim any pages | ||
1553 | * (above), or we've reclaimed an order of pages at least as | ||
1554 | * large as the allocation's order. In both cases, if the | ||
1555 | * allocation still fails, we stop retrying. | ||
1556 | */ | ||
1557 | if (gfp_mask & __GFP_REPEAT && pages_reclaimed < (1 << order)) | ||
1558 | return 1; | ||
1559 | |||
1560 | /* | ||
1561 | * Don't let big-order allocations loop unless the caller | ||
1562 | * explicitly requests that. | ||
1563 | */ | ||
1564 | if (gfp_mask & __GFP_NOFAIL) | ||
1565 | return 1; | ||
1566 | |||
1567 | return 0; | ||
1568 | } | ||
1569 | |||
1570 | static inline struct page * | ||
1571 | __alloc_pages_may_oom(gfp_t gfp_mask, unsigned int order, | ||
1572 | struct zonelist *zonelist, enum zone_type high_zoneidx, | ||
1573 | nodemask_t *nodemask, struct zone *preferred_zone, | ||
1574 | int migratetype) | ||
1575 | { | ||
1576 | struct page *page; | ||
1577 | |||
1578 | /* Acquire the OOM killer lock for the zones in zonelist */ | ||
1579 | if (!try_set_zone_oom(zonelist, gfp_mask)) { | ||
1580 | schedule_timeout_uninterruptible(1); | ||
1581 | return NULL; | ||
1582 | } | ||
1583 | |||
1584 | /* | ||
1585 | * Go through the zonelist yet one more time, keep very high watermark | ||
1586 | * here, this is only to catch a parallel oom killing, we must fail if | ||
1587 | * we're still under heavy pressure. | ||
1588 | */ | ||
1589 | page = get_page_from_freelist(gfp_mask|__GFP_HARDWALL, nodemask, | ||
1590 | order, zonelist, high_zoneidx, | ||
1591 | ALLOC_WMARK_HIGH|ALLOC_CPUSET, | ||
1592 | preferred_zone, migratetype); | ||
1593 | if (page) | ||
1594 | goto out; | ||
1595 | |||
1596 | /* The OOM killer will not help higher order allocs */ | ||
1597 | if (order > PAGE_ALLOC_COSTLY_ORDER && !(gfp_mask & __GFP_NOFAIL)) | ||
1598 | goto out; | ||
1599 | |||
1600 | /* Exhausted what can be done so it's blamo time */ | ||
1601 | out_of_memory(zonelist, gfp_mask, order); | ||
1602 | |||
1603 | out: | ||
1604 | clear_zonelist_oom(zonelist, gfp_mask); | ||
1605 | return page; | ||
1606 | } | ||
1607 | |||
1608 | /* The really slow allocator path where we enter direct reclaim */ | ||
1609 | static inline struct page * | ||
1610 | __alloc_pages_direct_reclaim(gfp_t gfp_mask, unsigned int order, | ||
1611 | struct zonelist *zonelist, enum zone_type high_zoneidx, | ||
1612 | nodemask_t *nodemask, int alloc_flags, struct zone *preferred_zone, | ||
1613 | int migratetype, unsigned long *did_some_progress) | ||
1614 | { | ||
1615 | struct page *page = NULL; | ||
1616 | struct reclaim_state reclaim_state; | ||
1617 | struct task_struct *p = current; | ||
1618 | |||
1619 | cond_resched(); | ||
1620 | |||
1621 | /* We now go into synchronous reclaim */ | ||
1622 | cpuset_memory_pressure_bump(); | ||
1623 | |||
1624 | /* | ||
1625 | * The task's cpuset might have expanded its set of allowable nodes | ||
1626 | */ | ||
1627 | p->flags |= PF_MEMALLOC; | ||
1628 | lockdep_set_current_reclaim_state(gfp_mask); | ||
1629 | reclaim_state.reclaimed_slab = 0; | ||
1630 | p->reclaim_state = &reclaim_state; | ||
1631 | |||
1632 | *did_some_progress = try_to_free_pages(zonelist, order, gfp_mask, nodemask); | ||
1633 | |||
1634 | p->reclaim_state = NULL; | ||
1635 | lockdep_clear_current_reclaim_state(); | ||
1636 | p->flags &= ~PF_MEMALLOC; | ||
1637 | |||
1638 | cond_resched(); | ||
1639 | |||
1640 | if (order != 0) | ||
1641 | drain_all_pages(); | ||
1642 | |||
1643 | if (likely(*did_some_progress)) | ||
1644 | page = get_page_from_freelist(gfp_mask, nodemask, order, | ||
1645 | zonelist, high_zoneidx, | ||
1646 | alloc_flags, preferred_zone, | ||
1647 | migratetype); | ||
1648 | return page; | ||
1649 | } | ||
1650 | |||
1472 | /* | 1651 | /* |
1473 | * This is the 'heart' of the zoned buddy allocator. | 1652 | * This is called in the allocator slow-path if the allocation request is of |
1653 | * sufficient urgency to ignore watermarks and take other desperate measures | ||
1474 | */ | 1654 | */ |
1475 | struct page * | 1655 | static inline struct page * |
1476 | __alloc_pages_internal(gfp_t gfp_mask, unsigned int order, | 1656 | __alloc_pages_high_priority(gfp_t gfp_mask, unsigned int order, |
1477 | struct zonelist *zonelist, nodemask_t *nodemask) | 1657 | struct zonelist *zonelist, enum zone_type high_zoneidx, |
1658 | nodemask_t *nodemask, struct zone *preferred_zone, | ||
1659 | int migratetype) | ||
1660 | { | ||
1661 | struct page *page; | ||
1662 | |||
1663 | do { | ||
1664 | page = get_page_from_freelist(gfp_mask, nodemask, order, | ||
1665 | zonelist, high_zoneidx, ALLOC_NO_WATERMARKS, | ||
1666 | preferred_zone, migratetype); | ||
1667 | |||
1668 | if (!page && gfp_mask & __GFP_NOFAIL) | ||
1669 | congestion_wait(WRITE, HZ/50); | ||
1670 | } while (!page && (gfp_mask & __GFP_NOFAIL)); | ||
1671 | |||
1672 | return page; | ||
1673 | } | ||
1674 | |||
1675 | static inline | ||
1676 | void wake_all_kswapd(unsigned int order, struct zonelist *zonelist, | ||
1677 | enum zone_type high_zoneidx) | ||
1478 | { | 1678 | { |
1479 | const gfp_t wait = gfp_mask & __GFP_WAIT; | ||
1480 | enum zone_type high_zoneidx = gfp_zone(gfp_mask); | ||
1481 | struct zoneref *z; | 1679 | struct zoneref *z; |
1482 | struct zone *zone; | 1680 | struct zone *zone; |
1483 | struct page *page; | ||
1484 | struct reclaim_state reclaim_state; | ||
1485 | struct task_struct *p = current; | ||
1486 | int do_retry; | ||
1487 | int alloc_flags; | ||
1488 | unsigned long did_some_progress; | ||
1489 | unsigned long pages_reclaimed = 0; | ||
1490 | 1681 | ||
1491 | lockdep_trace_alloc(gfp_mask); | 1682 | for_each_zone_zonelist(zone, z, zonelist, high_zoneidx) |
1683 | wakeup_kswapd(zone, order); | ||
1684 | } | ||
1492 | 1685 | ||
1493 | might_sleep_if(wait); | 1686 | static inline int |
1687 | gfp_to_alloc_flags(gfp_t gfp_mask) | ||
1688 | { | ||
1689 | struct task_struct *p = current; | ||
1690 | int alloc_flags = ALLOC_WMARK_MIN | ALLOC_CPUSET; | ||
1691 | const gfp_t wait = gfp_mask & __GFP_WAIT; | ||
1494 | 1692 | ||
1495 | if (should_fail_alloc_page(gfp_mask, order)) | 1693 | /* __GFP_HIGH is assumed to be the same as ALLOC_HIGH to save a branch. */ |
1496 | return NULL; | 1694 | BUILD_BUG_ON(__GFP_HIGH != ALLOC_HIGH); |
1497 | 1695 | ||
1498 | restart: | 1696 | /* |
1499 | z = zonelist->_zonerefs; /* the list of zones suitable for gfp_mask */ | 1697 | * The caller may dip into page reserves a bit more if the caller |
1698 | * cannot run direct reclaim, or if the caller has realtime scheduling | ||
1699 | * policy or is asking for __GFP_HIGH memory. GFP_ATOMIC requests will | ||
1700 | * set both ALLOC_HARDER (!wait) and ALLOC_HIGH (__GFP_HIGH). | ||
1701 | */ | ||
1702 | alloc_flags |= (gfp_mask & __GFP_HIGH); | ||
1500 | 1703 | ||
1501 | if (unlikely(!z->zone)) { | 1704 | if (!wait) { |
1705 | alloc_flags |= ALLOC_HARDER; | ||
1502 | /* | 1706 | /* |
1503 | * Happens if we have an empty zonelist as a result of | 1707 | * Ignore cpuset if GFP_ATOMIC (!wait) rather than fail alloc. |
1504 | * GFP_THISNODE being used on a memoryless node | 1708 | * See also cpuset_zone_allowed() comment in kernel/cpuset.c. |
1505 | */ | 1709 | */ |
1506 | return NULL; | 1710 | alloc_flags &= ~ALLOC_CPUSET; |
1711 | } else if (unlikely(rt_task(p))) | ||
1712 | alloc_flags |= ALLOC_HARDER; | ||
1713 | |||
1714 | if (likely(!(gfp_mask & __GFP_NOMEMALLOC))) { | ||
1715 | if (!in_interrupt() && | ||
1716 | ((p->flags & PF_MEMALLOC) || | ||
1717 | unlikely(test_thread_flag(TIF_MEMDIE)))) | ||
1718 | alloc_flags |= ALLOC_NO_WATERMARKS; | ||
1507 | } | 1719 | } |
1508 | 1720 | ||
1509 | page = get_page_from_freelist(gfp_mask|__GFP_HARDWALL, nodemask, order, | 1721 | return alloc_flags; |
1510 | zonelist, high_zoneidx, ALLOC_WMARK_LOW|ALLOC_CPUSET); | 1722 | } |
1511 | if (page) | 1723 | |
1512 | goto got_pg; | 1724 | static inline struct page * |
1725 | __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order, | ||
1726 | struct zonelist *zonelist, enum zone_type high_zoneidx, | ||
1727 | nodemask_t *nodemask, struct zone *preferred_zone, | ||
1728 | int migratetype) | ||
1729 | { | ||
1730 | const gfp_t wait = gfp_mask & __GFP_WAIT; | ||
1731 | struct page *page = NULL; | ||
1732 | int alloc_flags; | ||
1733 | unsigned long pages_reclaimed = 0; | ||
1734 | unsigned long did_some_progress; | ||
1735 | struct task_struct *p = current; | ||
1736 | |||
1737 | /* | ||
1738 | * In the slowpath, we sanity check order to avoid ever trying to | ||
1739 | * reclaim >= MAX_ORDER areas which will never succeed. Callers may | ||
1740 | * be using allocators in order of preference for an area that is | ||
1741 | * too large. | ||
1742 | */ | ||
1743 | if (WARN_ON_ONCE(order >= MAX_ORDER)) | ||
1744 | return NULL; | ||
1513 | 1745 | ||
1514 | /* | 1746 | /* |
1515 | * GFP_THISNODE (meaning __GFP_THISNODE, __GFP_NORETRY and | 1747 | * GFP_THISNODE (meaning __GFP_THISNODE, __GFP_NORETRY and |
@@ -1522,154 +1754,83 @@ restart: | |||
1522 | if (NUMA_BUILD && (gfp_mask & GFP_THISNODE) == GFP_THISNODE) | 1754 | if (NUMA_BUILD && (gfp_mask & GFP_THISNODE) == GFP_THISNODE) |
1523 | goto nopage; | 1755 | goto nopage; |
1524 | 1756 | ||
1525 | for_each_zone_zonelist(zone, z, zonelist, high_zoneidx) | 1757 | wake_all_kswapd(order, zonelist, high_zoneidx); |
1526 | wakeup_kswapd(zone, order); | ||
1527 | 1758 | ||
1528 | /* | 1759 | /* |
1529 | * OK, we're below the kswapd watermark and have kicked background | 1760 | * OK, we're below the kswapd watermark and have kicked background |
1530 | * reclaim. Now things get more complex, so set up alloc_flags according | 1761 | * reclaim. Now things get more complex, so set up alloc_flags according |
1531 | * to how we want to proceed. | 1762 | * to how we want to proceed. |
1532 | * | ||
1533 | * The caller may dip into page reserves a bit more if the caller | ||
1534 | * cannot run direct reclaim, or if the caller has realtime scheduling | ||
1535 | * policy or is asking for __GFP_HIGH memory. GFP_ATOMIC requests will | ||
1536 | * set both ALLOC_HARDER (!wait) and ALLOC_HIGH (__GFP_HIGH). | ||
1537 | */ | 1763 | */ |
1538 | alloc_flags = ALLOC_WMARK_MIN; | 1764 | alloc_flags = gfp_to_alloc_flags(gfp_mask); |
1539 | if ((unlikely(rt_task(p)) && !in_interrupt()) || !wait) | ||
1540 | alloc_flags |= ALLOC_HARDER; | ||
1541 | if (gfp_mask & __GFP_HIGH) | ||
1542 | alloc_flags |= ALLOC_HIGH; | ||
1543 | if (wait) | ||
1544 | alloc_flags |= ALLOC_CPUSET; | ||
1545 | 1765 | ||
1546 | /* | 1766 | restart: |
1547 | * Go through the zonelist again. Let __GFP_HIGH and allocations | 1767 | /* This is the last chance, in general, before the goto nopage. */ |
1548 | * coming from realtime tasks go deeper into reserves. | ||
1549 | * | ||
1550 | * This is the last chance, in general, before the goto nopage. | ||
1551 | * Ignore cpuset if GFP_ATOMIC (!wait) rather than fail alloc. | ||
1552 | * See also cpuset_zone_allowed() comment in kernel/cpuset.c. | ||
1553 | */ | ||
1554 | page = get_page_from_freelist(gfp_mask, nodemask, order, zonelist, | 1768 | page = get_page_from_freelist(gfp_mask, nodemask, order, zonelist, |
1555 | high_zoneidx, alloc_flags); | 1769 | high_zoneidx, alloc_flags & ~ALLOC_NO_WATERMARKS, |
1770 | preferred_zone, migratetype); | ||
1556 | if (page) | 1771 | if (page) |
1557 | goto got_pg; | 1772 | goto got_pg; |
1558 | 1773 | ||
1559 | /* This allocation should allow future memory freeing. */ | ||
1560 | |||
1561 | rebalance: | 1774 | rebalance: |
1562 | if (((p->flags & PF_MEMALLOC) || unlikely(test_thread_flag(TIF_MEMDIE))) | 1775 | /* Allocate without watermarks if the context allows */ |
1563 | && !in_interrupt()) { | 1776 | if (alloc_flags & ALLOC_NO_WATERMARKS) { |
1564 | if (!(gfp_mask & __GFP_NOMEMALLOC)) { | 1777 | page = __alloc_pages_high_priority(gfp_mask, order, |
1565 | nofail_alloc: | 1778 | zonelist, high_zoneidx, nodemask, |
1566 | /* go through the zonelist yet again, ignoring mins */ | 1779 | preferred_zone, migratetype); |
1567 | page = get_page_from_freelist(gfp_mask, nodemask, order, | 1780 | if (page) |
1568 | zonelist, high_zoneidx, ALLOC_NO_WATERMARKS); | 1781 | goto got_pg; |
1569 | if (page) | ||
1570 | goto got_pg; | ||
1571 | if (gfp_mask & __GFP_NOFAIL) { | ||
1572 | congestion_wait(WRITE, HZ/50); | ||
1573 | goto nofail_alloc; | ||
1574 | } | ||
1575 | } | ||
1576 | goto nopage; | ||
1577 | } | 1782 | } |
1578 | 1783 | ||
1579 | /* Atomic allocations - we can't balance anything */ | 1784 | /* Atomic allocations - we can't balance anything */ |
1580 | if (!wait) | 1785 | if (!wait) |
1581 | goto nopage; | 1786 | goto nopage; |
1582 | 1787 | ||
1583 | cond_resched(); | 1788 | /* Avoid recursion of direct reclaim */ |
1789 | if (p->flags & PF_MEMALLOC) | ||
1790 | goto nopage; | ||
1791 | |||
1792 | /* Try direct reclaim and then allocating */ | ||
1793 | page = __alloc_pages_direct_reclaim(gfp_mask, order, | ||
1794 | zonelist, high_zoneidx, | ||
1795 | nodemask, | ||
1796 | alloc_flags, preferred_zone, | ||
1797 | migratetype, &did_some_progress); | ||
1798 | if (page) | ||
1799 | goto got_pg; | ||
1584 | 1800 | ||
1585 | /* We now go into synchronous reclaim */ | ||
1586 | cpuset_memory_pressure_bump(); | ||
1587 | /* | 1801 | /* |
1588 | * The task's cpuset might have expanded its set of allowable nodes | 1802 | * If we failed to make any progress reclaiming, then we are |
1803 | * running out of options and have to consider going OOM | ||
1589 | */ | 1804 | */ |
1590 | cpuset_update_task_memory_state(); | 1805 | if (!did_some_progress) { |
1591 | p->flags |= PF_MEMALLOC; | 1806 | if ((gfp_mask & __GFP_FS) && !(gfp_mask & __GFP_NORETRY)) { |
1592 | 1807 | if (oom_killer_disabled) | |
1593 | lockdep_set_current_reclaim_state(gfp_mask); | 1808 | goto nopage; |
1594 | reclaim_state.reclaimed_slab = 0; | 1809 | page = __alloc_pages_may_oom(gfp_mask, order, |
1595 | p->reclaim_state = &reclaim_state; | 1810 | zonelist, high_zoneidx, |
1596 | 1811 | nodemask, preferred_zone, | |
1597 | did_some_progress = try_to_free_pages(zonelist, order, | 1812 | migratetype); |
1598 | gfp_mask, nodemask); | 1813 | if (page) |
1599 | 1814 | goto got_pg; | |
1600 | p->reclaim_state = NULL; | ||
1601 | lockdep_clear_current_reclaim_state(); | ||
1602 | p->flags &= ~PF_MEMALLOC; | ||
1603 | |||
1604 | cond_resched(); | ||
1605 | 1815 | ||
1606 | if (order != 0) | 1816 | /* |
1607 | drain_all_pages(); | 1817 | * The OOM killer does not trigger for high-order |
1818 | * ~__GFP_NOFAIL allocations so if no progress is being | ||
1819 | * made, there are no other options and retrying is | ||
1820 | * unlikely to help. | ||
1821 | */ | ||
1822 | if (order > PAGE_ALLOC_COSTLY_ORDER && | ||
1823 | !(gfp_mask & __GFP_NOFAIL)) | ||
1824 | goto nopage; | ||
1608 | 1825 | ||
1609 | if (likely(did_some_progress)) { | ||
1610 | page = get_page_from_freelist(gfp_mask, nodemask, order, | ||
1611 | zonelist, high_zoneidx, alloc_flags); | ||
1612 | if (page) | ||
1613 | goto got_pg; | ||
1614 | } else if ((gfp_mask & __GFP_FS) && !(gfp_mask & __GFP_NORETRY)) { | ||
1615 | if (!try_set_zone_oom(zonelist, gfp_mask)) { | ||
1616 | schedule_timeout_uninterruptible(1); | ||
1617 | goto restart; | 1826 | goto restart; |
1618 | } | 1827 | } |
1619 | |||
1620 | /* | ||
1621 | * Go through the zonelist yet one more time, keep | ||
1622 | * very high watermark here, this is only to catch | ||
1623 | * a parallel oom killing, we must fail if we're still | ||
1624 | * under heavy pressure. | ||
1625 | */ | ||
1626 | page = get_page_from_freelist(gfp_mask|__GFP_HARDWALL, nodemask, | ||
1627 | order, zonelist, high_zoneidx, | ||
1628 | ALLOC_WMARK_HIGH|ALLOC_CPUSET); | ||
1629 | if (page) { | ||
1630 | clear_zonelist_oom(zonelist, gfp_mask); | ||
1631 | goto got_pg; | ||
1632 | } | ||
1633 | |||
1634 | /* The OOM killer will not help higher order allocs so fail */ | ||
1635 | if (order > PAGE_ALLOC_COSTLY_ORDER) { | ||
1636 | clear_zonelist_oom(zonelist, gfp_mask); | ||
1637 | goto nopage; | ||
1638 | } | ||
1639 | |||
1640 | out_of_memory(zonelist, gfp_mask, order); | ||
1641 | clear_zonelist_oom(zonelist, gfp_mask); | ||
1642 | goto restart; | ||
1643 | } | 1828 | } |
1644 | 1829 | ||
1645 | /* | 1830 | /* Check if we should retry the allocation */ |
1646 | * Don't let big-order allocations loop unless the caller explicitly | ||
1647 | * requests that. Wait for some write requests to complete then retry. | ||
1648 | * | ||
1649 | * In this implementation, order <= PAGE_ALLOC_COSTLY_ORDER | ||
1650 | * means __GFP_NOFAIL, but that may not be true in other | ||
1651 | * implementations. | ||
1652 | * | ||
1653 | * For order > PAGE_ALLOC_COSTLY_ORDER, if __GFP_REPEAT is | ||
1654 | * specified, then we retry until we no longer reclaim any pages | ||
1655 | * (above), or we've reclaimed an order of pages at least as | ||
1656 | * large as the allocation's order. In both cases, if the | ||
1657 | * allocation still fails, we stop retrying. | ||
1658 | */ | ||
1659 | pages_reclaimed += did_some_progress; | 1831 | pages_reclaimed += did_some_progress; |
1660 | do_retry = 0; | 1832 | if (should_alloc_retry(gfp_mask, order, pages_reclaimed)) { |
1661 | if (!(gfp_mask & __GFP_NORETRY)) { | 1833 | /* Wait for some write requests to complete then retry */ |
1662 | if (order <= PAGE_ALLOC_COSTLY_ORDER) { | ||
1663 | do_retry = 1; | ||
1664 | } else { | ||
1665 | if (gfp_mask & __GFP_REPEAT && | ||
1666 | pages_reclaimed < (1 << order)) | ||
1667 | do_retry = 1; | ||
1668 | } | ||
1669 | if (gfp_mask & __GFP_NOFAIL) | ||
1670 | do_retry = 1; | ||
1671 | } | ||
1672 | if (do_retry) { | ||
1673 | congestion_wait(WRITE, HZ/50); | 1834 | congestion_wait(WRITE, HZ/50); |
1674 | goto rebalance; | 1835 | goto rebalance; |
1675 | } | 1836 | } |
@@ -1687,8 +1848,53 @@ got_pg: | |||
1687 | if (kmemcheck_enabled) | 1848 | if (kmemcheck_enabled) |
1688 | kmemcheck_pagealloc_alloc(page, order, gfp_mask); | 1849 | kmemcheck_pagealloc_alloc(page, order, gfp_mask); |
1689 | return page; | 1850 | return page; |
1851 | |||
1852 | } | ||
1853 | |||
1854 | /* | ||
1855 | * This is the 'heart' of the zoned buddy allocator. | ||
1856 | */ | ||
1857 | struct page * | ||
1858 | __alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order, | ||
1859 | struct zonelist *zonelist, nodemask_t *nodemask) | ||
1860 | { | ||
1861 | enum zone_type high_zoneidx = gfp_zone(gfp_mask); | ||
1862 | struct zone *preferred_zone; | ||
1863 | struct page *page; | ||
1864 | int migratetype = allocflags_to_migratetype(gfp_mask); | ||
1865 | |||
1866 | lockdep_trace_alloc(gfp_mask); | ||
1867 | |||
1868 | might_sleep_if(gfp_mask & __GFP_WAIT); | ||
1869 | |||
1870 | if (should_fail_alloc_page(gfp_mask, order)) | ||
1871 | return NULL; | ||
1872 | |||
1873 | /* | ||
1874 | * Check the zones suitable for the gfp_mask contain at least one | ||
1875 | * valid zone. It's possible to have an empty zonelist as a result | ||
1876 | * of GFP_THISNODE and a memoryless node | ||
1877 | */ | ||
1878 | if (unlikely(!zonelist->_zonerefs->zone)) | ||
1879 | return NULL; | ||
1880 | |||
1881 | /* The preferred zone is used for statistics later */ | ||
1882 | first_zones_zonelist(zonelist, high_zoneidx, nodemask, &preferred_zone); | ||
1883 | if (!preferred_zone) | ||
1884 | return NULL; | ||
1885 | |||
1886 | /* First allocation attempt */ | ||
1887 | page = get_page_from_freelist(gfp_mask|__GFP_HARDWALL, nodemask, order, | ||
1888 | zonelist, high_zoneidx, ALLOC_WMARK_LOW|ALLOC_CPUSET, | ||
1889 | preferred_zone, migratetype); | ||
1890 | if (unlikely(!page)) | ||
1891 | page = __alloc_pages_slowpath(gfp_mask, order, | ||
1892 | zonelist, high_zoneidx, nodemask, | ||
1893 | preferred_zone, migratetype); | ||
1894 | |||
1895 | return page; | ||
1690 | } | 1896 | } |
1691 | EXPORT_SYMBOL(__alloc_pages_internal); | 1897 | EXPORT_SYMBOL(__alloc_pages_nodemask); |
1692 | 1898 | ||
1693 | /* | 1899 | /* |
1694 | * Common helper functions. | 1900 | * Common helper functions. |
@@ -1817,7 +2023,7 @@ static unsigned int nr_free_zone_pages(int offset) | |||
1817 | 2023 | ||
1818 | for_each_zone_zonelist(zone, z, zonelist, offset) { | 2024 | for_each_zone_zonelist(zone, z, zonelist, offset) { |
1819 | unsigned long size = zone->present_pages; | 2025 | unsigned long size = zone->present_pages; |
1820 | unsigned long high = zone->pages_high; | 2026 | unsigned long high = high_wmark_pages(zone); |
1821 | if (size > high) | 2027 | if (size > high) |
1822 | sum += size - high; | 2028 | sum += size - high; |
1823 | } | 2029 | } |
@@ -1909,19 +2115,14 @@ void show_free_areas(void) | |||
1909 | 2115 | ||
1910 | printk("Active_anon:%lu active_file:%lu inactive_anon:%lu\n" | 2116 | printk("Active_anon:%lu active_file:%lu inactive_anon:%lu\n" |
1911 | " inactive_file:%lu" | 2117 | " inactive_file:%lu" |
1912 | //TODO: check/adjust line lengths | ||
1913 | #ifdef CONFIG_UNEVICTABLE_LRU | ||
1914 | " unevictable:%lu" | 2118 | " unevictable:%lu" |
1915 | #endif | ||
1916 | " dirty:%lu writeback:%lu unstable:%lu\n" | 2119 | " dirty:%lu writeback:%lu unstable:%lu\n" |
1917 | " free:%lu slab:%lu mapped:%lu pagetables:%lu bounce:%lu\n", | 2120 | " free:%lu slab:%lu mapped:%lu pagetables:%lu bounce:%lu\n", |
1918 | global_page_state(NR_ACTIVE_ANON), | 2121 | global_page_state(NR_ACTIVE_ANON), |
1919 | global_page_state(NR_ACTIVE_FILE), | 2122 | global_page_state(NR_ACTIVE_FILE), |
1920 | global_page_state(NR_INACTIVE_ANON), | 2123 | global_page_state(NR_INACTIVE_ANON), |
1921 | global_page_state(NR_INACTIVE_FILE), | 2124 | global_page_state(NR_INACTIVE_FILE), |
1922 | #ifdef CONFIG_UNEVICTABLE_LRU | ||
1923 | global_page_state(NR_UNEVICTABLE), | 2125 | global_page_state(NR_UNEVICTABLE), |
1924 | #endif | ||
1925 | global_page_state(NR_FILE_DIRTY), | 2126 | global_page_state(NR_FILE_DIRTY), |
1926 | global_page_state(NR_WRITEBACK), | 2127 | global_page_state(NR_WRITEBACK), |
1927 | global_page_state(NR_UNSTABLE_NFS), | 2128 | global_page_state(NR_UNSTABLE_NFS), |
@@ -1945,25 +2146,21 @@ void show_free_areas(void) | |||
1945 | " inactive_anon:%lukB" | 2146 | " inactive_anon:%lukB" |
1946 | " active_file:%lukB" | 2147 | " active_file:%lukB" |
1947 | " inactive_file:%lukB" | 2148 | " inactive_file:%lukB" |
1948 | #ifdef CONFIG_UNEVICTABLE_LRU | ||
1949 | " unevictable:%lukB" | 2149 | " unevictable:%lukB" |
1950 | #endif | ||
1951 | " present:%lukB" | 2150 | " present:%lukB" |
1952 | " pages_scanned:%lu" | 2151 | " pages_scanned:%lu" |
1953 | " all_unreclaimable? %s" | 2152 | " all_unreclaimable? %s" |
1954 | "\n", | 2153 | "\n", |
1955 | zone->name, | 2154 | zone->name, |
1956 | K(zone_page_state(zone, NR_FREE_PAGES)), | 2155 | K(zone_page_state(zone, NR_FREE_PAGES)), |
1957 | K(zone->pages_min), | 2156 | K(min_wmark_pages(zone)), |
1958 | K(zone->pages_low), | 2157 | K(low_wmark_pages(zone)), |
1959 | K(zone->pages_high), | 2158 | K(high_wmark_pages(zone)), |
1960 | K(zone_page_state(zone, NR_ACTIVE_ANON)), | 2159 | K(zone_page_state(zone, NR_ACTIVE_ANON)), |
1961 | K(zone_page_state(zone, NR_INACTIVE_ANON)), | 2160 | K(zone_page_state(zone, NR_INACTIVE_ANON)), |
1962 | K(zone_page_state(zone, NR_ACTIVE_FILE)), | 2161 | K(zone_page_state(zone, NR_ACTIVE_FILE)), |
1963 | K(zone_page_state(zone, NR_INACTIVE_FILE)), | 2162 | K(zone_page_state(zone, NR_INACTIVE_FILE)), |
1964 | #ifdef CONFIG_UNEVICTABLE_LRU | ||
1965 | K(zone_page_state(zone, NR_UNEVICTABLE)), | 2163 | K(zone_page_state(zone, NR_UNEVICTABLE)), |
1966 | #endif | ||
1967 | K(zone->present_pages), | 2164 | K(zone->present_pages), |
1968 | zone->pages_scanned, | 2165 | zone->pages_scanned, |
1969 | (zone_is_all_unreclaimable(zone) ? "yes" : "no") | 2166 | (zone_is_all_unreclaimable(zone) ? "yes" : "no") |
@@ -2121,7 +2318,7 @@ int numa_zonelist_order_handler(ctl_table *table, int write, | |||
2121 | } | 2318 | } |
2122 | 2319 | ||
2123 | 2320 | ||
2124 | #define MAX_NODE_LOAD (num_online_nodes()) | 2321 | #define MAX_NODE_LOAD (nr_online_nodes) |
2125 | static int node_load[MAX_NUMNODES]; | 2322 | static int node_load[MAX_NUMNODES]; |
2126 | 2323 | ||
2127 | /** | 2324 | /** |
@@ -2330,7 +2527,7 @@ static void build_zonelists(pg_data_t *pgdat) | |||
2330 | 2527 | ||
2331 | /* NUMA-aware ordering of nodes */ | 2528 | /* NUMA-aware ordering of nodes */ |
2332 | local_node = pgdat->node_id; | 2529 | local_node = pgdat->node_id; |
2333 | load = num_online_nodes(); | 2530 | load = nr_online_nodes; |
2334 | prev_node = local_node; | 2531 | prev_node = local_node; |
2335 | nodes_clear(used_mask); | 2532 | nodes_clear(used_mask); |
2336 | 2533 | ||
@@ -2481,7 +2678,7 @@ void build_all_zonelists(void) | |||
2481 | 2678 | ||
2482 | printk("Built %i zonelists in %s order, mobility grouping %s. " | 2679 | printk("Built %i zonelists in %s order, mobility grouping %s. " |
2483 | "Total pages: %ld\n", | 2680 | "Total pages: %ld\n", |
2484 | num_online_nodes(), | 2681 | nr_online_nodes, |
2485 | zonelist_order_name[current_zonelist_order], | 2682 | zonelist_order_name[current_zonelist_order], |
2486 | page_group_by_mobility_disabled ? "off" : "on", | 2683 | page_group_by_mobility_disabled ? "off" : "on", |
2487 | vm_total_pages); | 2684 | vm_total_pages); |
@@ -2560,8 +2757,8 @@ static inline unsigned long wait_table_bits(unsigned long size) | |||
2560 | 2757 | ||
2561 | /* | 2758 | /* |
2562 | * Mark a number of pageblocks as MIGRATE_RESERVE. The number | 2759 | * Mark a number of pageblocks as MIGRATE_RESERVE. The number |
2563 | * of blocks reserved is based on zone->pages_min. The memory within the | 2760 | * of blocks reserved is based on min_wmark_pages(zone). The memory within |
2564 | * reserve will tend to store contiguous free pages. Setting min_free_kbytes | 2761 | * the reserve will tend to store contiguous free pages. Setting min_free_kbytes |
2565 | * higher will lead to a bigger reserve which will get freed as contiguous | 2762 | * higher will lead to a bigger reserve which will get freed as contiguous |
2566 | * blocks as reclaim kicks in | 2763 | * blocks as reclaim kicks in |
2567 | */ | 2764 | */ |
@@ -2574,7 +2771,7 @@ static void setup_zone_migrate_reserve(struct zone *zone) | |||
2574 | /* Get the start pfn, end pfn and the number of blocks to reserve */ | 2771 | /* Get the start pfn, end pfn and the number of blocks to reserve */ |
2575 | start_pfn = zone->zone_start_pfn; | 2772 | start_pfn = zone->zone_start_pfn; |
2576 | end_pfn = start_pfn + zone->spanned_pages; | 2773 | end_pfn = start_pfn + zone->spanned_pages; |
2577 | reserve = roundup(zone->pages_min, pageblock_nr_pages) >> | 2774 | reserve = roundup(min_wmark_pages(zone), pageblock_nr_pages) >> |
2578 | pageblock_order; | 2775 | pageblock_order; |
2579 | 2776 | ||
2580 | for (pfn = start_pfn; pfn < end_pfn; pfn += pageblock_nr_pages) { | 2777 | for (pfn = start_pfn; pfn < end_pfn; pfn += pageblock_nr_pages) { |
@@ -3506,7 +3703,7 @@ static void __paginginit free_area_init_core(struct pglist_data *pgdat, | |||
3506 | zone_pcp_init(zone); | 3703 | zone_pcp_init(zone); |
3507 | for_each_lru(l) { | 3704 | for_each_lru(l) { |
3508 | INIT_LIST_HEAD(&zone->lru[l].list); | 3705 | INIT_LIST_HEAD(&zone->lru[l].list); |
3509 | zone->lru[l].nr_scan = 0; | 3706 | zone->lru[l].nr_saved_scan = 0; |
3510 | } | 3707 | } |
3511 | zone->reclaim_stat.recent_rotated[0] = 0; | 3708 | zone->reclaim_stat.recent_rotated[0] = 0; |
3512 | zone->reclaim_stat.recent_rotated[1] = 0; | 3709 | zone->reclaim_stat.recent_rotated[1] = 0; |
@@ -4043,6 +4240,11 @@ void __init free_area_init_nodes(unsigned long *max_zone_pfn) | |||
4043 | early_node_map[i].start_pfn, | 4240 | early_node_map[i].start_pfn, |
4044 | early_node_map[i].end_pfn); | 4241 | early_node_map[i].end_pfn); |
4045 | 4242 | ||
4243 | /* | ||
4244 | * find_zone_movable_pfns_for_nodes/early_calculate_totalpages init | ||
4245 | * that node_mask, clear it at first | ||
4246 | */ | ||
4247 | nodes_clear(node_states[N_HIGH_MEMORY]); | ||
4046 | /* Initialise every node */ | 4248 | /* Initialise every node */ |
4047 | mminit_verify_pageflags_layout(); | 4249 | mminit_verify_pageflags_layout(); |
4048 | setup_nr_node_ids(); | 4250 | setup_nr_node_ids(); |
@@ -4177,8 +4379,8 @@ static void calculate_totalreserve_pages(void) | |||
4177 | max = zone->lowmem_reserve[j]; | 4379 | max = zone->lowmem_reserve[j]; |
4178 | } | 4380 | } |
4179 | 4381 | ||
4180 | /* we treat pages_high as reserved pages. */ | 4382 | /* we treat the high watermark as reserved pages. */ |
4181 | max += zone->pages_high; | 4383 | max += high_wmark_pages(zone); |
4182 | 4384 | ||
4183 | if (max > zone->present_pages) | 4385 | if (max > zone->present_pages) |
4184 | max = zone->present_pages; | 4386 | max = zone->present_pages; |
@@ -4228,12 +4430,13 @@ static void setup_per_zone_lowmem_reserve(void) | |||
4228 | } | 4430 | } |
4229 | 4431 | ||
4230 | /** | 4432 | /** |
4231 | * setup_per_zone_pages_min - called when min_free_kbytes changes. | 4433 | * setup_per_zone_wmarks - called when min_free_kbytes changes |
4434 | * or when memory is hot-{added|removed} | ||
4232 | * | 4435 | * |
4233 | * Ensures that the pages_{min,low,high} values for each zone are set correctly | 4436 | * Ensures that the watermark[min,low,high] values for each zone are set |
4234 | * with respect to min_free_kbytes. | 4437 | * correctly with respect to min_free_kbytes. |
4235 | */ | 4438 | */ |
4236 | void setup_per_zone_pages_min(void) | 4439 | void setup_per_zone_wmarks(void) |
4237 | { | 4440 | { |
4238 | unsigned long pages_min = min_free_kbytes >> (PAGE_SHIFT - 10); | 4441 | unsigned long pages_min = min_free_kbytes >> (PAGE_SHIFT - 10); |
4239 | unsigned long lowmem_pages = 0; | 4442 | unsigned long lowmem_pages = 0; |
@@ -4258,7 +4461,7 @@ void setup_per_zone_pages_min(void) | |||
4258 | * need highmem pages, so cap pages_min to a small | 4461 | * need highmem pages, so cap pages_min to a small |
4259 | * value here. | 4462 | * value here. |
4260 | * | 4463 | * |
4261 | * The (pages_high-pages_low) and (pages_low-pages_min) | 4464 | * The WMARK_HIGH-WMARK_LOW and (WMARK_LOW-WMARK_MIN) |
4262 | * deltas controls asynch page reclaim, and so should | 4465 | * deltas controls asynch page reclaim, and so should |
4263 | * not be capped for highmem. | 4466 | * not be capped for highmem. |
4264 | */ | 4467 | */ |
@@ -4269,17 +4472,17 @@ void setup_per_zone_pages_min(void) | |||
4269 | min_pages = SWAP_CLUSTER_MAX; | 4472 | min_pages = SWAP_CLUSTER_MAX; |
4270 | if (min_pages > 128) | 4473 | if (min_pages > 128) |
4271 | min_pages = 128; | 4474 | min_pages = 128; |
4272 | zone->pages_min = min_pages; | 4475 | zone->watermark[WMARK_MIN] = min_pages; |
4273 | } else { | 4476 | } else { |
4274 | /* | 4477 | /* |
4275 | * If it's a lowmem zone, reserve a number of pages | 4478 | * If it's a lowmem zone, reserve a number of pages |
4276 | * proportionate to the zone's size. | 4479 | * proportionate to the zone's size. |
4277 | */ | 4480 | */ |
4278 | zone->pages_min = tmp; | 4481 | zone->watermark[WMARK_MIN] = tmp; |
4279 | } | 4482 | } |
4280 | 4483 | ||
4281 | zone->pages_low = zone->pages_min + (tmp >> 2); | 4484 | zone->watermark[WMARK_LOW] = min_wmark_pages(zone) + (tmp >> 2); |
4282 | zone->pages_high = zone->pages_min + (tmp >> 1); | 4485 | zone->watermark[WMARK_HIGH] = min_wmark_pages(zone) + (tmp >> 1); |
4283 | setup_zone_migrate_reserve(zone); | 4486 | setup_zone_migrate_reserve(zone); |
4284 | spin_unlock_irqrestore(&zone->lock, flags); | 4487 | spin_unlock_irqrestore(&zone->lock, flags); |
4285 | } | 4488 | } |
@@ -4289,8 +4492,6 @@ void setup_per_zone_pages_min(void) | |||
4289 | } | 4492 | } |
4290 | 4493 | ||
4291 | /** | 4494 | /** |
4292 | * setup_per_zone_inactive_ratio - called when min_free_kbytes changes. | ||
4293 | * | ||
4294 | * The inactive anon list should be small enough that the VM never has to | 4495 | * The inactive anon list should be small enough that the VM never has to |
4295 | * do too much work, but large enough that each inactive page has a chance | 4496 | * do too much work, but large enough that each inactive page has a chance |
4296 | * to be referenced again before it is swapped out. | 4497 | * to be referenced again before it is swapped out. |
@@ -4311,21 +4512,26 @@ void setup_per_zone_pages_min(void) | |||
4311 | * 1TB 101 10GB | 4512 | * 1TB 101 10GB |
4312 | * 10TB 320 32GB | 4513 | * 10TB 320 32GB |
4313 | */ | 4514 | */ |
4314 | static void setup_per_zone_inactive_ratio(void) | 4515 | void calculate_zone_inactive_ratio(struct zone *zone) |
4315 | { | 4516 | { |
4316 | struct zone *zone; | 4517 | unsigned int gb, ratio; |
4317 | |||
4318 | for_each_zone(zone) { | ||
4319 | unsigned int gb, ratio; | ||
4320 | 4518 | ||
4321 | /* Zone size in gigabytes */ | 4519 | /* Zone size in gigabytes */ |
4322 | gb = zone->present_pages >> (30 - PAGE_SHIFT); | 4520 | gb = zone->present_pages >> (30 - PAGE_SHIFT); |
4521 | if (gb) | ||
4323 | ratio = int_sqrt(10 * gb); | 4522 | ratio = int_sqrt(10 * gb); |
4324 | if (!ratio) | 4523 | else |
4325 | ratio = 1; | 4524 | ratio = 1; |
4326 | 4525 | ||
4327 | zone->inactive_ratio = ratio; | 4526 | zone->inactive_ratio = ratio; |
4328 | } | 4527 | } |
4528 | |||
4529 | static void __init setup_per_zone_inactive_ratio(void) | ||
4530 | { | ||
4531 | struct zone *zone; | ||
4532 | |||
4533 | for_each_zone(zone) | ||
4534 | calculate_zone_inactive_ratio(zone); | ||
4329 | } | 4535 | } |
4330 | 4536 | ||
4331 | /* | 4537 | /* |
@@ -4352,7 +4558,7 @@ static void setup_per_zone_inactive_ratio(void) | |||
4352 | * 8192MB: 11584k | 4558 | * 8192MB: 11584k |
4353 | * 16384MB: 16384k | 4559 | * 16384MB: 16384k |
4354 | */ | 4560 | */ |
4355 | static int __init init_per_zone_pages_min(void) | 4561 | static int __init init_per_zone_wmark_min(void) |
4356 | { | 4562 | { |
4357 | unsigned long lowmem_kbytes; | 4563 | unsigned long lowmem_kbytes; |
4358 | 4564 | ||
@@ -4363,12 +4569,12 @@ static int __init init_per_zone_pages_min(void) | |||
4363 | min_free_kbytes = 128; | 4569 | min_free_kbytes = 128; |
4364 | if (min_free_kbytes > 65536) | 4570 | if (min_free_kbytes > 65536) |
4365 | min_free_kbytes = 65536; | 4571 | min_free_kbytes = 65536; |
4366 | setup_per_zone_pages_min(); | 4572 | setup_per_zone_wmarks(); |
4367 | setup_per_zone_lowmem_reserve(); | 4573 | setup_per_zone_lowmem_reserve(); |
4368 | setup_per_zone_inactive_ratio(); | 4574 | setup_per_zone_inactive_ratio(); |
4369 | return 0; | 4575 | return 0; |
4370 | } | 4576 | } |
4371 | module_init(init_per_zone_pages_min) | 4577 | module_init(init_per_zone_wmark_min) |
4372 | 4578 | ||
4373 | /* | 4579 | /* |
4374 | * min_free_kbytes_sysctl_handler - just a wrapper around proc_dointvec() so | 4580 | * min_free_kbytes_sysctl_handler - just a wrapper around proc_dointvec() so |
@@ -4380,7 +4586,7 @@ int min_free_kbytes_sysctl_handler(ctl_table *table, int write, | |||
4380 | { | 4586 | { |
4381 | proc_dointvec(table, write, file, buffer, length, ppos); | 4587 | proc_dointvec(table, write, file, buffer, length, ppos); |
4382 | if (write) | 4588 | if (write) |
4383 | setup_per_zone_pages_min(); | 4589 | setup_per_zone_wmarks(); |
4384 | return 0; | 4590 | return 0; |
4385 | } | 4591 | } |
4386 | 4592 | ||
@@ -4424,7 +4630,7 @@ int sysctl_min_slab_ratio_sysctl_handler(ctl_table *table, int write, | |||
4424 | * whenever sysctl_lowmem_reserve_ratio changes. | 4630 | * whenever sysctl_lowmem_reserve_ratio changes. |
4425 | * | 4631 | * |
4426 | * The reserve ratio obviously has absolutely no relation with the | 4632 | * The reserve ratio obviously has absolutely no relation with the |
4427 | * pages_min watermarks. The lowmem reserve ratio can only make sense | 4633 | * minimum watermarks. The lowmem reserve ratio can only make sense |
4428 | * if in function of the boot time zone sizes. | 4634 | * if in function of the boot time zone sizes. |
4429 | */ | 4635 | */ |
4430 | int lowmem_reserve_ratio_sysctl_handler(ctl_table *table, int write, | 4636 | int lowmem_reserve_ratio_sysctl_handler(ctl_table *table, int write, |
@@ -4531,23 +4737,13 @@ void *__init alloc_large_system_hash(const char *tablename, | |||
4531 | else if (hashdist) | 4737 | else if (hashdist) |
4532 | table = __vmalloc(size, GFP_ATOMIC, PAGE_KERNEL); | 4738 | table = __vmalloc(size, GFP_ATOMIC, PAGE_KERNEL); |
4533 | else { | 4739 | else { |
4534 | unsigned long order = get_order(size); | ||
4535 | table = (void*) __get_free_pages(GFP_ATOMIC, order); | ||
4536 | /* | 4740 | /* |
4537 | * If bucketsize is not a power-of-two, we may free | 4741 | * If bucketsize is not a power-of-two, we may free |
4538 | * some pages at the end of hash table. | 4742 | * some pages at the end of hash table which |
4743 | * alloc_pages_exact() automatically does | ||
4539 | */ | 4744 | */ |
4540 | if (table) { | 4745 | if (get_order(size) < MAX_ORDER) |
4541 | unsigned long alloc_end = (unsigned long)table + | 4746 | table = alloc_pages_exact(size, GFP_ATOMIC); |
4542 | (PAGE_SIZE << order); | ||
4543 | unsigned long used = (unsigned long)table + | ||
4544 | PAGE_ALIGN(size); | ||
4545 | split_page(virt_to_page(table), order); | ||
4546 | while (used < alloc_end) { | ||
4547 | free_page(used); | ||
4548 | used += PAGE_SIZE; | ||
4549 | } | ||
4550 | } | ||
4551 | } | 4747 | } |
4552 | } while (!table && size > PAGE_SIZE && --log2qty); | 4748 | } while (!table && size > PAGE_SIZE && --log2qty); |
4553 | 4749 | ||
diff --git a/mm/page_io.c b/mm/page_io.c index 3023c475e041..c6f3e5071de3 100644 --- a/mm/page_io.c +++ b/mm/page_io.c | |||
@@ -120,7 +120,7 @@ out: | |||
120 | return ret; | 120 | return ret; |
121 | } | 121 | } |
122 | 122 | ||
123 | int swap_readpage(struct file *file, struct page *page) | 123 | int swap_readpage(struct page *page) |
124 | { | 124 | { |
125 | struct bio *bio; | 125 | struct bio *bio; |
126 | int ret = 0; | 126 | int ret = 0; |
diff --git a/mm/readahead.c b/mm/readahead.c index 133b6d525513..aa1aa2345235 100644 --- a/mm/readahead.c +++ b/mm/readahead.c | |||
@@ -133,15 +133,12 @@ out: | |||
133 | } | 133 | } |
134 | 134 | ||
135 | /* | 135 | /* |
136 | * do_page_cache_readahead actually reads a chunk of disk. It allocates all | 136 | * __do_page_cache_readahead() actually reads a chunk of disk. It allocates all |
137 | * the pages first, then submits them all for I/O. This avoids the very bad | 137 | * the pages first, then submits them all for I/O. This avoids the very bad |
138 | * behaviour which would occur if page allocations are causing VM writeback. | 138 | * behaviour which would occur if page allocations are causing VM writeback. |
139 | * We really don't want to intermingle reads and writes like that. | 139 | * We really don't want to intermingle reads and writes like that. |
140 | * | 140 | * |
141 | * Returns the number of pages requested, or the maximum amount of I/O allowed. | 141 | * Returns the number of pages requested, or the maximum amount of I/O allowed. |
142 | * | ||
143 | * do_page_cache_readahead() returns -1 if it encountered request queue | ||
144 | * congestion. | ||
145 | */ | 142 | */ |
146 | static int | 143 | static int |
147 | __do_page_cache_readahead(struct address_space *mapping, struct file *filp, | 144 | __do_page_cache_readahead(struct address_space *mapping, struct file *filp, |
@@ -210,6 +207,7 @@ int force_page_cache_readahead(struct address_space *mapping, struct file *filp, | |||
210 | if (unlikely(!mapping->a_ops->readpage && !mapping->a_ops->readpages)) | 207 | if (unlikely(!mapping->a_ops->readpage && !mapping->a_ops->readpages)) |
211 | return -EINVAL; | 208 | return -EINVAL; |
212 | 209 | ||
210 | nr_to_read = max_sane_readahead(nr_to_read); | ||
213 | while (nr_to_read) { | 211 | while (nr_to_read) { |
214 | int err; | 212 | int err; |
215 | 213 | ||
@@ -231,22 +229,6 @@ int force_page_cache_readahead(struct address_space *mapping, struct file *filp, | |||
231 | } | 229 | } |
232 | 230 | ||
233 | /* | 231 | /* |
234 | * This version skips the IO if the queue is read-congested, and will tell the | ||
235 | * block layer to abandon the readahead if request allocation would block. | ||
236 | * | ||
237 | * force_page_cache_readahead() will ignore queue congestion and will block on | ||
238 | * request queues. | ||
239 | */ | ||
240 | int do_page_cache_readahead(struct address_space *mapping, struct file *filp, | ||
241 | pgoff_t offset, unsigned long nr_to_read) | ||
242 | { | ||
243 | if (bdi_read_congested(mapping->backing_dev_info)) | ||
244 | return -1; | ||
245 | |||
246 | return __do_page_cache_readahead(mapping, filp, offset, nr_to_read, 0); | ||
247 | } | ||
248 | |||
249 | /* | ||
250 | * Given a desired number of PAGE_CACHE_SIZE readahead pages, return a | 232 | * Given a desired number of PAGE_CACHE_SIZE readahead pages, return a |
251 | * sensible upper limit. | 233 | * sensible upper limit. |
252 | */ | 234 | */ |
@@ -259,7 +241,7 @@ unsigned long max_sane_readahead(unsigned long nr) | |||
259 | /* | 241 | /* |
260 | * Submit IO for the read-ahead request in file_ra_state. | 242 | * Submit IO for the read-ahead request in file_ra_state. |
261 | */ | 243 | */ |
262 | static unsigned long ra_submit(struct file_ra_state *ra, | 244 | unsigned long ra_submit(struct file_ra_state *ra, |
263 | struct address_space *mapping, struct file *filp) | 245 | struct address_space *mapping, struct file *filp) |
264 | { | 246 | { |
265 | int actual; | 247 | int actual; |
@@ -348,6 +330,59 @@ static unsigned long get_next_ra_size(struct file_ra_state *ra, | |||
348 | */ | 330 | */ |
349 | 331 | ||
350 | /* | 332 | /* |
333 | * Count contiguously cached pages from @offset-1 to @offset-@max, | ||
334 | * this count is a conservative estimation of | ||
335 | * - length of the sequential read sequence, or | ||
336 | * - thrashing threshold in memory tight systems | ||
337 | */ | ||
338 | static pgoff_t count_history_pages(struct address_space *mapping, | ||
339 | struct file_ra_state *ra, | ||
340 | pgoff_t offset, unsigned long max) | ||
341 | { | ||
342 | pgoff_t head; | ||
343 | |||
344 | rcu_read_lock(); | ||
345 | head = radix_tree_prev_hole(&mapping->page_tree, offset - 1, max); | ||
346 | rcu_read_unlock(); | ||
347 | |||
348 | return offset - 1 - head; | ||
349 | } | ||
350 | |||
351 | /* | ||
352 | * page cache context based read-ahead | ||
353 | */ | ||
354 | static int try_context_readahead(struct address_space *mapping, | ||
355 | struct file_ra_state *ra, | ||
356 | pgoff_t offset, | ||
357 | unsigned long req_size, | ||
358 | unsigned long max) | ||
359 | { | ||
360 | pgoff_t size; | ||
361 | |||
362 | size = count_history_pages(mapping, ra, offset, max); | ||
363 | |||
364 | /* | ||
365 | * no history pages: | ||
366 | * it could be a random read | ||
367 | */ | ||
368 | if (!size) | ||
369 | return 0; | ||
370 | |||
371 | /* | ||
372 | * starts from beginning of file: | ||
373 | * it is a strong indication of long-run stream (or whole-file-read) | ||
374 | */ | ||
375 | if (size >= offset) | ||
376 | size *= 2; | ||
377 | |||
378 | ra->start = offset; | ||
379 | ra->size = get_init_ra_size(size + req_size, max); | ||
380 | ra->async_size = ra->size; | ||
381 | |||
382 | return 1; | ||
383 | } | ||
384 | |||
385 | /* | ||
351 | * A minimal readahead algorithm for trivial sequential/random reads. | 386 | * A minimal readahead algorithm for trivial sequential/random reads. |
352 | */ | 387 | */ |
353 | static unsigned long | 388 | static unsigned long |
@@ -356,34 +391,26 @@ ondemand_readahead(struct address_space *mapping, | |||
356 | bool hit_readahead_marker, pgoff_t offset, | 391 | bool hit_readahead_marker, pgoff_t offset, |
357 | unsigned long req_size) | 392 | unsigned long req_size) |
358 | { | 393 | { |
359 | int max = ra->ra_pages; /* max readahead pages */ | 394 | unsigned long max = max_sane_readahead(ra->ra_pages); |
360 | pgoff_t prev_offset; | 395 | |
361 | int sequential; | 396 | /* |
397 | * start of file | ||
398 | */ | ||
399 | if (!offset) | ||
400 | goto initial_readahead; | ||
362 | 401 | ||
363 | /* | 402 | /* |
364 | * It's the expected callback offset, assume sequential access. | 403 | * It's the expected callback offset, assume sequential access. |
365 | * Ramp up sizes, and push forward the readahead window. | 404 | * Ramp up sizes, and push forward the readahead window. |
366 | */ | 405 | */ |
367 | if (offset && (offset == (ra->start + ra->size - ra->async_size) || | 406 | if ((offset == (ra->start + ra->size - ra->async_size) || |
368 | offset == (ra->start + ra->size))) { | 407 | offset == (ra->start + ra->size))) { |
369 | ra->start += ra->size; | 408 | ra->start += ra->size; |
370 | ra->size = get_next_ra_size(ra, max); | 409 | ra->size = get_next_ra_size(ra, max); |
371 | ra->async_size = ra->size; | 410 | ra->async_size = ra->size; |
372 | goto readit; | 411 | goto readit; |
373 | } | 412 | } |
374 | 413 | ||
375 | prev_offset = ra->prev_pos >> PAGE_CACHE_SHIFT; | ||
376 | sequential = offset - prev_offset <= 1UL || req_size > max; | ||
377 | |||
378 | /* | ||
379 | * Standalone, small read. | ||
380 | * Read as is, and do not pollute the readahead state. | ||
381 | */ | ||
382 | if (!hit_readahead_marker && !sequential) { | ||
383 | return __do_page_cache_readahead(mapping, filp, | ||
384 | offset, req_size, 0); | ||
385 | } | ||
386 | |||
387 | /* | 414 | /* |
388 | * Hit a marked page without valid readahead state. | 415 | * Hit a marked page without valid readahead state. |
389 | * E.g. interleaved reads. | 416 | * E.g. interleaved reads. |
@@ -394,7 +421,7 @@ ondemand_readahead(struct address_space *mapping, | |||
394 | pgoff_t start; | 421 | pgoff_t start; |
395 | 422 | ||
396 | rcu_read_lock(); | 423 | rcu_read_lock(); |
397 | start = radix_tree_next_hole(&mapping->page_tree, offset,max+1); | 424 | start = radix_tree_next_hole(&mapping->page_tree, offset+1,max); |
398 | rcu_read_unlock(); | 425 | rcu_read_unlock(); |
399 | 426 | ||
400 | if (!start || start - offset > max) | 427 | if (!start || start - offset > max) |
@@ -402,23 +429,53 @@ ondemand_readahead(struct address_space *mapping, | |||
402 | 429 | ||
403 | ra->start = start; | 430 | ra->start = start; |
404 | ra->size = start - offset; /* old async_size */ | 431 | ra->size = start - offset; /* old async_size */ |
432 | ra->size += req_size; | ||
405 | ra->size = get_next_ra_size(ra, max); | 433 | ra->size = get_next_ra_size(ra, max); |
406 | ra->async_size = ra->size; | 434 | ra->async_size = ra->size; |
407 | goto readit; | 435 | goto readit; |
408 | } | 436 | } |
409 | 437 | ||
410 | /* | 438 | /* |
411 | * It may be one of | 439 | * oversize read |
412 | * - first read on start of file | 440 | */ |
413 | * - sequential cache miss | 441 | if (req_size > max) |
414 | * - oversize random read | 442 | goto initial_readahead; |
415 | * Start readahead for it. | 443 | |
444 | /* | ||
445 | * sequential cache miss | ||
446 | */ | ||
447 | if (offset - (ra->prev_pos >> PAGE_CACHE_SHIFT) <= 1UL) | ||
448 | goto initial_readahead; | ||
449 | |||
450 | /* | ||
451 | * Query the page cache and look for the traces(cached history pages) | ||
452 | * that a sequential stream would leave behind. | ||
453 | */ | ||
454 | if (try_context_readahead(mapping, ra, offset, req_size, max)) | ||
455 | goto readit; | ||
456 | |||
457 | /* | ||
458 | * standalone, small random read | ||
459 | * Read as is, and do not pollute the readahead state. | ||
416 | */ | 460 | */ |
461 | return __do_page_cache_readahead(mapping, filp, offset, req_size, 0); | ||
462 | |||
463 | initial_readahead: | ||
417 | ra->start = offset; | 464 | ra->start = offset; |
418 | ra->size = get_init_ra_size(req_size, max); | 465 | ra->size = get_init_ra_size(req_size, max); |
419 | ra->async_size = ra->size > req_size ? ra->size - req_size : ra->size; | 466 | ra->async_size = ra->size > req_size ? ra->size - req_size : ra->size; |
420 | 467 | ||
421 | readit: | 468 | readit: |
469 | /* | ||
470 | * Will this read hit the readahead marker made by itself? | ||
471 | * If so, trigger the readahead marker hit now, and merge | ||
472 | * the resulted next readahead window into the current one. | ||
473 | */ | ||
474 | if (offset == ra->start && ra->size == ra->async_size) { | ||
475 | ra->async_size = get_next_ra_size(ra, max); | ||
476 | ra->size += ra->async_size; | ||
477 | } | ||
478 | |||
422 | return ra_submit(ra, mapping, filp); | 479 | return ra_submit(ra, mapping, filp); |
423 | } | 480 | } |
424 | 481 | ||
@@ -333,7 +333,9 @@ static int page_mapped_in_vma(struct page *page, struct vm_area_struct *vma) | |||
333 | * repeatedly from either page_referenced_anon or page_referenced_file. | 333 | * repeatedly from either page_referenced_anon or page_referenced_file. |
334 | */ | 334 | */ |
335 | static int page_referenced_one(struct page *page, | 335 | static int page_referenced_one(struct page *page, |
336 | struct vm_area_struct *vma, unsigned int *mapcount) | 336 | struct vm_area_struct *vma, |
337 | unsigned int *mapcount, | ||
338 | unsigned long *vm_flags) | ||
337 | { | 339 | { |
338 | struct mm_struct *mm = vma->vm_mm; | 340 | struct mm_struct *mm = vma->vm_mm; |
339 | unsigned long address; | 341 | unsigned long address; |
@@ -381,11 +383,14 @@ out_unmap: | |||
381 | (*mapcount)--; | 383 | (*mapcount)--; |
382 | pte_unmap_unlock(pte, ptl); | 384 | pte_unmap_unlock(pte, ptl); |
383 | out: | 385 | out: |
386 | if (referenced) | ||
387 | *vm_flags |= vma->vm_flags; | ||
384 | return referenced; | 388 | return referenced; |
385 | } | 389 | } |
386 | 390 | ||
387 | static int page_referenced_anon(struct page *page, | 391 | static int page_referenced_anon(struct page *page, |
388 | struct mem_cgroup *mem_cont) | 392 | struct mem_cgroup *mem_cont, |
393 | unsigned long *vm_flags) | ||
389 | { | 394 | { |
390 | unsigned int mapcount; | 395 | unsigned int mapcount; |
391 | struct anon_vma *anon_vma; | 396 | struct anon_vma *anon_vma; |
@@ -405,7 +410,8 @@ static int page_referenced_anon(struct page *page, | |||
405 | */ | 410 | */ |
406 | if (mem_cont && !mm_match_cgroup(vma->vm_mm, mem_cont)) | 411 | if (mem_cont && !mm_match_cgroup(vma->vm_mm, mem_cont)) |
407 | continue; | 412 | continue; |
408 | referenced += page_referenced_one(page, vma, &mapcount); | 413 | referenced += page_referenced_one(page, vma, |
414 | &mapcount, vm_flags); | ||
409 | if (!mapcount) | 415 | if (!mapcount) |
410 | break; | 416 | break; |
411 | } | 417 | } |
@@ -418,6 +424,7 @@ static int page_referenced_anon(struct page *page, | |||
418 | * page_referenced_file - referenced check for object-based rmap | 424 | * page_referenced_file - referenced check for object-based rmap |
419 | * @page: the page we're checking references on. | 425 | * @page: the page we're checking references on. |
420 | * @mem_cont: target memory controller | 426 | * @mem_cont: target memory controller |
427 | * @vm_flags: collect encountered vma->vm_flags who actually referenced the page | ||
421 | * | 428 | * |
422 | * For an object-based mapped page, find all the places it is mapped and | 429 | * For an object-based mapped page, find all the places it is mapped and |
423 | * check/clear the referenced flag. This is done by following the page->mapping | 430 | * check/clear the referenced flag. This is done by following the page->mapping |
@@ -427,7 +434,8 @@ static int page_referenced_anon(struct page *page, | |||
427 | * This function is only called from page_referenced for object-based pages. | 434 | * This function is only called from page_referenced for object-based pages. |
428 | */ | 435 | */ |
429 | static int page_referenced_file(struct page *page, | 436 | static int page_referenced_file(struct page *page, |
430 | struct mem_cgroup *mem_cont) | 437 | struct mem_cgroup *mem_cont, |
438 | unsigned long *vm_flags) | ||
431 | { | 439 | { |
432 | unsigned int mapcount; | 440 | unsigned int mapcount; |
433 | struct address_space *mapping = page->mapping; | 441 | struct address_space *mapping = page->mapping; |
@@ -467,7 +475,8 @@ static int page_referenced_file(struct page *page, | |||
467 | */ | 475 | */ |
468 | if (mem_cont && !mm_match_cgroup(vma->vm_mm, mem_cont)) | 476 | if (mem_cont && !mm_match_cgroup(vma->vm_mm, mem_cont)) |
469 | continue; | 477 | continue; |
470 | referenced += page_referenced_one(page, vma, &mapcount); | 478 | referenced += page_referenced_one(page, vma, |
479 | &mapcount, vm_flags); | ||
471 | if (!mapcount) | 480 | if (!mapcount) |
472 | break; | 481 | break; |
473 | } | 482 | } |
@@ -481,29 +490,35 @@ static int page_referenced_file(struct page *page, | |||
481 | * @page: the page to test | 490 | * @page: the page to test |
482 | * @is_locked: caller holds lock on the page | 491 | * @is_locked: caller holds lock on the page |
483 | * @mem_cont: target memory controller | 492 | * @mem_cont: target memory controller |
493 | * @vm_flags: collect encountered vma->vm_flags who actually referenced the page | ||
484 | * | 494 | * |
485 | * Quick test_and_clear_referenced for all mappings to a page, | 495 | * Quick test_and_clear_referenced for all mappings to a page, |
486 | * returns the number of ptes which referenced the page. | 496 | * returns the number of ptes which referenced the page. |
487 | */ | 497 | */ |
488 | int page_referenced(struct page *page, int is_locked, | 498 | int page_referenced(struct page *page, |
489 | struct mem_cgroup *mem_cont) | 499 | int is_locked, |
500 | struct mem_cgroup *mem_cont, | ||
501 | unsigned long *vm_flags) | ||
490 | { | 502 | { |
491 | int referenced = 0; | 503 | int referenced = 0; |
492 | 504 | ||
493 | if (TestClearPageReferenced(page)) | 505 | if (TestClearPageReferenced(page)) |
494 | referenced++; | 506 | referenced++; |
495 | 507 | ||
508 | *vm_flags = 0; | ||
496 | if (page_mapped(page) && page->mapping) { | 509 | if (page_mapped(page) && page->mapping) { |
497 | if (PageAnon(page)) | 510 | if (PageAnon(page)) |
498 | referenced += page_referenced_anon(page, mem_cont); | 511 | referenced += page_referenced_anon(page, mem_cont, |
512 | vm_flags); | ||
499 | else if (is_locked) | 513 | else if (is_locked) |
500 | referenced += page_referenced_file(page, mem_cont); | 514 | referenced += page_referenced_file(page, mem_cont, |
515 | vm_flags); | ||
501 | else if (!trylock_page(page)) | 516 | else if (!trylock_page(page)) |
502 | referenced++; | 517 | referenced++; |
503 | else { | 518 | else { |
504 | if (page->mapping) | 519 | if (page->mapping) |
505 | referenced += | 520 | referenced += page_referenced_file(page, |
506 | page_referenced_file(page, mem_cont); | 521 | mem_cont, vm_flags); |
507 | unlock_page(page); | 522 | unlock_page(page); |
508 | } | 523 | } |
509 | } | 524 | } |
@@ -1202,7 +1217,6 @@ int try_to_unmap(struct page *page, int migration) | |||
1202 | return ret; | 1217 | return ret; |
1203 | } | 1218 | } |
1204 | 1219 | ||
1205 | #ifdef CONFIG_UNEVICTABLE_LRU | ||
1206 | /** | 1220 | /** |
1207 | * try_to_munlock - try to munlock a page | 1221 | * try_to_munlock - try to munlock a page |
1208 | * @page: the page to be munlocked | 1222 | * @page: the page to be munlocked |
@@ -1226,4 +1240,4 @@ int try_to_munlock(struct page *page) | |||
1226 | else | 1240 | else |
1227 | return try_to_unmap_file(page, 1, 0); | 1241 | return try_to_unmap_file(page, 1, 0); |
1228 | } | 1242 | } |
1229 | #endif | 1243 | |
diff --git a/mm/shmem.c b/mm/shmem.c index 0132fbd45a23..e89d7ec18eda 100644 --- a/mm/shmem.c +++ b/mm/shmem.c | |||
@@ -1097,7 +1097,7 @@ static int shmem_writepage(struct page *page, struct writeback_control *wbc) | |||
1097 | shmem_swp_unmap(entry); | 1097 | shmem_swp_unmap(entry); |
1098 | unlock: | 1098 | unlock: |
1099 | spin_unlock(&info->lock); | 1099 | spin_unlock(&info->lock); |
1100 | swap_free(swap); | 1100 | swapcache_free(swap, NULL); |
1101 | redirty: | 1101 | redirty: |
1102 | set_page_dirty(page); | 1102 | set_page_dirty(page); |
1103 | if (wbc->for_reclaim) | 1103 | if (wbc->for_reclaim) |
@@ -2612,7 +2612,7 @@ int shmem_unuse(swp_entry_t entry, struct page *page) | |||
2612 | * @size: size to be set for the file | 2612 | * @size: size to be set for the file |
2613 | * @flags: VM_NORESERVE suppresses pre-accounting of the entire object size | 2613 | * @flags: VM_NORESERVE suppresses pre-accounting of the entire object size |
2614 | */ | 2614 | */ |
2615 | struct file *shmem_file_setup(char *name, loff_t size, unsigned long flags) | 2615 | struct file *shmem_file_setup(const char *name, loff_t size, unsigned long flags) |
2616 | { | 2616 | { |
2617 | int error; | 2617 | int error; |
2618 | struct file *file; | 2618 | struct file *file; |
@@ -818,7 +818,6 @@ static void __slab_error(const char *function, struct kmem_cache *cachep, | |||
818 | */ | 818 | */ |
819 | 819 | ||
820 | static int use_alien_caches __read_mostly = 1; | 820 | static int use_alien_caches __read_mostly = 1; |
821 | static int numa_platform __read_mostly = 1; | ||
822 | static int __init noaliencache_setup(char *s) | 821 | static int __init noaliencache_setup(char *s) |
823 | { | 822 | { |
824 | use_alien_caches = 0; | 823 | use_alien_caches = 0; |
@@ -1377,10 +1376,8 @@ void __init kmem_cache_init(void) | |||
1377 | int order; | 1376 | int order; |
1378 | int node; | 1377 | int node; |
1379 | 1378 | ||
1380 | if (num_possible_nodes() == 1) { | 1379 | if (num_possible_nodes() == 1) |
1381 | use_alien_caches = 0; | 1380 | use_alien_caches = 0; |
1382 | numa_platform = 0; | ||
1383 | } | ||
1384 | 1381 | ||
1385 | for (i = 0; i < NUM_INIT_LISTS; i++) { | 1382 | for (i = 0; i < NUM_INIT_LISTS; i++) { |
1386 | kmem_list3_init(&initkmem_list3[i]); | 1383 | kmem_list3_init(&initkmem_list3[i]); |
@@ -1627,7 +1624,7 @@ static void *kmem_getpages(struct kmem_cache *cachep, gfp_t flags, int nodeid) | |||
1627 | if (cachep->flags & SLAB_RECLAIM_ACCOUNT) | 1624 | if (cachep->flags & SLAB_RECLAIM_ACCOUNT) |
1628 | flags |= __GFP_RECLAIMABLE; | 1625 | flags |= __GFP_RECLAIMABLE; |
1629 | 1626 | ||
1630 | page = alloc_pages_node(nodeid, flags | __GFP_NOTRACK, cachep->gfporder); | 1627 | page = alloc_pages_exact_node(nodeid, flags | __GFP_NOTRACK, cachep->gfporder); |
1631 | if (!page) | 1628 | if (!page) |
1632 | return NULL; | 1629 | return NULL; |
1633 | 1630 | ||
@@ -3193,7 +3190,7 @@ retry: | |||
3193 | if (local_flags & __GFP_WAIT) | 3190 | if (local_flags & __GFP_WAIT) |
3194 | local_irq_enable(); | 3191 | local_irq_enable(); |
3195 | kmem_flagcheck(cache, flags); | 3192 | kmem_flagcheck(cache, flags); |
3196 | obj = kmem_getpages(cache, local_flags, -1); | 3193 | obj = kmem_getpages(cache, local_flags, numa_node_id()); |
3197 | if (local_flags & __GFP_WAIT) | 3194 | if (local_flags & __GFP_WAIT) |
3198 | local_irq_disable(); | 3195 | local_irq_disable(); |
3199 | if (obj) { | 3196 | if (obj) { |
@@ -3530,7 +3527,7 @@ static inline void __cache_free(struct kmem_cache *cachep, void *objp) | |||
3530 | * variable to skip the call, which is mostly likely to be present in | 3527 | * variable to skip the call, which is mostly likely to be present in |
3531 | * the cache. | 3528 | * the cache. |
3532 | */ | 3529 | */ |
3533 | if (numa_platform && cache_free_alien(cachep, objp)) | 3530 | if (nr_online_nodes > 1 && cache_free_alien(cachep, objp)) |
3534 | return; | 3531 | return; |
3535 | 3532 | ||
3536 | if (likely(ac->avail < ac->limit)) { | 3533 | if (likely(ac->avail < ac->limit)) { |
@@ -46,7 +46,7 @@ | |||
46 | * NUMA support in SLOB is fairly simplistic, pushing most of the real | 46 | * NUMA support in SLOB is fairly simplistic, pushing most of the real |
47 | * logic down to the page allocator, and simply doing the node accounting | 47 | * logic down to the page allocator, and simply doing the node accounting |
48 | * on the upper levels. In the event that a node id is explicitly | 48 | * on the upper levels. In the event that a node id is explicitly |
49 | * provided, alloc_pages_node() with the specified node id is used | 49 | * provided, alloc_pages_exact_node() with the specified node id is used |
50 | * instead. The common case (or when the node id isn't explicitly provided) | 50 | * instead. The common case (or when the node id isn't explicitly provided) |
51 | * will default to the current node, as per numa_node_id(). | 51 | * will default to the current node, as per numa_node_id(). |
52 | * | 52 | * |
@@ -244,7 +244,7 @@ static void *slob_new_pages(gfp_t gfp, int order, int node) | |||
244 | 244 | ||
245 | #ifdef CONFIG_NUMA | 245 | #ifdef CONFIG_NUMA |
246 | if (node != -1) | 246 | if (node != -1) |
247 | page = alloc_pages_node(node, gfp, order); | 247 | page = alloc_pages_exact_node(node, gfp, order); |
248 | else | 248 | else |
249 | #endif | 249 | #endif |
250 | page = alloc_pages(gfp, order); | 250 | page = alloc_pages(gfp, order); |
@@ -3765,7 +3765,7 @@ static int list_locations(struct kmem_cache *s, char *buf, | |||
3765 | to_cpumask(l->cpus)); | 3765 | to_cpumask(l->cpus)); |
3766 | } | 3766 | } |
3767 | 3767 | ||
3768 | if (num_online_nodes() > 1 && !nodes_empty(l->nodes) && | 3768 | if (nr_online_nodes > 1 && !nodes_empty(l->nodes) && |
3769 | len < PAGE_SIZE - 60) { | 3769 | len < PAGE_SIZE - 60) { |
3770 | len += sprintf(buf + len, " nodes="); | 3770 | len += sprintf(buf + len, " nodes="); |
3771 | len += nodelist_scnprintf(buf + len, PAGE_SIZE - len - 50, | 3771 | len += nodelist_scnprintf(buf + len, PAGE_SIZE - len - 50, |
diff --git a/mm/swap_state.c b/mm/swap_state.c index 1416e7e9e02d..42cd38eba79f 100644 --- a/mm/swap_state.c +++ b/mm/swap_state.c | |||
@@ -124,7 +124,6 @@ void __delete_from_swap_cache(struct page *page) | |||
124 | /** | 124 | /** |
125 | * add_to_swap - allocate swap space for a page | 125 | * add_to_swap - allocate swap space for a page |
126 | * @page: page we want to move to swap | 126 | * @page: page we want to move to swap |
127 | * @gfp_mask: memory allocation flags | ||
128 | * | 127 | * |
129 | * Allocate swap space for the page and add the page to the | 128 | * Allocate swap space for the page and add the page to the |
130 | * swap cache. Caller needs to hold the page lock. | 129 | * swap cache. Caller needs to hold the page lock. |
@@ -162,11 +161,11 @@ int add_to_swap(struct page *page) | |||
162 | return 1; | 161 | return 1; |
163 | case -EEXIST: | 162 | case -EEXIST: |
164 | /* Raced with "speculative" read_swap_cache_async */ | 163 | /* Raced with "speculative" read_swap_cache_async */ |
165 | swap_free(entry); | 164 | swapcache_free(entry, NULL); |
166 | continue; | 165 | continue; |
167 | default: | 166 | default: |
168 | /* -ENOMEM radix-tree allocation failure */ | 167 | /* -ENOMEM radix-tree allocation failure */ |
169 | swap_free(entry); | 168 | swapcache_free(entry, NULL); |
170 | return 0; | 169 | return 0; |
171 | } | 170 | } |
172 | } | 171 | } |
@@ -188,8 +187,7 @@ void delete_from_swap_cache(struct page *page) | |||
188 | __delete_from_swap_cache(page); | 187 | __delete_from_swap_cache(page); |
189 | spin_unlock_irq(&swapper_space.tree_lock); | 188 | spin_unlock_irq(&swapper_space.tree_lock); |
190 | 189 | ||
191 | mem_cgroup_uncharge_swapcache(page, entry); | 190 | swapcache_free(entry, page); |
192 | swap_free(entry); | ||
193 | page_cache_release(page); | 191 | page_cache_release(page); |
194 | } | 192 | } |
195 | 193 | ||
@@ -293,7 +291,10 @@ struct page *read_swap_cache_async(swp_entry_t entry, gfp_t gfp_mask, | |||
293 | /* | 291 | /* |
294 | * Swap entry may have been freed since our caller observed it. | 292 | * Swap entry may have been freed since our caller observed it. |
295 | */ | 293 | */ |
296 | if (!swap_duplicate(entry)) | 294 | err = swapcache_prepare(entry); |
295 | if (err == -EEXIST) /* seems racy */ | ||
296 | continue; | ||
297 | if (err) /* swp entry is obsolete ? */ | ||
297 | break; | 298 | break; |
298 | 299 | ||
299 | /* | 300 | /* |
@@ -312,12 +313,12 @@ struct page *read_swap_cache_async(swp_entry_t entry, gfp_t gfp_mask, | |||
312 | * Initiate read into locked page and return. | 313 | * Initiate read into locked page and return. |
313 | */ | 314 | */ |
314 | lru_cache_add_anon(new_page); | 315 | lru_cache_add_anon(new_page); |
315 | swap_readpage(NULL, new_page); | 316 | swap_readpage(new_page); |
316 | return new_page; | 317 | return new_page; |
317 | } | 318 | } |
318 | ClearPageSwapBacked(new_page); | 319 | ClearPageSwapBacked(new_page); |
319 | __clear_page_locked(new_page); | 320 | __clear_page_locked(new_page); |
320 | swap_free(entry); | 321 | swapcache_free(entry, NULL); |
321 | } while (err != -ENOMEM); | 322 | } while (err != -ENOMEM); |
322 | 323 | ||
323 | if (new_page) | 324 | if (new_page) |
diff --git a/mm/swapfile.c b/mm/swapfile.c index 312fafe0ab6e..28faa01cf578 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c | |||
@@ -53,6 +53,59 @@ static struct swap_info_struct swap_info[MAX_SWAPFILES]; | |||
53 | 53 | ||
54 | static DEFINE_MUTEX(swapon_mutex); | 54 | static DEFINE_MUTEX(swapon_mutex); |
55 | 55 | ||
56 | /* For reference count accounting in swap_map */ | ||
57 | /* enum for swap_map[] handling. internal use only */ | ||
58 | enum { | ||
59 | SWAP_MAP = 0, /* ops for reference from swap users */ | ||
60 | SWAP_CACHE, /* ops for reference from swap cache */ | ||
61 | }; | ||
62 | |||
63 | static inline int swap_count(unsigned short ent) | ||
64 | { | ||
65 | return ent & SWAP_COUNT_MASK; | ||
66 | } | ||
67 | |||
68 | static inline bool swap_has_cache(unsigned short ent) | ||
69 | { | ||
70 | return !!(ent & SWAP_HAS_CACHE); | ||
71 | } | ||
72 | |||
73 | static inline unsigned short encode_swapmap(int count, bool has_cache) | ||
74 | { | ||
75 | unsigned short ret = count; | ||
76 | |||
77 | if (has_cache) | ||
78 | return SWAP_HAS_CACHE | ret; | ||
79 | return ret; | ||
80 | } | ||
81 | |||
82 | /* returnes 1 if swap entry is freed */ | ||
83 | static int | ||
84 | __try_to_reclaim_swap(struct swap_info_struct *si, unsigned long offset) | ||
85 | { | ||
86 | int type = si - swap_info; | ||
87 | swp_entry_t entry = swp_entry(type, offset); | ||
88 | struct page *page; | ||
89 | int ret = 0; | ||
90 | |||
91 | page = find_get_page(&swapper_space, entry.val); | ||
92 | if (!page) | ||
93 | return 0; | ||
94 | /* | ||
95 | * This function is called from scan_swap_map() and it's called | ||
96 | * by vmscan.c at reclaiming pages. So, we hold a lock on a page, here. | ||
97 | * We have to use trylock for avoiding deadlock. This is a special | ||
98 | * case and you should use try_to_free_swap() with explicit lock_page() | ||
99 | * in usual operations. | ||
100 | */ | ||
101 | if (trylock_page(page)) { | ||
102 | ret = try_to_free_swap(page); | ||
103 | unlock_page(page); | ||
104 | } | ||
105 | page_cache_release(page); | ||
106 | return ret; | ||
107 | } | ||
108 | |||
56 | /* | 109 | /* |
57 | * We need this because the bdev->unplug_fn can sleep and we cannot | 110 | * We need this because the bdev->unplug_fn can sleep and we cannot |
58 | * hold swap_lock while calling the unplug_fn. And swap_lock | 111 | * hold swap_lock while calling the unplug_fn. And swap_lock |
@@ -167,7 +220,8 @@ static int wait_for_discard(void *word) | |||
167 | #define SWAPFILE_CLUSTER 256 | 220 | #define SWAPFILE_CLUSTER 256 |
168 | #define LATENCY_LIMIT 256 | 221 | #define LATENCY_LIMIT 256 |
169 | 222 | ||
170 | static inline unsigned long scan_swap_map(struct swap_info_struct *si) | 223 | static inline unsigned long scan_swap_map(struct swap_info_struct *si, |
224 | int cache) | ||
171 | { | 225 | { |
172 | unsigned long offset; | 226 | unsigned long offset; |
173 | unsigned long scan_base; | 227 | unsigned long scan_base; |
@@ -273,6 +327,19 @@ checks: | |||
273 | goto no_page; | 327 | goto no_page; |
274 | if (offset > si->highest_bit) | 328 | if (offset > si->highest_bit) |
275 | scan_base = offset = si->lowest_bit; | 329 | scan_base = offset = si->lowest_bit; |
330 | |||
331 | /* reuse swap entry of cache-only swap if not busy. */ | ||
332 | if (vm_swap_full() && si->swap_map[offset] == SWAP_HAS_CACHE) { | ||
333 | int swap_was_freed; | ||
334 | spin_unlock(&swap_lock); | ||
335 | swap_was_freed = __try_to_reclaim_swap(si, offset); | ||
336 | spin_lock(&swap_lock); | ||
337 | /* entry was freed successfully, try to use this again */ | ||
338 | if (swap_was_freed) | ||
339 | goto checks; | ||
340 | goto scan; /* check next one */ | ||
341 | } | ||
342 | |||
276 | if (si->swap_map[offset]) | 343 | if (si->swap_map[offset]) |
277 | goto scan; | 344 | goto scan; |
278 | 345 | ||
@@ -285,7 +352,10 @@ checks: | |||
285 | si->lowest_bit = si->max; | 352 | si->lowest_bit = si->max; |
286 | si->highest_bit = 0; | 353 | si->highest_bit = 0; |
287 | } | 354 | } |
288 | si->swap_map[offset] = 1; | 355 | if (cache == SWAP_CACHE) /* at usual swap-out via vmscan.c */ |
356 | si->swap_map[offset] = encode_swapmap(0, true); | ||
357 | else /* at suspend */ | ||
358 | si->swap_map[offset] = encode_swapmap(1, false); | ||
289 | si->cluster_next = offset + 1; | 359 | si->cluster_next = offset + 1; |
290 | si->flags -= SWP_SCANNING; | 360 | si->flags -= SWP_SCANNING; |
291 | 361 | ||
@@ -351,6 +421,10 @@ scan: | |||
351 | spin_lock(&swap_lock); | 421 | spin_lock(&swap_lock); |
352 | goto checks; | 422 | goto checks; |
353 | } | 423 | } |
424 | if (vm_swap_full() && si->swap_map[offset] == SWAP_HAS_CACHE) { | ||
425 | spin_lock(&swap_lock); | ||
426 | goto checks; | ||
427 | } | ||
354 | if (unlikely(--latency_ration < 0)) { | 428 | if (unlikely(--latency_ration < 0)) { |
355 | cond_resched(); | 429 | cond_resched(); |
356 | latency_ration = LATENCY_LIMIT; | 430 | latency_ration = LATENCY_LIMIT; |
@@ -362,6 +436,10 @@ scan: | |||
362 | spin_lock(&swap_lock); | 436 | spin_lock(&swap_lock); |
363 | goto checks; | 437 | goto checks; |
364 | } | 438 | } |
439 | if (vm_swap_full() && si->swap_map[offset] == SWAP_HAS_CACHE) { | ||
440 | spin_lock(&swap_lock); | ||
441 | goto checks; | ||
442 | } | ||
365 | if (unlikely(--latency_ration < 0)) { | 443 | if (unlikely(--latency_ration < 0)) { |
366 | cond_resched(); | 444 | cond_resched(); |
367 | latency_ration = LATENCY_LIMIT; | 445 | latency_ration = LATENCY_LIMIT; |
@@ -401,7 +479,8 @@ swp_entry_t get_swap_page(void) | |||
401 | continue; | 479 | continue; |
402 | 480 | ||
403 | swap_list.next = next; | 481 | swap_list.next = next; |
404 | offset = scan_swap_map(si); | 482 | /* This is called for allocating swap entry for cache */ |
483 | offset = scan_swap_map(si, SWAP_CACHE); | ||
405 | if (offset) { | 484 | if (offset) { |
406 | spin_unlock(&swap_lock); | 485 | spin_unlock(&swap_lock); |
407 | return swp_entry(type, offset); | 486 | return swp_entry(type, offset); |
@@ -415,6 +494,7 @@ noswap: | |||
415 | return (swp_entry_t) {0}; | 494 | return (swp_entry_t) {0}; |
416 | } | 495 | } |
417 | 496 | ||
497 | /* The only caller of this function is now susupend routine */ | ||
418 | swp_entry_t get_swap_page_of_type(int type) | 498 | swp_entry_t get_swap_page_of_type(int type) |
419 | { | 499 | { |
420 | struct swap_info_struct *si; | 500 | struct swap_info_struct *si; |
@@ -424,7 +504,8 @@ swp_entry_t get_swap_page_of_type(int type) | |||
424 | si = swap_info + type; | 504 | si = swap_info + type; |
425 | if (si->flags & SWP_WRITEOK) { | 505 | if (si->flags & SWP_WRITEOK) { |
426 | nr_swap_pages--; | 506 | nr_swap_pages--; |
427 | offset = scan_swap_map(si); | 507 | /* This is called for allocating swap entry, not cache */ |
508 | offset = scan_swap_map(si, SWAP_MAP); | ||
428 | if (offset) { | 509 | if (offset) { |
429 | spin_unlock(&swap_lock); | 510 | spin_unlock(&swap_lock); |
430 | return swp_entry(type, offset); | 511 | return swp_entry(type, offset); |
@@ -471,25 +552,38 @@ out: | |||
471 | return NULL; | 552 | return NULL; |
472 | } | 553 | } |
473 | 554 | ||
474 | static int swap_entry_free(struct swap_info_struct *p, swp_entry_t ent) | 555 | static int swap_entry_free(struct swap_info_struct *p, |
556 | swp_entry_t ent, int cache) | ||
475 | { | 557 | { |
476 | unsigned long offset = swp_offset(ent); | 558 | unsigned long offset = swp_offset(ent); |
477 | int count = p->swap_map[offset]; | 559 | int count = swap_count(p->swap_map[offset]); |
478 | 560 | bool has_cache; | |
479 | if (count < SWAP_MAP_MAX) { | 561 | |
480 | count--; | 562 | has_cache = swap_has_cache(p->swap_map[offset]); |
481 | p->swap_map[offset] = count; | 563 | |
482 | if (!count) { | 564 | if (cache == SWAP_MAP) { /* dropping usage count of swap */ |
483 | if (offset < p->lowest_bit) | 565 | if (count < SWAP_MAP_MAX) { |
484 | p->lowest_bit = offset; | 566 | count--; |
485 | if (offset > p->highest_bit) | 567 | p->swap_map[offset] = encode_swapmap(count, has_cache); |
486 | p->highest_bit = offset; | ||
487 | if (p->prio > swap_info[swap_list.next].prio) | ||
488 | swap_list.next = p - swap_info; | ||
489 | nr_swap_pages++; | ||
490 | p->inuse_pages--; | ||
491 | mem_cgroup_uncharge_swap(ent); | ||
492 | } | 568 | } |
569 | } else { /* dropping swap cache flag */ | ||
570 | VM_BUG_ON(!has_cache); | ||
571 | p->swap_map[offset] = encode_swapmap(count, false); | ||
572 | |||
573 | } | ||
574 | /* return code. */ | ||
575 | count = p->swap_map[offset]; | ||
576 | /* free if no reference */ | ||
577 | if (!count) { | ||
578 | if (offset < p->lowest_bit) | ||
579 | p->lowest_bit = offset; | ||
580 | if (offset > p->highest_bit) | ||
581 | p->highest_bit = offset; | ||
582 | if (p->prio > swap_info[swap_list.next].prio) | ||
583 | swap_list.next = p - swap_info; | ||
584 | nr_swap_pages++; | ||
585 | p->inuse_pages--; | ||
586 | mem_cgroup_uncharge_swap(ent); | ||
493 | } | 587 | } |
494 | return count; | 588 | return count; |
495 | } | 589 | } |
@@ -504,9 +598,26 @@ void swap_free(swp_entry_t entry) | |||
504 | 598 | ||
505 | p = swap_info_get(entry); | 599 | p = swap_info_get(entry); |
506 | if (p) { | 600 | if (p) { |
507 | swap_entry_free(p, entry); | 601 | swap_entry_free(p, entry, SWAP_MAP); |
602 | spin_unlock(&swap_lock); | ||
603 | } | ||
604 | } | ||
605 | |||
606 | /* | ||
607 | * Called after dropping swapcache to decrease refcnt to swap entries. | ||
608 | */ | ||
609 | void swapcache_free(swp_entry_t entry, struct page *page) | ||
610 | { | ||
611 | struct swap_info_struct *p; | ||
612 | |||
613 | if (page) | ||
614 | mem_cgroup_uncharge_swapcache(page, entry); | ||
615 | p = swap_info_get(entry); | ||
616 | if (p) { | ||
617 | swap_entry_free(p, entry, SWAP_CACHE); | ||
508 | spin_unlock(&swap_lock); | 618 | spin_unlock(&swap_lock); |
509 | } | 619 | } |
620 | return; | ||
510 | } | 621 | } |
511 | 622 | ||
512 | /* | 623 | /* |
@@ -521,8 +632,7 @@ static inline int page_swapcount(struct page *page) | |||
521 | entry.val = page_private(page); | 632 | entry.val = page_private(page); |
522 | p = swap_info_get(entry); | 633 | p = swap_info_get(entry); |
523 | if (p) { | 634 | if (p) { |
524 | /* Subtract the 1 for the swap cache itself */ | 635 | count = swap_count(p->swap_map[swp_offset(entry)]); |
525 | count = p->swap_map[swp_offset(entry)] - 1; | ||
526 | spin_unlock(&swap_lock); | 636 | spin_unlock(&swap_lock); |
527 | } | 637 | } |
528 | return count; | 638 | return count; |
@@ -584,7 +694,7 @@ int free_swap_and_cache(swp_entry_t entry) | |||
584 | 694 | ||
585 | p = swap_info_get(entry); | 695 | p = swap_info_get(entry); |
586 | if (p) { | 696 | if (p) { |
587 | if (swap_entry_free(p, entry) == 1) { | 697 | if (swap_entry_free(p, entry, SWAP_MAP) == SWAP_HAS_CACHE) { |
588 | page = find_get_page(&swapper_space, entry.val); | 698 | page = find_get_page(&swapper_space, entry.val); |
589 | if (page && !trylock_page(page)) { | 699 | if (page && !trylock_page(page)) { |
590 | page_cache_release(page); | 700 | page_cache_release(page); |
@@ -891,7 +1001,7 @@ static unsigned int find_next_to_unuse(struct swap_info_struct *si, | |||
891 | i = 1; | 1001 | i = 1; |
892 | } | 1002 | } |
893 | count = si->swap_map[i]; | 1003 | count = si->swap_map[i]; |
894 | if (count && count != SWAP_MAP_BAD) | 1004 | if (count && swap_count(count) != SWAP_MAP_BAD) |
895 | break; | 1005 | break; |
896 | } | 1006 | } |
897 | return i; | 1007 | return i; |
@@ -995,13 +1105,13 @@ static int try_to_unuse(unsigned int type) | |||
995 | */ | 1105 | */ |
996 | shmem = 0; | 1106 | shmem = 0; |
997 | swcount = *swap_map; | 1107 | swcount = *swap_map; |
998 | if (swcount > 1) { | 1108 | if (swap_count(swcount)) { |
999 | if (start_mm == &init_mm) | 1109 | if (start_mm == &init_mm) |
1000 | shmem = shmem_unuse(entry, page); | 1110 | shmem = shmem_unuse(entry, page); |
1001 | else | 1111 | else |
1002 | retval = unuse_mm(start_mm, entry, page); | 1112 | retval = unuse_mm(start_mm, entry, page); |
1003 | } | 1113 | } |
1004 | if (*swap_map > 1) { | 1114 | if (swap_count(*swap_map)) { |
1005 | int set_start_mm = (*swap_map >= swcount); | 1115 | int set_start_mm = (*swap_map >= swcount); |
1006 | struct list_head *p = &start_mm->mmlist; | 1116 | struct list_head *p = &start_mm->mmlist; |
1007 | struct mm_struct *new_start_mm = start_mm; | 1117 | struct mm_struct *new_start_mm = start_mm; |
@@ -1011,7 +1121,7 @@ static int try_to_unuse(unsigned int type) | |||
1011 | atomic_inc(&new_start_mm->mm_users); | 1121 | atomic_inc(&new_start_mm->mm_users); |
1012 | atomic_inc(&prev_mm->mm_users); | 1122 | atomic_inc(&prev_mm->mm_users); |
1013 | spin_lock(&mmlist_lock); | 1123 | spin_lock(&mmlist_lock); |
1014 | while (*swap_map > 1 && !retval && !shmem && | 1124 | while (swap_count(*swap_map) && !retval && !shmem && |
1015 | (p = p->next) != &start_mm->mmlist) { | 1125 | (p = p->next) != &start_mm->mmlist) { |
1016 | mm = list_entry(p, struct mm_struct, mmlist); | 1126 | mm = list_entry(p, struct mm_struct, mmlist); |
1017 | if (!atomic_inc_not_zero(&mm->mm_users)) | 1127 | if (!atomic_inc_not_zero(&mm->mm_users)) |
@@ -1023,14 +1133,16 @@ static int try_to_unuse(unsigned int type) | |||
1023 | cond_resched(); | 1133 | cond_resched(); |
1024 | 1134 | ||
1025 | swcount = *swap_map; | 1135 | swcount = *swap_map; |
1026 | if (swcount <= 1) | 1136 | if (!swap_count(swcount)) /* any usage ? */ |
1027 | ; | 1137 | ; |
1028 | else if (mm == &init_mm) { | 1138 | else if (mm == &init_mm) { |
1029 | set_start_mm = 1; | 1139 | set_start_mm = 1; |
1030 | shmem = shmem_unuse(entry, page); | 1140 | shmem = shmem_unuse(entry, page); |
1031 | } else | 1141 | } else |
1032 | retval = unuse_mm(mm, entry, page); | 1142 | retval = unuse_mm(mm, entry, page); |
1033 | if (set_start_mm && *swap_map < swcount) { | 1143 | |
1144 | if (set_start_mm && | ||
1145 | swap_count(*swap_map) < swcount) { | ||
1034 | mmput(new_start_mm); | 1146 | mmput(new_start_mm); |
1035 | atomic_inc(&mm->mm_users); | 1147 | atomic_inc(&mm->mm_users); |
1036 | new_start_mm = mm; | 1148 | new_start_mm = mm; |
@@ -1057,21 +1169,25 @@ static int try_to_unuse(unsigned int type) | |||
1057 | } | 1169 | } |
1058 | 1170 | ||
1059 | /* | 1171 | /* |
1060 | * How could swap count reach 0x7fff when the maximum | 1172 | * How could swap count reach 0x7ffe ? |
1061 | * pid is 0x7fff, and there's no way to repeat a swap | 1173 | * There's no way to repeat a swap page within an mm |
1062 | * page within an mm (except in shmem, where it's the | 1174 | * (except in shmem, where it's the shared object which takes |
1063 | * shared object which takes the reference count)? | 1175 | * the reference count)? |
1064 | * We believe SWAP_MAP_MAX cannot occur in Linux 2.4. | 1176 | * We believe SWAP_MAP_MAX cannot occur.(if occur, unsigned |
1065 | * | 1177 | * short is too small....) |
1066 | * If that's wrong, then we should worry more about | 1178 | * If that's wrong, then we should worry more about |
1067 | * exit_mmap() and do_munmap() cases described above: | 1179 | * exit_mmap() and do_munmap() cases described above: |
1068 | * we might be resetting SWAP_MAP_MAX too early here. | 1180 | * we might be resetting SWAP_MAP_MAX too early here. |
1069 | * We know "Undead"s can happen, they're okay, so don't | 1181 | * We know "Undead"s can happen, they're okay, so don't |
1070 | * report them; but do report if we reset SWAP_MAP_MAX. | 1182 | * report them; but do report if we reset SWAP_MAP_MAX. |
1071 | */ | 1183 | */ |
1072 | if (*swap_map == SWAP_MAP_MAX) { | 1184 | /* We might release the lock_page() in unuse_mm(). */ |
1185 | if (!PageSwapCache(page) || page_private(page) != entry.val) | ||
1186 | goto retry; | ||
1187 | |||
1188 | if (swap_count(*swap_map) == SWAP_MAP_MAX) { | ||
1073 | spin_lock(&swap_lock); | 1189 | spin_lock(&swap_lock); |
1074 | *swap_map = 1; | 1190 | *swap_map = encode_swapmap(0, true); |
1075 | spin_unlock(&swap_lock); | 1191 | spin_unlock(&swap_lock); |
1076 | reset_overflow = 1; | 1192 | reset_overflow = 1; |
1077 | } | 1193 | } |
@@ -1089,7 +1205,8 @@ static int try_to_unuse(unsigned int type) | |||
1089 | * pages would be incorrect if swap supported "shared | 1205 | * pages would be incorrect if swap supported "shared |
1090 | * private" pages, but they are handled by tmpfs files. | 1206 | * private" pages, but they are handled by tmpfs files. |
1091 | */ | 1207 | */ |
1092 | if ((*swap_map > 1) && PageDirty(page) && PageSwapCache(page)) { | 1208 | if (swap_count(*swap_map) && |
1209 | PageDirty(page) && PageSwapCache(page)) { | ||
1093 | struct writeback_control wbc = { | 1210 | struct writeback_control wbc = { |
1094 | .sync_mode = WB_SYNC_NONE, | 1211 | .sync_mode = WB_SYNC_NONE, |
1095 | }; | 1212 | }; |
@@ -1116,6 +1233,7 @@ static int try_to_unuse(unsigned int type) | |||
1116 | * mark page dirty so shrink_page_list will preserve it. | 1233 | * mark page dirty so shrink_page_list will preserve it. |
1117 | */ | 1234 | */ |
1118 | SetPageDirty(page); | 1235 | SetPageDirty(page); |
1236 | retry: | ||
1119 | unlock_page(page); | 1237 | unlock_page(page); |
1120 | page_cache_release(page); | 1238 | page_cache_release(page); |
1121 | 1239 | ||
@@ -1942,15 +2060,23 @@ void si_swapinfo(struct sysinfo *val) | |||
1942 | * | 2060 | * |
1943 | * Note: if swap_map[] reaches SWAP_MAP_MAX the entries are treated as | 2061 | * Note: if swap_map[] reaches SWAP_MAP_MAX the entries are treated as |
1944 | * "permanent", but will be reclaimed by the next swapoff. | 2062 | * "permanent", but will be reclaimed by the next swapoff. |
2063 | * Returns error code in following case. | ||
2064 | * - success -> 0 | ||
2065 | * - swp_entry is invalid -> EINVAL | ||
2066 | * - swp_entry is migration entry -> EINVAL | ||
2067 | * - swap-cache reference is requested but there is already one. -> EEXIST | ||
2068 | * - swap-cache reference is requested but the entry is not used. -> ENOENT | ||
1945 | */ | 2069 | */ |
1946 | int swap_duplicate(swp_entry_t entry) | 2070 | static int __swap_duplicate(swp_entry_t entry, bool cache) |
1947 | { | 2071 | { |
1948 | struct swap_info_struct * p; | 2072 | struct swap_info_struct * p; |
1949 | unsigned long offset, type; | 2073 | unsigned long offset, type; |
1950 | int result = 0; | 2074 | int result = -EINVAL; |
2075 | int count; | ||
2076 | bool has_cache; | ||
1951 | 2077 | ||
1952 | if (is_migration_entry(entry)) | 2078 | if (is_migration_entry(entry)) |
1953 | return 1; | 2079 | return -EINVAL; |
1954 | 2080 | ||
1955 | type = swp_type(entry); | 2081 | type = swp_type(entry); |
1956 | if (type >= nr_swapfiles) | 2082 | if (type >= nr_swapfiles) |
@@ -1959,17 +2085,40 @@ int swap_duplicate(swp_entry_t entry) | |||
1959 | offset = swp_offset(entry); | 2085 | offset = swp_offset(entry); |
1960 | 2086 | ||
1961 | spin_lock(&swap_lock); | 2087 | spin_lock(&swap_lock); |
1962 | if (offset < p->max && p->swap_map[offset]) { | 2088 | |
1963 | if (p->swap_map[offset] < SWAP_MAP_MAX - 1) { | 2089 | if (unlikely(offset >= p->max)) |
1964 | p->swap_map[offset]++; | 2090 | goto unlock_out; |
1965 | result = 1; | 2091 | |
1966 | } else if (p->swap_map[offset] <= SWAP_MAP_MAX) { | 2092 | count = swap_count(p->swap_map[offset]); |
2093 | has_cache = swap_has_cache(p->swap_map[offset]); | ||
2094 | |||
2095 | if (cache == SWAP_CACHE) { /* called for swapcache/swapin-readahead */ | ||
2096 | |||
2097 | /* set SWAP_HAS_CACHE if there is no cache and entry is used */ | ||
2098 | if (!has_cache && count) { | ||
2099 | p->swap_map[offset] = encode_swapmap(count, true); | ||
2100 | result = 0; | ||
2101 | } else if (has_cache) /* someone added cache */ | ||
2102 | result = -EEXIST; | ||
2103 | else if (!count) /* no users */ | ||
2104 | result = -ENOENT; | ||
2105 | |||
2106 | } else if (count || has_cache) { | ||
2107 | if (count < SWAP_MAP_MAX - 1) { | ||
2108 | p->swap_map[offset] = encode_swapmap(count + 1, | ||
2109 | has_cache); | ||
2110 | result = 0; | ||
2111 | } else if (count <= SWAP_MAP_MAX) { | ||
1967 | if (swap_overflow++ < 5) | 2112 | if (swap_overflow++ < 5) |
1968 | printk(KERN_WARNING "swap_dup: swap entry overflow\n"); | 2113 | printk(KERN_WARNING |
1969 | p->swap_map[offset] = SWAP_MAP_MAX; | 2114 | "swap_dup: swap entry overflow\n"); |
1970 | result = 1; | 2115 | p->swap_map[offset] = encode_swapmap(SWAP_MAP_MAX, |
2116 | has_cache); | ||
2117 | result = 0; | ||
1971 | } | 2118 | } |
1972 | } | 2119 | } else |
2120 | result = -ENOENT; /* unused swap entry */ | ||
2121 | unlock_out: | ||
1973 | spin_unlock(&swap_lock); | 2122 | spin_unlock(&swap_lock); |
1974 | out: | 2123 | out: |
1975 | return result; | 2124 | return result; |
@@ -1978,6 +2127,27 @@ bad_file: | |||
1978 | printk(KERN_ERR "swap_dup: %s%08lx\n", Bad_file, entry.val); | 2127 | printk(KERN_ERR "swap_dup: %s%08lx\n", Bad_file, entry.val); |
1979 | goto out; | 2128 | goto out; |
1980 | } | 2129 | } |
2130 | /* | ||
2131 | * increase reference count of swap entry by 1. | ||
2132 | */ | ||
2133 | void swap_duplicate(swp_entry_t entry) | ||
2134 | { | ||
2135 | __swap_duplicate(entry, SWAP_MAP); | ||
2136 | } | ||
2137 | |||
2138 | /* | ||
2139 | * @entry: swap entry for which we allocate swap cache. | ||
2140 | * | ||
2141 | * Called when allocating swap cache for exising swap entry, | ||
2142 | * This can return error codes. Returns 0 at success. | ||
2143 | * -EBUSY means there is a swap cache. | ||
2144 | * Note: return code is different from swap_duplicate(). | ||
2145 | */ | ||
2146 | int swapcache_prepare(swp_entry_t entry) | ||
2147 | { | ||
2148 | return __swap_duplicate(entry, SWAP_CACHE); | ||
2149 | } | ||
2150 | |||
1981 | 2151 | ||
1982 | struct swap_info_struct * | 2152 | struct swap_info_struct * |
1983 | get_swap_info_struct(unsigned type) | 2153 | get_swap_info_struct(unsigned type) |
@@ -2016,7 +2186,7 @@ int valid_swaphandles(swp_entry_t entry, unsigned long *offset) | |||
2016 | /* Don't read in free or bad pages */ | 2186 | /* Don't read in free or bad pages */ |
2017 | if (!si->swap_map[toff]) | 2187 | if (!si->swap_map[toff]) |
2018 | break; | 2188 | break; |
2019 | if (si->swap_map[toff] == SWAP_MAP_BAD) | 2189 | if (swap_count(si->swap_map[toff]) == SWAP_MAP_BAD) |
2020 | break; | 2190 | break; |
2021 | } | 2191 | } |
2022 | /* Count contiguous allocated slots below our target */ | 2192 | /* Count contiguous allocated slots below our target */ |
@@ -2024,7 +2194,7 @@ int valid_swaphandles(swp_entry_t entry, unsigned long *offset) | |||
2024 | /* Don't read in free or bad pages */ | 2194 | /* Don't read in free or bad pages */ |
2025 | if (!si->swap_map[toff]) | 2195 | if (!si->swap_map[toff]) |
2026 | break; | 2196 | break; |
2027 | if (si->swap_map[toff] == SWAP_MAP_BAD) | 2197 | if (swap_count(si->swap_map[toff]) == SWAP_MAP_BAD) |
2028 | break; | 2198 | break; |
2029 | } | 2199 | } |
2030 | spin_unlock(&swap_lock); | 2200 | spin_unlock(&swap_lock); |
diff --git a/mm/truncate.c b/mm/truncate.c index 12e1579f9165..ccc3ecf7cb98 100644 --- a/mm/truncate.c +++ b/mm/truncate.c | |||
@@ -267,8 +267,21 @@ void truncate_inode_pages(struct address_space *mapping, loff_t lstart) | |||
267 | } | 267 | } |
268 | EXPORT_SYMBOL(truncate_inode_pages); | 268 | EXPORT_SYMBOL(truncate_inode_pages); |
269 | 269 | ||
270 | unsigned long __invalidate_mapping_pages(struct address_space *mapping, | 270 | /** |
271 | pgoff_t start, pgoff_t end, bool be_atomic) | 271 | * invalidate_mapping_pages - Invalidate all the unlocked pages of one inode |
272 | * @mapping: the address_space which holds the pages to invalidate | ||
273 | * @start: the offset 'from' which to invalidate | ||
274 | * @end: the offset 'to' which to invalidate (inclusive) | ||
275 | * | ||
276 | * This function only removes the unlocked pages, if you want to | ||
277 | * remove all the pages of one inode, you must call truncate_inode_pages. | ||
278 | * | ||
279 | * invalidate_mapping_pages() will not block on IO activity. It will not | ||
280 | * invalidate pages which are dirty, locked, under writeback or mapped into | ||
281 | * pagetables. | ||
282 | */ | ||
283 | unsigned long invalidate_mapping_pages(struct address_space *mapping, | ||
284 | pgoff_t start, pgoff_t end) | ||
272 | { | 285 | { |
273 | struct pagevec pvec; | 286 | struct pagevec pvec; |
274 | pgoff_t next = start; | 287 | pgoff_t next = start; |
@@ -309,30 +322,10 @@ unlock: | |||
309 | break; | 322 | break; |
310 | } | 323 | } |
311 | pagevec_release(&pvec); | 324 | pagevec_release(&pvec); |
312 | if (likely(!be_atomic)) | 325 | cond_resched(); |
313 | cond_resched(); | ||
314 | } | 326 | } |
315 | return ret; | 327 | return ret; |
316 | } | 328 | } |
317 | |||
318 | /** | ||
319 | * invalidate_mapping_pages - Invalidate all the unlocked pages of one inode | ||
320 | * @mapping: the address_space which holds the pages to invalidate | ||
321 | * @start: the offset 'from' which to invalidate | ||
322 | * @end: the offset 'to' which to invalidate (inclusive) | ||
323 | * | ||
324 | * This function only removes the unlocked pages, if you want to | ||
325 | * remove all the pages of one inode, you must call truncate_inode_pages. | ||
326 | * | ||
327 | * invalidate_mapping_pages() will not block on IO activity. It will not | ||
328 | * invalidate pages which are dirty, locked, under writeback or mapped into | ||
329 | * pagetables. | ||
330 | */ | ||
331 | unsigned long invalidate_mapping_pages(struct address_space *mapping, | ||
332 | pgoff_t start, pgoff_t end) | ||
333 | { | ||
334 | return __invalidate_mapping_pages(mapping, start, end, false); | ||
335 | } | ||
336 | EXPORT_SYMBOL(invalidate_mapping_pages); | 329 | EXPORT_SYMBOL(invalidate_mapping_pages); |
337 | 330 | ||
338 | /* | 331 | /* |
@@ -233,13 +233,21 @@ void arch_pick_mmap_layout(struct mm_struct *mm) | |||
233 | * @pages: array that receives pointers to the pages pinned. | 233 | * @pages: array that receives pointers to the pages pinned. |
234 | * Should be at least nr_pages long. | 234 | * Should be at least nr_pages long. |
235 | * | 235 | * |
236 | * Attempt to pin user pages in memory without taking mm->mmap_sem. | ||
237 | * If not successful, it will fall back to taking the lock and | ||
238 | * calling get_user_pages(). | ||
239 | * | ||
240 | * Returns number of pages pinned. This may be fewer than the number | 236 | * Returns number of pages pinned. This may be fewer than the number |
241 | * requested. If nr_pages is 0 or negative, returns 0. If no pages | 237 | * requested. If nr_pages is 0 or negative, returns 0. If no pages |
242 | * were pinned, returns -errno. | 238 | * were pinned, returns -errno. |
239 | * | ||
240 | * get_user_pages_fast provides equivalent functionality to get_user_pages, | ||
241 | * operating on current and current->mm, with force=0 and vma=NULL. However | ||
242 | * unlike get_user_pages, it must be called without mmap_sem held. | ||
243 | * | ||
244 | * get_user_pages_fast may take mmap_sem and page table locks, so no | ||
245 | * assumptions can be made about lack of locking. get_user_pages_fast is to be | ||
246 | * implemented in a way that is advantageous (vs get_user_pages()) when the | ||
247 | * user memory area is already faulted in and present in ptes. However if the | ||
248 | * pages have to be faulted in, it may turn out to be slightly slower so | ||
249 | * callers need to carefully consider what to use. On many architectures, | ||
250 | * get_user_pages_fast simply falls back to get_user_pages. | ||
243 | */ | 251 | */ |
244 | int __attribute__((weak)) get_user_pages_fast(unsigned long start, | 252 | int __attribute__((weak)) get_user_pages_fast(unsigned long start, |
245 | int nr_pages, int write, struct page **pages) | 253 | int nr_pages, int write, struct page **pages) |
diff --git a/mm/vmscan.c b/mm/vmscan.c index 95c08a8cc2ba..4139aa52b941 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
@@ -470,8 +470,7 @@ static int __remove_mapping(struct address_space *mapping, struct page *page) | |||
470 | swp_entry_t swap = { .val = page_private(page) }; | 470 | swp_entry_t swap = { .val = page_private(page) }; |
471 | __delete_from_swap_cache(page); | 471 | __delete_from_swap_cache(page); |
472 | spin_unlock_irq(&mapping->tree_lock); | 472 | spin_unlock_irq(&mapping->tree_lock); |
473 | mem_cgroup_uncharge_swapcache(page, swap); | 473 | swapcache_free(swap, page); |
474 | swap_free(swap); | ||
475 | } else { | 474 | } else { |
476 | __remove_from_page_cache(page); | 475 | __remove_from_page_cache(page); |
477 | spin_unlock_irq(&mapping->tree_lock); | 476 | spin_unlock_irq(&mapping->tree_lock); |
@@ -514,7 +513,6 @@ int remove_mapping(struct address_space *mapping, struct page *page) | |||
514 | * | 513 | * |
515 | * lru_lock must not be held, interrupts must be enabled. | 514 | * lru_lock must not be held, interrupts must be enabled. |
516 | */ | 515 | */ |
517 | #ifdef CONFIG_UNEVICTABLE_LRU | ||
518 | void putback_lru_page(struct page *page) | 516 | void putback_lru_page(struct page *page) |
519 | { | 517 | { |
520 | int lru; | 518 | int lru; |
@@ -568,20 +566,6 @@ redo: | |||
568 | put_page(page); /* drop ref from isolate */ | 566 | put_page(page); /* drop ref from isolate */ |
569 | } | 567 | } |
570 | 568 | ||
571 | #else /* CONFIG_UNEVICTABLE_LRU */ | ||
572 | |||
573 | void putback_lru_page(struct page *page) | ||
574 | { | ||
575 | int lru; | ||
576 | VM_BUG_ON(PageLRU(page)); | ||
577 | |||
578 | lru = !!TestClearPageActive(page) + page_is_file_cache(page); | ||
579 | lru_cache_add_lru(page, lru); | ||
580 | put_page(page); | ||
581 | } | ||
582 | #endif /* CONFIG_UNEVICTABLE_LRU */ | ||
583 | |||
584 | |||
585 | /* | 569 | /* |
586 | * shrink_page_list() returns the number of reclaimed pages | 570 | * shrink_page_list() returns the number of reclaimed pages |
587 | */ | 571 | */ |
@@ -593,6 +577,7 @@ static unsigned long shrink_page_list(struct list_head *page_list, | |||
593 | struct pagevec freed_pvec; | 577 | struct pagevec freed_pvec; |
594 | int pgactivate = 0; | 578 | int pgactivate = 0; |
595 | unsigned long nr_reclaimed = 0; | 579 | unsigned long nr_reclaimed = 0; |
580 | unsigned long vm_flags; | ||
596 | 581 | ||
597 | cond_resched(); | 582 | cond_resched(); |
598 | 583 | ||
@@ -643,7 +628,8 @@ static unsigned long shrink_page_list(struct list_head *page_list, | |||
643 | goto keep_locked; | 628 | goto keep_locked; |
644 | } | 629 | } |
645 | 630 | ||
646 | referenced = page_referenced(page, 1, sc->mem_cgroup); | 631 | referenced = page_referenced(page, 1, |
632 | sc->mem_cgroup, &vm_flags); | ||
647 | /* In active use or really unfreeable? Activate it. */ | 633 | /* In active use or really unfreeable? Activate it. */ |
648 | if (sc->order <= PAGE_ALLOC_COSTLY_ORDER && | 634 | if (sc->order <= PAGE_ALLOC_COSTLY_ORDER && |
649 | referenced && page_mapping_inuse(page)) | 635 | referenced && page_mapping_inuse(page)) |
@@ -943,18 +929,10 @@ static unsigned long isolate_lru_pages(unsigned long nr_to_scan, | |||
943 | /* Check that we have not crossed a zone boundary. */ | 929 | /* Check that we have not crossed a zone boundary. */ |
944 | if (unlikely(page_zone_id(cursor_page) != zone_id)) | 930 | if (unlikely(page_zone_id(cursor_page) != zone_id)) |
945 | continue; | 931 | continue; |
946 | switch (__isolate_lru_page(cursor_page, mode, file)) { | 932 | if (__isolate_lru_page(cursor_page, mode, file) == 0) { |
947 | case 0: | ||
948 | list_move(&cursor_page->lru, dst); | 933 | list_move(&cursor_page->lru, dst); |
949 | nr_taken++; | 934 | nr_taken++; |
950 | scan++; | 935 | scan++; |
951 | break; | ||
952 | |||
953 | case -EBUSY: | ||
954 | /* else it is being freed elsewhere */ | ||
955 | list_move(&cursor_page->lru, src); | ||
956 | default: | ||
957 | break; /* ! on LRU or wrong list */ | ||
958 | } | 936 | } |
959 | } | 937 | } |
960 | } | 938 | } |
@@ -1061,6 +1039,19 @@ static unsigned long shrink_inactive_list(unsigned long max_scan, | |||
1061 | unsigned long nr_scanned = 0; | 1039 | unsigned long nr_scanned = 0; |
1062 | unsigned long nr_reclaimed = 0; | 1040 | unsigned long nr_reclaimed = 0; |
1063 | struct zone_reclaim_stat *reclaim_stat = get_reclaim_stat(zone, sc); | 1041 | struct zone_reclaim_stat *reclaim_stat = get_reclaim_stat(zone, sc); |
1042 | int lumpy_reclaim = 0; | ||
1043 | |||
1044 | /* | ||
1045 | * If we need a large contiguous chunk of memory, or have | ||
1046 | * trouble getting a small set of contiguous pages, we | ||
1047 | * will reclaim both active and inactive pages. | ||
1048 | * | ||
1049 | * We use the same threshold as pageout congestion_wait below. | ||
1050 | */ | ||
1051 | if (sc->order > PAGE_ALLOC_COSTLY_ORDER) | ||
1052 | lumpy_reclaim = 1; | ||
1053 | else if (sc->order && priority < DEF_PRIORITY - 2) | ||
1054 | lumpy_reclaim = 1; | ||
1064 | 1055 | ||
1065 | pagevec_init(&pvec, 1); | 1056 | pagevec_init(&pvec, 1); |
1066 | 1057 | ||
@@ -1073,19 +1064,7 @@ static unsigned long shrink_inactive_list(unsigned long max_scan, | |||
1073 | unsigned long nr_freed; | 1064 | unsigned long nr_freed; |
1074 | unsigned long nr_active; | 1065 | unsigned long nr_active; |
1075 | unsigned int count[NR_LRU_LISTS] = { 0, }; | 1066 | unsigned int count[NR_LRU_LISTS] = { 0, }; |
1076 | int mode = ISOLATE_INACTIVE; | 1067 | int mode = lumpy_reclaim ? ISOLATE_BOTH : ISOLATE_INACTIVE; |
1077 | |||
1078 | /* | ||
1079 | * If we need a large contiguous chunk of memory, or have | ||
1080 | * trouble getting a small set of contiguous pages, we | ||
1081 | * will reclaim both active and inactive pages. | ||
1082 | * | ||
1083 | * We use the same threshold as pageout congestion_wait below. | ||
1084 | */ | ||
1085 | if (sc->order > PAGE_ALLOC_COSTLY_ORDER) | ||
1086 | mode = ISOLATE_BOTH; | ||
1087 | else if (sc->order && priority < DEF_PRIORITY - 2) | ||
1088 | mode = ISOLATE_BOTH; | ||
1089 | 1068 | ||
1090 | nr_taken = sc->isolate_pages(sc->swap_cluster_max, | 1069 | nr_taken = sc->isolate_pages(sc->swap_cluster_max, |
1091 | &page_list, &nr_scan, sc->order, mode, | 1070 | &page_list, &nr_scan, sc->order, mode, |
@@ -1122,7 +1101,7 @@ static unsigned long shrink_inactive_list(unsigned long max_scan, | |||
1122 | * but that should be acceptable to the caller | 1101 | * but that should be acceptable to the caller |
1123 | */ | 1102 | */ |
1124 | if (nr_freed < nr_taken && !current_is_kswapd() && | 1103 | if (nr_freed < nr_taken && !current_is_kswapd() && |
1125 | sc->order > PAGE_ALLOC_COSTLY_ORDER) { | 1104 | lumpy_reclaim) { |
1126 | congestion_wait(WRITE, HZ/10); | 1105 | congestion_wait(WRITE, HZ/10); |
1127 | 1106 | ||
1128 | /* | 1107 | /* |
@@ -1217,18 +1196,54 @@ static inline void note_zone_scanning_priority(struct zone *zone, int priority) | |||
1217 | * But we had to alter page->flags anyway. | 1196 | * But we had to alter page->flags anyway. |
1218 | */ | 1197 | */ |
1219 | 1198 | ||
1199 | static void move_active_pages_to_lru(struct zone *zone, | ||
1200 | struct list_head *list, | ||
1201 | enum lru_list lru) | ||
1202 | { | ||
1203 | unsigned long pgmoved = 0; | ||
1204 | struct pagevec pvec; | ||
1205 | struct page *page; | ||
1206 | |||
1207 | pagevec_init(&pvec, 1); | ||
1208 | |||
1209 | while (!list_empty(list)) { | ||
1210 | page = lru_to_page(list); | ||
1211 | prefetchw_prev_lru_page(page, list, flags); | ||
1212 | |||
1213 | VM_BUG_ON(PageLRU(page)); | ||
1214 | SetPageLRU(page); | ||
1215 | |||
1216 | VM_BUG_ON(!PageActive(page)); | ||
1217 | if (!is_active_lru(lru)) | ||
1218 | ClearPageActive(page); /* we are de-activating */ | ||
1219 | |||
1220 | list_move(&page->lru, &zone->lru[lru].list); | ||
1221 | mem_cgroup_add_lru_list(page, lru); | ||
1222 | pgmoved++; | ||
1223 | |||
1224 | if (!pagevec_add(&pvec, page) || list_empty(list)) { | ||
1225 | spin_unlock_irq(&zone->lru_lock); | ||
1226 | if (buffer_heads_over_limit) | ||
1227 | pagevec_strip(&pvec); | ||
1228 | __pagevec_release(&pvec); | ||
1229 | spin_lock_irq(&zone->lru_lock); | ||
1230 | } | ||
1231 | } | ||
1232 | __mod_zone_page_state(zone, NR_LRU_BASE + lru, pgmoved); | ||
1233 | if (!is_active_lru(lru)) | ||
1234 | __count_vm_events(PGDEACTIVATE, pgmoved); | ||
1235 | } | ||
1220 | 1236 | ||
1221 | static void shrink_active_list(unsigned long nr_pages, struct zone *zone, | 1237 | static void shrink_active_list(unsigned long nr_pages, struct zone *zone, |
1222 | struct scan_control *sc, int priority, int file) | 1238 | struct scan_control *sc, int priority, int file) |
1223 | { | 1239 | { |
1224 | unsigned long pgmoved; | 1240 | unsigned long pgmoved; |
1225 | int pgdeactivate = 0; | ||
1226 | unsigned long pgscanned; | 1241 | unsigned long pgscanned; |
1242 | unsigned long vm_flags; | ||
1227 | LIST_HEAD(l_hold); /* The pages which were snipped off */ | 1243 | LIST_HEAD(l_hold); /* The pages which were snipped off */ |
1244 | LIST_HEAD(l_active); | ||
1228 | LIST_HEAD(l_inactive); | 1245 | LIST_HEAD(l_inactive); |
1229 | struct page *page; | 1246 | struct page *page; |
1230 | struct pagevec pvec; | ||
1231 | enum lru_list lru; | ||
1232 | struct zone_reclaim_stat *reclaim_stat = get_reclaim_stat(zone, sc); | 1247 | struct zone_reclaim_stat *reclaim_stat = get_reclaim_stat(zone, sc); |
1233 | 1248 | ||
1234 | lru_add_drain(); | 1249 | lru_add_drain(); |
@@ -1245,13 +1260,14 @@ static void shrink_active_list(unsigned long nr_pages, struct zone *zone, | |||
1245 | } | 1260 | } |
1246 | reclaim_stat->recent_scanned[!!file] += pgmoved; | 1261 | reclaim_stat->recent_scanned[!!file] += pgmoved; |
1247 | 1262 | ||
1263 | __count_zone_vm_events(PGREFILL, zone, pgscanned); | ||
1248 | if (file) | 1264 | if (file) |
1249 | __mod_zone_page_state(zone, NR_ACTIVE_FILE, -pgmoved); | 1265 | __mod_zone_page_state(zone, NR_ACTIVE_FILE, -pgmoved); |
1250 | else | 1266 | else |
1251 | __mod_zone_page_state(zone, NR_ACTIVE_ANON, -pgmoved); | 1267 | __mod_zone_page_state(zone, NR_ACTIVE_ANON, -pgmoved); |
1252 | spin_unlock_irq(&zone->lru_lock); | 1268 | spin_unlock_irq(&zone->lru_lock); |
1253 | 1269 | ||
1254 | pgmoved = 0; | 1270 | pgmoved = 0; /* count referenced (mapping) mapped pages */ |
1255 | while (!list_empty(&l_hold)) { | 1271 | while (!list_empty(&l_hold)) { |
1256 | cond_resched(); | 1272 | cond_resched(); |
1257 | page = lru_to_page(&l_hold); | 1273 | page = lru_to_page(&l_hold); |
@@ -1264,58 +1280,44 @@ static void shrink_active_list(unsigned long nr_pages, struct zone *zone, | |||
1264 | 1280 | ||
1265 | /* page_referenced clears PageReferenced */ | 1281 | /* page_referenced clears PageReferenced */ |
1266 | if (page_mapping_inuse(page) && | 1282 | if (page_mapping_inuse(page) && |
1267 | page_referenced(page, 0, sc->mem_cgroup)) | 1283 | page_referenced(page, 0, sc->mem_cgroup, &vm_flags)) { |
1268 | pgmoved++; | 1284 | pgmoved++; |
1285 | /* | ||
1286 | * Identify referenced, file-backed active pages and | ||
1287 | * give them one more trip around the active list. So | ||
1288 | * that executable code get better chances to stay in | ||
1289 | * memory under moderate memory pressure. Anon pages | ||
1290 | * are not likely to be evicted by use-once streaming | ||
1291 | * IO, plus JVM can create lots of anon VM_EXEC pages, | ||
1292 | * so we ignore them here. | ||
1293 | */ | ||
1294 | if ((vm_flags & VM_EXEC) && !PageAnon(page)) { | ||
1295 | list_add(&page->lru, &l_active); | ||
1296 | continue; | ||
1297 | } | ||
1298 | } | ||
1269 | 1299 | ||
1270 | list_add(&page->lru, &l_inactive); | 1300 | list_add(&page->lru, &l_inactive); |
1271 | } | 1301 | } |
1272 | 1302 | ||
1273 | /* | 1303 | /* |
1274 | * Move the pages to the [file or anon] inactive list. | 1304 | * Move pages back to the lru list. |
1275 | */ | 1305 | */ |
1276 | pagevec_init(&pvec, 1); | ||
1277 | lru = LRU_BASE + file * LRU_FILE; | ||
1278 | |||
1279 | spin_lock_irq(&zone->lru_lock); | 1306 | spin_lock_irq(&zone->lru_lock); |
1280 | /* | 1307 | /* |
1281 | * Count referenced pages from currently used mappings as | 1308 | * Count referenced pages from currently used mappings as rotated, |
1282 | * rotated, even though they are moved to the inactive list. | 1309 | * even though only some of them are actually re-activated. This |
1283 | * This helps balance scan pressure between file and anonymous | 1310 | * helps balance scan pressure between file and anonymous pages in |
1284 | * pages in get_scan_ratio. | 1311 | * get_scan_ratio. |
1285 | */ | 1312 | */ |
1286 | reclaim_stat->recent_rotated[!!file] += pgmoved; | 1313 | reclaim_stat->recent_rotated[!!file] += pgmoved; |
1287 | 1314 | ||
1288 | pgmoved = 0; | 1315 | move_active_pages_to_lru(zone, &l_active, |
1289 | while (!list_empty(&l_inactive)) { | 1316 | LRU_ACTIVE + file * LRU_FILE); |
1290 | page = lru_to_page(&l_inactive); | 1317 | move_active_pages_to_lru(zone, &l_inactive, |
1291 | prefetchw_prev_lru_page(page, &l_inactive, flags); | 1318 | LRU_BASE + file * LRU_FILE); |
1292 | VM_BUG_ON(PageLRU(page)); | ||
1293 | SetPageLRU(page); | ||
1294 | VM_BUG_ON(!PageActive(page)); | ||
1295 | ClearPageActive(page); | ||
1296 | 1319 | ||
1297 | list_move(&page->lru, &zone->lru[lru].list); | ||
1298 | mem_cgroup_add_lru_list(page, lru); | ||
1299 | pgmoved++; | ||
1300 | if (!pagevec_add(&pvec, page)) { | ||
1301 | __mod_zone_page_state(zone, NR_LRU_BASE + lru, pgmoved); | ||
1302 | spin_unlock_irq(&zone->lru_lock); | ||
1303 | pgdeactivate += pgmoved; | ||
1304 | pgmoved = 0; | ||
1305 | if (buffer_heads_over_limit) | ||
1306 | pagevec_strip(&pvec); | ||
1307 | __pagevec_release(&pvec); | ||
1308 | spin_lock_irq(&zone->lru_lock); | ||
1309 | } | ||
1310 | } | ||
1311 | __mod_zone_page_state(zone, NR_LRU_BASE + lru, pgmoved); | ||
1312 | pgdeactivate += pgmoved; | ||
1313 | __count_zone_vm_events(PGREFILL, zone, pgscanned); | ||
1314 | __count_vm_events(PGDEACTIVATE, pgdeactivate); | ||
1315 | spin_unlock_irq(&zone->lru_lock); | 1320 | spin_unlock_irq(&zone->lru_lock); |
1316 | if (buffer_heads_over_limit) | ||
1317 | pagevec_strip(&pvec); | ||
1318 | pagevec_release(&pvec); | ||
1319 | } | 1321 | } |
1320 | 1322 | ||
1321 | static int inactive_anon_is_low_global(struct zone *zone) | 1323 | static int inactive_anon_is_low_global(struct zone *zone) |
@@ -1350,12 +1352,48 @@ static int inactive_anon_is_low(struct zone *zone, struct scan_control *sc) | |||
1350 | return low; | 1352 | return low; |
1351 | } | 1353 | } |
1352 | 1354 | ||
1355 | static int inactive_file_is_low_global(struct zone *zone) | ||
1356 | { | ||
1357 | unsigned long active, inactive; | ||
1358 | |||
1359 | active = zone_page_state(zone, NR_ACTIVE_FILE); | ||
1360 | inactive = zone_page_state(zone, NR_INACTIVE_FILE); | ||
1361 | |||
1362 | return (active > inactive); | ||
1363 | } | ||
1364 | |||
1365 | /** | ||
1366 | * inactive_file_is_low - check if file pages need to be deactivated | ||
1367 | * @zone: zone to check | ||
1368 | * @sc: scan control of this context | ||
1369 | * | ||
1370 | * When the system is doing streaming IO, memory pressure here | ||
1371 | * ensures that active file pages get deactivated, until more | ||
1372 | * than half of the file pages are on the inactive list. | ||
1373 | * | ||
1374 | * Once we get to that situation, protect the system's working | ||
1375 | * set from being evicted by disabling active file page aging. | ||
1376 | * | ||
1377 | * This uses a different ratio than the anonymous pages, because | ||
1378 | * the page cache uses a use-once replacement algorithm. | ||
1379 | */ | ||
1380 | static int inactive_file_is_low(struct zone *zone, struct scan_control *sc) | ||
1381 | { | ||
1382 | int low; | ||
1383 | |||
1384 | if (scanning_global_lru(sc)) | ||
1385 | low = inactive_file_is_low_global(zone); | ||
1386 | else | ||
1387 | low = mem_cgroup_inactive_file_is_low(sc->mem_cgroup); | ||
1388 | return low; | ||
1389 | } | ||
1390 | |||
1353 | static unsigned long shrink_list(enum lru_list lru, unsigned long nr_to_scan, | 1391 | static unsigned long shrink_list(enum lru_list lru, unsigned long nr_to_scan, |
1354 | struct zone *zone, struct scan_control *sc, int priority) | 1392 | struct zone *zone, struct scan_control *sc, int priority) |
1355 | { | 1393 | { |
1356 | int file = is_file_lru(lru); | 1394 | int file = is_file_lru(lru); |
1357 | 1395 | ||
1358 | if (lru == LRU_ACTIVE_FILE) { | 1396 | if (lru == LRU_ACTIVE_FILE && inactive_file_is_low(zone, sc)) { |
1359 | shrink_active_list(nr_to_scan, zone, sc, priority, file); | 1397 | shrink_active_list(nr_to_scan, zone, sc, priority, file); |
1360 | return 0; | 1398 | return 0; |
1361 | } | 1399 | } |
@@ -1384,13 +1422,6 @@ static void get_scan_ratio(struct zone *zone, struct scan_control *sc, | |||
1384 | unsigned long ap, fp; | 1422 | unsigned long ap, fp; |
1385 | struct zone_reclaim_stat *reclaim_stat = get_reclaim_stat(zone, sc); | 1423 | struct zone_reclaim_stat *reclaim_stat = get_reclaim_stat(zone, sc); |
1386 | 1424 | ||
1387 | /* If we have no swap space, do not bother scanning anon pages. */ | ||
1388 | if (!sc->may_swap || (nr_swap_pages <= 0)) { | ||
1389 | percent[0] = 0; | ||
1390 | percent[1] = 100; | ||
1391 | return; | ||
1392 | } | ||
1393 | |||
1394 | anon = zone_nr_pages(zone, sc, LRU_ACTIVE_ANON) + | 1425 | anon = zone_nr_pages(zone, sc, LRU_ACTIVE_ANON) + |
1395 | zone_nr_pages(zone, sc, LRU_INACTIVE_ANON); | 1426 | zone_nr_pages(zone, sc, LRU_INACTIVE_ANON); |
1396 | file = zone_nr_pages(zone, sc, LRU_ACTIVE_FILE) + | 1427 | file = zone_nr_pages(zone, sc, LRU_ACTIVE_FILE) + |
@@ -1400,7 +1431,7 @@ static void get_scan_ratio(struct zone *zone, struct scan_control *sc, | |||
1400 | free = zone_page_state(zone, NR_FREE_PAGES); | 1431 | free = zone_page_state(zone, NR_FREE_PAGES); |
1401 | /* If we have very few page cache pages, | 1432 | /* If we have very few page cache pages, |
1402 | force-scan anon pages. */ | 1433 | force-scan anon pages. */ |
1403 | if (unlikely(file + free <= zone->pages_high)) { | 1434 | if (unlikely(file + free <= high_wmark_pages(zone))) { |
1404 | percent[0] = 100; | 1435 | percent[0] = 100; |
1405 | percent[1] = 0; | 1436 | percent[1] = 0; |
1406 | return; | 1437 | return; |
@@ -1455,6 +1486,26 @@ static void get_scan_ratio(struct zone *zone, struct scan_control *sc, | |||
1455 | percent[1] = 100 - percent[0]; | 1486 | percent[1] = 100 - percent[0]; |
1456 | } | 1487 | } |
1457 | 1488 | ||
1489 | /* | ||
1490 | * Smallish @nr_to_scan's are deposited in @nr_saved_scan, | ||
1491 | * until we collected @swap_cluster_max pages to scan. | ||
1492 | */ | ||
1493 | static unsigned long nr_scan_try_batch(unsigned long nr_to_scan, | ||
1494 | unsigned long *nr_saved_scan, | ||
1495 | unsigned long swap_cluster_max) | ||
1496 | { | ||
1497 | unsigned long nr; | ||
1498 | |||
1499 | *nr_saved_scan += nr_to_scan; | ||
1500 | nr = *nr_saved_scan; | ||
1501 | |||
1502 | if (nr >= swap_cluster_max) | ||
1503 | *nr_saved_scan = 0; | ||
1504 | else | ||
1505 | nr = 0; | ||
1506 | |||
1507 | return nr; | ||
1508 | } | ||
1458 | 1509 | ||
1459 | /* | 1510 | /* |
1460 | * This is a basic per-zone page freer. Used by both kswapd and direct reclaim. | 1511 | * This is a basic per-zone page freer. Used by both kswapd and direct reclaim. |
@@ -1468,26 +1519,30 @@ static void shrink_zone(int priority, struct zone *zone, | |||
1468 | enum lru_list l; | 1519 | enum lru_list l; |
1469 | unsigned long nr_reclaimed = sc->nr_reclaimed; | 1520 | unsigned long nr_reclaimed = sc->nr_reclaimed; |
1470 | unsigned long swap_cluster_max = sc->swap_cluster_max; | 1521 | unsigned long swap_cluster_max = sc->swap_cluster_max; |
1522 | int noswap = 0; | ||
1471 | 1523 | ||
1472 | get_scan_ratio(zone, sc, percent); | 1524 | /* If we have no swap space, do not bother scanning anon pages. */ |
1525 | if (!sc->may_swap || (nr_swap_pages <= 0)) { | ||
1526 | noswap = 1; | ||
1527 | percent[0] = 0; | ||
1528 | percent[1] = 100; | ||
1529 | } else | ||
1530 | get_scan_ratio(zone, sc, percent); | ||
1473 | 1531 | ||
1474 | for_each_evictable_lru(l) { | 1532 | for_each_evictable_lru(l) { |
1475 | int file = is_file_lru(l); | 1533 | int file = is_file_lru(l); |
1476 | unsigned long scan; | 1534 | unsigned long scan; |
1477 | 1535 | ||
1478 | scan = zone_nr_pages(zone, sc, l); | 1536 | scan = zone_nr_pages(zone, sc, l); |
1479 | if (priority) { | 1537 | if (priority || noswap) { |
1480 | scan >>= priority; | 1538 | scan >>= priority; |
1481 | scan = (scan * percent[file]) / 100; | 1539 | scan = (scan * percent[file]) / 100; |
1482 | } | 1540 | } |
1483 | if (scanning_global_lru(sc)) { | 1541 | if (scanning_global_lru(sc)) |
1484 | zone->lru[l].nr_scan += scan; | 1542 | nr[l] = nr_scan_try_batch(scan, |
1485 | nr[l] = zone->lru[l].nr_scan; | 1543 | &zone->lru[l].nr_saved_scan, |
1486 | if (nr[l] >= swap_cluster_max) | 1544 | swap_cluster_max); |
1487 | zone->lru[l].nr_scan = 0; | 1545 | else |
1488 | else | ||
1489 | nr[l] = 0; | ||
1490 | } else | ||
1491 | nr[l] = scan; | 1546 | nr[l] = scan; |
1492 | } | 1547 | } |
1493 | 1548 | ||
@@ -1521,7 +1576,7 @@ static void shrink_zone(int priority, struct zone *zone, | |||
1521 | * Even if we did not try to evict anon pages at all, we want to | 1576 | * Even if we did not try to evict anon pages at all, we want to |
1522 | * rebalance the anon lru active/inactive ratio. | 1577 | * rebalance the anon lru active/inactive ratio. |
1523 | */ | 1578 | */ |
1524 | if (inactive_anon_is_low(zone, sc)) | 1579 | if (inactive_anon_is_low(zone, sc) && nr_swap_pages > 0) |
1525 | shrink_active_list(SWAP_CLUSTER_MAX, zone, sc, priority, 0); | 1580 | shrink_active_list(SWAP_CLUSTER_MAX, zone, sc, priority, 0); |
1526 | 1581 | ||
1527 | throttle_vm_writeout(sc->gfp_mask); | 1582 | throttle_vm_writeout(sc->gfp_mask); |
@@ -1532,11 +1587,13 @@ static void shrink_zone(int priority, struct zone *zone, | |||
1532 | * try to reclaim pages from zones which will satisfy the caller's allocation | 1587 | * try to reclaim pages from zones which will satisfy the caller's allocation |
1533 | * request. | 1588 | * request. |
1534 | * | 1589 | * |
1535 | * We reclaim from a zone even if that zone is over pages_high. Because: | 1590 | * We reclaim from a zone even if that zone is over high_wmark_pages(zone). |
1591 | * Because: | ||
1536 | * a) The caller may be trying to free *extra* pages to satisfy a higher-order | 1592 | * a) The caller may be trying to free *extra* pages to satisfy a higher-order |
1537 | * allocation or | 1593 | * allocation or |
1538 | * b) The zones may be over pages_high but they must go *over* pages_high to | 1594 | * b) The target zone may be at high_wmark_pages(zone) but the lower zones |
1539 | * satisfy the `incremental min' zone defense algorithm. | 1595 | * must go *over* high_wmark_pages(zone) to satisfy the `incremental min' |
1596 | * zone defense algorithm. | ||
1540 | * | 1597 | * |
1541 | * If a zone is deemed to be full of pinned pages then just give it a light | 1598 | * If a zone is deemed to be full of pinned pages then just give it a light |
1542 | * scan then give up on it. | 1599 | * scan then give up on it. |
@@ -1742,7 +1799,7 @@ unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *mem_cont, | |||
1742 | 1799 | ||
1743 | /* | 1800 | /* |
1744 | * For kswapd, balance_pgdat() will work across all this node's zones until | 1801 | * For kswapd, balance_pgdat() will work across all this node's zones until |
1745 | * they are all at pages_high. | 1802 | * they are all at high_wmark_pages(zone). |
1746 | * | 1803 | * |
1747 | * Returns the number of pages which were actually freed. | 1804 | * Returns the number of pages which were actually freed. |
1748 | * | 1805 | * |
@@ -1755,11 +1812,11 @@ unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *mem_cont, | |||
1755 | * the zone for when the problem goes away. | 1812 | * the zone for when the problem goes away. |
1756 | * | 1813 | * |
1757 | * kswapd scans the zones in the highmem->normal->dma direction. It skips | 1814 | * kswapd scans the zones in the highmem->normal->dma direction. It skips |
1758 | * zones which have free_pages > pages_high, but once a zone is found to have | 1815 | * zones which have free_pages > high_wmark_pages(zone), but once a zone is |
1759 | * free_pages <= pages_high, we scan that zone and the lower zones regardless | 1816 | * found to have free_pages <= high_wmark_pages(zone), we scan that zone and the |
1760 | * of the number of free pages in the lower zones. This interoperates with | 1817 | * lower zones regardless of the number of free pages in the lower zones. This |
1761 | * the page allocator fallback scheme to ensure that aging of pages is balanced | 1818 | * interoperates with the page allocator fallback scheme to ensure that aging |
1762 | * across the zones. | 1819 | * of pages is balanced across the zones. |
1763 | */ | 1820 | */ |
1764 | static unsigned long balance_pgdat(pg_data_t *pgdat, int order) | 1821 | static unsigned long balance_pgdat(pg_data_t *pgdat, int order) |
1765 | { | 1822 | { |
@@ -1780,7 +1837,8 @@ static unsigned long balance_pgdat(pg_data_t *pgdat, int order) | |||
1780 | }; | 1837 | }; |
1781 | /* | 1838 | /* |
1782 | * temp_priority is used to remember the scanning priority at which | 1839 | * temp_priority is used to remember the scanning priority at which |
1783 | * this zone was successfully refilled to free_pages == pages_high. | 1840 | * this zone was successfully refilled to |
1841 | * free_pages == high_wmark_pages(zone). | ||
1784 | */ | 1842 | */ |
1785 | int temp_priority[MAX_NR_ZONES]; | 1843 | int temp_priority[MAX_NR_ZONES]; |
1786 | 1844 | ||
@@ -1825,8 +1883,8 @@ loop_again: | |||
1825 | shrink_active_list(SWAP_CLUSTER_MAX, zone, | 1883 | shrink_active_list(SWAP_CLUSTER_MAX, zone, |
1826 | &sc, priority, 0); | 1884 | &sc, priority, 0); |
1827 | 1885 | ||
1828 | if (!zone_watermark_ok(zone, order, zone->pages_high, | 1886 | if (!zone_watermark_ok(zone, order, |
1829 | 0, 0)) { | 1887 | high_wmark_pages(zone), 0, 0)) { |
1830 | end_zone = i; | 1888 | end_zone = i; |
1831 | break; | 1889 | break; |
1832 | } | 1890 | } |
@@ -1860,8 +1918,8 @@ loop_again: | |||
1860 | priority != DEF_PRIORITY) | 1918 | priority != DEF_PRIORITY) |
1861 | continue; | 1919 | continue; |
1862 | 1920 | ||
1863 | if (!zone_watermark_ok(zone, order, zone->pages_high, | 1921 | if (!zone_watermark_ok(zone, order, |
1864 | end_zone, 0)) | 1922 | high_wmark_pages(zone), end_zone, 0)) |
1865 | all_zones_ok = 0; | 1923 | all_zones_ok = 0; |
1866 | temp_priority[i] = priority; | 1924 | temp_priority[i] = priority; |
1867 | sc.nr_scanned = 0; | 1925 | sc.nr_scanned = 0; |
@@ -1870,8 +1928,8 @@ loop_again: | |||
1870 | * We put equal pressure on every zone, unless one | 1928 | * We put equal pressure on every zone, unless one |
1871 | * zone has way too many pages free already. | 1929 | * zone has way too many pages free already. |
1872 | */ | 1930 | */ |
1873 | if (!zone_watermark_ok(zone, order, 8*zone->pages_high, | 1931 | if (!zone_watermark_ok(zone, order, |
1874 | end_zone, 0)) | 1932 | 8*high_wmark_pages(zone), end_zone, 0)) |
1875 | shrink_zone(priority, zone, &sc); | 1933 | shrink_zone(priority, zone, &sc); |
1876 | reclaim_state->reclaimed_slab = 0; | 1934 | reclaim_state->reclaimed_slab = 0; |
1877 | nr_slab = shrink_slab(sc.nr_scanned, GFP_KERNEL, | 1935 | nr_slab = shrink_slab(sc.nr_scanned, GFP_KERNEL, |
@@ -2037,7 +2095,7 @@ void wakeup_kswapd(struct zone *zone, int order) | |||
2037 | return; | 2095 | return; |
2038 | 2096 | ||
2039 | pgdat = zone->zone_pgdat; | 2097 | pgdat = zone->zone_pgdat; |
2040 | if (zone_watermark_ok(zone, order, zone->pages_low, 0, 0)) | 2098 | if (zone_watermark_ok(zone, order, low_wmark_pages(zone), 0, 0)) |
2041 | return; | 2099 | return; |
2042 | if (pgdat->kswapd_max_order < order) | 2100 | if (pgdat->kswapd_max_order < order) |
2043 | pgdat->kswapd_max_order = order; | 2101 | pgdat->kswapd_max_order = order; |
@@ -2084,11 +2142,11 @@ static void shrink_all_zones(unsigned long nr_pages, int prio, | |||
2084 | l == LRU_ACTIVE_FILE)) | 2142 | l == LRU_ACTIVE_FILE)) |
2085 | continue; | 2143 | continue; |
2086 | 2144 | ||
2087 | zone->lru[l].nr_scan += (lru_pages >> prio) + 1; | 2145 | zone->lru[l].nr_saved_scan += (lru_pages >> prio) + 1; |
2088 | if (zone->lru[l].nr_scan >= nr_pages || pass > 3) { | 2146 | if (zone->lru[l].nr_saved_scan >= nr_pages || pass > 3) { |
2089 | unsigned long nr_to_scan; | 2147 | unsigned long nr_to_scan; |
2090 | 2148 | ||
2091 | zone->lru[l].nr_scan = 0; | 2149 | zone->lru[l].nr_saved_scan = 0; |
2092 | nr_to_scan = min(nr_pages, lru_pages); | 2150 | nr_to_scan = min(nr_pages, lru_pages); |
2093 | nr_reclaimed += shrink_list(l, nr_to_scan, zone, | 2151 | nr_reclaimed += shrink_list(l, nr_to_scan, zone, |
2094 | sc, prio); | 2152 | sc, prio); |
@@ -2290,6 +2348,48 @@ int sysctl_min_unmapped_ratio = 1; | |||
2290 | */ | 2348 | */ |
2291 | int sysctl_min_slab_ratio = 5; | 2349 | int sysctl_min_slab_ratio = 5; |
2292 | 2350 | ||
2351 | static inline unsigned long zone_unmapped_file_pages(struct zone *zone) | ||
2352 | { | ||
2353 | unsigned long file_mapped = zone_page_state(zone, NR_FILE_MAPPED); | ||
2354 | unsigned long file_lru = zone_page_state(zone, NR_INACTIVE_FILE) + | ||
2355 | zone_page_state(zone, NR_ACTIVE_FILE); | ||
2356 | |||
2357 | /* | ||
2358 | * It's possible for there to be more file mapped pages than | ||
2359 | * accounted for by the pages on the file LRU lists because | ||
2360 | * tmpfs pages accounted for as ANON can also be FILE_MAPPED | ||
2361 | */ | ||
2362 | return (file_lru > file_mapped) ? (file_lru - file_mapped) : 0; | ||
2363 | } | ||
2364 | |||
2365 | /* Work out how many page cache pages we can reclaim in this reclaim_mode */ | ||
2366 | static long zone_pagecache_reclaimable(struct zone *zone) | ||
2367 | { | ||
2368 | long nr_pagecache_reclaimable; | ||
2369 | long delta = 0; | ||
2370 | |||
2371 | /* | ||
2372 | * If RECLAIM_SWAP is set, then all file pages are considered | ||
2373 | * potentially reclaimable. Otherwise, we have to worry about | ||
2374 | * pages like swapcache and zone_unmapped_file_pages() provides | ||
2375 | * a better estimate | ||
2376 | */ | ||
2377 | if (zone_reclaim_mode & RECLAIM_SWAP) | ||
2378 | nr_pagecache_reclaimable = zone_page_state(zone, NR_FILE_PAGES); | ||
2379 | else | ||
2380 | nr_pagecache_reclaimable = zone_unmapped_file_pages(zone); | ||
2381 | |||
2382 | /* If we can't clean pages, remove dirty pages from consideration */ | ||
2383 | if (!(zone_reclaim_mode & RECLAIM_WRITE)) | ||
2384 | delta += zone_page_state(zone, NR_FILE_DIRTY); | ||
2385 | |||
2386 | /* Watch for any possible underflows due to delta */ | ||
2387 | if (unlikely(delta > nr_pagecache_reclaimable)) | ||
2388 | delta = nr_pagecache_reclaimable; | ||
2389 | |||
2390 | return nr_pagecache_reclaimable - delta; | ||
2391 | } | ||
2392 | |||
2293 | /* | 2393 | /* |
2294 | * Try to free up some pages from this zone through reclaim. | 2394 | * Try to free up some pages from this zone through reclaim. |
2295 | */ | 2395 | */ |
@@ -2324,9 +2424,7 @@ static int __zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order) | |||
2324 | reclaim_state.reclaimed_slab = 0; | 2424 | reclaim_state.reclaimed_slab = 0; |
2325 | p->reclaim_state = &reclaim_state; | 2425 | p->reclaim_state = &reclaim_state; |
2326 | 2426 | ||
2327 | if (zone_page_state(zone, NR_FILE_PAGES) - | 2427 | if (zone_pagecache_reclaimable(zone) > zone->min_unmapped_pages) { |
2328 | zone_page_state(zone, NR_FILE_MAPPED) > | ||
2329 | zone->min_unmapped_pages) { | ||
2330 | /* | 2428 | /* |
2331 | * Free memory by calling shrink zone with increasing | 2429 | * Free memory by calling shrink zone with increasing |
2332 | * priorities until we have enough memory freed. | 2430 | * priorities until we have enough memory freed. |
@@ -2384,20 +2482,18 @@ int zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order) | |||
2384 | * if less than a specified percentage of the zone is used by | 2482 | * if less than a specified percentage of the zone is used by |
2385 | * unmapped file backed pages. | 2483 | * unmapped file backed pages. |
2386 | */ | 2484 | */ |
2387 | if (zone_page_state(zone, NR_FILE_PAGES) - | 2485 | if (zone_pagecache_reclaimable(zone) <= zone->min_unmapped_pages && |
2388 | zone_page_state(zone, NR_FILE_MAPPED) <= zone->min_unmapped_pages | 2486 | zone_page_state(zone, NR_SLAB_RECLAIMABLE) <= zone->min_slab_pages) |
2389 | && zone_page_state(zone, NR_SLAB_RECLAIMABLE) | 2487 | return ZONE_RECLAIM_FULL; |
2390 | <= zone->min_slab_pages) | ||
2391 | return 0; | ||
2392 | 2488 | ||
2393 | if (zone_is_all_unreclaimable(zone)) | 2489 | if (zone_is_all_unreclaimable(zone)) |
2394 | return 0; | 2490 | return ZONE_RECLAIM_FULL; |
2395 | 2491 | ||
2396 | /* | 2492 | /* |
2397 | * Do not scan if the allocation should not be delayed. | 2493 | * Do not scan if the allocation should not be delayed. |
2398 | */ | 2494 | */ |
2399 | if (!(gfp_mask & __GFP_WAIT) || (current->flags & PF_MEMALLOC)) | 2495 | if (!(gfp_mask & __GFP_WAIT) || (current->flags & PF_MEMALLOC)) |
2400 | return 0; | 2496 | return ZONE_RECLAIM_NOSCAN; |
2401 | 2497 | ||
2402 | /* | 2498 | /* |
2403 | * Only run zone reclaim on the local zone or on zones that do not | 2499 | * Only run zone reclaim on the local zone or on zones that do not |
@@ -2407,18 +2503,21 @@ int zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order) | |||
2407 | */ | 2503 | */ |
2408 | node_id = zone_to_nid(zone); | 2504 | node_id = zone_to_nid(zone); |
2409 | if (node_state(node_id, N_CPU) && node_id != numa_node_id()) | 2505 | if (node_state(node_id, N_CPU) && node_id != numa_node_id()) |
2410 | return 0; | 2506 | return ZONE_RECLAIM_NOSCAN; |
2411 | 2507 | ||
2412 | if (zone_test_and_set_flag(zone, ZONE_RECLAIM_LOCKED)) | 2508 | if (zone_test_and_set_flag(zone, ZONE_RECLAIM_LOCKED)) |
2413 | return 0; | 2509 | return ZONE_RECLAIM_NOSCAN; |
2510 | |||
2414 | ret = __zone_reclaim(zone, gfp_mask, order); | 2511 | ret = __zone_reclaim(zone, gfp_mask, order); |
2415 | zone_clear_flag(zone, ZONE_RECLAIM_LOCKED); | 2512 | zone_clear_flag(zone, ZONE_RECLAIM_LOCKED); |
2416 | 2513 | ||
2514 | if (!ret) | ||
2515 | count_vm_event(PGSCAN_ZONE_RECLAIM_FAILED); | ||
2516 | |||
2417 | return ret; | 2517 | return ret; |
2418 | } | 2518 | } |
2419 | #endif | 2519 | #endif |
2420 | 2520 | ||
2421 | #ifdef CONFIG_UNEVICTABLE_LRU | ||
2422 | /* | 2521 | /* |
2423 | * page_evictable - test whether a page is evictable | 2522 | * page_evictable - test whether a page is evictable |
2424 | * @page: the page to test | 2523 | * @page: the page to test |
@@ -2665,4 +2764,3 @@ void scan_unevictable_unregister_node(struct node *node) | |||
2665 | sysdev_remove_file(&node->sysdev, &attr_scan_unevictable_pages); | 2764 | sysdev_remove_file(&node->sysdev, &attr_scan_unevictable_pages); |
2666 | } | 2765 | } |
2667 | 2766 | ||
2668 | #endif | ||
diff --git a/mm/vmstat.c b/mm/vmstat.c index 74d66dba0cbe..138bed53706e 100644 --- a/mm/vmstat.c +++ b/mm/vmstat.c | |||
@@ -629,10 +629,8 @@ static const char * const vmstat_text[] = { | |||
629 | "nr_active_anon", | 629 | "nr_active_anon", |
630 | "nr_inactive_file", | 630 | "nr_inactive_file", |
631 | "nr_active_file", | 631 | "nr_active_file", |
632 | #ifdef CONFIG_UNEVICTABLE_LRU | ||
633 | "nr_unevictable", | 632 | "nr_unevictable", |
634 | "nr_mlock", | 633 | "nr_mlock", |
635 | #endif | ||
636 | "nr_anon_pages", | 634 | "nr_anon_pages", |
637 | "nr_mapped", | 635 | "nr_mapped", |
638 | "nr_file_pages", | 636 | "nr_file_pages", |
@@ -675,6 +673,9 @@ static const char * const vmstat_text[] = { | |||
675 | TEXTS_FOR_ZONES("pgscan_kswapd") | 673 | TEXTS_FOR_ZONES("pgscan_kswapd") |
676 | TEXTS_FOR_ZONES("pgscan_direct") | 674 | TEXTS_FOR_ZONES("pgscan_direct") |
677 | 675 | ||
676 | #ifdef CONFIG_NUMA | ||
677 | "zone_reclaim_failed", | ||
678 | #endif | ||
678 | "pginodesteal", | 679 | "pginodesteal", |
679 | "slabs_scanned", | 680 | "slabs_scanned", |
680 | "kswapd_steal", | 681 | "kswapd_steal", |
@@ -687,7 +688,6 @@ static const char * const vmstat_text[] = { | |||
687 | "htlb_buddy_alloc_success", | 688 | "htlb_buddy_alloc_success", |
688 | "htlb_buddy_alloc_fail", | 689 | "htlb_buddy_alloc_fail", |
689 | #endif | 690 | #endif |
690 | #ifdef CONFIG_UNEVICTABLE_LRU | ||
691 | "unevictable_pgs_culled", | 691 | "unevictable_pgs_culled", |
692 | "unevictable_pgs_scanned", | 692 | "unevictable_pgs_scanned", |
693 | "unevictable_pgs_rescued", | 693 | "unevictable_pgs_rescued", |
@@ -697,7 +697,6 @@ static const char * const vmstat_text[] = { | |||
697 | "unevictable_pgs_stranded", | 697 | "unevictable_pgs_stranded", |
698 | "unevictable_pgs_mlockfreed", | 698 | "unevictable_pgs_mlockfreed", |
699 | #endif | 699 | #endif |
700 | #endif | ||
701 | }; | 700 | }; |
702 | 701 | ||
703 | static void zoneinfo_show_print(struct seq_file *m, pg_data_t *pgdat, | 702 | static void zoneinfo_show_print(struct seq_file *m, pg_data_t *pgdat, |
@@ -710,18 +709,14 @@ static void zoneinfo_show_print(struct seq_file *m, pg_data_t *pgdat, | |||
710 | "\n min %lu" | 709 | "\n min %lu" |
711 | "\n low %lu" | 710 | "\n low %lu" |
712 | "\n high %lu" | 711 | "\n high %lu" |
713 | "\n scanned %lu (aa: %lu ia: %lu af: %lu if: %lu)" | 712 | "\n scanned %lu" |
714 | "\n spanned %lu" | 713 | "\n spanned %lu" |
715 | "\n present %lu", | 714 | "\n present %lu", |
716 | zone_page_state(zone, NR_FREE_PAGES), | 715 | zone_page_state(zone, NR_FREE_PAGES), |
717 | zone->pages_min, | 716 | min_wmark_pages(zone), |
718 | zone->pages_low, | 717 | low_wmark_pages(zone), |
719 | zone->pages_high, | 718 | high_wmark_pages(zone), |
720 | zone->pages_scanned, | 719 | zone->pages_scanned, |
721 | zone->lru[LRU_ACTIVE_ANON].nr_scan, | ||
722 | zone->lru[LRU_INACTIVE_ANON].nr_scan, | ||
723 | zone->lru[LRU_ACTIVE_FILE].nr_scan, | ||
724 | zone->lru[LRU_INACTIVE_FILE].nr_scan, | ||
725 | zone->spanned_pages, | 720 | zone->spanned_pages, |
726 | zone->present_pages); | 721 | zone->present_pages); |
727 | 722 | ||
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index 8847add6ca16..5ed8931dfe98 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c | |||
@@ -124,7 +124,7 @@ svc_pool_map_choose_mode(void) | |||
124 | { | 124 | { |
125 | unsigned int node; | 125 | unsigned int node; |
126 | 126 | ||
127 | if (num_online_nodes() > 1) { | 127 | if (nr_online_nodes > 1) { |
128 | /* | 128 | /* |
129 | * Actually have multiple NUMA nodes, | 129 | * Actually have multiple NUMA nodes, |
130 | * so split pools on NUMA node boundaries | 130 | * so split pools on NUMA node boundaries |
diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index 60dc0c48c929..3e733146cd51 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl | |||
@@ -13,7 +13,7 @@ | |||
13 | use strict; | 13 | use strict; |
14 | 14 | ||
15 | my $P = $0; | 15 | my $P = $0; |
16 | my $V = '0.15'; | 16 | my $V = '0.16'; |
17 | 17 | ||
18 | use Getopt::Long qw(:config no_auto_abbrev); | 18 | use Getopt::Long qw(:config no_auto_abbrev); |
19 | 19 | ||
@@ -55,6 +55,10 @@ foreach my $chief (@penguin_chief) { | |||
55 | } | 55 | } |
56 | my $penguin_chiefs = "\(" . join("|",@penguin_chief_names) . "\)"; | 56 | my $penguin_chiefs = "\(" . join("|",@penguin_chief_names) . "\)"; |
57 | 57 | ||
58 | # rfc822 email address - preloaded methods go here. | ||
59 | my $rfc822_lwsp = "(?:(?:\\r\\n)?[ \\t])"; | ||
60 | my $rfc822_char = '[\\000-\\377]'; | ||
61 | |||
58 | if (!GetOptions( | 62 | if (!GetOptions( |
59 | 'email!' => \$email, | 63 | 'email!' => \$email, |
60 | 'git!' => \$email_git, | 64 | 'git!' => \$email_git, |
@@ -161,7 +165,7 @@ foreach my $file (@ARGV) { | |||
161 | } | 165 | } |
162 | close(PATCH); | 166 | close(PATCH); |
163 | if ($file_cnt == @files) { | 167 | if ($file_cnt == @files) { |
164 | die "$P: file '${file}' doesn't appear to be a patch. " | 168 | warn "$P: file '${file}' doesn't appear to be a patch. " |
165 | . "Add -f to options?\n"; | 169 | . "Add -f to options?\n"; |
166 | } | 170 | } |
167 | @files = sort_and_uniq(@files); | 171 | @files = sort_and_uniq(@files); |
@@ -169,6 +173,7 @@ foreach my $file (@ARGV) { | |||
169 | } | 173 | } |
170 | 174 | ||
171 | my @email_to = (); | 175 | my @email_to = (); |
176 | my @list_to = (); | ||
172 | my @scm = (); | 177 | my @scm = (); |
173 | my @web = (); | 178 | my @web = (); |
174 | my @subsystem = (); | 179 | my @subsystem = (); |
@@ -182,7 +187,7 @@ foreach my $file (@files) { | |||
182 | 187 | ||
183 | my $exclude = 0; | 188 | my $exclude = 0; |
184 | foreach my $line (@typevalue) { | 189 | foreach my $line (@typevalue) { |
185 | if ($line =~ m/^(\C):(.*)/) { | 190 | if ($line =~ m/^(\C):\s*(.*)/) { |
186 | my $type = $1; | 191 | my $type = $1; |
187 | my $value = $2; | 192 | my $value = $2; |
188 | if ($type eq 'X') { | 193 | if ($type eq 'X') { |
@@ -196,7 +201,7 @@ foreach my $file (@files) { | |||
196 | if (!$exclude) { | 201 | if (!$exclude) { |
197 | my $tvi = 0; | 202 | my $tvi = 0; |
198 | foreach my $line (@typevalue) { | 203 | foreach my $line (@typevalue) { |
199 | if ($line =~ m/^(\C):(.*)/) { | 204 | if ($line =~ m/^(\C):\s*(.*)/) { |
200 | my $type = $1; | 205 | my $type = $1; |
201 | my $value = $2; | 206 | my $value = $2; |
202 | if ($type eq 'F') { | 207 | if ($type eq 'F') { |
@@ -215,29 +220,33 @@ foreach my $file (@files) { | |||
215 | 220 | ||
216 | } | 221 | } |
217 | 222 | ||
218 | if ($email_git_penguin_chiefs) { | 223 | if ($email) { |
219 | foreach my $chief (@penguin_chief) { | 224 | foreach my $chief (@penguin_chief) { |
220 | if ($chief =~ m/^(.*):(.*)/) { | 225 | if ($chief =~ m/^(.*):(.*)/) { |
221 | my $chief_name = $1; | 226 | my $email_address; |
222 | my $chief_addr = $2; | ||
223 | if ($email_usename) { | 227 | if ($email_usename) { |
224 | push(@email_to, format_email($chief_name, $chief_addr)); | 228 | $email_address = format_email($1, $2); |
229 | } else { | ||
230 | $email_address = $2; | ||
231 | } | ||
232 | if ($email_git_penguin_chiefs) { | ||
233 | push(@email_to, $email_address); | ||
225 | } else { | 234 | } else { |
226 | push(@email_to, $chief_addr); | 235 | @email_to = grep(!/${email_address}/, @email_to); |
227 | } | 236 | } |
228 | } | 237 | } |
229 | } | 238 | } |
230 | } | 239 | } |
231 | 240 | ||
232 | if ($email) { | 241 | if ($email || $email_list) { |
233 | my $address_cnt = @email_to; | 242 | my @to = (); |
234 | if ($address_cnt == 0 && $email_list) { | 243 | if ($email) { |
235 | push(@email_to, "linux-kernel\@vger.kernel.org"); | 244 | @to = (@to, @email_to); |
236 | } | 245 | } |
237 | 246 | if ($email_list) { | |
238 | #Don't sort email address list, but do remove duplicates | 247 | @to = (@to, @list_to); |
239 | @email_to = uniq(@email_to); | 248 | } |
240 | output(@email_to); | 249 | output(uniq(@to)); |
241 | } | 250 | } |
242 | 251 | ||
243 | if ($scm) { | 252 | if ($scm) { |
@@ -307,10 +316,10 @@ Output type options: | |||
307 | --multiline => print 1 entry per line | 316 | --multiline => print 1 entry per line |
308 | 317 | ||
309 | Default options: | 318 | Default options: |
310 | [--email --git --m --l --multiline] | 319 | [--email --git --m --n --l --multiline] |
311 | 320 | ||
312 | Other options: | 321 | Other options: |
313 | --version -> show version | 322 | --version => show version |
314 | --help => show this help information | 323 | --help => show this help information |
315 | 324 | ||
316 | EOT | 325 | EOT |
@@ -347,6 +356,7 @@ sub format_email { | |||
347 | my ($name, $email) = @_; | 356 | my ($name, $email) = @_; |
348 | 357 | ||
349 | $name =~ s/^\s+|\s+$//g; | 358 | $name =~ s/^\s+|\s+$//g; |
359 | $name =~ s/^\"|\"$//g; | ||
350 | $email =~ s/^\s+|\s+$//g; | 360 | $email =~ s/^\s+|\s+$//g; |
351 | 361 | ||
352 | my $formatted_email = ""; | 362 | my $formatted_email = ""; |
@@ -366,36 +376,41 @@ sub add_categories { | |||
366 | $index = $index - 1; | 376 | $index = $index - 1; |
367 | while ($index >= 0) { | 377 | while ($index >= 0) { |
368 | my $tv = $typevalue[$index]; | 378 | my $tv = $typevalue[$index]; |
369 | if ($tv =~ m/^(\C):(.*)/) { | 379 | if ($tv =~ m/^(\C):\s*(.*)/) { |
370 | my $ptype = $1; | 380 | my $ptype = $1; |
371 | my $pvalue = $2; | 381 | my $pvalue = $2; |
372 | if ($ptype eq "L") { | 382 | if ($ptype eq "L") { |
373 | my $subscr = $pvalue; | 383 | my $list_address = $pvalue; |
374 | if ($subscr =~ m/\s*\(subscribers-only\)/) { | 384 | my $list_additional = ""; |
385 | if ($list_address =~ m/([^\s]+)\s+(.*)$/) { | ||
386 | $list_address = $1; | ||
387 | $list_additional = $2; | ||
388 | } | ||
389 | if ($list_additional =~ m/subscribers-only/) { | ||
375 | if ($email_subscriber_list) { | 390 | if ($email_subscriber_list) { |
376 | $subscr =~ s/\s*\(subscribers-only\)//g; | 391 | push(@list_to, $list_address); |
377 | push(@email_to, $subscr); | ||
378 | } | 392 | } |
379 | } else { | 393 | } else { |
380 | if ($email_list) { | 394 | if ($email_list) { |
381 | push(@email_to, $pvalue); | 395 | push(@list_to, $list_address); |
382 | } | 396 | } |
383 | } | 397 | } |
384 | } elsif ($ptype eq "M") { | 398 | } elsif ($ptype eq "M") { |
385 | if ($email_maintainer) { | 399 | my $p_used = 0; |
386 | if ($index >= 0) { | 400 | if ($index >= 0) { |
387 | my $tv = $typevalue[$index - 1]; | 401 | my $tv = $typevalue[$index - 1]; |
388 | if ($tv =~ m/^(\C):(.*)/) { | 402 | if ($tv =~ m/^(\C):\s*(.*)/) { |
389 | if ($1 eq "P" && $email_usename) { | 403 | if ($1 eq "P") { |
390 | push(@email_to, format_email($2, $pvalue)); | 404 | if ($email_usename) { |
391 | } else { | 405 | push_email_address(format_email($2, $pvalue)); |
392 | push(@email_to, $pvalue); | 406 | $p_used = 1; |
393 | } | 407 | } |
394 | } | 408 | } |
395 | } else { | ||
396 | push(@email_to, $pvalue); | ||
397 | } | 409 | } |
398 | } | 410 | } |
411 | if (!$p_used) { | ||
412 | push_email_addresses($pvalue); | ||
413 | } | ||
399 | } elsif ($ptype eq "T") { | 414 | } elsif ($ptype eq "T") { |
400 | push(@scm, $pvalue); | 415 | push(@scm, $pvalue); |
401 | } elsif ($ptype eq "W") { | 416 | } elsif ($ptype eq "W") { |
@@ -412,10 +427,45 @@ sub add_categories { | |||
412 | } | 427 | } |
413 | } | 428 | } |
414 | 429 | ||
430 | sub push_email_address { | ||
431 | my ($email_address) = @_; | ||
432 | |||
433 | my $email_name = ""; | ||
434 | if ($email_address =~ m/([^<]+)<(.*\@.*)>$/) { | ||
435 | $email_name = $1; | ||
436 | $email_address = $2; | ||
437 | } | ||
438 | |||
439 | if ($email_maintainer) { | ||
440 | if ($email_usename && $email_name) { | ||
441 | push(@email_to, format_email($email_name, $email_address)); | ||
442 | } else { | ||
443 | push(@email_to, $email_address); | ||
444 | } | ||
445 | } | ||
446 | } | ||
447 | |||
448 | sub push_email_addresses { | ||
449 | my ($address) = @_; | ||
450 | |||
451 | my @address_list = (); | ||
452 | |||
453 | if (rfc822_valid($address)) { | ||
454 | push_email_address($address); | ||
455 | } elsif (@address_list = rfc822_validlist($address)) { | ||
456 | my $array_count = shift(@address_list); | ||
457 | while (my $entry = shift(@address_list)) { | ||
458 | push_email_address($entry); | ||
459 | } | ||
460 | } else { | ||
461 | warn("Invalid MAINTAINERS address: '" . $address . "'\n"); | ||
462 | } | ||
463 | } | ||
464 | |||
415 | sub which { | 465 | sub which { |
416 | my ($bin) = @_; | 466 | my ($bin) = @_; |
417 | 467 | ||
418 | foreach my $path (split /:/, $ENV{PATH}) { | 468 | foreach my $path (split(/:/, $ENV{PATH})) { |
419 | if (-e "$path/$bin") { | 469 | if (-e "$path/$bin") { |
420 | return "$path/$bin"; | 470 | return "$path/$bin"; |
421 | } | 471 | } |
@@ -434,16 +484,21 @@ sub recent_git_signoffs { | |||
434 | my @lines = (); | 484 | my @lines = (); |
435 | 485 | ||
436 | if (which("git") eq "") { | 486 | if (which("git") eq "") { |
437 | die("$P: git not found. Add --nogit to options?\n"); | 487 | warn("$P: git not found. Add --nogit to options?\n"); |
488 | return; | ||
489 | } | ||
490 | if (!(-d ".git")) { | ||
491 | warn("$P: .git directory not found. Use a git repository for better results.\n"); | ||
492 | warn("$P: perhaps 'git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git'\n"); | ||
493 | return; | ||
438 | } | 494 | } |
439 | 495 | ||
440 | $cmd = "git log --since=${email_git_since} -- ${file}"; | 496 | $cmd = "git log --since=${email_git_since} -- ${file}"; |
441 | $cmd .= " | grep -Pi \"^[-_ a-z]+by:.*\\\@\""; | 497 | $cmd .= " | grep -Ei \"^[-_ a-z]+by:.*\\\@.*\$\""; |
442 | if (!$email_git_penguin_chiefs) { | 498 | if (!$email_git_penguin_chiefs) { |
443 | $cmd .= " | grep -Pv \"${penguin_chiefs}\""; | 499 | $cmd .= " | grep -Ev \"${penguin_chiefs}\""; |
444 | } | 500 | } |
445 | $cmd .= " | cut -f2- -d\":\""; | 501 | $cmd .= " | cut -f2- -d\":\""; |
446 | $cmd .= " | sed -e \"s/^\\s+//g\""; | ||
447 | $cmd .= " | sort | uniq -c | sort -rn"; | 502 | $cmd .= " | sort | uniq -c | sort -rn"; |
448 | 503 | ||
449 | $output = `${cmd}`; | 504 | $output = `${cmd}`; |
@@ -465,10 +520,6 @@ sub recent_git_signoffs { | |||
465 | if ($line =~ m/(.+)<(.+)>/) { | 520 | if ($line =~ m/(.+)<(.+)>/) { |
466 | my $git_name = $1; | 521 | my $git_name = $1; |
467 | my $git_addr = $2; | 522 | my $git_addr = $2; |
468 | $git_name =~ tr/^\"//; | ||
469 | $git_name =~ tr/^\\s*//; | ||
470 | $git_name =~ tr/\"$//; | ||
471 | $git_name =~ tr/\\s*$//; | ||
472 | if ($email_usename) { | 523 | if ($email_usename) { |
473 | push(@email_to, format_email($git_name, $git_addr)); | 524 | push(@email_to, format_email($git_name, $git_addr)); |
474 | } else { | 525 | } else { |
@@ -481,7 +532,6 @@ sub recent_git_signoffs { | |||
481 | push(@email_to, $line); | 532 | push(@email_to, $line); |
482 | } | 533 | } |
483 | } | 534 | } |
484 | return $output; | ||
485 | } | 535 | } |
486 | 536 | ||
487 | sub uniq { | 537 | sub uniq { |
@@ -513,3 +563,97 @@ sub output { | |||
513 | print("\n"); | 563 | print("\n"); |
514 | } | 564 | } |
515 | } | 565 | } |
566 | |||
567 | my $rfc822re; | ||
568 | |||
569 | sub make_rfc822re { | ||
570 | # Basic lexical tokens are specials, domain_literal, quoted_string, atom, and | ||
571 | # comment. We must allow for rfc822_lwsp (or comments) after each of these. | ||
572 | # This regexp will only work on addresses which have had comments stripped | ||
573 | # and replaced with rfc822_lwsp. | ||
574 | |||
575 | my $specials = '()<>@,;:\\\\".\\[\\]'; | ||
576 | my $controls = '\\000-\\037\\177'; | ||
577 | |||
578 | my $dtext = "[^\\[\\]\\r\\\\]"; | ||
579 | my $domain_literal = "\\[(?:$dtext|\\\\.)*\\]$rfc822_lwsp*"; | ||
580 | |||
581 | my $quoted_string = "\"(?:[^\\\"\\r\\\\]|\\\\.|$rfc822_lwsp)*\"$rfc822_lwsp*"; | ||
582 | |||
583 | # Use zero-width assertion to spot the limit of an atom. A simple | ||
584 | # $rfc822_lwsp* causes the regexp engine to hang occasionally. | ||
585 | my $atom = "[^$specials $controls]+(?:$rfc822_lwsp+|\\Z|(?=[\\[\"$specials]))"; | ||
586 | my $word = "(?:$atom|$quoted_string)"; | ||
587 | my $localpart = "$word(?:\\.$rfc822_lwsp*$word)*"; | ||
588 | |||
589 | my $sub_domain = "(?:$atom|$domain_literal)"; | ||
590 | my $domain = "$sub_domain(?:\\.$rfc822_lwsp*$sub_domain)*"; | ||
591 | |||
592 | my $addr_spec = "$localpart\@$rfc822_lwsp*$domain"; | ||
593 | |||
594 | my $phrase = "$word*"; | ||
595 | my $route = "(?:\@$domain(?:,\@$rfc822_lwsp*$domain)*:$rfc822_lwsp*)"; | ||
596 | my $route_addr = "\\<$rfc822_lwsp*$route?$addr_spec\\>$rfc822_lwsp*"; | ||
597 | my $mailbox = "(?:$addr_spec|$phrase$route_addr)"; | ||
598 | |||
599 | my $group = "$phrase:$rfc822_lwsp*(?:$mailbox(?:,\\s*$mailbox)*)?;\\s*"; | ||
600 | my $address = "(?:$mailbox|$group)"; | ||
601 | |||
602 | return "$rfc822_lwsp*$address"; | ||
603 | } | ||
604 | |||
605 | sub rfc822_strip_comments { | ||
606 | my $s = shift; | ||
607 | # Recursively remove comments, and replace with a single space. The simpler | ||
608 | # regexps in the Email Addressing FAQ are imperfect - they will miss escaped | ||
609 | # chars in atoms, for example. | ||
610 | |||
611 | while ($s =~ s/^((?:[^"\\]|\\.)* | ||
612 | (?:"(?:[^"\\]|\\.)*"(?:[^"\\]|\\.)*)*) | ||
613 | \((?:[^()\\]|\\.)*\)/$1 /osx) {} | ||
614 | return $s; | ||
615 | } | ||
616 | |||
617 | # valid: returns true if the parameter is an RFC822 valid address | ||
618 | # | ||
619 | sub rfc822_valid ($) { | ||
620 | my $s = rfc822_strip_comments(shift); | ||
621 | |||
622 | if (!$rfc822re) { | ||
623 | $rfc822re = make_rfc822re(); | ||
624 | } | ||
625 | |||
626 | return $s =~ m/^$rfc822re$/so && $s =~ m/^$rfc822_char*$/; | ||
627 | } | ||
628 | |||
629 | # validlist: In scalar context, returns true if the parameter is an RFC822 | ||
630 | # valid list of addresses. | ||
631 | # | ||
632 | # In list context, returns an empty list on failure (an invalid | ||
633 | # address was found); otherwise a list whose first element is the | ||
634 | # number of addresses found and whose remaining elements are the | ||
635 | # addresses. This is needed to disambiguate failure (invalid) | ||
636 | # from success with no addresses found, because an empty string is | ||
637 | # a valid list. | ||
638 | |||
639 | sub rfc822_validlist ($) { | ||
640 | my $s = rfc822_strip_comments(shift); | ||
641 | |||
642 | if (!$rfc822re) { | ||
643 | $rfc822re = make_rfc822re(); | ||
644 | } | ||
645 | # * null list items are valid according to the RFC | ||
646 | # * the '1' business is to aid in distinguishing failure from no results | ||
647 | |||
648 | my @r; | ||
649 | if ($s =~ m/^(?:$rfc822re)?(?:,(?:$rfc822re)?)*$/so && | ||
650 | $s =~ m/^$rfc822_char*$/) { | ||
651 | while ($s =~ m/(?:^|,$rfc822_lwsp*)($rfc822re)/gos) { | ||
652 | push @r, $1; | ||
653 | } | ||
654 | return wantarray ? (scalar(@r), @r) : 1; | ||
655 | } | ||
656 | else { | ||
657 | return wantarray ? () : 0; | ||
658 | } | ||
659 | } | ||
diff --git a/scripts/gfp-translate b/scripts/gfp-translate new file mode 100644 index 000000000000..073cb6d152a0 --- /dev/null +++ b/scripts/gfp-translate | |||
@@ -0,0 +1,81 @@ | |||
1 | #!/bin/bash | ||
2 | # Translate the bits making up a GFP mask | ||
3 | # (c) 2009, Mel Gorman <mel@csn.ul.ie> | ||
4 | # Licensed under the terms of the GNU GPL License version 2 | ||
5 | SOURCE= | ||
6 | GFPMASK=none | ||
7 | |||
8 | # Helper function to report failures and exit | ||
9 | die() { | ||
10 | echo ERROR: $@ | ||
11 | if [ "$TMPFILE" != "" ]; then | ||
12 | rm -f $TMPFILE | ||
13 | fi | ||
14 | exit -1 | ||
15 | } | ||
16 | |||
17 | usage() { | ||
18 | echo "usage: gfp-translate [-h] [ --source DIRECTORY ] gfpmask" | ||
19 | exit 0 | ||
20 | } | ||
21 | |||
22 | # Parse command-line arguements | ||
23 | while [ $# -gt 0 ]; do | ||
24 | case $1 in | ||
25 | --source) | ||
26 | SOURCE=$2 | ||
27 | shift 2 | ||
28 | ;; | ||
29 | -h) | ||
30 | usage | ||
31 | ;; | ||
32 | --help) | ||
33 | usage | ||
34 | ;; | ||
35 | *) | ||
36 | GFPMASK=$1 | ||
37 | shift | ||
38 | ;; | ||
39 | esac | ||
40 | done | ||
41 | |||
42 | # Guess the kernel source directory if it's not set. Preference is in order of | ||
43 | # o current directory | ||
44 | # o /usr/src/linux | ||
45 | if [ "$SOURCE" = "" ]; then | ||
46 | if [ -r "/usr/src/linux/Makefile" ]; then | ||
47 | SOURCE=/usr/src/linux | ||
48 | fi | ||
49 | if [ -r "`pwd`/Makefile" ]; then | ||
50 | SOURCE=`pwd` | ||
51 | fi | ||
52 | fi | ||
53 | |||
54 | # Confirm that a source directory exists | ||
55 | if [ ! -r "$SOURCE/Makefile" ]; then | ||
56 | die "Could not locate kernel source directory or it is invalid" | ||
57 | fi | ||
58 | |||
59 | # Confirm that a GFP mask has been specified | ||
60 | if [ "$GFPMASK" = "none" ]; then | ||
61 | usage | ||
62 | fi | ||
63 | |||
64 | # Extract GFP flags from the kernel source | ||
65 | TMPFILE=`mktemp -t gfptranslate-XXXXXX` || exit 1 | ||
66 | grep "^#define __GFP" $SOURCE/include/linux/gfp.h | sed -e 's/(__force gfp_t)//' | sed -e 's/u)/)/' | grep -v GFP_BITS | sed -e 's/)\//) \//' > $TMPFILE | ||
67 | |||
68 | # Parse the flags | ||
69 | IFS=" | ||
70 | " | ||
71 | echo Source: $SOURCE | ||
72 | echo Parsing: $GFPMASK | ||
73 | for LINE in `cat $TMPFILE`; do | ||
74 | MASK=`echo $LINE | awk '{print $3}'` | ||
75 | if [ $(($GFPMASK&$MASK)) -ne 0 ]; then | ||
76 | echo $LINE | ||
77 | fi | ||
78 | done | ||
79 | |||
80 | rm -f $TMPFILE | ||
81 | exit 0 | ||
diff --git a/scripts/pnmtologo.c b/scripts/pnmtologo.c index 6aa2a2483f8d..64f5ddb09ea6 100644 --- a/scripts/pnmtologo.c +++ b/scripts/pnmtologo.c | |||
@@ -237,22 +237,22 @@ static void write_header(void) | |||
237 | fprintf(out, " * Linux logo %s\n", logoname); | 237 | fprintf(out, " * Linux logo %s\n", logoname); |
238 | fputs(" */\n\n", out); | 238 | fputs(" */\n\n", out); |
239 | fputs("#include <linux/linux_logo.h>\n\n", out); | 239 | fputs("#include <linux/linux_logo.h>\n\n", out); |
240 | fprintf(out, "static unsigned char %s_data[] __initdata = {\n", | 240 | fprintf(out, "static const unsigned char %s_data[] __initconst = {\n", |
241 | logoname); | 241 | logoname); |
242 | } | 242 | } |
243 | 243 | ||
244 | static void write_footer(void) | 244 | static void write_footer(void) |
245 | { | 245 | { |
246 | fputs("\n};\n\n", out); | 246 | fputs("\n};\n\n", out); |
247 | fprintf(out, "struct linux_logo %s __initdata = {\n", logoname); | 247 | fprintf(out, "const struct linux_logo %s __initconst = {\n", logoname); |
248 | fprintf(out, " .type\t= %s,\n", logo_types[logo_type]); | 248 | fprintf(out, "\t.type\t\t= %s,\n", logo_types[logo_type]); |
249 | fprintf(out, " .width\t= %d,\n", logo_width); | 249 | fprintf(out, "\t.width\t\t= %d,\n", logo_width); |
250 | fprintf(out, " .height\t= %d,\n", logo_height); | 250 | fprintf(out, "\t.height\t\t= %d,\n", logo_height); |
251 | if (logo_type == LINUX_LOGO_CLUT224) { | 251 | if (logo_type == LINUX_LOGO_CLUT224) { |
252 | fprintf(out, " .clutsize\t= %d,\n", logo_clutsize); | 252 | fprintf(out, "\t.clutsize\t= %d,\n", logo_clutsize); |
253 | fprintf(out, " .clut\t= %s_clut,\n", logoname); | 253 | fprintf(out, "\t.clut\t\t= %s_clut,\n", logoname); |
254 | } | 254 | } |
255 | fprintf(out, " .data\t= %s_data\n", logoname); | 255 | fprintf(out, "\t.data\t\t= %s_data\n", logoname); |
256 | fputs("};\n\n", out); | 256 | fputs("};\n\n", out); |
257 | 257 | ||
258 | /* close logo file */ | 258 | /* close logo file */ |
@@ -374,7 +374,7 @@ static void write_logo_clut224(void) | |||
374 | fputs("\n};\n\n", out); | 374 | fputs("\n};\n\n", out); |
375 | 375 | ||
376 | /* write logo clut */ | 376 | /* write logo clut */ |
377 | fprintf(out, "static unsigned char %s_clut[] __initdata = {\n", | 377 | fprintf(out, "static const unsigned char %s_clut[] __initconst = {\n", |
378 | logoname); | 378 | logoname); |
379 | write_hex_cnt = 0; | 379 | write_hex_cnt = 0; |
380 | for (i = 0; i < logo_clutsize; i++) { | 380 | for (i = 0; i < logo_clutsize; i++) { |
diff --git a/sound/drivers/pcsp/pcsp.h b/sound/drivers/pcsp/pcsp.h index cdef2664218f..174dd2ff0f22 100644 --- a/sound/drivers/pcsp/pcsp.h +++ b/sound/drivers/pcsp/pcsp.h | |||
@@ -10,6 +10,7 @@ | |||
10 | #define __PCSP_H__ | 10 | #define __PCSP_H__ |
11 | 11 | ||
12 | #include <linux/hrtimer.h> | 12 | #include <linux/hrtimer.h> |
13 | #include <linux/timex.h> | ||
13 | #if defined(CONFIG_MIPS) || defined(CONFIG_X86) | 14 | #if defined(CONFIG_MIPS) || defined(CONFIG_X86) |
14 | /* Use the global PIT lock ! */ | 15 | /* Use the global PIT lock ! */ |
15 | #include <asm/i8253.h> | 16 | #include <asm/i8253.h> |
diff --git a/sound/oss/pas2_pcm.c b/sound/oss/pas2_pcm.c index 36c3ea62086b..8f7d175767a2 100644 --- a/sound/oss/pas2_pcm.c +++ b/sound/oss/pas2_pcm.c | |||
@@ -17,7 +17,7 @@ | |||
17 | 17 | ||
18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
19 | #include <linux/spinlock.h> | 19 | #include <linux/spinlock.h> |
20 | #include <asm/timex.h> | 20 | #include <linux/timex.h> |
21 | #include "sound_config.h" | 21 | #include "sound_config.h" |
22 | 22 | ||
23 | #include "pas2.h" | 23 | #include "pas2.h" |