Commit 367b39f0 authored by Hugh Dickins's avatar Hugh Dickins Committed by Linus Torvalds

[PATCH] ptwalk: copy_pte_range hang

This patch is the odd-one-out of the sequence.  The one before adjusted
copy_pte_range from a for loop to a do while loop, and it was therefore
simplest to check for lockbreak before copying pte: possibility that it
might keep getting preempted without making progress under some loads.

Some loads such as startup: 2*HT*P4 with preemption cannot even reach
multiuser login.  Suspect needs_lockbreak is broken, can get in a state
when it remains forever true.  Investigate that later: for now, and for
all time, it makes sense to aim for a little progress before breaking
out; and we can manage more pte_nones than copies.
Signed-off-by: default avatarHugh Dickins <hugh@veritas.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent a5afe74c
......@@ -328,6 +328,7 @@ static int copy_pte_range(struct mm_struct *dst_mm, struct mm_struct *src_mm,
{
pte_t *src_pte, *dst_pte;
unsigned long vm_flags = vma->vm_flags;
int progress;
again:
dst_pte = pte_alloc_map(dst_mm, dst_pmd, addr);
......@@ -335,19 +336,23 @@ static int copy_pte_range(struct mm_struct *dst_mm, struct mm_struct *src_mm,
return -ENOMEM;
src_pte = pte_offset_map_nested(src_pmd, addr);
progress = 0;
spin_lock(&src_mm->page_table_lock);
do {
/*
* We are holding two locks at this point - either of them
* could generate latencies in another task on another CPU.
*/
if (need_resched() ||
if (progress >= 32 && (need_resched() ||
need_lockbreak(&src_mm->page_table_lock) ||
need_lockbreak(&dst_mm->page_table_lock))
need_lockbreak(&dst_mm->page_table_lock)))
break;
if (pte_none(*src_pte))
if (pte_none(*src_pte)) {
progress++;
continue;
}
copy_one_pte(dst_mm, src_mm, dst_pte, src_pte, vm_flags, addr);
progress += 8;
} while (dst_pte++, src_pte++, addr += PAGE_SIZE, addr != end);
spin_unlock(&src_mm->page_table_lock);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment