mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-22 01:51:51 +00:00
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 <weldonliu@tencent.com>
This commit is contained in:
parent
a63eafd62d
commit
266f15028c
@ -58,6 +58,9 @@ struct page_read {
|
||||
/* Whether or not pages can be read in PIE code */
|
||||
bool pieok;
|
||||
|
||||
/* Whether or not disable image deduplication*/
|
||||
bool disable_dedup;
|
||||
|
||||
/* Private data of reader */
|
||||
struct cr_img *pmi;
|
||||
struct cr_img *pi;
|
||||
@ -112,6 +115,8 @@ int pagemap_render_iovec(struct list_head *from, struct task_restore_args *ta);
|
||||
*/
|
||||
extern void dup_page_read(struct page_read *src, struct page_read *dst);
|
||||
|
||||
extern void page_read_disable_dedup(struct page_read *pr);
|
||||
|
||||
extern int dedup_one_iovec(struct page_read *pr, unsigned long base, unsigned long len);
|
||||
|
||||
static inline unsigned long pagemap_len(PagemapEntry *pe)
|
||||
|
@ -261,7 +261,7 @@ static int read_local_page(struct page_read *pr, unsigned long vaddr, unsigned l
|
||||
break;
|
||||
}
|
||||
|
||||
if (opts.auto_dedup) {
|
||||
if (opts.auto_dedup && !pr->disable_dedup) {
|
||||
ret = punch_hole(pr, pr->pi_off, len, false);
|
||||
if (ret == -1)
|
||||
return -1;
|
||||
@ -792,6 +792,7 @@ int open_page_read_at(int dfd, unsigned long img_id, struct page_read *pr, int p
|
||||
pr->bunch.iov_base = NULL;
|
||||
pr->pmes = NULL;
|
||||
pr->pieok = false;
|
||||
pr->disable_dedup = false;
|
||||
|
||||
pr->pmi = open_image_at(dfd, i_typ, O_RSTR, img_id);
|
||||
if (!pr->pmi)
|
||||
@ -852,6 +853,14 @@ int open_page_read(unsigned long img_id, struct page_read *pr, int pr_flags)
|
||||
|
||||
#define DUP_IDS_BASE 1000
|
||||
|
||||
void page_read_disable_dedup(struct page_read *pr)
|
||||
{
|
||||
pr_debug("disable dedup, id: %d\n", pr->id);
|
||||
pr->disable_dedup = true;
|
||||
if (pr->parent)
|
||||
page_read_disable_dedup(pr->parent);
|
||||
}
|
||||
|
||||
void dup_page_read(struct page_read *src, struct page_read *dst)
|
||||
{
|
||||
static int dup_ids = 1;
|
||||
|
@ -1098,6 +1098,8 @@ static int handle_fork(struct lazy_pages_info *parent_lpi, struct uffd_msg *msg)
|
||||
|
||||
lpi_get(lpi->parent);
|
||||
|
||||
page_read_disable_dedup(&parent_lpi->pr);
|
||||
page_read_disable_dedup(&lpi->pr);
|
||||
return 1;
|
||||
|
||||
out:
|
||||
|
Loading…
x
Reference in New Issue
Block a user