diff --git a/mm/swapfile.c b/mm/swapfile.c index 1743386d2401..b365cbe99cc3 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -732,6 +732,7 @@ static int scan_swap_map_slots(struct swap_info_struct *si, unsigned long last_in_cluster = 0; int latency_ration = LATENCY_LIMIT; int n_ret = 0; + bool scanned_many = false; /* * We try to cluster swap pages by allocating them sequentially @@ -863,6 +864,25 @@ static int scan_swap_map_slots(struct swap_info_struct *si, goto checks; } + /* + * Even if there's no free clusters available (fragmented), + * try to scan a little more quickly with lock held unless we + * have scanned too many slots already. + */ + if (!scanned_many) { + unsigned long scan_limit; + + if (offset < scan_base) + scan_limit = scan_base; + else + scan_limit = si->highest_bit; + for (; offset <= scan_limit && --latency_ration > 0; + offset++) { + if (!si->swap_map[offset]) + goto checks; + } + } + done: si->flags -= SWP_SCANNING; return n_ret; @@ -881,6 +901,7 @@ static int scan_swap_map_slots(struct swap_info_struct *si, if (unlikely(--latency_ration < 0)) { cond_resched(); latency_ration = LATENCY_LIMIT; + scanned_many = true; } } offset = si->lowest_bit; @@ -896,6 +917,7 @@ static int scan_swap_map_slots(struct swap_info_struct *si, if (unlikely(--latency_ration < 0)) { cond_resched(); latency_ration = LATENCY_LIMIT; + scanned_many = true; } offset++; }