Projects STRLCPY criu Commits a0738c75
🤬
  • vma: Do not open similar VMAs multiple times

    On real apps it's typical to have sequences ov VMAs with
    absolutely the same file mapped. We've seen this dump-time
    and fixed multiple openings of map_files links with the
    file_borrowed flag.
    
    Restore situation is the same -- the vm_open() call in many
    cases re-open the same path with the same flags. This slows
    things down.
    
    To fix this -- chain VMAs with mapped files to each other
    and only the first one opens the file and only the last
    one closes it.
    
    ✓ travis-ci: success for mem: Do not re-open files for mappings when not required
    Signed-off-by: Pavel Emelyanov <[email protected]>
  • Loading...
  • Pavel Emelyanov committed 7 years ago
    a0738c75
    1 parent 77e9c5d8
  • ■ ■ ■ ■ ■ ■
    criu/files-reg.c
    skipped 1623 lines
    1624 1624   return open_reg_fd(fd);
    1625 1625  }
    1626 1626   
     1627 +static int borrow_filemap(int pid, struct vma_area *vma)
     1628 +{
     1629 + struct vma_area *fvma = vma->fvma;
     1630 + 
     1631 + BUG_ON(!(fvma->e->status & VMA_NO_CLOSE));
     1632 + vma->e->fd = fvma->e->fd;
     1633 + 
     1634 + return 0;
     1635 +}
     1636 + 
    1627 1637  static int open_filemap(int pid, struct vma_area *vma)
    1628 1638  {
    1629 1639   u32 flags;
    skipped 16 lines
    1646 1656   return 0;
    1647 1657  }
    1648 1658   
    1649  -int collect_filemap(struct vma_area *vma)
     1659 +int collect_filemap(struct vma_area *vma, struct vma_file_ctx *ctx)
    1650 1660  {
    1651 1661   struct file_desc *fd;
    1652 1662   
    skipped 12 lines
    1665 1675   return -1;
    1666 1676   
    1667 1677   vma->vmfd = fd;
    1668  - vma->vm_open = open_filemap;
     1678 + if (ctx->vma && ctx->flags == vma->e->flags && ctx->fd == fd) {
     1679 + vma->vm_open = borrow_filemap;
     1680 + vma->fvma = ctx->vma;
     1681 + ctx->vma->e->status |= VMA_NO_CLOSE;
     1682 + /* Change VMA so that next borrower sets NO_CLOSE on us */
     1683 + ctx->vma = vma;
     1684 + } else {
     1685 + vma->vm_open = open_filemap;
     1686 + ctx->flags = vma->e->fdflags;
     1687 + ctx->fd = fd;
     1688 + ctx->vma = vma;
     1689 + }
     1690 + 
    1669 1691   return 0;
    1670 1692  }
    1671 1693   
    skipped 83 lines
  • ■ ■ ■ ■ ■
    criu/include/files-reg.h
    skipped 39 lines
    40 40   
    41 41  extern struct file_desc *try_collect_special_file(u32 id, int optional);
    42 42  #define collect_special_file(id) try_collect_special_file(id, 0)
    43  -extern int collect_filemap(struct vma_area *);
     43 +struct vma_file_ctx {
     44 + u32 flags;
     45 + struct file_desc *fd;
     46 + struct vma_area *vma;
     47 +};
     48 +extern int collect_filemap(struct vma_area *, struct vma_file_ctx *ctx);
    44 49   
    45 50  extern int collect_remaps_and_regfiles(void);
    46 51   
    skipped 11 lines
  • ■ ■ ■ ■ ■
    criu/include/image.h
    skipped 88 lines
    89 89  #define VMA_AREA_VVAR (1 << 12)
    90 90  #define VMA_AREA_AIORING (1 << 13)
    91 91   
     92 +#define VMA_NO_CLOSE (1 << 28)
    92 93  #define VMA_NO_PROT_WRITE (1 << 29)
    93 94  #define VMA_PREMMAPED (1 << 30)
    94 95  #define VMA_UNSUPP (1 << 31)
    skipped 78 lines
  • ■ ■ ■ ■ ■
    criu/include/vma.h
    skipped 52 lines
    53 53   int (*vm_open)(int pid, struct vma_area *vma);
    54 54   struct file_desc *vmfd;
    55 55   struct vma_area *pvma; /* parent for inherited VMAs */
     56 + struct vma_area *fvma; /* vma from which to borrow a file */
    56 57   unsigned long *page_bitmap; /* existent pages */
    57 58   unsigned long premmaped_addr; /* restore only */
    58 59   
    skipped 69 lines
  • ■ ■ ■ ■ ■ ■
    criu/mem.c
    skipped 449 lines
    450 450   int ret = -1, vn = 0;
    451 451   struct cr_img *img;
    452 452   struct rst_info *ri = rsti(i);
     453 + struct vma_file_ctx ctx = {};
    453 454   
    454 455   img = open_image(CR_FD_MM, O_RSTR, pid);
    455 456   if (!img)
    skipped 53 lines
    509 510   ret = collect_shmem(pid, vma);
    510 511   else if (vma_area_is(vma, VMA_FILE_PRIVATE) ||
    511 512   vma_area_is(vma, VMA_FILE_SHARED))
    512  - ret = collect_filemap(vma);
     513 + ret = collect_filemap(vma, &ctx);
    513 514   else if (vma_area_is(vma, VMA_AREA_SOCKET))
    514 515   ret = collect_socket_map(vma);
    515 516   else
    skipped 160 lines
    676 677   return -1;
    677 678   }
    678 679   
    679  - if (vma_area_is(vma, VMA_FILE_PRIVATE))
     680 + if (vma_area_is(vma, VMA_FILE_PRIVATE) &&
     681 + !vma_area_is(vma, VMA_NO_CLOSE))
    680 682   close(vma->e->fd);
    681 683   } else {
    682 684   void *paddr;
    skipped 455 lines
  • ■ ■ ■ ■ ■
    criu/pie/restorer.c
    skipped 617 lines
    618 618   vma_entry->fd,
    619 619   vma_entry->pgoff);
    620 620   
    621  - if (vma_entry->fd != -1)
     621 + if ((vma_entry->fd != -1) &&
     622 + !(vma_entry->status & VMA_NO_CLOSE))
    622 623   sys_close(vma_entry->fd);
    623 624   
    624 625   return addr;
    skipped 969 lines
Please wait...
Page is in error, reload to recover