<div dir="ltr">Hello.<div><br></div><div>Looks good for me.</div></div><div class="gmail_extra"><br><div class="gmail_quote">2016-10-29 8:36 GMT+03:00 Andrei Vagin <span dir="ltr"><<a href="mailto:avagin@openvz.org" target="_blank">avagin@openvz.org</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">From: Andrei Vagin <<a href="mailto:avagin@virtuozzo.com">avagin@virtuozzo.com</a>><br>
<br>
When pages are swapped out we can't detect their presence<br>
with mincore.<br>
<br>
Pavel found that lseek(SEEK_DATA, SEEK_HOLE) can show which<br>
pages are used.<br>
<br>
Cc: Eugene Batalov <<a href="mailto:eabatalov89@gmail.com">eabatalov89@gmail.com</a>><br>
Cc: Cyrill Gorcunov <<a href="mailto:gorcunov@openvz.org">gorcunov@openvz.org</a>><br>
Signed-off-by: Andrei Vagin <<a href="mailto:avagin@virtuozzo.com">avagin@virtuozzo.com</a>><br>
---<br>
criu/shmem.c | 57 ++++++++++++++++++++++++++++++<wbr>++++++++++++++-------------<br>
1 file changed, 44 insertions(+), 13 deletions(-)<br>
<br>
diff --git a/criu/shmem.c b/criu/shmem.c<br>
index 8af612c..5065abd 100644<br>
--- a/criu/shmem.c<br>
+++ b/criu/shmem.c<br>
@@ -24,6 +24,11 @@<br>
#include "protobuf.h"<br>
#include "images/pagemap.pb-c.h"<br>
<br>
+#ifndef SEEK_DATA<br>
+#define SEEK_DATA 3<br>
+#define SEEK_HOLE 4<br>
+#endif<br>
+<br>
/*<br>
* Hash table and routines for keeping shmid -> shmem_xinfo mappings<br>
*/<br>
@@ -628,14 +633,40 @@ static int dump_pages(struct page_pipe *pp, struct page_xfer *xfer, void *addr)<br>
return page_xfer_dump_pages(xfer, pp, (unsigned long)addr, true);<br>
}<br>
<br>
+static int next_data_segment(int fd, unsigned long pfn,<br>
+ unsigned long *next_data_pfn, unsigned long *next_hole_pfn)<br>
+{<br>
+ off_t off;<br>
+<br>
+ off = lseek(fd, pfn * PAGE_SIZE, SEEK_DATA);<br>
+ if (off == (off_t) -1) {<br>
+ if (errno == ENXIO) {<br>
+ *next_data_pfn = ~0UL;<br>
+ *next_hole_pfn = ~0UL;<br>
+ return 0;<br>
+ }<br>
+ pr_perror("Unable to lseek(SEEK_DATA)");<br>
+ return -1;<br>
+ }<br>
+ *next_data_pfn = off / PAGE_SIZE;<br>
+<br>
+ off = lseek(fd, off, SEEK_HOLE);<br>
+ if (off == (off_t) -1) {<br>
+ pr_perror("Unable to lseek(SEEK_HOLE)");<br>
+ return -1;<br>
+ }<br>
+ *next_hole_pfn = off / PAGE_SIZE;<br>
+<br>
+ return 0;<br>
+}<br>
+<br>
static int dump_one_shmem(struct shmem_info *si)<br>
{<br>
struct page_pipe *pp;<br>
struct page_xfer xfer;<br>
int err, ret = -1, fd;<br>
- unsigned char *mc_map = NULL;<br>
void *addr = NULL;<br>
- unsigned long pfn, nrpages;<br>
+ unsigned long pfn, nrpages, next_data_pnf = 0, next_hole_pfn = 0;<br>
<br>
pr_info("Dumping shared memory %ld\n", si->shmid);<br>
<br>
@@ -644,7 +675,6 @@ static int dump_one_shmem(struct shmem_info *si)<br>
goto err;<br>
<br>
addr = mmap(NULL, si->size, PROT_READ, MAP_SHARED, fd, 0);<br>
- close(fd);<br>
if (addr == MAP_FAILED) {<br>
pr_err("Can't map shmem 0x%lx (0x%lx-0x%lx)\n",<br>
si->shmid, si->start, si->end);<br>
@@ -652,13 +682,6 @@ static int dump_one_shmem(struct shmem_info *si)<br>
}<br>
<br>
nrpages = (si->size + PAGE_SIZE - 1) / PAGE_SIZE;<br>
- mc_map = xmalloc(nrpages * sizeof(*mc_map));<br>
- if (!mc_map)<br>
- goto err_unmap;<br>
- /* We can't rely only on PME bits for anon shmem */<br>
- err = mincore(addr, si->size, mc_map);<br>
- if (err)<br>
- goto err_unmap;<br>
<br>
pp = create_page_pipe((nrpages + 1) / 2, NULL, PP_CHUNK_MODE);<br>
if (!pp)<br>
@@ -673,13 +696,21 @@ static int dump_one_shmem(struct shmem_info *si)<br>
bool use_mc = true;<br>
unsigned long pgaddr;<br>
<br>
+ if (pfn >= next_hole_pfn &&<br>
+ next_data_segment(fd, pfn, &next_data_pnf, &next_hole_pfn))<br>
+ goto err_xfer;<br>
+<br>
if (is_shmem_tracking_en()) {<br>
pgstate = get_pstate(si->pstate_map, pfn);<br>
use_mc = pgstate == PST_DONT_DUMP;<br>
}<br>
<br>
- if (use_mc && !(mc_map[pfn] & PAGE_RSS))<br>
- continue;<br>
+ if (use_mc) {<br>
+ if (pfn < next_data_pnf)<br>
+ pgstate = PST_ZERO;<br>
+ else<br>
+ pgstate = PST_DIRTY;<br>
+ }<br>
<br>
pgaddr = (unsigned long)addr + pfn * PAGE_SIZE;<br>
again:<br>
@@ -709,7 +740,7 @@ err_pp:<br>
err_unmap:<br>
munmap(addr, si->size);<br>
err:<br>
- xfree(mc_map);<br>
+ close_safe(&fd);<br>
return ret;<br>
}<br>
<span class="HOEnZb"><font color="#888888"><br>
--<br>
2.7.4<br>
<br>
</font></span></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature" data-smartmail="gmail_signature">Best regards,<br>Eugene Batalov.</div>
</div>