aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/swap.h8
-rw-r--r--mm/swapfile.c66
2 files changed, 41 insertions, 33 deletions
diff --git a/include/linux/swap.h b/include/linux/swap.h
index 410c8e473727..9cabb8b21aba 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -133,14 +133,14 @@ enum {
133 * The in-memory structure used to track swap areas. 133 * The in-memory structure used to track swap areas.
134 */ 134 */
135struct swap_info_struct { 135struct swap_info_struct {
136 unsigned int flags; 136 unsigned long flags;
137 int prio; /* swap priority */ 137 int prio; /* swap priority */
138 int next; /* next entry on swap list */
138 struct file *swap_file; 139 struct file *swap_file;
139 struct block_device *bdev; 140 struct block_device *bdev;
140 struct list_head extent_list; 141 struct list_head extent_list;
141 struct swap_extent *curr_swap_extent; 142 struct swap_extent *curr_swap_extent;
142 unsigned old_block_size; 143 unsigned short *swap_map;
143 unsigned short * swap_map;
144 unsigned int lowest_bit; 144 unsigned int lowest_bit;
145 unsigned int highest_bit; 145 unsigned int highest_bit;
146 unsigned int cluster_next; 146 unsigned int cluster_next;
@@ -148,7 +148,7 @@ struct swap_info_struct {
148 unsigned int pages; 148 unsigned int pages;
149 unsigned int max; 149 unsigned int max;
150 unsigned int inuse_pages; 150 unsigned int inuse_pages;
151 int next; /* next entry on swap list */ 151 unsigned int old_block_size;
152}; 152};
153 153
154struct swap_list_t { 154struct swap_list_t {
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 85ff603385c3..4d9855f86e7d 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -89,7 +89,8 @@ void swap_unplug_io_fn(struct backing_dev_info *unused_bdi, struct page *page)
89 89
90static inline unsigned long scan_swap_map(struct swap_info_struct *si) 90static inline unsigned long scan_swap_map(struct swap_info_struct *si)
91{ 91{
92 unsigned long offset, last_in_cluster; 92 unsigned long offset;
93 unsigned long last_in_cluster;
93 int latency_ration = LATENCY_LIMIT; 94 int latency_ration = LATENCY_LIMIT;
94 95
95 /* 96 /*
@@ -103,10 +104,13 @@ static inline unsigned long scan_swap_map(struct swap_info_struct *si)
103 */ 104 */
104 105
105 si->flags += SWP_SCANNING; 106 si->flags += SWP_SCANNING;
106 if (unlikely(!si->cluster_nr)) { 107 offset = si->cluster_next;
107 si->cluster_nr = SWAPFILE_CLUSTER - 1; 108
108 if (si->pages - si->inuse_pages < SWAPFILE_CLUSTER) 109 if (unlikely(!si->cluster_nr--)) {
109 goto lowest; 110 if (si->pages - si->inuse_pages < SWAPFILE_CLUSTER) {
111 si->cluster_nr = SWAPFILE_CLUSTER - 1;
112 goto checks;
113 }
110 spin_unlock(&swap_lock); 114 spin_unlock(&swap_lock);
111 115
112 offset = si->lowest_bit; 116 offset = si->lowest_bit;
@@ -118,43 +122,47 @@ static inline unsigned long scan_swap_map(struct swap_info_struct *si)
118 last_in_cluster = offset + SWAPFILE_CLUSTER; 122 last_in_cluster = offset + SWAPFILE_CLUSTER;
119 else if (offset == last_in_cluster) { 123 else if (offset == last_in_cluster) {
120 spin_lock(&swap_lock); 124 spin_lock(&swap_lock);
121 si->cluster_next = offset-SWAPFILE_CLUSTER+1; 125 offset -= SWAPFILE_CLUSTER - 1;
122 goto cluster; 126 si->cluster_next = offset;
127 si->cluster_nr = SWAPFILE_CLUSTER - 1;
128 goto checks;
123 } 129 }
124 if (unlikely(--latency_ration < 0)) { 130 if (unlikely(--latency_ration < 0)) {
125 cond_resched(); 131 cond_resched();
126 latency_ration = LATENCY_LIMIT; 132 latency_ration = LATENCY_LIMIT;
127 } 133 }
128 } 134 }
135
136 offset = si->lowest_bit;
129 spin_lock(&swap_lock); 137 spin_lock(&swap_lock);
130 goto lowest; 138 si->cluster_nr = SWAPFILE_CLUSTER - 1;
131 } 139 }
132 140
133 si->cluster_nr--; 141checks:
134cluster: 142 if (!(si->flags & SWP_WRITEOK))
135 offset = si->cluster_next;
136 if (offset > si->highest_bit)
137lowest: offset = si->lowest_bit;
138checks: if (!(si->flags & SWP_WRITEOK))
139 goto no_page; 143 goto no_page;
140 if (!si->highest_bit) 144 if (!si->highest_bit)
141 goto no_page; 145 goto no_page;
142 if (!si->swap_map[offset]) { 146 if (offset > si->highest_bit)
143 if (offset == si->lowest_bit) 147 offset = si->lowest_bit;
144 si->lowest_bit++; 148 if (si->swap_map[offset])
145 if (offset == si->highest_bit) 149 goto scan;
146 si->highest_bit--; 150
147 si->inuse_pages++; 151 if (offset == si->lowest_bit)
148 if (si->inuse_pages == si->pages) { 152 si->lowest_bit++;
149 si->lowest_bit = si->max; 153 if (offset == si->highest_bit)
150 si->highest_bit = 0; 154 si->highest_bit--;
151 } 155 si->inuse_pages++;
152 si->swap_map[offset] = 1; 156 if (si->inuse_pages == si->pages) {
153 si->cluster_next = offset + 1; 157 si->lowest_bit = si->max;
154 si->flags -= SWP_SCANNING; 158 si->highest_bit = 0;
155 return offset;
156 } 159 }
160 si->swap_map[offset] = 1;
161 si->cluster_next = offset + 1;
162 si->flags -= SWP_SCANNING;
163 return offset;
157 164
165scan:
158 spin_unlock(&swap_lock); 166 spin_unlock(&swap_lock);
159 while (++offset <= si->highest_bit) { 167 while (++offset <= si->highest_bit) {
160 if (!si->swap_map[offset]) { 168 if (!si->swap_map[offset]) {
@@ -167,7 +175,7 @@ checks: if (!(si->flags & SWP_WRITEOK))
167 } 175 }
168 } 176 }
169 spin_lock(&swap_lock); 177 spin_lock(&swap_lock);
170 goto lowest; 178 goto checks;
171 179
172no_page: 180no_page:
173 si->flags -= SWP_SCANNING; 181 si->flags -= SWP_SCANNING;