Commit dc7abdfb authored by Pavel Emelyanov's avatar Pavel Emelyanov

vma: Don't lookup file_desc for vma twice

We do it first -- on collect, second -- on restore. The
2nd lookup is excessive, we can put fd pointer on vm_area
at lookup and reuse one later.
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent fd412019
...@@ -226,7 +226,7 @@ static int map_private_vma(pid_t pid, struct vma_area *vma, void *tgt_addr, ...@@ -226,7 +226,7 @@ static int map_private_vma(pid_t pid, struct vma_area *vma, void *tgt_addr,
struct vma_area *p = *pvma; struct vma_area *p = *pvma;
if (vma_area_is(vma, VMA_FILE_PRIVATE)) { if (vma_area_is(vma, VMA_FILE_PRIVATE)) {
ret = get_filemap_fd(pid, vma->e); ret = get_filemap_fd(vma);
if (ret < 0) { if (ret < 0) {
pr_err("Can't fixup VMA's fd\n"); pr_err("Can't fixup VMA's fd\n");
return -1; return -1;
...@@ -583,7 +583,7 @@ static int open_vmas(int pid) ...@@ -583,7 +583,7 @@ static int open_vmas(int pid)
else if (vma_area_is(vma, VMA_ANON_SHARED)) else if (vma_area_is(vma, VMA_ANON_SHARED))
ret = get_shmem_fd(pid, vma->e); ret = get_shmem_fd(pid, vma->e);
else if (vma_area_is(vma, VMA_FILE_SHARED)) else if (vma_area_is(vma, VMA_FILE_SHARED))
ret = get_filemap_fd(pid, vma->e); ret = get_filemap_fd(vma);
else if (vma_area_is(vma, VMA_AREA_SOCKET)) else if (vma_area_is(vma, VMA_AREA_SOCKET))
ret = get_socket_fd(pid, vma->e); ret = get_socket_fd(pid, vma->e);
else else
......
...@@ -118,7 +118,7 @@ static void collect_fifo_fd(struct file_desc *d, ...@@ -118,7 +118,7 @@ static void collect_fifo_fd(struct file_desc *d,
struct fifo_info *info; struct fifo_info *info;
info = container_of(d, struct fifo_info, d); info = container_of(d, struct fifo_info, d);
if (collect_special_file(info->fe->id)) if (collect_special_file(info->fe->id) == NULL)
BUG(); BUG();
collect_gen_fd(fle, ri); collect_gen_fd(fle, ri);
......
...@@ -672,14 +672,26 @@ static int open_fe_fd(struct file_desc *fd) ...@@ -672,14 +672,26 @@ static int open_fe_fd(struct file_desc *fd)
int open_reg_by_id(u32 id) int open_reg_by_id(u32 id)
{ {
/* /*
* This one gets called by exe link, chroot, * This one gets called by exe link, chroot and cwd
* cwd and file vmas restoring code. No need * restoring code. No need in calling lseek on either
* in calling lseek on either of them. * of them.
*/ */
return open_path_by_id(id, do_open_reg_noseek, NULL); return open_path_by_id(id, do_open_reg_noseek, NULL);
} }
int get_filemap_fd(struct vma_area *vma)
{
/*
* Thevma->fd should have been assigned in collect_filemap
*
* We open file w/o lseek, as mappings don't care about it
*/
BUG_ON(vma->fd == NULL);
return open_path(vma->fd, do_open_reg_noseek, NULL);
}
static void remap_get(struct file_desc *fdesc, char typ) static void remap_get(struct file_desc *fdesc, char typ)
{ {
struct reg_file_info *rfi; struct reg_file_info *rfi;
...@@ -708,7 +720,7 @@ static struct file_desc_ops reg_desc_ops = { ...@@ -708,7 +720,7 @@ static struct file_desc_ops reg_desc_ops = {
.collect_fd = collect_reg_fd, .collect_fd = collect_reg_fd,
}; };
int collect_special_file(u32 id) struct file_desc *collect_special_file(u32 id)
{ {
struct file_desc *fdesc; struct file_desc *fdesc;
...@@ -722,11 +734,11 @@ int collect_special_file(u32 id) ...@@ -722,11 +734,11 @@ int collect_special_file(u32 id)
fdesc = find_file_desc_raw(FD_TYPES__REG, id); fdesc = find_file_desc_raw(FD_TYPES__REG, id);
if (fdesc == NULL) { if (fdesc == NULL) {
pr_err("No entry for reg-file-ID %#x\n", id); pr_err("No entry for reg-file-ID %#x\n", id);
return -1; return NULL;
} }
remap_get(fdesc, 's'); remap_get(fdesc, 's');
return 0; return fdesc;
} }
static int collect_one_regfile(void *o, ProtobufCMessage *base) static int collect_one_regfile(void *o, ProtobufCMessage *base)
......
...@@ -1087,11 +1087,6 @@ out: ...@@ -1087,11 +1087,6 @@ out:
return ret; return ret;
} }
int get_filemap_fd(int pid, VmaEntry *vma_entry)
{
return open_reg_by_id(vma_entry->shmid);
}
int shared_fdt_prepare(struct pstree_item *item) int shared_fdt_prepare(struct pstree_item *item)
{ {
struct pstree_item *parent = item->parent; struct pstree_item *parent = item->parent;
......
...@@ -34,7 +34,7 @@ extern int dump_one_reg_file(int lfd, u32 id, const struct fd_parms *p); ...@@ -34,7 +34,7 @@ extern int dump_one_reg_file(int lfd, u32 id, const struct fd_parms *p);
extern struct file_remap *lookup_ghost_remap(u32 dev, u32 ino); extern struct file_remap *lookup_ghost_remap(u32 dev, u32 ino);
extern void remap_put(struct file_remap *remap); extern void remap_put(struct file_remap *remap);
extern int collect_special_file(u32 id); extern struct file_desc *collect_special_file(u32 id);
extern struct collect_image_info reg_file_cinfo; extern struct collect_image_info reg_file_cinfo;
extern struct collect_image_info remap_cinfo; extern struct collect_image_info remap_cinfo;
......
...@@ -145,7 +145,7 @@ extern int prepare_fds(struct pstree_item *me); ...@@ -145,7 +145,7 @@ extern int prepare_fds(struct pstree_item *me);
extern int prepare_fd_pid(struct pstree_item *me); extern int prepare_fd_pid(struct pstree_item *me);
extern int prepare_ctl_tty(int pid, struct rst_info *rst_info, u32 ctl_tty_id); extern int prepare_ctl_tty(int pid, struct rst_info *rst_info, u32 ctl_tty_id);
extern int prepare_shared_fdinfo(void); extern int prepare_shared_fdinfo(void);
extern int get_filemap_fd(int pid, VmaEntry *vma_entry); extern int get_filemap_fd(struct vma_area *);
extern int prepare_fs(int pid); extern int prepare_fs(int pid);
extern int set_fd_flags(int fd, int flags); extern int set_fd_flags(int fd, int flags);
......
...@@ -21,6 +21,8 @@ static inline void vm_area_list_init(struct vm_area_list *vml) ...@@ -21,6 +21,8 @@ static inline void vm_area_list_init(struct vm_area_list *vml)
vml->longest = 0; vml->longest = 0;
} }
struct file_desc;
struct vma_area { struct vma_area {
struct list_head list; struct list_head list;
VmaEntry *e; VmaEntry *e;
...@@ -28,6 +30,7 @@ struct vma_area { ...@@ -28,6 +30,7 @@ struct vma_area {
union { union {
int vm_file_fd; int vm_file_fd;
int vm_socket_id; int vm_socket_id;
struct file_desc *fd;
}; };
unsigned long *page_bitmap; /* existent pages */ unsigned long *page_bitmap; /* existent pages */
unsigned long *ppage_bitmap; /* parent's existent pages */ unsigned long *ppage_bitmap; /* parent's existent pages */
......
...@@ -342,9 +342,16 @@ int parasite_dump_pages_seized(struct parasite_ctl *ctl, ...@@ -342,9 +342,16 @@ int parasite_dump_pages_seized(struct parasite_ctl *ctl,
return ret; return ret;
} }
static inline int collect_filemap(VmaEntry *vme) static inline int collect_filemap(struct vma_area *vma)
{ {
return collect_special_file(vme->shmid); struct file_desc *fd;
fd = collect_special_file(vma->e->shmid);
if (!fd)
return -1;
vma->fd = fd;
return 0;
} }
int prepare_mm_pid(struct pstree_item *i) int prepare_mm_pid(struct pstree_item *i)
...@@ -365,7 +372,7 @@ int prepare_mm_pid(struct pstree_item *i) ...@@ -365,7 +372,7 @@ int prepare_mm_pid(struct pstree_item *i)
if (ret < 0) if (ret < 0)
return -1; return -1;
if (collect_special_file(ri->mm->exe_file_id)) if (collect_special_file(ri->mm->exe_file_id) == NULL)
return -1; return -1;
pr_debug("Found %zd VMAs in image\n", ri->mm->n_vmas); pr_debug("Found %zd VMAs in image\n", ri->mm->n_vmas);
...@@ -415,7 +422,7 @@ int prepare_mm_pid(struct pstree_item *i) ...@@ -415,7 +422,7 @@ int prepare_mm_pid(struct pstree_item *i)
ret = collect_shmem(pid, vma->e); ret = collect_shmem(pid, vma->e);
else if (vma_area_is(vma, VMA_FILE_PRIVATE) || else if (vma_area_is(vma, VMA_FILE_PRIVATE) ||
vma_area_is(vma, VMA_FILE_SHARED)) vma_area_is(vma, VMA_FILE_SHARED))
ret = collect_filemap(vma->e); ret = collect_filemap(vma);
else else
ret = 0; ret = 0;
if (ret) if (ret)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment