diff --git a/mm/mmu_gather.c b/mm/mmu_gather.c index 205fdbb5792a9eb62e23fbdb43880f2924369def..1c66771f088bbac02de5e7c7b6a49f9694efccd8 100644 --- a/mm/mmu_gather.c +++ b/mm/mmu_gather.c @@ -46,8 +46,20 @@ static void tlb_batch_pages_flush(struct mmu_gather *tlb) struct mmu_gather_batch *batch; for (batch = &tlb->local; batch && batch->nr; batch = batch->next) { - free_pages_and_swap_cache(batch->pages, batch->nr); - batch->nr = 0; + struct page **pages = batch->pages; + + do { + /* + * limit free batch count when PAGE_SIZE > 4K + */ + unsigned int nr = min(512U, batch->nr); + + free_pages_and_swap_cache(pages, nr); + pages += nr; + batch->nr -= nr; + + cond_resched(); + } while (batch->nr); } tlb->active = &tlb->local; }