Commit 5d5e8b80 authored by Cyrill Gorcunov's avatar Cyrill Gorcunov

retore: Fix up shared anonymous memory restore procedure

Restorer does really restore shared memory (including page
contents restore) only on master process, while all other
processes do open such memory area via map_files/ procfs entry
so that we might have a situation when shared VMA is present
in some particular core-%d.img file but it's not listed in
collected shmems array and find_shmem_by_pid will return NULL.
This is perfectly fine, be ready for that.

Another issue is that shared memory might look like

CR_FD_SHMEM: /home/cyrill/projects/kernel/crtools/shmem-2641.img
----------------------------------------
0x7f2200775000-0x7f2200776000 id 19664
0x7f2200776000-0x7f2200777000 id 19663
----------------------------------------

So vma area is [x;y) range and we should distinguish two
shmem lookup cases

 - one when we search for page in shmem area
 - second when we lookup shmem area in collected ranges

They both have a different lookup conditions so single
find_shmem splitted into two helpers find_shmem and
find_shmem_page as appropriate.

This patch finally fixes the three process asynchronious
shared memory updates test-case.
Signed-off-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
parent 1b21a27b
......@@ -650,6 +650,40 @@ err:
return -1;
}
static struct shmem_info *
find_shmem(struct shmems *shms, unsigned long start, unsigned long shmid)
{
struct shmem_info *si;
int i;
for (i = 0; i < shms->nr_shmems; i++) {
si = &shms->entries[i];
if (si->start == start &&
si->end > start &&
si->shmid == shmid)
return si;
}
return NULL;
}
static struct shmem_info *
find_shmem_page(struct shmems *shms, unsigned long addr, unsigned long shmid)
{
struct shmem_info *si;
int i;
for (i = 0; i < shms->nr_shmems; i++) {
si = &shms->entries[i];
if (si->start <= addr &&
si->end > addr &&
si->shmid == shmid)
return si;
}
return NULL;
}
static int try_fixup_shared_map(int pid, struct vma_entry *vi, int fd)
{
struct shmem_info *si;
......@@ -744,7 +778,7 @@ static inline bool should_restore_page(int pid, unsigned long va)
if (!shmid)
return true;
si = find_shmem(shmems, va, shmid);
si = find_shmem_page(shmems, va, shmid);
return si->pid == pid;
}
......
......@@ -306,30 +306,17 @@ struct shmems {
struct shmem_info entries[0];
};
static struct shmem_info *
find_shmem(struct shmems *shms, unsigned long addr, unsigned long shmid)
{
struct shmem_info *si;
int i;
for (i = 0; i < shms->nr_shmems; i++) {
si = shms->entries + i;
if (si->start <= addr && si->end >= addr && si->shmid == shmid)
return si;
}
return NULL;
}
static always_inline struct shmem_info *
find_shmem_by_pid(struct shmems *shms, unsigned long addr, int pid)
find_shmem_by_pid(struct shmems *shmems, unsigned long start, int pid)
{
struct shmem_info *si;
int i;
for (i = 0; i < shms->nr_shmems; i++) {
si = shms->entries + i;
if (si->start <= addr && si->end >= addr && si->real_pid == pid)
for (i = 0; i < shmems->nr_shmems; i++) {
si = &shmems->entries[i];
if (si->start == start &&
si->end > start &&
si->real_pid == pid)
return si;
}
......
......@@ -170,6 +170,7 @@ self_len_end:
struct rt_sigframe *rt_sigframe;
unsigned long new_sp, fsgs_base;
pid_t my_pid = sys_getpid();
core_entry = first_on_heap(core_entry, args->mem_zone.heap);
vma_entry = next_on_heap(vma_entry, core_entry);
......@@ -329,14 +330,9 @@ self_len_end:
entry = find_shmem_by_pid(args->shmems,
vma_entry->start,
sys_getpid());
if (!entry) {
write_num_n(__LINE__);
write_hex_n(vma_entry->start);
goto core_restore_end;
}
cr_wait_set(&entry->lock, 1);
my_pid);
if (entry)
cr_wait_set(&entry->lock, 1);
}
if (vma_entry->prot & PROT_WRITE)
......
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