On Thu, Apr 24, 2014 at 1:02 PM, Hugh Dickins wrote: > > There is no need to free all the pages immediately after doing the > TLB flush: that's merely how it's structured at present; page freeing > can be left until the end as now, or when out from under the spinlock. Hmm. In fact, if we to the actual TLB flush still under the ptl lock, the current code will "just work". We can just keep the set_page_dirty() at the scanning part, because there's no race with mkclean() as long as we hold the lock. So all that requires would be to split our current "tlb_flush_mmu()" into the actual tlb flushing part, and the free_pages_and_swap_cache() part. And then we do the TLB flushing inside the ptl, to make sure that we flush tlb's before anybody can do mkclean(). And then we make the case of doing "set_page_dirty()" force a TLB flush (but *not* force breaking out of the loop). This gives us the best of all worlds: - maximum batching for the common case (no shared dirty pte entries) - if we find any dirty page table entries, we will batch as much as we can within the ptl lock - we do the TLB shootdown holding the page table lock (but that's not new - ptep_get_and_flush does the same - but we do the batched freeing of pages outside the lock - and the patch is pretty simple too (no need for the "one dirty bit in the 'struct page *' pointer" games. IOW, how about the attached patch that entirely replaces my previous two patches. DaveH - does this fix your test-case, while _not_ introducing any new BUG_ON() triggers? I didn't test the patch, maybe I did something stupid. It compiles for me, but it only works for the HAVE_GENERIC_MMU_GATHER case, but introducing tlb_flush_mmu_tlbonly() and tlb_flush_mmu_free() into the non-generic cases should be trivial, since they really are just that old "tlb_flush_mmu()" function split up (the tlb_flush_mmu() function remains available for other non-forced flush users) So assuming this does work for DaveH, then the arm/ia64/um/whatever people would need to do those trivial transforms too, but it really shouldn't be too painful. Comments? DaveH? Linus