diff options
author | Hugh Dickins <hugh@veritas.com> | 2006-03-17 02:04:09 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-17 10:51:26 -0500 |
commit | 6f5e6b9e69bf043074a0edabe3d271899c34eb79 (patch) | |
tree | 8833d7267d6653a2bf786b055f05640c9a64dc4d /mm | |
parent | 7670f023aabd976c25862e4c6fb9f6d9d2758153 (diff) |
[PATCH] fix free swap cache latency
Lee Revell reported 28ms latency when process with lots of swapped memory
exits.
2.6.15 introduced a latency regression when unmapping: in accounting the
zap_work latency breaker, pte_none counted 1, pte_present PAGE_SIZE, but a
swap entry counted nothing at all. We think of pages present as the slow
case, but Lee's trace shows that free_swap_and_cache's radix tree lookup
can make a lot of work - and we could have been doing it many thousands of
times without a latency break.
Move the zap_work update up to account swap entries like pages present.
This does account non-linear pte_file entries, and unmap_mapping_range
skipping over swap entries, by the same amount even though they're quick:
but neither of those cases deserves complicating the code (and they're
treated no worse than they were in 2.6.14).
Signed-off-by: Hugh Dickins <hugh@veritas.com>
Acked-by: Nick Piggin <npiggin@suse.de>
Acked-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'mm')
-rw-r--r-- | mm/memory.c | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/mm/memory.c b/mm/memory.c index 9abc6008544b..85e80a57db29 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
@@ -623,11 +623,12 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb, | |||
623 | (*zap_work)--; | 623 | (*zap_work)--; |
624 | continue; | 624 | continue; |
625 | } | 625 | } |
626 | |||
627 | (*zap_work) -= PAGE_SIZE; | ||
628 | |||
626 | if (pte_present(ptent)) { | 629 | if (pte_present(ptent)) { |
627 | struct page *page; | 630 | struct page *page; |
628 | 631 | ||
629 | (*zap_work) -= PAGE_SIZE; | ||
630 | |||
631 | page = vm_normal_page(vma, addr, ptent); | 632 | page = vm_normal_page(vma, addr, ptent); |
632 | if (unlikely(details) && page) { | 633 | if (unlikely(details) && page) { |
633 | /* | 634 | /* |