aboutsummaryrefslogtreecommitdiffstats
path: root/mm/swapfile.c
diff options
context:
space:
mode:
authorHugh Dickins <hugh@veritas.com>2005-09-03 18:54:38 -0400
committerLinus Torvalds <torvalds@evo.osdl.org>2005-09-05 03:05:41 -0400
commit7dfad4183bf9cd92f977caa3c12cc74f0eefc0e6 (patch)
treee11306e1e82acba1832f07fdfb3296c34cf6e934 /mm/swapfile.c
parentfb4f88dcabdc716c7c350e09cf4a38a419b007e1 (diff)
[PATCH] swap: scan_swap_map restyled
Rewrite scan_swap_map to allocate in just the same way as before (taking the next free entry SWAPFILE_CLUSTER-1 times, then restarting at the lowest wholly empty cluster, falling back to lowest entry if none), but with a view towards dropping the lock in the next patch. Signed-off-by: Hugh Dickins <hugh@veritas.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'mm/swapfile.c')
-rw-r--r--mm/swapfile.c93
1 files changed, 48 insertions, 45 deletions
diff --git a/mm/swapfile.c b/mm/swapfile.c
index e54d60af6b58..c70248aab536 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -86,64 +86,67 @@ void swap_unplug_io_fn(struct backing_dev_info *unused_bdi, struct page *page)
86 86
87static inline unsigned long scan_swap_map(struct swap_info_struct *si) 87static inline unsigned long scan_swap_map(struct swap_info_struct *si)
88{ 88{
89 unsigned long offset; 89 unsigned long offset, last_in_cluster;
90
90 /* 91 /*
91 * We try to cluster swap pages by allocating them 92 * We try to cluster swap pages by allocating them sequentially
92 * sequentially in swap. Once we've allocated 93 * in swap. Once we've allocated SWAPFILE_CLUSTER pages this
93 * SWAPFILE_CLUSTER pages this way, however, we resort to 94 * way, however, we resort to first-free allocation, starting
94 * first-free allocation, starting a new cluster. This 95 * a new cluster. This prevents us from scattering swap pages
95 * prevents us from scattering swap pages all over the entire 96 * all over the entire swap partition, so that we reduce
96 * swap partition, so that we reduce overall disk seek times 97 * overall disk seek times between swap pages. -- sct
97 * between swap pages. -- sct */ 98 * But we do now try to find an empty cluster. -Andrea
98 if (si->cluster_nr) { 99 */
99 while (si->cluster_next <= si->highest_bit) { 100
100 offset = si->cluster_next++; 101 if (unlikely(!si->cluster_nr)) {
102 si->cluster_nr = SWAPFILE_CLUSTER - 1;
103 if (si->pages - si->inuse_pages < SWAPFILE_CLUSTER)
104 goto lowest;
105
106 offset = si->lowest_bit;
107 last_in_cluster = offset + SWAPFILE_CLUSTER - 1;
108
109 /* Locate the first empty (unaligned) cluster */
110 for (; last_in_cluster <= si->highest_bit; offset++) {
101 if (si->swap_map[offset]) 111 if (si->swap_map[offset])
102 continue; 112 last_in_cluster = offset + SWAPFILE_CLUSTER;
103 si->cluster_nr--; 113 else if (offset == last_in_cluster) {
104 goto got_page; 114 si->cluster_next = offset-SWAPFILE_CLUSTER-1;
105 } 115 goto cluster;
106 }
107 si->cluster_nr = SWAPFILE_CLUSTER;
108
109 /* try to find an empty (even not aligned) cluster. */
110 offset = si->lowest_bit;
111 check_next_cluster:
112 if (offset+SWAPFILE_CLUSTER-1 <= si->highest_bit)
113 {
114 unsigned long nr;
115 for (nr = offset; nr < offset+SWAPFILE_CLUSTER; nr++)
116 if (si->swap_map[nr])
117 {
118 offset = nr+1;
119 goto check_next_cluster;
120 } 116 }
121 /* We found a completly empty cluster, so start 117 }
122 * using it. 118 goto lowest;
123 */
124 goto got_page;
125 } 119 }
126 /* No luck, so now go finegrined as usual. -Andrea */ 120
127 for (offset = si->lowest_bit; offset <= si->highest_bit ; offset++) { 121 si->cluster_nr--;
128 if (si->swap_map[offset]) 122cluster:
129 continue; 123 offset = si->cluster_next;
130 si->lowest_bit = offset+1; 124 if (offset > si->highest_bit)
131 got_page: 125lowest: offset = si->lowest_bit;
132 if (offset == si->lowest_bit) 126 if (!si->highest_bit)
127 goto no_page;
128 if (!si->swap_map[offset]) {
129got_page: if (offset == si->lowest_bit)
133 si->lowest_bit++; 130 si->lowest_bit++;
134 if (offset == si->highest_bit) 131 if (offset == si->highest_bit)
135 si->highest_bit--; 132 si->highest_bit--;
136 if (si->lowest_bit > si->highest_bit) { 133 si->inuse_pages++;
134 if (si->inuse_pages == si->pages) {
137 si->lowest_bit = si->max; 135 si->lowest_bit = si->max;
138 si->highest_bit = 0; 136 si->highest_bit = 0;
139 } 137 }
140 si->swap_map[offset] = 1; 138 si->swap_map[offset] = 1;
141 si->inuse_pages++; 139 si->cluster_next = offset + 1;
142 si->cluster_next = offset+1;
143 return offset; 140 return offset;
144 } 141 }
145 si->lowest_bit = si->max; 142
146 si->highest_bit = 0; 143 while (++offset <= si->highest_bit) {
144 if (!si->swap_map[offset])
145 goto got_page;
146 }
147 goto lowest;
148
149no_page:
147 return 0; 150 return 0;
148} 151}
149 152