Skip to content

Commit 266f150

Browse files
Liu Huaavagin
authored andcommitted
uffd: Disable image deduplication after fork
After a fork, both the child and parent processes may trigger a page fault (#PF) at the same virtual address, referencing the same position in the page image. If deduplication is enabled, the last process to trigger the page fault will fail. Therefore, deduplication should be disabled after a fork to prevent this issue. Signed-off-by: Liu Hua <[email protected]>
1 parent a63eafd commit 266f150

File tree

3 files changed

+17
-1
lines changed

3 files changed

+17
-1
lines changed

criu/include/pagemap.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ struct page_read {
5858
/* Whether or not pages can be read in PIE code */
5959
bool pieok;
6060

61+
/* Whether or not disable image deduplication*/
62+
bool disable_dedup;
63+
6164
/* Private data of reader */
6265
struct cr_img *pmi;
6366
struct cr_img *pi;
@@ -112,6 +115,8 @@ int pagemap_render_iovec(struct list_head *from, struct task_restore_args *ta);
112115
*/
113116
extern void dup_page_read(struct page_read *src, struct page_read *dst);
114117

118+
extern void page_read_disable_dedup(struct page_read *pr);
119+
115120
extern int dedup_one_iovec(struct page_read *pr, unsigned long base, unsigned long len);
116121

117122
static inline unsigned long pagemap_len(PagemapEntry *pe)

criu/pagemap.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ static int read_local_page(struct page_read *pr, unsigned long vaddr, unsigned l
261261
break;
262262
}
263263

264-
if (opts.auto_dedup) {
264+
if (opts.auto_dedup && !pr->disable_dedup) {
265265
ret = punch_hole(pr, pr->pi_off, len, false);
266266
if (ret == -1)
267267
return -1;
@@ -792,6 +792,7 @@ int open_page_read_at(int dfd, unsigned long img_id, struct page_read *pr, int p
792792
pr->bunch.iov_base = NULL;
793793
pr->pmes = NULL;
794794
pr->pieok = false;
795+
pr->disable_dedup = false;
795796

796797
pr->pmi = open_image_at(dfd, i_typ, O_RSTR, img_id);
797798
if (!pr->pmi)
@@ -852,6 +853,14 @@ int open_page_read(unsigned long img_id, struct page_read *pr, int pr_flags)
852853

853854
#define DUP_IDS_BASE 1000
854855

856+
void page_read_disable_dedup(struct page_read *pr)
857+
{
858+
pr_debug("disable dedup, id: %d\n", pr->id);
859+
pr->disable_dedup = true;
860+
if (pr->parent)
861+
page_read_disable_dedup(pr->parent);
862+
}
863+
855864
void dup_page_read(struct page_read *src, struct page_read *dst)
856865
{
857866
static int dup_ids = 1;

criu/uffd.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1098,6 +1098,8 @@ static int handle_fork(struct lazy_pages_info *parent_lpi, struct uffd_msg *msg)
10981098

10991099
lpi_get(lpi->parent);
11001100

1101+
page_read_disable_dedup(&parent_lpi->pr);
1102+
page_read_disable_dedup(&lpi->pr);
11011103
return 1;
11021104

11031105
out:

0 commit comments

Comments
 (0)