[RH7,RFC] mm/softdirty: reset soft-dirty tracking on fork

Submitted by Pavel Tikhomirov on Jan. 25, 2018, 12:10 p.m.


Message ID 20180125121036.30594-1-ptikhomirov@virtuozzo.com
State New
Series "mm/softdirty: reset soft-dirty tracking on fork"
Headers show

Commit Message

Pavel Tikhomirov Jan. 25, 2018, 12:10 p.m.
When a new task forked we leave soft-dirty bits on vmas and ptes
unchanged, so if we do iterative checkpoint-restore we will see
soft-clean memory for a process forked in target subtree between two
iterative checkpoints.

Imagine situation:

1. We have a task P and it has local variable V which has a value A.
2. Task P forks a child C with pid PID.
3. C changes the value of V to B.
4. We checkpoint memory for pid PID into an image and clear softdirty.
5. C exits.
6. P forks another child C' with the same pid PID. (use ns_last_pid)
(C and C' are indistinguishable (same starttime, same pid), except for
the value of V)
7. We do a second checkpoint for pid PID and we already have a memory
image for it from the previous step.

As we inherit dirty bits on fork, the stack for the task C' is
"soft-clean".  Checkpoint code relies on soft-dirty tracking and just
skips "soft-clean" pages, and will use corresponding page from previous
iteration on page restore.

8. Restore process C'' with pid PID from iterative snapshot.

Obviously C'' has value B in variable V not A as it was for C' at the
time of checkpoint. - What is _wrong_ checkpoint-restore!

To fix dirty-tracking we should reset dirty bits on fork, so if new task
appeared it will have soft-dirty memory and checkpoint does not skip
it's memory.

Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
 kernel/fork.c | 1 +
 1 file changed, 1 insertion(+)

Patch hide | download patch | download mbox

diff --git a/kernel/fork.c b/kernel/fork.c
index 645b489e33e0..1cd17c8277db 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -476,6 +476,7 @@  static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
 		if (anon_vma_fork(tmp, mpnt))
 			goto fail_nomem_anon_vma_fork;
 		tmp->vm_flags &= ~(VM_LOCKED);
+		tmp->vm_flags |= VM_SOFTDIRTY;
 		tmp->vm_next = tmp->vm_prev = NULL;
 		tmp->vm_private_data2 = NULL;
 		file = tmp->vm_file;