mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-30 22:05:36 +00:00
shmem: Get rid of static array of dumped shmem areas
These are used by single process, no need in keeping them in such a strange way. Plus, turn this array into a hash table for better search. Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
@@ -1523,9 +1523,6 @@ int cr_dump_tasks(pid_t pid, const struct cr_options *opts)
|
|||||||
if (!glob_fdset)
|
if (!glob_fdset)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
if (init_shmem_dump())
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
for_each_pstree_item(item) {
|
for_each_pstree_item(item) {
|
||||||
if (dump_one_task(item))
|
if (dump_one_task(item))
|
||||||
goto err;
|
goto err;
|
||||||
@@ -1548,7 +1545,6 @@ int cr_dump_tasks(pid_t pid, const struct cr_options *opts)
|
|||||||
|
|
||||||
fd_id_show_tree();
|
fd_id_show_tree();
|
||||||
err:
|
err:
|
||||||
fini_shmem_dump();
|
|
||||||
close_cr_fdset(&glob_fdset);
|
close_cr_fdset(&glob_fdset);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -13,6 +13,4 @@ extern struct shmems *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);
|
||||||
int init_shmem_dump(void);
|
|
||||||
void fini_shmem_dump(void);
|
|
||||||
#endif
|
#endif
|
||||||
|
52
shmem.c
52
shmem.c
@@ -229,41 +229,45 @@ struct shmem_info_dump {
|
|||||||
unsigned long start;
|
unsigned long start;
|
||||||
unsigned long end;
|
unsigned long end;
|
||||||
int pid;
|
int pid;
|
||||||
|
|
||||||
|
struct shmem_info_dump *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int nr_shmems;
|
#define SHMEM_HASH_SIZE 32
|
||||||
static struct shmem_info_dump *dump_shmems;
|
static struct shmem_info_dump *shmems_hash[SHMEM_HASH_SIZE];
|
||||||
|
|
||||||
static struct shmem_info_dump *shmem_find(unsigned long shmid)
|
static struct shmem_info_dump *shmem_find(struct shmem_info_dump **chain,
|
||||||
|
unsigned long shmid)
|
||||||
{
|
{
|
||||||
int i;
|
struct shmem_info_dump *sh;
|
||||||
|
|
||||||
for (i = 0; i < nr_shmems; i++)
|
for (sh = *chain; sh; sh = sh->next)
|
||||||
if (dump_shmems[i].shmid == shmid)
|
if (sh->shmid == shmid)
|
||||||
return &dump_shmems[i];
|
return sh;
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int add_shmem_area(pid_t pid, VmaEntry *vma)
|
int add_shmem_area(pid_t pid, VmaEntry *vma)
|
||||||
{
|
{
|
||||||
struct shmem_info_dump *si;
|
struct shmem_info_dump *si, **chain;
|
||||||
unsigned long size = vma->pgoff + (vma->end - vma->start);
|
unsigned long size = vma->pgoff + (vma->end - vma->start);
|
||||||
|
|
||||||
si = shmem_find(vma->shmid);
|
chain = &shmems_hash[vma->shmid % SHMEM_HASH_SIZE];
|
||||||
|
si = shmem_find(chain, vma->shmid);
|
||||||
if (si) {
|
if (si) {
|
||||||
if (si->size < size)
|
if (si->size < size)
|
||||||
si->size = size;
|
si->size = size;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
nr_shmems++;
|
si = xmalloc(sizeof(*si));
|
||||||
if (nr_shmems * sizeof(*si) == SHMEMS_SIZE) {
|
if (!si)
|
||||||
pr_err("OOM storing shmems\n");
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
|
|
||||||
si = &dump_shmems[nr_shmems - 1];
|
si->next = *chain;
|
||||||
|
*chain = si;
|
||||||
|
|
||||||
si->size = size;
|
si->size = size;
|
||||||
si->pid = pid;
|
si->pid = pid;
|
||||||
si->start = vma->start;
|
si->start = vma->start;
|
||||||
@@ -273,15 +277,19 @@ int add_shmem_area(pid_t pid, VmaEntry *vma)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define for_each_shmem_dump(_i, _si) \
|
||||||
|
for (i = 0; i < SHMEM_HASH_SIZE; i++) \
|
||||||
|
for (si = shmems_hash[i]; si; si = si->next)
|
||||||
|
|
||||||
int cr_dump_shmem(void)
|
int cr_dump_shmem(void)
|
||||||
{
|
{
|
||||||
int err, fd;
|
int i, err, fd;
|
||||||
unsigned char *map = NULL;
|
unsigned char *map = NULL;
|
||||||
void *addr = NULL;
|
void *addr = NULL;
|
||||||
struct shmem_info_dump *si;
|
struct shmem_info_dump *si;
|
||||||
unsigned long pfn, nrpages;
|
unsigned long pfn, nrpages;
|
||||||
|
|
||||||
for (si = dump_shmems; si < &dump_shmems[nr_shmems]; si++) {
|
for_each_shmem_dump (i, si) {
|
||||||
pr_info("Dumping shared memory 0x%lx\n", si->shmid);
|
pr_info("Dumping shared memory 0x%lx\n", si->shmid);
|
||||||
|
|
||||||
nrpages = (si->size + PAGE_SIZE - 1) / PAGE_SIZE;
|
nrpages = (si->size + PAGE_SIZE - 1) / PAGE_SIZE;
|
||||||
@@ -346,15 +354,3 @@ err:
|
|||||||
xfree(map);
|
xfree(map);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int init_shmem_dump(void)
|
|
||||||
{
|
|
||||||
nr_shmems = 0;
|
|
||||||
dump_shmems = xmalloc(SHMEMS_SIZE);
|
|
||||||
return dump_shmems == NULL ? -1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void fini_shmem_dump(void)
|
|
||||||
{
|
|
||||||
xfree(dump_shmems);
|
|
||||||
}
|
|
||||||
|
Reference in New Issue
Block a user