On Mon 29-07-19 16:10:37, Minchan Kim wrote: > In our testing(carmera recording), Miguel and Wei found unmap_page_range > takes above 6ms with preemption disabled easily. When I see that, the > reason is it holds page table spinlock during entire 512 page operation > in a PMD. 6.2ms is never trivial for user experince if RT task couldn't > run in the time because it could make frame drop or glitch audio problem.
Where is the time spent during the tear down? 512 pages doesn't sound like a lot to tear down. Is it the TLB flushing? > This patch adds preemption point like coyp_pte_range. > > Reported-by: Miguel de Dios <miguelded...@google.com> > Reported-by: Wei Wang <w...@google.com> > Cc: Michal Hocko <mho...@kernel.org> > Cc: Johannes Weiner <han...@cmpxchg.org> > Cc: Mel Gorman <mgor...@techsingularity.net> > Signed-off-by: Minchan Kim <minc...@kernel.org> > --- > mm/memory.c | 19 ++++++++++++++++--- > 1 file changed, 16 insertions(+), 3 deletions(-) > > diff --git a/mm/memory.c b/mm/memory.c > index 2e796372927fd..bc3e0c5e4f89b 100644 > --- a/mm/memory.c > +++ b/mm/memory.c > @@ -1007,6 +1007,7 @@ static unsigned long zap_pte_range(struct mmu_gather > *tlb, > struct zap_details *details) > { > struct mm_struct *mm = tlb->mm; > + int progress = 0; > int force_flush = 0; > int rss[NR_MM_COUNTERS]; > spinlock_t *ptl; > @@ -1022,7 +1023,16 @@ static unsigned long zap_pte_range(struct mmu_gather > *tlb, > flush_tlb_batched_pending(mm); > arch_enter_lazy_mmu_mode(); > do { > - pte_t ptent = *pte; > + pte_t ptent; > + > + if (progress >= 32) { > + progress = 0; > + if (need_resched()) > + break; > + } > + progress += 8; Why 8? > + > + ptent = *pte; > if (pte_none(ptent)) > continue; > > @@ -1123,8 +1133,11 @@ static unsigned long zap_pte_range(struct mmu_gather > *tlb, > if (force_flush) { > force_flush = 0; > tlb_flush_mmu(tlb); > - if (addr != end) > - goto again; > + } > + > + if (addr != end) { > + progress = 0; > + goto again; > } > > return addr; > -- > 2.22.0.709.g102302147b-goog -- Michal Hocko SUSE Labs