Messages in this thread | | | Date | Thu, 21 Aug 2008 11:53:16 +0200 | From | Louis Rilling <> | Subject | Re: [RFC v2][PATCH 4/9] Memory management - dump state |
| |
On Wed, Aug 20, 2008 at 11:05:15PM -0400, Oren Laadan wrote: > > For each VMA, there is a 'struct cr_vma'; if the VMA is file-mapped, > it will be followed by the file name. The cr_vma->npages will tell > how many pages were dumped for this VMA. Then it will be followed > by the actual data: first a dump of the addresses of all dumped > pages (npages entries) followed by a dump of the contents of all > dumped pages (npages pages). Then will come the next VMA and so on.
[...]
> diff --git a/checkpoint/ckpt_mem.c b/checkpoint/ckpt_mem.c > new file mode 100644 > index 0000000..a23aa29 > --- /dev/null > +++ b/checkpoint/ckpt_mem.c
[...]
> +/** > + * cr_vma_fill_pgarr - fill a page-array with addr/page tuples for a vma > + * @ctx - checkpoint context > + * @pgarr - page-array to fill > + * @vma - vma to scan > + * @start - start address (updated) > + */ > +static int cr_vma_fill_pgarr(struct cr_ctx *ctx, struct cr_pgarr *pgarr, > + struct vm_area_struct *vma, unsigned long *start) > +{ > + unsigned long end = vma->vm_end; > + unsigned long addr = *start; > + struct page **pagep; > + unsigned long *addrp; > + int cow, nr, ret = 0; > + > + nr = pgarr->nleft; > + pagep = &pgarr->pages[pgarr->nused]; > + addrp = &pgarr->addrs[pgarr->nused]; > + cow = !!vma->vm_file; > + > + while (addr < end) { > + struct page *page; > + > + /* simplified version of get_user_pages(): already have vma, > + * only need FOLL_TOUCH, and (for now) ignore fault stats */ > + > + cond_resched(); > + while (!(page = follow_page(vma, addr, FOLL_TOUCH))) { > + ret = handle_mm_fault(vma->vm_mm, vma, addr, 0); > + if (ret & VM_FAULT_ERROR) { > + if (ret & VM_FAULT_OOM) > + ret = -ENOMEM; > + else if (ret & VM_FAULT_SIGBUS) > + ret = -EFAULT; > + else > + BUG(); > + break; > + }
+ ret = 0;
> + cond_resched(); > + } > + > + if (IS_ERR(page)) { > + ret = PTR_ERR(page); > + break; > + }
Need to check ret here:
+ if (ret) break;
> + > + if (page == ZERO_PAGE(0)) > + page = NULL; /* zero page: ignore */ > + else if (cow && page_mapping(page) != NULL) > + page = NULL; /* clean cow: ignore */ > + else { > + get_page(page); > + *(addrp++) = addr; > + *(pagep++) = page; > + if (--nr == 0) { > + addr += PAGE_SIZE; > + break; > + } > + } > + > + addr += PAGE_SIZE; > + } > + > + if (unlikely(ret < 0)) { > + nr = pgarr->nleft - nr; > + while (nr--) > + page_cache_release(*(--pagep)); > + return ret; > + } > + > + *start = addr; > + return (pgarr->nleft - nr); > +}
[...]
Thanks,
Louis
-- Dr Louis Rilling Kerlabs Skype: louis.rilling Batiment Germanium Phone: (+33|0) 6 80 89 08 23 80 avenue des Buttes de Coesmes http://www.kerlabs.com/ 35700 Rennes [unhandled content-type:application/pgp-signature] | |