2013-03-01 20:12:58 +04:00
|
|
|
#ifndef __CR_PAGE_PIPE_H__
|
|
|
|
#define __CR_PAGE_PIPE_H__
|
2013-11-15 14:04:46 +04:00
|
|
|
|
2013-03-01 20:12:58 +04:00
|
|
|
#include <sys/uio.h>
|
|
|
|
#include "list.h"
|
|
|
|
|
2013-04-16 11:34:53 +04:00
|
|
|
/*
|
|
|
|
* page_pipe is a descriptor of task's virtual memory
|
|
|
|
* with pipes, containing pages.
|
|
|
|
*
|
|
|
|
* A page-pipe may contain holes -- these are pagemap
|
|
|
|
* entries without pages. Holes are stored in separate
|
|
|
|
* array to optimize paged iovs feed into vmsplice --
|
|
|
|
* they will be sent there in one go.
|
|
|
|
*
|
|
|
|
* A hole is a pagemap entry that doesn't have pages
|
|
|
|
* in it, since they are present in previous (parent)
|
|
|
|
* snapshot.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* This page-pipe vs holes vs task vmem vs image layout
|
|
|
|
* is described below.
|
|
|
|
*
|
|
|
|
* Task memory: (+ present, - not present pages)
|
|
|
|
* 0 0 0 0 1 1 1
|
|
|
|
* 0 3 6 B 1 8 C
|
|
|
|
* ---+++-----++++++-------++++----
|
|
|
|
*
|
|
|
|
* Page-pipe iovs:
|
|
|
|
*
|
|
|
|
* bufs = 03:3,0B:6,18:4
|
|
|
|
* holes = <empty>
|
|
|
|
*
|
|
|
|
* The pagemap.img would purely contain page-pipe bufs.
|
|
|
|
*
|
|
|
|
* Pages image will contain pages at
|
|
|
|
*
|
|
|
|
* 03,04,05,0B,0C,0D,0E,0F,10,18,19,1A,1B
|
|
|
|
*
|
|
|
|
* stored one by one.
|
|
|
|
*
|
|
|
|
* Not let's imagine task touches some pages and its mem
|
|
|
|
* looks like: (+ present, = old present, - non present)
|
|
|
|
*
|
|
|
|
* 0 0 0 0 11 11 1
|
|
|
|
* 0 3 6 B 12 78 C
|
|
|
|
* ---==+-----====+++-----++===----
|
|
|
|
*
|
|
|
|
* (not new pages at 11 and 17 vaddrs)
|
|
|
|
*
|
|
|
|
* The new --snapshot'ed page-pipe would look like
|
|
|
|
*
|
|
|
|
* bufs = 05:1,0F:3,17:2
|
|
|
|
* holes = 03:2,0B:4,19:3
|
|
|
|
*
|
|
|
|
* So the pagemap.img would look like
|
|
|
|
*
|
|
|
|
* 03:2:P,05:1,0B:4:P,0F:3,17:2,19:3:P
|
|
|
|
*
|
|
|
|
* (the page_xfer_dump_pages generates one)
|
|
|
|
*
|
|
|
|
* where P means "in parent", i.e. respective pages should
|
|
|
|
* be looked up in the parent pagemap (not pages.img, but
|
|
|
|
* the pagemap, and then the offset in previous pages.img
|
|
|
|
* should be calculated, see the read_pagemap_page routine).
|
|
|
|
*
|
|
|
|
* New pages.img file would contain only pages for
|
|
|
|
*
|
|
|
|
* 05,0F,10,11,17,18
|
|
|
|
*/
|
|
|
|
|
2013-03-01 20:12:58 +04:00
|
|
|
struct page_pipe_buf {
|
2013-04-16 11:34:53 +04:00
|
|
|
int p[2]; /* pipe with pages */
|
2013-03-01 20:12:58 +04:00
|
|
|
unsigned int pipe_size; /* how many pages can be fit into pipe */
|
|
|
|
unsigned int pages_in; /* how many pages are there */
|
|
|
|
unsigned int nr_segs; /* how many iov-s are busy */
|
2013-04-16 11:34:53 +04:00
|
|
|
struct iovec *iov; /* vaddr:len map */
|
|
|
|
struct list_head l; /* links into page_pipe->bufs */
|
2013-03-01 20:12:58 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
struct page_pipe {
|
2013-04-16 11:34:53 +04:00
|
|
|
unsigned int nr_pipes; /* how many page_pipe_bufs in there */
|
|
|
|
struct list_head bufs; /* list of bufs */
|
2014-02-08 23:16:43 +04:00
|
|
|
struct list_head free_bufs; /* list of bufs */
|
2013-04-16 11:34:53 +04:00
|
|
|
unsigned int nr_iovs; /* number of iovs */
|
|
|
|
unsigned int free_iov; /* first free iov */
|
|
|
|
struct iovec *iovs; /* iovs. They are provided into create_page_pipe
|
|
|
|
and all bufs have their iov-s in there */
|
2013-04-11 17:49:56 +04:00
|
|
|
|
2013-04-16 11:34:53 +04:00
|
|
|
unsigned int nr_holes; /* number of holes allocated */
|
|
|
|
unsigned int free_hole; /* number of holes in use */
|
|
|
|
struct iovec *holes; /* holes */
|
2014-02-08 23:16:43 +04:00
|
|
|
|
|
|
|
bool chunk_mode; /* Restrict the maximum buffer size of pipes
|
|
|
|
and dump memory for a few iterations */
|
2013-03-01 20:12:58 +04:00
|
|
|
};
|
|
|
|
|
2014-02-08 23:16:43 +04:00
|
|
|
extern struct page_pipe *create_page_pipe(unsigned int nr,
|
|
|
|
struct iovec *, bool chunk_mode);
|
2013-11-15 14:04:48 +04:00
|
|
|
extern void destroy_page_pipe(struct page_pipe *p);
|
|
|
|
extern int page_pipe_add_page(struct page_pipe *p, unsigned long addr);
|
|
|
|
extern int page_pipe_add_hole(struct page_pipe *p, unsigned long addr);
|
2013-04-11 17:51:25 +04:00
|
|
|
|
2013-11-15 14:04:48 +04:00
|
|
|
extern void debug_show_page_pipe(struct page_pipe *pp);
|
2014-02-08 23:16:43 +04:00
|
|
|
void page_pipe_reinit(struct page_pipe *pp);
|
2013-11-15 14:04:46 +04:00
|
|
|
|
2013-11-15 14:04:45 +04:00
|
|
|
#endif /* __CR_PAGE_PIPE_H__ */
|