Commit 45f39e04 authored by Pavel Emelyanov's avatar Pavel Emelyanov

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: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 7ed35d8a
...@@ -143,9 +143,6 @@ static int root_prepare_shared(void) ...@@ -143,9 +143,6 @@ static int root_prepare_shared(void)
pr_info("Preparing info about shared resources\n"); pr_info("Preparing info about shared resources\n");
if (prepare_shmem_restore())
return -1;
if (prepare_shared_tty()) if (prepare_shared_tty())
return -1; return -1;
...@@ -2166,7 +2163,6 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core) ...@@ -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 task_restore_core_args) & 1);
BUILD_BUG_ON(sizeof(struct thread_restore_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); BUILD_BUG_ON(TASK_ENTRIES_SIZE % PAGE_SIZE);
restore_task_vma_len = round_up(sizeof(*task_args), 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) ...@@ -2222,7 +2218,7 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
restore_bootstrap_len = restorer_len + restore_bootstrap_len = restorer_len +
restore_task_vma_len + restore_task_vma_len +
restore_thread_vma_len + restore_thread_vma_len +
SHMEMS_SIZE + TASK_ENTRIES_SIZE + TASK_ENTRIES_SIZE +
rst_mem_remap_size(); rst_mem_remap_size();
/* /*
...@@ -2303,12 +2299,6 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core) ...@@ -2303,12 +2299,6 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
*/ */
mem += restore_task_vma_len + restore_thread_vma_len; 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); ret = shmem_remap(task_entries, mem, TASK_ENTRIES_SIZE);
if (ret < 0) if (ret < 0)
goto err; goto err;
...@@ -2324,6 +2314,9 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core) ...@@ -2324,6 +2314,9 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
if (rst_mem_remap(mem)) if (rst_mem_remap(mem))
goto err; 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->nr_vmas = rst_vmas.nr;
task_args->tgt_vmas = rst_mem_remap_ptr(tgt_vmas, RM_PRIVATE); task_args->tgt_vmas = rst_mem_remap_ptr(tgt_vmas, RM_PRIVATE);
......
...@@ -105,7 +105,8 @@ struct task_restore_core_args { ...@@ -105,7 +105,8 @@ struct task_restore_core_args {
int nr_zombies; int nr_zombies;
thread_restore_fcall_t clone_restore_fn; /* helper address for clone() call */ thread_restore_fcall_t clone_restore_fn; /* helper address for clone() call */
struct thread_restore_args *thread_args; /* array of thread arguments */ 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; struct task_entries *task_entries;
void *rst_mem; void *rst_mem;
unsigned long rst_mem_size; unsigned long rst_mem_size;
...@@ -150,8 +151,6 @@ struct task_restore_core_args { ...@@ -150,8 +151,6 @@ struct task_restore_core_args {
unsigned long vdso_rt_parked_at; /* safe place to keep vdso */ unsigned long vdso_rt_parked_at; /* safe place to keep vdso */
} __aligned(sizeof(long)); } __aligned(sizeof(long));
#define SHMEMS_SIZE 4096
#define RESTORE_ALIGN_STACK(start, size) \ #define RESTORE_ALIGN_STACK(start, size) \
(ALIGN((start) + (size) - sizeof(long), sizeof(long))) (ALIGN((start) + (size) - sizeof(long), sizeof(long)))
...@@ -177,11 +176,6 @@ struct shmem_info { ...@@ -177,11 +176,6 @@ struct shmem_info {
futex_t lock; futex_t lock;
}; };
struct shmems {
int nr_shmems;
struct shmem_info entries[0];
};
#define TASK_ENTRIES_SIZE 4096 #define TASK_ENTRIES_SIZE 4096
enum { enum {
...@@ -208,16 +202,14 @@ struct task_entries { ...@@ -208,16 +202,14 @@ struct task_entries {
}; };
static always_inline struct shmem_info * 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; struct shmem_info *si;
int i; int i;
for (i = 0; i < shmems->nr_shmems; i++) { for (i = 0, si = shmems; i < nr; i++, si++)
si = &shmems->entries[i];
if (si->shmid == shmid) if (si->shmid == shmid)
return si; return si;
}
return NULL; return NULL;
} }
......
...@@ -8,8 +8,8 @@ int prepare_shmem_restore(void); ...@@ -8,8 +8,8 @@ int prepare_shmem_restore(void);
void show_saved_shmems(void); void show_saved_shmems(void);
int get_shmem_fd(int pid, VmaEntry *vi); int get_shmem_fd(int pid, VmaEntry *vi);
struct shmems; extern unsigned long nr_shmems;
extern struct shmems *rst_shmems; extern unsigned int rst_shmems;
int cr_dump_shmem(void); int cr_dump_shmem(void);
int add_shmem_area(pid_t pid, VmaEntry *vma); int add_shmem_area(pid_t pid, VmaEntry *vma);
......
...@@ -704,7 +704,7 @@ long __export_restore_task(struct task_restore_core_args *args) ...@@ -704,7 +704,7 @@ long __export_restore_task(struct task_restore_core_args *args)
if (vma_entry_is(vma_entry, VMA_ANON_SHARED)) { if (vma_entry_is(vma_entry, VMA_ANON_SHARED)) {
struct shmem_info *entry; struct shmem_info *entry;
entry = find_shmem(args->shmems, entry = find_shmem(args->shmems, args->nr_shmems,
vma_entry->shmid); vma_entry->shmid);
if (entry && entry->pid == my_pid && if (entry && entry->pid == my_pid &&
entry->start == vma_entry->start) entry->start == vma_entry->start)
...@@ -746,11 +746,7 @@ long __export_restore_task(struct task_restore_core_args *args) ...@@ -746,11 +746,7 @@ long __export_restore_task(struct task_restore_core_args *args)
} }
} }
ret = sys_munmap(args->shmems, SHMEMS_SIZE); ret = 0;
if (ret < 0) {
pr_err("Can't unmap shmem %ld\n", ret);
goto core_restore_end;
}
/* /*
* Tune up the task fields. * Tune up the task fields.
......
...@@ -8,31 +8,40 @@ ...@@ -8,31 +8,40 @@
#include "restorer.h" #include "restorer.h"
#include "page-pipe.h" #include "page-pipe.h"
#include "page-xfer.h" #include "page-xfer.h"
#include "rst-malloc.h"
#include "protobuf.h" #include "protobuf.h"
#include "protobuf/pagemap.pb-c.h" #include "protobuf/pagemap.pb-c.h"
struct shmems *rst_shmems; unsigned long nr_shmems;
unsigned int rst_shmems;
void show_saved_shmems(void) void show_saved_shmems(void)
{ {
int i; int i;
struct shmem_info *si;
pr_info("\tSaved shmems:\n"); pr_info("\tSaved shmems:\n");
si = rst_mem_remap_ptr(rst_shmems, RM_SHREMAP);
for (i = 0; i < rst_shmems->nr_shmems; i++) for (i = 0; i < nr_shmems; i++, si++)
pr_info("\t\tstart: 0x%016lx shmid: 0x%lx pid: %d\n", pr_info("\t\tstart: 0x%016lx shmid: 0x%lx pid: %d\n",
rst_shmems->entries[i].start, si->start, si->shmid, si->pid);
rst_shmems->entries[i].shmid, }
rst_shmems->entries[i].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) static int collect_shmem(int pid, VmaEntry *vi)
{ {
int nr_shmems = rst_shmems->nr_shmems;
unsigned long size = vi->pgoff + vi->end - vi->start; unsigned long size = vi->pgoff + vi->end - vi->start;
struct shmem_info *si; struct shmem_info *si;
si = find_shmem(rst_shmems, vi->shmid); si = find_shmem_by_id(vi->shmid);
if (si) { if (si) {
if (si->size < size) if (si->size < size)
...@@ -54,18 +63,13 @@ static int collect_shmem(int pid, VmaEntry *vi) ...@@ -54,18 +63,13 @@ static int collect_shmem(int pid, VmaEntry *vi)
return 0; return 0;
} }
if ((nr_shmems + 1) * sizeof(struct shmem_info) + si = rst_mem_alloc(sizeof(struct shmem_info), RM_SHREMAP);
sizeof (struct shmems) >= SHMEMS_SIZE) { if (!si)
pr_err("OOM storing shmems\n");
return -1; return -1;
}
pr_info("Add new shmem 0x%"PRIx64" (0x0160x%"PRIx64"-0x0160x%"PRIx64")\n", pr_info("Add new shmem 0x%"PRIx64" (0x0160x%"PRIx64"-0x0160x%"PRIx64")\n",
vi->shmid, vi->start, vi->end); vi->shmid, vi->start, vi->end);
si = &rst_shmems->entries[nr_shmems];
rst_shmems->nr_shmems++;
si->start = vi->start; si->start = vi->start;
si->end = vi->end; si->end = vi->end;
si->shmid = vi->shmid; si->shmid = vi->shmid;
...@@ -73,6 +77,7 @@ static int collect_shmem(int pid, VmaEntry *vi) ...@@ -73,6 +77,7 @@ static int collect_shmem(int pid, VmaEntry *vi)
si->size = size; si->size = size;
si->fd = -1; si->fd = -1;
nr_shmems++;
futex_init(&si->lock); futex_init(&si->lock);
return 0; return 0;
...@@ -203,7 +208,7 @@ int get_shmem_fd(int pid, VmaEntry *vi) ...@@ -203,7 +208,7 @@ int get_shmem_fd(int pid, VmaEntry *vi)
void *addr; void *addr;
int f; 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); pr_info("Search for 0x%016"PRIx64" shmem 0x%"PRIx64" %p/%d\n", vi->start, vi->shmid, si, si ? si->pid : -1);
if (!si) { if (!si) {
pr_err("Can't find my shmem 0x%016"PRIx64"\n", vi->start); 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) ...@@ -248,18 +253,6 @@ int get_shmem_fd(int pid, VmaEntry *vi)
return f; 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 { struct shmem_info_dump {
unsigned long size; unsigned long size;
unsigned long shmid; unsigned long shmid;
......
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