From 38a44fec0347cd14bf379ad7e2a523499bd160fb Mon Sep 17 00:00:00 2001 From: Dariusz Sosnowski Date: Tue, 15 Sep 2020 23:21:51 +0200 Subject: [PATCH] MonitoredSharedMemory: PoC - snapshot hugepages --- src/MonitoredSharedMemory.cc | 39 ++++++++++++++++++++++++++++++------ src/Session.cc | 24 ++++++++++++++++++---- src/record_syscall.cc | 6 ++++++ 3 files changed, 59 insertions(+), 10 deletions(-) diff --git a/src/MonitoredSharedMemory.cc b/src/MonitoredSharedMemory.cc index 29aac3183ca..74eaa51a402 100644 --- a/src/MonitoredSharedMemory.cc +++ b/src/MonitoredSharedMemory.cc @@ -19,13 +19,39 @@ MonitoredSharedMemory::~MonitoredSharedMemory() { munmap(real_mem, size); } static const char dconf_suffix[] = "/dconf/user"; +// static const char dpdk_prefix[] = "/run/dpdk/rte"; + +static const char rtemap_prefix[] = "/dev/hugepages/rtemap"; + void MonitoredSharedMemory::maybe_monitor(RecordTask* t, const string& file_name, const AddressSpace::Mapping& m, - int tracee_fd, uint64_t offset) { + int tracee_fd, uint64_t offset) +{ + bool is_dconf = true; + // bool is_dpdk = true; + bool is_rtemap = true; + size_t dconf_suffix_len = sizeof(dconf_suffix) - 1; if (file_name.size() < dconf_suffix_len || file_name.substr(file_name.size() - dconf_suffix_len) != dconf_suffix) { + is_dconf = false; + } + + // size_t dpdk_prefix_len = sizeof(dpdk_prefix) - 1; + // if (file_name.size() < dpdk_prefix_len || + // file_name.substr(0, dpdk_prefix_len) != dpdk_prefix) { + // is_dpdk = false; + // } + + size_t rtemap_prefix_len = sizeof(rtemap_prefix) - 1; + if (file_name.size() < rtemap_prefix_len || + file_name.substr(0, rtemap_prefix_len) != rtemap_prefix) { + is_rtemap = false; + } + + // if (!is_dconf && !is_dpdk && !is_rtemap) { + if (!is_dconf && !is_rtemap) { return; } @@ -33,7 +59,7 @@ void MonitoredSharedMemory::maybe_monitor(RecordTask* t, ScopedFd fd = remote.retrieve_fd(tracee_fd); uint8_t* real_mem = static_cast( - mmap(NULL, m.map.size(), PROT_READ, MAP_SHARED, fd, offset)); + mmap(NULL, m.map.size(), PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset)); ASSERT(t, real_mem != MAP_FAILED); auto result = shared_ptr( @@ -74,10 +100,11 @@ void MonitoredSharedMemory::check_for_changes(RecordTask* t, m = Session::recreate_shared_mmap(remote, m, Session::DISCARD_CONTENTS, move(msm)); } - if (!memcmp(m.local_addr, real_mem, size)) { - return; - } - memcpy(m.local_addr, real_mem, size); + // if (!memcmp(m.local_addr, real_mem, size)) { + // return; + // } + // memcpy(m.local_addr, real_mem, size); + memcpy(real_mem, m.local_addr, size); t->record_local(m.map.start(), size, real_mem); } } diff --git a/src/Session.cc b/src/Session.cc index 77a492391e7..7598e414341 100644 --- a/src/Session.cc +++ b/src/Session.cc @@ -429,20 +429,36 @@ static void remap_shared_mmap(AutoRemoteSyscalls& remote, EmuFs& emu_fs, KernelMapping Session::create_shared_mmap( AutoRemoteSyscalls& remote, size_t size, remote_ptr map_hint, const char* name, int tracee_prot, int tracee_flags, - MonitoredSharedMemory::shr_ptr&& monitored) { + MonitoredSharedMemory::shr_ptr&& monitored) +{ + bool is_huge_backed = false; + + if (monitored) { + is_huge_backed = true; + } + static int nonce = 0; // Create the segment we'll share with the tracee. char path[PATH_MAX]; - snprintf(path, sizeof(path) - 1, "%s%s%s-%d-%d", tmp_dir(), + if (!is_huge_backed) { + snprintf(path, sizeof(path) - 1, "%s%s%s-%d-%d", tmp_dir(), rr_mapping_prefix(), name, remote.task()->real_tgid(), nonce++); + } else { + snprintf(path, sizeof(path) - 1, "%s%s%s-%d-%d", "/dev/hugepages", + rr_mapping_prefix(), name, remote.task()->real_tgid(), nonce++); + } ScopedFd shmem_fd(path, O_CREAT | O_EXCL | O_RDWR); /* Remove the fs name so that we don't have to worry about * cleaning up this segment in error conditions. */ - unlink(path); + if (!is_huge_backed) { + unlink(path); + } int child_shmem_fd = remote.send_fd(shmem_fd); - resize_shmem_segment(shmem_fd, size); + if (!is_huge_backed) { + resize_shmem_segment(shmem_fd, size); + } LOG(debug) << "created shmem segment " << path; // Map the segment in ours and the tracee's address spaces. diff --git a/src/record_syscall.cc b/src/record_syscall.cc index 3927c0f8cc3..2d814e2ac6c 100644 --- a/src/record_syscall.cc +++ b/src/record_syscall.cc @@ -5524,6 +5524,12 @@ static void process_mmap(RecordTask* t, size_t length, int prot, int flags, MonitoredSharedMemory::maybe_monitor(t, tracee_file_name, t->vm()->mapping_of(addr), fd, offset); } + + if ((prot & (PROT_WRITE | PROT_READ)) == (PROT_WRITE | PROT_READ) && (flags & MAP_SHARED) && + !effectively_anonymous) { + MonitoredSharedMemory::maybe_monitor(t, tracee_file_name, + t->vm()->mapping_of(addr), fd, offset); + } } static void process_mremap(RecordTask* t, remote_ptr old_addr,