Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 126228
b: refs/heads/master
c: c60aa17
h: refs/heads/master
v: v3
  • Loading branch information
Hugh Dickins authored and Linus Torvalds committed Jan 6, 2009
1 parent ea09eec commit fa060c4
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 5 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 20137a490f397d9c01fc9fadd83a8d198bda4477
refs/heads/master: c60aa176c6de82703f064082b909496fc4fee956
50 changes: 46 additions & 4 deletions trunk/mm/swapfile.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ static int wait_for_discard(void *word)
static inline unsigned long scan_swap_map(struct swap_info_struct *si)
{
unsigned long offset;
unsigned long scan_base;
unsigned long last_in_cluster = 0;
int latency_ration = LATENCY_LIMIT;
int found_free_cluster = 0;
Expand All @@ -181,10 +182,11 @@ static inline unsigned long scan_swap_map(struct swap_info_struct *si)
* all over the entire swap partition, so that we reduce
* overall disk seek times between swap pages. -- sct
* But we do now try to find an empty cluster. -Andrea
* And we let swap pages go all over an SSD partition. Hugh
*/

si->flags += SWP_SCANNING;
offset = si->cluster_next;
scan_base = offset = si->cluster_next;

if (unlikely(!si->cluster_nr--)) {
if (si->pages - si->inuse_pages < SWAPFILE_CLUSTER) {
Expand All @@ -206,7 +208,16 @@ static inline unsigned long scan_swap_map(struct swap_info_struct *si)
}
spin_unlock(&swap_lock);

offset = si->lowest_bit;
/*
* If seek is expensive, start searching for new cluster from
* start of partition, to minimize the span of allocated swap.
* But if seek is cheap, search from our current position, so
* that swap is allocated from all over the partition: if the
* Flash Translation Layer only remaps within limited zones,
* we don't want to wear out the first zone too quickly.
*/
if (!(si->flags & SWP_SOLIDSTATE))
scan_base = offset = si->lowest_bit;
last_in_cluster = offset + SWAPFILE_CLUSTER - 1;

/* Locate the first empty (unaligned) cluster */
Expand All @@ -228,6 +239,27 @@ static inline unsigned long scan_swap_map(struct swap_info_struct *si)
}

offset = si->lowest_bit;
last_in_cluster = offset + SWAPFILE_CLUSTER - 1;

/* Locate the first empty (unaligned) cluster */
for (; last_in_cluster < scan_base; offset++) {
if (si->swap_map[offset])
last_in_cluster = offset + SWAPFILE_CLUSTER;
else if (offset == last_in_cluster) {
spin_lock(&swap_lock);
offset -= SWAPFILE_CLUSTER - 1;
si->cluster_next = offset;
si->cluster_nr = SWAPFILE_CLUSTER - 1;
found_free_cluster = 1;
goto checks;
}
if (unlikely(--latency_ration < 0)) {
cond_resched();
latency_ration = LATENCY_LIMIT;
}
}

offset = scan_base;
spin_lock(&swap_lock);
si->cluster_nr = SWAPFILE_CLUSTER - 1;
si->lowest_alloc = 0;
Expand All @@ -239,7 +271,7 @@ static inline unsigned long scan_swap_map(struct swap_info_struct *si)
if (!si->highest_bit)
goto no_page;
if (offset > si->highest_bit)
offset = si->lowest_bit;
scan_base = offset = si->lowest_bit;
if (si->swap_map[offset])
goto scan;

Expand Down Expand Up @@ -323,8 +355,18 @@ static inline unsigned long scan_swap_map(struct swap_info_struct *si)
latency_ration = LATENCY_LIMIT;
}
}
offset = si->lowest_bit;
while (++offset < scan_base) {
if (!si->swap_map[offset]) {
spin_lock(&swap_lock);
goto checks;
}
if (unlikely(--latency_ration < 0)) {
cond_resched();
latency_ration = LATENCY_LIMIT;
}
}
spin_lock(&swap_lock);
goto checks;

no_page:
si->flags -= SWP_SCANNING;
Expand Down

0 comments on commit fa060c4

Please sign in to comment.