Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] swap: scan_swap_map latency breaks

The get_swap_page/scan_swap_map latency can be so bad that even those without
preemption configured deserve relief: periodically cond_resched.

Signed-off-by: Hugh Dickins <hugh@veritas.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

Hugh Dickins and committed by
Linus Torvalds
048c27fd 52b7efdb

+12 -2
+12 -2
mm/swapfile.c
··· 56 56 */ 57 57 static DECLARE_RWSEM(swap_unplug_sem); 58 58 59 - #define SWAPFILE_CLUSTER 256 60 - 61 59 void swap_unplug_io_fn(struct backing_dev_info *unused_bdi, struct page *page) 62 60 { 63 61 swp_entry_t entry; ··· 82 84 up_read(&swap_unplug_sem); 83 85 } 84 86 87 + #define SWAPFILE_CLUSTER 256 88 + #define LATENCY_LIMIT 256 89 + 85 90 static inline unsigned long scan_swap_map(struct swap_info_struct *si) 86 91 { 87 92 unsigned long offset, last_in_cluster; 93 + int latency_ration = LATENCY_LIMIT; 88 94 89 95 /* 90 96 * We try to cluster swap pages by allocating them sequentially ··· 118 116 swap_device_lock(si); 119 117 si->cluster_next = offset-SWAPFILE_CLUSTER-1; 120 118 goto cluster; 119 + } 120 + if (unlikely(--latency_ration < 0)) { 121 + cond_resched(); 122 + latency_ration = LATENCY_LIMIT; 121 123 } 122 124 } 123 125 swap_device_lock(si); ··· 158 152 if (!si->swap_map[offset]) { 159 153 swap_device_lock(si); 160 154 goto checks; 155 + } 156 + if (unlikely(--latency_ration < 0)) { 157 + cond_resched(); 158 + latency_ration = LATENCY_LIMIT; 161 159 } 162 160 } 163 161 swap_device_lock(si);