mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-31 06:15:24 +00:00
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 <xemul@parallels.com>
This commit is contained in:
15
cr-restore.c
15
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);
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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);
|
||||
|
@@ -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.
|
||||
|
49
shmem.c
49
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;
|
||||
|
Reference in New Issue
Block a user