[PATCH] mm: copy_pte_range progress fix
My latency breaking in copy_pte_range didn't work as intended: instead of checking at regularish intervals, after the first interval it checked every time around the loop, too impatient to be preempted. Fix that. Signed-off-by: Hugh Dickins <hugh@veritas.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
09ad4bbc3a
commit
e040f218bb
1 changed files with 8 additions and 6 deletions
14
mm/memory.c
14
mm/memory.c
|
@ -410,7 +410,7 @@ static int copy_pte_range(struct mm_struct *dst_mm, struct mm_struct *src_mm,
|
||||||
{
|
{
|
||||||
pte_t *src_pte, *dst_pte;
|
pte_t *src_pte, *dst_pte;
|
||||||
unsigned long vm_flags = vma->vm_flags;
|
unsigned long vm_flags = vma->vm_flags;
|
||||||
int progress;
|
int progress = 0;
|
||||||
|
|
||||||
again:
|
again:
|
||||||
dst_pte = pte_alloc_map(dst_mm, dst_pmd, addr);
|
dst_pte = pte_alloc_map(dst_mm, dst_pmd, addr);
|
||||||
|
@ -418,17 +418,19 @@ static int copy_pte_range(struct mm_struct *dst_mm, struct mm_struct *src_mm,
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
src_pte = pte_offset_map_nested(src_pmd, addr);
|
src_pte = pte_offset_map_nested(src_pmd, addr);
|
||||||
|
|
||||||
progress = 0;
|
|
||||||
spin_lock(&src_mm->page_table_lock);
|
spin_lock(&src_mm->page_table_lock);
|
||||||
do {
|
do {
|
||||||
/*
|
/*
|
||||||
* We are holding two locks at this point - either of them
|
* We are holding two locks at this point - either of them
|
||||||
* could generate latencies in another task on another CPU.
|
* could generate latencies in another task on another CPU.
|
||||||
*/
|
*/
|
||||||
if (progress >= 32 && (need_resched() ||
|
if (progress >= 32) {
|
||||||
need_lockbreak(&src_mm->page_table_lock) ||
|
progress = 0;
|
||||||
need_lockbreak(&dst_mm->page_table_lock)))
|
if (need_resched() ||
|
||||||
break;
|
need_lockbreak(&src_mm->page_table_lock) ||
|
||||||
|
need_lockbreak(&dst_mm->page_table_lock))
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (pte_none(*src_pte)) {
|
if (pte_none(*src_pte)) {
|
||||||
progress++;
|
progress++;
|
||||||
continue;
|
continue;
|
||||||
|
|
Loading…
Reference in a new issue