[PATCH] hugetlb: add cond_resched() to __unmap_hugepage_range()

Leon Hwang <[email protected]>
Newsgroups org.kvack.linux-mm,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
Packet receive timeouts were traced to sparse HugeTLB unmapping in
production. A task unmapping a sparse 2.5 TiB HugeTLB mapping could
remain in kernel context for over 40 ms without reaching a scheduling
point while walking empty huge PTEs. Although hard IRQs could still be
handled, the per-CPU ksoftirqd thread and other runnable tasks could not
run during that interval, delaying NET_RX softirq work queued to
ksoftirqd.

Add cond_resched() at the beginning of the hugepage loop so ksoftirqd
and other runnable tasks can run between iterations. Testing with
PREEMPT_NONE showed that the maximum interval between scheduling points
fell from over 40 ms to below 2.5 ms. Total time spent in
__unmap_hugepage_range() remained about 36 ms.

Reported-by: Lance Yang <[email protected]>
Tested-by: Lance Yang <[email protected]>
Signed-off-by: Leon Hwang <[email protected]>
---
 mm/hugetlb.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index dded1768193a..0a91aac2369f 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -5233,6 +5233,8 @@ void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct *vma,
 	last_addr_mask = hugetlb_mask_last_page(h);
 	address = start;
 	for (; address < end; address += sz) {
+		cond_resched();
+
 		ptep = hugetlb_walk(vma, address, sz);
 		if (!ptep) {
 			address |= last_addr_mask;
-- 
2.55.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.