Merge "meminfo: Add API to read pagemap for a vma within a process."
This commit is contained in:
commit
15a3a287f2
|
@ -65,5 +65,17 @@ class PageAcct final {
|
|||
::android::base::unique_fd pageidle_fd_;
|
||||
};
|
||||
|
||||
// Returns if the page present bit is set in the value
|
||||
// passed in.
|
||||
bool page_present(uint64_t pagemap_val);
|
||||
|
||||
// Returns if the page swapped bit is set in the value
|
||||
// passed in.
|
||||
bool page_swapped(uint64_t pagemap_val);
|
||||
|
||||
// Returns the page frame number (physical page) from
|
||||
// pagemap value
|
||||
uint64_t page_pfn(uint64_t pagemap_val);
|
||||
|
||||
} // namespace meminfo
|
||||
} // namespace android
|
||||
|
|
|
@ -73,6 +73,13 @@ class ProcMemInfo final {
|
|||
|
||||
const std::vector<uint16_t>& SwapOffsets();
|
||||
|
||||
// Reads /proc/<pid>/pagemap for this process for each page within
|
||||
// the 'vma' and stores that in 'pagemap'. It is assumed that the 'vma'
|
||||
// is obtained by calling Maps() or 'ForEachVma' for the same object. No special checks
|
||||
// are made to see if 'vma' is *valid*.
|
||||
// Returns false if anything goes wrong, 'true' otherwise.
|
||||
bool PageMap(const Vma& vma, std::vector<uint64_t>* pagemap);
|
||||
|
||||
~ProcMemInfo() = default;
|
||||
|
||||
private:
|
||||
|
|
|
@ -121,6 +121,23 @@ TEST_F(ValidateProcMemInfo, TestSwapOffsets) {
|
|||
EXPECT_EQ(proc_usage.swap / getpagesize(), swap_offsets.size());
|
||||
}
|
||||
|
||||
TEST_F(ValidateProcMemInfo, TestPageMap) {
|
||||
std::vector<uint64_t> pagemap;
|
||||
|
||||
auto vma_callback = [&](const Vma& vma) {
|
||||
uint64_t* pmap_out;
|
||||
size_t len;
|
||||
ASSERT_EQ(0, pm_process_pagemap_range(proc, vma.start, vma.end, &pmap_out, &len));
|
||||
ASSERT_TRUE(proc_mem->PageMap(vma, &pagemap));
|
||||
|
||||
EXPECT_EQ(len, ((vma.end - vma.start) / getpagesize()));
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
EXPECT_EQ(pmap_out[i], pagemap[i]);
|
||||
}
|
||||
};
|
||||
ASSERT_TRUE(proc_mem->ForEachVma(vma_callback));
|
||||
}
|
||||
|
||||
class ValidateProcMemInfoWss : public ::testing::Test {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
|
|
|
@ -138,5 +138,18 @@ int PageAcct::GetPageIdle(uint64_t pfn) const {
|
|||
return !!(idle_bits & (1ULL << (pfn % 64)));
|
||||
}
|
||||
|
||||
// Public methods
|
||||
bool page_present(uint64_t pagemap_val) {
|
||||
return PAGE_PRESENT(pagemap_val);
|
||||
}
|
||||
|
||||
bool page_swapped(uint64_t pagemap_val) {
|
||||
return PAGE_SWAPPED(pagemap_val);
|
||||
}
|
||||
|
||||
uint64_t page_pfn(uint64_t pagemap_val) {
|
||||
return PAGE_PFN(pagemap_val);
|
||||
}
|
||||
|
||||
} // namespace meminfo
|
||||
} // namespace android
|
||||
|
|
|
@ -199,6 +199,33 @@ const std::vector<uint16_t>& ProcMemInfo::SwapOffsets() {
|
|||
return swap_offsets_;
|
||||
}
|
||||
|
||||
bool ProcMemInfo::PageMap(const Vma& vma, std::vector<uint64_t>* pagemap) {
|
||||
pagemap->clear();
|
||||
std::string pagemap_file = ::android::base::StringPrintf("/proc/%d/pagemap", pid_);
|
||||
::android::base::unique_fd pagemap_fd(
|
||||
TEMP_FAILURE_RETRY(open(pagemap_file.c_str(), O_RDONLY | O_CLOEXEC)));
|
||||
if (pagemap_fd < 0) {
|
||||
PLOG(ERROR) << "Failed to open " << pagemap_file;
|
||||
return false;
|
||||
}
|
||||
|
||||
uint64_t nr_pages = (vma.end - vma.start) / getpagesize();
|
||||
pagemap->reserve(nr_pages);
|
||||
|
||||
uint64_t idx = vma.start / getpagesize();
|
||||
uint64_t last = idx + nr_pages;
|
||||
uint64_t val;
|
||||
for (; idx < last; idx++) {
|
||||
if (pread64(pagemap_fd, &val, sizeof(uint64_t), idx * sizeof(uint64_t)) < 0) {
|
||||
PLOG(ERROR) << "Failed to read page frames from page map for pid: " << pid_;
|
||||
return false;
|
||||
}
|
||||
pagemap->emplace_back(val);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ProcMemInfo::ReadMaps(bool get_wss) {
|
||||
// Each object reads /proc/<pid>/maps only once. This is done to make sure programs that are
|
||||
// running for the lifetime of the system can recycle the objects and don't have to
|
||||
|
|
Loading…
Reference in New Issue