From 45f39e0415ee986c6a75e5c6a5bedd77d6615af6 Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Sat, 2 Nov 2013 01:06:31 +0400 Subject: [PATCH] rst: Make shmem restore to use rst-malloc This actually fixes a bug -- memory for shmem info was not allocated dynamically, thus we were limited in the amount of shmems to be restored. Signed-off-by: Pavel Emelyanov --- cr-restore.c | 15 ++++---------- include/restorer.h | 16 ++++----------- include/shmem.h | 4 ++-- pie/restorer.c | 8 ++------ shmem.c | 49 ++++++++++++++++++++-------------------------- 5 files changed, 33 insertions(+), 59 deletions(-) diff --git a/cr-restore.c b/cr-restore.c index 30d9fe445..6e4c0217e 100644 --- a/cr-restore.c +++ b/cr-restore.c @@ -143,9 +143,6 @@ static int root_prepare_shared(void) pr_info("Preparing info about shared resources\n"); - if (prepare_shmem_restore()) - return -1; - if (prepare_shared_tty()) return -1; @@ -2166,7 +2163,6 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core) BUILD_BUG_ON(sizeof(struct task_restore_core_args) & 1); BUILD_BUG_ON(sizeof(struct thread_restore_args) & 1); - BUILD_BUG_ON(SHMEMS_SIZE % PAGE_SIZE); BUILD_BUG_ON(TASK_ENTRIES_SIZE % PAGE_SIZE); restore_task_vma_len = round_up(sizeof(*task_args), PAGE_SIZE); @@ -2222,7 +2218,7 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core) restore_bootstrap_len = restorer_len + restore_task_vma_len + restore_thread_vma_len + - SHMEMS_SIZE + TASK_ENTRIES_SIZE + + TASK_ENTRIES_SIZE + rst_mem_remap_size(); /* @@ -2303,12 +2299,6 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core) */ mem += restore_task_vma_len + restore_thread_vma_len; - ret = shmem_remap(rst_shmems, mem, SHMEMS_SIZE); - if (ret < 0) - goto err; - task_args->shmems = mem; - - mem += SHMEMS_SIZE; ret = shmem_remap(task_entries, mem, TASK_ENTRIES_SIZE); if (ret < 0) goto err; @@ -2324,6 +2314,9 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core) if (rst_mem_remap(mem)) goto err; + task_args->shmems = rst_mem_remap_ptr(rst_shmems, RM_SHREMAP); + task_args->nr_shmems = nr_shmems; + task_args->nr_vmas = rst_vmas.nr; task_args->tgt_vmas = rst_mem_remap_ptr(tgt_vmas, RM_PRIVATE); diff --git a/include/restorer.h b/include/restorer.h index 3458a5be3..e76d68d4c 100644 --- a/include/restorer.h +++ b/include/restorer.h @@ -105,7 +105,8 @@ struct task_restore_core_args { int nr_zombies; thread_restore_fcall_t clone_restore_fn; /* helper address for clone() call */ struct thread_restore_args *thread_args; /* array of thread arguments */ - struct shmems *shmems; + struct shmem_info *shmems; + unsigned int nr_shmems; struct task_entries *task_entries; void *rst_mem; unsigned long rst_mem_size; @@ -150,8 +151,6 @@ struct task_restore_core_args { unsigned long vdso_rt_parked_at; /* safe place to keep vdso */ } __aligned(sizeof(long)); -#define SHMEMS_SIZE 4096 - #define RESTORE_ALIGN_STACK(start, size) \ (ALIGN((start) + (size) - sizeof(long), sizeof(long))) @@ -177,11 +176,6 @@ struct shmem_info { futex_t lock; }; -struct shmems { - int nr_shmems; - struct shmem_info entries[0]; -}; - #define TASK_ENTRIES_SIZE 4096 enum { @@ -208,16 +202,14 @@ struct task_entries { }; static always_inline struct shmem_info * -find_shmem(struct shmems *shmems, unsigned long shmid) +find_shmem(struct shmem_info *shmems, int nr, unsigned long shmid) { struct shmem_info *si; int i; - for (i = 0; i < shmems->nr_shmems; i++) { - si = &shmems->entries[i]; + for (i = 0, si = shmems; i < nr; i++, si++) if (si->shmid == shmid) return si; - } return NULL; } diff --git a/include/shmem.h b/include/shmem.h index f6ee3e25f..9594e69c0 100644 --- a/include/shmem.h +++ b/include/shmem.h @@ -8,8 +8,8 @@ int prepare_shmem_restore(void); void show_saved_shmems(void); int get_shmem_fd(int pid, VmaEntry *vi); -struct shmems; -extern struct shmems *rst_shmems; +extern unsigned long nr_shmems; +extern unsigned int rst_shmems; int cr_dump_shmem(void); int add_shmem_area(pid_t pid, VmaEntry *vma); diff --git a/pie/restorer.c b/pie/restorer.c index 693722349..2e96584c4 100644 --- a/pie/restorer.c +++ b/pie/restorer.c @@ -704,7 +704,7 @@ long __export_restore_task(struct task_restore_core_args *args) if (vma_entry_is(vma_entry, VMA_ANON_SHARED)) { struct shmem_info *entry; - entry = find_shmem(args->shmems, + entry = find_shmem(args->shmems, args->nr_shmems, vma_entry->shmid); if (entry && entry->pid == my_pid && entry->start == vma_entry->start) @@ -746,11 +746,7 @@ long __export_restore_task(struct task_restore_core_args *args) } } - ret = sys_munmap(args->shmems, SHMEMS_SIZE); - if (ret < 0) { - pr_err("Can't unmap shmem %ld\n", ret); - goto core_restore_end; - } + ret = 0; /* * Tune up the task fields. diff --git a/shmem.c b/shmem.c index 769dc3007..e88287f2d 100644 --- a/shmem.c +++ b/shmem.c @@ -8,31 +8,40 @@ #include "restorer.h" #include "page-pipe.h" #include "page-xfer.h" +#include "rst-malloc.h" #include "protobuf.h" #include "protobuf/pagemap.pb-c.h" -struct shmems *rst_shmems; +unsigned long nr_shmems; +unsigned int rst_shmems; void show_saved_shmems(void) { int i; + struct shmem_info *si; pr_info("\tSaved shmems:\n"); - - for (i = 0; i < rst_shmems->nr_shmems; i++) + si = rst_mem_remap_ptr(rst_shmems, RM_SHREMAP); + for (i = 0; i < nr_shmems; i++, si++) pr_info("\t\tstart: 0x%016lx shmid: 0x%lx pid: %d\n", - rst_shmems->entries[i].start, - rst_shmems->entries[i].shmid, - rst_shmems->entries[i].pid); + si->start, si->shmid, si->pid); +} + + +static struct shmem_info *find_shmem_by_id(unsigned long id) +{ + struct shmem_info *si; + + si = rst_mem_remap_ptr(rst_shmems, RM_SHREMAP); + return find_shmem(si, nr_shmems, id); } static int collect_shmem(int pid, VmaEntry *vi) { - int nr_shmems = rst_shmems->nr_shmems; unsigned long size = vi->pgoff + vi->end - vi->start; struct shmem_info *si; - si = find_shmem(rst_shmems, vi->shmid); + si = find_shmem_by_id(vi->shmid); if (si) { if (si->size < size) @@ -54,18 +63,13 @@ static int collect_shmem(int pid, VmaEntry *vi) return 0; } - if ((nr_shmems + 1) * sizeof(struct shmem_info) + - sizeof (struct shmems) >= SHMEMS_SIZE) { - pr_err("OOM storing shmems\n"); + si = rst_mem_alloc(sizeof(struct shmem_info), RM_SHREMAP); + if (!si) return -1; - } pr_info("Add new shmem 0x%"PRIx64" (0x0160x%"PRIx64"-0x0160x%"PRIx64")\n", vi->shmid, vi->start, vi->end); - si = &rst_shmems->entries[nr_shmems]; - rst_shmems->nr_shmems++; - si->start = vi->start; si->end = vi->end; si->shmid = vi->shmid; @@ -73,6 +77,7 @@ static int collect_shmem(int pid, VmaEntry *vi) si->size = size; si->fd = -1; + nr_shmems++; futex_init(&si->lock); return 0; @@ -203,7 +208,7 @@ int get_shmem_fd(int pid, VmaEntry *vi) void *addr; int f; - si = find_shmem(rst_shmems, vi->shmid); + si = find_shmem_by_id(vi->shmid); pr_info("Search for 0x%016"PRIx64" shmem 0x%"PRIx64" %p/%d\n", vi->start, vi->shmid, si, si ? si->pid : -1); if (!si) { pr_err("Can't find my shmem 0x%016"PRIx64"\n", vi->start); @@ -248,18 +253,6 @@ int get_shmem_fd(int pid, VmaEntry *vi) return f; } -int prepare_shmem_restore(void) -{ - rst_shmems = mmap(NULL, SHMEMS_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, 0, 0); - if (rst_shmems == MAP_FAILED) { - pr_perror("Can't map shmem"); - return -1; - } - - rst_shmems->nr_shmems = 0; - return 0; -} - struct shmem_info_dump { unsigned long size; unsigned long shmid;