[CRIU] Re: [PATCH cr] restore: optimize restorer_get_vma_hint
Cyrill Gorcunov
gorcunov at openvz.org
Sat Apr 7 04:18:46 EDT 2012
On Sat, Apr 07, 2012 at 11:09:29AM +0400, Andrey Vagin wrote:
> It's an O(n) algorithm.
>
> Now we iterate both lists simultaneously to find a hole.
>
> Signed-off-by: Andrey Vagin <avagin at openvz.org>
> ---
> cr-restore.c | 49 ++++++++++++++++++++++++++++++++-----------------
> 1 files changed, 32 insertions(+), 17 deletions(-)
>
> diff --git a/cr-restore.c b/cr-restore.c
> index 2162fc1..8405336 100644
> --- a/cr-restore.c
> +++ b/cr-restore.c
> @@ -870,39 +870,54 @@ static int restore_all_tasks(pid_t pid, struct cr_options *opts)
> return restore_root_task(pid, opts);
> }
>
> +#define TASK_SIZE_MAX ((1UL << 47) - PAGE_SIZE)
> static long restorer_get_vma_hint(pid_t pid, struct list_head *tgt_vma_list,
> struct list_head *self_vma_list, long vma_len)
> {
> - struct vma_area *t_vma;
> + struct vma_area *t_vma, *s_vma;
> long prev_vma_end = 0;
> + struct vma_area end_vma;
> +
> + end_vma.vma.start = end_vma.vma.end = TASK_SIZE_MAX;
> + prev_vma_end = PAGE_SIZE;
>
> /*
> * Here we need some heuristics -- the VMA which restorer will
> * belong to should not be unmapped, so we need to gueess out
> * where to put it in.
> - *
> - * Yes, I know it's an O(n^2) algorithm, but usually there are
> - * not that many VMAs presented so instead of consuming memory
> - * better to stick with it.
> */
>
> - list_for_each_entry(t_vma, tgt_vma_list, list) {
> - if (prev_vma_end && ((t_vma->vma.start - prev_vma_end) > vma_len)) {
> - struct vma_area *s_vma;
> - unsigned long prev_vma_end2 = 0;
> + s_vma = list_first_entry(self_vma_list, struct vma_area, list);
> + t_vma = list_first_entry(tgt_vma_list, struct vma_area, list);
>
> - list_for_each_entry(s_vma, self_vma_list, list) {
> - if (prev_vma_end2 + vma_len > t_vma->vma.start)
> - break;
> - if (prev_vma_end2 && (prev_vma_end2 >= prev_vma_end) &&
> - ((s_vma->vma.start - prev_vma_end2) > vma_len))
> - return prev_vma_end2;
> + while (1) {
> + if (prev_vma_end + vma_len > s_vma->vma.start) {
> + if (s_vma->list.next == self_vma_list) {
> + s_vma = &end_vma;
If s_vma is the last one on self_vma_list you could break immediately, no?
And the snippet I somehow miss is -- how the situation handled when
hole
a b
source |----| |-----|
target |----| |-----|
c d
the hole fits the requested size but the hole is shifted
in target, so that you've
prev_vma_end = a
and then you find that a - d > vma_len and return a
as start address for new mapping while finally it
might intersect with address c.
Or I miss something obvious?
Cyrill
More information about the CRIU
mailing list