Commit 61c6360c authored by Pavel Emelyanov's avatar Pavel Emelyanov

mem: Update soft-dirty detection to work on -mm tree

The soft-dirty API has changed slightly -- now the bit in
question _is_ in pagemap file (not pagemap2) but to see it
we have to reset soft-dirty for anyone first.

Teach the kerndat soft-dirty checker this fact. The actual
pagemap reading code already knows select pagemap/pagemap2
file itself.
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 1412904e
#ifndef __CR_MEM_H__ #ifndef __CR_MEM_H__
#define __CR_MEM_H__ #define __CR_MEM_H__
struct vm_area_list; struct vm_area_list;
int do_task_reset_dirty_track(int pid);
unsigned int dump_pages_args_size(struct vm_area_list *vmas); unsigned int dump_pages_args_size(struct vm_area_list *vmas);
struct parasite_ctl; struct parasite_ctl;
struct page_pipe; struct page_pipe;
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "log.h" #include "log.h"
#include "kerndat.h" #include "kerndat.h"
#include "mem.h"
#include "asm/types.h" #include "asm/types.h"
dev_t kerndat_shmem_dev; dev_t kerndat_shmem_dev;
...@@ -69,9 +70,16 @@ int kerndat_get_dirty_track(void) ...@@ -69,9 +70,16 @@ int kerndat_get_dirty_track(void)
return ret; return ret;
} }
map[0] = '\0';
pm2 = open("/proc/self/pagemap2", O_RDONLY); pm2 = open("/proc/self/pagemap2", O_RDONLY);
if (pm2 < 0) {
/*
* Kernel shows soft-dirty bits only if this soft-dirty
* was at least once re-set. (this is to be removed in
* a couple of kernel releases)
*/
do_task_reset_dirty_track(getpid());
pm2 = open("/proc/self/pagemap", O_RDONLY);
}
if (pm2 < 0) { if (pm2 < 0) {
munmap(map, PAGE_SIZE); munmap(map, PAGE_SIZE);
if (errno == ENOENT) { if (errno == ENOENT) {
...@@ -83,6 +91,8 @@ int kerndat_get_dirty_track(void) ...@@ -83,6 +91,8 @@ int kerndat_get_dirty_track(void)
return ret; return ret;
} }
map[0] = '\0';
lseek(pm2, (unsigned long)map / PAGE_SIZE * sizeof(u64), SEEK_SET); lseek(pm2, (unsigned long)map / PAGE_SIZE * sizeof(u64), SEEK_SET);
ret = read(pm2, &pmap, sizeof(pmap)); ret = read(pm2, &pmap, sizeof(pmap));
if (ret < 0){ if (ret < 0){
......
...@@ -42,9 +42,6 @@ struct mem_snap_ctx { ...@@ -42,9 +42,6 @@ struct mem_snap_ctx {
static int task_reset_dirty_track(int pid) static int task_reset_dirty_track(int pid)
{ {
int fd, ret;
char cmd[] = "4";
if (!opts.track_mem) if (!opts.track_mem)
return 0; return 0;
...@@ -54,7 +51,16 @@ static int task_reset_dirty_track(int pid) ...@@ -54,7 +51,16 @@ static int task_reset_dirty_track(int pid)
return -1; return -1;
} }
return do_task_reset_dirty_track(pid);
}
int do_task_reset_dirty_track(int pid)
{
int fd, ret;
char cmd[] = "4";
pr_info("Reset %d's dirty tracking\n", pid); pr_info("Reset %d's dirty tracking\n", pid);
fd = open_proc_rw(pid, "clear_refs"); fd = open_proc_rw(pid, "clear_refs");
if (fd < 0) if (fd < 0)
return -1; return -1;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment