diff options
author | Hugh Dickins <hugh@veritas.com> | 2005-09-03 15:54:40 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@evo.osdl.org> | 2005-09-05 00:05:41 -0700 |
commit | 048c27fd72816b44e096997d1c6901c3abbfd45b (patch) | |
tree | 159a00b71ce9db161a48e4fc07b212db455a2cf1 /mm/swapfile.c | |
parent | 52b7efdbe5f5696fc80338560a3fc51e0b0a993c (diff) |
[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>
Diffstat (limited to 'mm/swapfile.c')
-rw-r--r-- | mm/swapfile.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/mm/swapfile.c b/mm/swapfile.c index fdee145afc6f..e675ae55f87d 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -56,8 +56,6 @@ static DECLARE_MUTEX(swapon_sem); */ static DECLARE_RWSEM(swap_unplug_sem); -#define SWAPFILE_CLUSTER 256 - void swap_unplug_io_fn(struct backing_dev_info *unused_bdi, struct page *page) { swp_entry_t entry; @@ -84,9 +82,13 @@ void swap_unplug_io_fn(struct backing_dev_info *unused_bdi, struct page *page) up_read(&swap_unplug_sem); } +#define SWAPFILE_CLUSTER 256 +#define LATENCY_LIMIT 256 + static inline unsigned long scan_swap_map(struct swap_info_struct *si) { unsigned long offset, last_in_cluster; + int latency_ration = LATENCY_LIMIT; /* * We try to cluster swap pages by allocating them sequentially @@ -117,6 +119,10 @@ static inline unsigned long scan_swap_map(struct swap_info_struct *si) si->cluster_next = offset-SWAPFILE_CLUSTER-1; goto cluster; } + if (unlikely(--latency_ration < 0)) { + cond_resched(); + latency_ration = LATENCY_LIMIT; + } } swap_device_lock(si); goto lowest; @@ -153,6 +159,10 @@ checks: if (!(si->flags & SWP_WRITEOK)) swap_device_lock(si); goto checks; } + if (unlikely(--latency_ration < 0)) { + cond_resched(); + latency_ration = LATENCY_LIMIT; + } } swap_device_lock(si); goto lowest; |