From: Hugh Dickins The low-latency unmap_vmas patch silently moved the zap_bytes test after the TLB finish and lockbreak and regather: why? That not only makes zap_bytes redundant (might as well use ZAP_BLOCK_SIZE), it makes the unmap_vmas level redundant too - it's all about saving TLB flushes when unmapping a series of small vmas. Move zap_bytes test back before the lockbreak, and delete the curious comment that a small zap block size doesn't matter: it's true need_flush prevents TLB flush when no page has been unmapped, but unmapping pages in small blocks involves many more TLB flushes than in large blocks. Signed-off-by: Hugh Dickins Signed-off-by: Andrew Morton --- 25-akpm/mm/memory.c | 9 +++------ 1 files changed, 3 insertions(+), 6 deletions(-) diff -puN mm/memory.c~vmtrunc-restore-unmap_vmas-zap_bytes mm/memory.c --- 25/mm/memory.c~vmtrunc-restore-unmap_vmas-zap_bytes 2004-11-17 20:46:38.297535408 -0800 +++ 25-akpm/mm/memory.c 2004-11-17 20:46:38.301534800 -0800 @@ -613,10 +613,6 @@ static void unmap_page_range(struct mmu_ } #ifdef CONFIG_PREEMPT -/* - * It's not an issue to have a small zap block size - TLB flushes - * only happen once normally, due to the tlb->need_flush optimization. - */ # define ZAP_BLOCK_SIZE (8 * PAGE_SIZE) #else /* No preempt: go for improved straight-line efficiency */ @@ -695,6 +691,9 @@ int unmap_vmas(struct mmu_gather **tlbp, start += block; zap_bytes -= block; + if ((long)zap_bytes > 0) + continue; + if (!atomic) { int fullmm = tlb_is_full_mm(*tlbp); tlb_finish_mmu(*tlbp, tlb_start, start); @@ -702,8 +701,6 @@ int unmap_vmas(struct mmu_gather **tlbp, *tlbp = tlb_gather_mmu(mm, fullmm); tlb_start_valid = 0; } - if ((long)zap_bytes > 0) - continue; zap_bytes = ZAP_BLOCK_SIZE; } } _