1 --- kernel-maemo-2.6.28.orig/mm/swapfile.c
2 +++ kernel-maemo-2.6.28/mm/swapfile.c
4 static int swap_entry_free(struct swap_info_struct *p, unsigned long offset)
6 int count = p->swap_map[offset];
9 - if (count < SWAP_MAP_MAX) {
11 - p->swap_map[offset] = count;
13 - if (offset < p->lowest_bit)
14 - p->lowest_bit = offset;
15 - if (offset > p->highest_bit)
16 - p->highest_bit = offset;
17 - if (p->prio > swap_info[swap_list.next].prio)
18 - swap_list.next = p - swap_info;
24 + if (count >= SWAP_MAP_MAX)
28 + p->swap_map[offset] = count;
32 + spin_lock(&p->remap_lock);
34 + if (offset < p->lowest_bit)
35 + p->lowest_bit = offset;
36 + if (offset > p->highest_bit)
37 + p->highest_bit = offset;
38 + if (p->prio > swap_info[swap_list.next].prio)
39 + swap_list.next = p - swap_info;
43 + /* Re-map the page number */
44 + old = p->swap_remap[offset] & 0x7FFFFFFF;
45 + /* Zero means it was not re-mapped */
48 + /* Clear the re-mapping */
49 + p->swap_remap[offset] &= 0x80000000;
50 + /* Mark the re-mapped page as unused */
51 + p->swap_remap[old] &= 0x7FFFFFFF;
52 + /* Record how many free pages there are */
55 + spin_unlock(&p->remap_lock);
60 @@ -977,14 +996,123 @@
61 spin_unlock(&mmlist_lock);
64 +/* Find the largest sequence of free pages */
65 +int find_gap(struct swap_info_struct *sis)
67 + unsigned i, uninitialized_var(start), uninitialized_var(gap_next);
68 + unsigned uninitialized_var(gap_end), gap_size = 0;
71 + spin_unlock(&sis->remap_lock);
73 + mutex_lock(&sis->remap_mutex);
75 + /* Check if a gap was found while we waited for the mutex */
76 + spin_lock(&sis->remap_lock);
77 + if (sis->gap_next <= sis->gap_end) {
78 + mutex_unlock(&sis->remap_mutex);
81 + if (!sis->gaps_exist) {
82 + mutex_unlock(&sis->remap_mutex);
85 + spin_unlock(&sis->remap_lock);
88 + * There is no current gap, so no new re-mappings can be made without
89 + * going through this function (find_gap) which is protected by the
92 + for (i = 1; i < sis->max; i++) {
94 + if (!(sis->swap_remap[i] & 0x80000000))
96 + if (i - start > gap_size) {
99 + gap_size = i - start;
103 + if (sis->swap_remap[i] & 0x80000000)
110 + spin_lock(&sis->remap_lock);
111 + if (in_gap && i - start > gap_size) {
112 + sis->gap_next = start;
113 + sis->gap_end = i - 1;
115 + sis->gap_next = gap_next;
116 + sis->gap_end = gap_end;
118 + mutex_unlock(&sis->remap_mutex);
123 * Use this swapdev's extent info to locate the (PAGE_SIZE) block which
124 * corresponds to page offset `offset'.
126 -sector_t map_swap_page(struct swap_info_struct *sis, pgoff_t offset)
127 +sector_t map_swap_page(struct swap_info_struct *sis, pgoff_t offset, int write)
129 struct swap_extent *se = sis->curr_swap_extent;
130 struct swap_extent *start_se = se;
134 + * Instead of using the offset we are given, re-map it to the next
135 + * sequential position.
137 + spin_lock(&sis->remap_lock);
138 + /* Get the old re-mapping */
139 + old = sis->swap_remap[offset] & 0x7FFFFFFF;
141 + /* See if we have free pages */
142 + if (sis->gap_next > sis->gap_end) {
143 + /* The gap is used up. Find another one */
144 + if (!sis->gaps_exist || find_gap(sis) < 0) {
146 + * Out of space, so this page must have a
147 + * re-mapping, so use that.
150 + sis->gap_next = sis->gap_end = old;
153 + /* Zero means it was not re-mapped previously */
155 + /* Clear the re-mapping */
156 + sis->swap_remap[offset] &= 0x80000000;
157 + /* Mark the re-mapped page as unused */
158 + sis->swap_remap[old] &= 0x7FFFFFFF;
160 + /* Record how many free pages there are */
161 + sis->gaps_exist -= 1;
163 + /* Create the re-mapping to the next free page */
164 + sis->swap_remap[offset] |= sis->gap_next;
165 + /* Mark it as used */
166 + sis->swap_remap[sis->gap_next] |= 0x80000000;
167 + /* Use the re-mapped page number */
168 + offset = sis->gap_next;
169 + /* Update the free pages gap */
170 + sis->gap_next += 1;
173 + * Always read from the existing re-mapping
174 + * if there is one. There may not be because
175 + * 'swapin_readahead()' has won a race with
181 + spin_unlock(&sis->remap_lock);
184 struct list_head *lh;
185 @@ -1015,7 +1143,8 @@
188 sis = swap_info + swap_type;
189 - return (sis->flags & SWP_WRITEOK) ? map_swap_page(sis, offset) : 0;
190 +#error map_swap_page does not support hibernation
191 + return (sis->flags & SWP_WRITEOK) ? map_swap_page(sis, offset, 0) : 0;
193 #endif /* CONFIG_HIBERNATION */
195 @@ -1342,6 +1471,7 @@
197 spin_unlock(&swap_lock);
198 mutex_unlock(&swapon_mutex);
199 + vfree(p->swap_remap);
201 inode = mapping->host;
202 if (S_ISBLK(inode->i_mode)) {
203 @@ -1485,6 +1615,7 @@
204 unsigned long maxpages = 1;
206 unsigned short *swap_map = NULL;
207 + unsigned int *swap_remap = NULL;
208 struct page *page = NULL;
209 struct inode *inode = NULL;
211 @@ -1654,9 +1785,15 @@
215 + swap_remap = vmalloc(maxpages * sizeof(unsigned));
222 memset(swap_map, 0, maxpages * sizeof(short));
223 + memset(swap_remap, 0, maxpages * sizeof(unsigned));
224 for (i = 0; i < swap_header->info.nr_badpages; i++) {
225 int page_nr = swap_header->info.badpages[i];
226 if (page_nr <= 0 || page_nr >= swap_header->info.last_page)
227 @@ -1696,6 +1833,12 @@
229 p->prio = --least_priority;
230 p->swap_map = swap_map;
231 + p->swap_remap = swap_remap;
233 + p->gap_end = p->max - 1;
234 + p->gaps_exist = p->max - 1;
235 + spin_lock_init(&p->remap_lock);
236 + mutex_init(&p->remap_mutex);
237 p->flags = SWP_ACTIVE;
238 nr_swap_pages += nr_good_pages;
239 total_swap_pages += nr_good_pages;
240 @@ -1734,6 +1877,7 @@
243 spin_unlock(&swap_lock);
247 filp_close(swap_file, NULL);