From d9434ae382cb389781af0e5039f18e648447511e Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Thu, 16 Oct 2014 15:21:01 -0400 Subject: [PATCH] gen_memstats: add kpageflags to the database Change-Id: I6a2fddb9b2153095f8372a0bc02d4e7dea782d29 --- .../Catalyst/Utilities/CMakeLists.txt | 1 + .../Catalyst/Utilities/gen_memstats.cxx | 148 +++++++++++++++++- .../Catalyst/Utilities/read_kpageflags.cxx | 50 ++++++ .../Catalyst/Utilities/read_kpageflags.h | 37 +++++ 4 files changed, 231 insertions(+), 5 deletions(-) create mode 100644 CoProcessing/Catalyst/Utilities/read_kpageflags.cxx create mode 100644 CoProcessing/Catalyst/Utilities/read_kpageflags.h diff --git a/CoProcessing/Catalyst/Utilities/CMakeLists.txt b/CoProcessing/Catalyst/Utilities/CMakeLists.txt index 1851789ad0..6d68215b38 100644 --- a/CoProcessing/Catalyst/Utilities/CMakeLists.txt +++ b/CoProcessing/Catalyst/Utilities/CMakeLists.txt @@ -1,6 +1,7 @@ add_executable(gen_memstats gen_memstats.cxx read_kpagecount.cxx + read_kpageflags.cxx read_map.cxx read_pagemap.cxx) target_link_libraries(gen_memstats diff --git a/CoProcessing/Catalyst/Utilities/gen_memstats.cxx b/CoProcessing/Catalyst/Utilities/gen_memstats.cxx index de4102b91c..fb1589dd80 100644 --- a/CoProcessing/Catalyst/Utilities/gen_memstats.cxx +++ b/CoProcessing/Catalyst/Utilities/gen_memstats.cxx @@ -1,4 +1,5 @@ #include "read_kpagecount.h" +#include "read_kpageflags.h" #include "read_map.h" #include "read_pagemap.h" @@ -52,15 +53,16 @@ typedef raii safe_sql_stmt; int main(int argc, char* argv[]) { if (argc < 4) { - std::cerr << "usage: " << argv[0] << " " << std::endl; + std::cerr << "usage: " << argv[0] << " " << std::endl; return EXIT_FAILURE; } const char* maps_path = argv[1]; const char* pagemap_path = argv[2]; - const char* kpagecount_path = argv[3]; - int rank = atoi(argv[4]); - const char* database_path = argv[5]; + const char* kpageflags_path = argv[3]; + const char* kpagecount_path = argv[4]; + int rank = atoi(argv[5]); + const char* database_path = argv[6]; std::ifstream imaps(maps_path); safe_fd ipagemap(open(pagemap_path, 0), close); @@ -68,6 +70,11 @@ int main(int argc, char* argv[]) { perror("failed to open pagemap file"); return EXIT_FAILURE; } + safe_fd ikpageflags(open(kpageflags_path, 0), close); + if (ikpageflags < 0) { + perror("failed to open kpageflags file"); + return EXIT_FAILURE; + } safe_fd ikpagecount(open(kpagecount_path, 0), close); if (ikpagecount < 0) { perror("failed to open kpagecount file"); @@ -93,6 +100,7 @@ int main(int argc, char* argv[]) { safe_sql_stmt sql_insert_map(NULL, sqlite3_finalize); safe_sql_stmt sql_insert_pagemap(NULL, sqlite3_finalize); + safe_sql_stmt sql_insert_kpageflags(NULL, sqlite3_finalize); safe_sql_stmt sql_insert_kpagecount(NULL, sqlite3_finalize); if (sqlite3_prepare(sql, @@ -132,6 +140,38 @@ int main(int argc, char* argv[]) { sqlerror(sql, "preparing pagemap insert statement"); return EXIT_FAILURE; } + if (sqlite3_prepare(sql, + "INSERT INTO kpageflags VALUES (" + " null," + " :pfn," + " :locked," + " :error," + " :referenced," + " :uptodate," + " :dirty," + " :lru," + " :active," + " :slab," + " :writeback," + " :reclaim," + " :buddy," + " :mmap," + " :anon," + " :swapcache," + " :swapbacked," + " :compound_head," + " :compound_tail," + " :huge," + " :unevictable," + " :hwpoison," + " :nopage," + " :ksm," + " :thp" + ");", + -1, &sql_insert_kpageflags.get(), NULL) != SQLITE_OK) { + sqlerror(sql, "preparing kpageflags insert statement"); + return EXIT_FAILURE; + } if (sqlite3_prepare(sql, "INSERT INTO kpagecount VALUES (" " null," @@ -169,6 +209,31 @@ int main(int argc, char* argv[]) { MAKE_INDEX(pagemap, swap_offset); MAKE_INDEX(pagemap, swap_type); + MAKE_INDEX(kpageflags, pfn); + MAKE_INDEX(kpageflags, locked); + MAKE_INDEX(kpageflags, error); + MAKE_INDEX(kpageflags, referenced); + MAKE_INDEX(kpageflags, uptodate); + MAKE_INDEX(kpageflags, dirty); + MAKE_INDEX(kpageflags, lru); + MAKE_INDEX(kpageflags, active); + MAKE_INDEX(kpageflags, slab); + MAKE_INDEX(kpageflags, writeback); + MAKE_INDEX(kpageflags, reclaim); + MAKE_INDEX(kpageflags, buddy); + MAKE_INDEX(kpageflags, mmap); + MAKE_INDEX(kpageflags, anon); + MAKE_INDEX(kpageflags, swapcache); + MAKE_INDEX(kpageflags, swapbacked); + MAKE_INDEX(kpageflags, compound_head); + MAKE_INDEX(kpageflags, compound_tail); + MAKE_INDEX(kpageflags, huge); + MAKE_INDEX(kpageflags, unevictable); + MAKE_INDEX(kpageflags, hwpoison); + MAKE_INDEX(kpageflags, nopage); + MAKE_INDEX(kpageflags, ksm); + MAKE_INDEX(kpageflags, thp); + MAKE_INDEX(kpagecount, pfn); MAKE_INDEX(kpagecount, count); @@ -188,6 +253,7 @@ int main(int argc, char* argv[]) { const int pagesize = getpagesize(); map_t map; pagemap_t pagemap; + kpageflags_t kpageflags; kpagecount_t kpagecount; BIND(map, rank, int, rank); @@ -255,13 +321,49 @@ int main(int argc, char* argv[]) { } for (std::set::const_iterator i = pfns.begin(); i != pfns.end(); ++i) { - int status = read_kpagecount(ikpagecount, *i, &kpagecount); + int status = read_kpageflags(ikpageflags, *i, &kpageflags); if (status < 0) { return EXIT_FAILURE; } else if (status) { break; } + status = read_kpagecount(ikpagecount, *i, &kpagecount); + if (status < 0) { + return EXIT_FAILURE; + } else if (status) { + break; + } + + BIND(kpageflags, pfn, int64, *i); + BIND(kpageflags, locked, int, kpageflags.flags.locked); + BIND(kpageflags, error, int, kpageflags.flags.error); + BIND(kpageflags, referenced, int, kpageflags.flags.referenced); + BIND(kpageflags, uptodate, int, kpageflags.flags.uptodate); + BIND(kpageflags, dirty, int, kpageflags.flags.dirty); + BIND(kpageflags, lru, int, kpageflags.flags.lru); + BIND(kpageflags, active, int, kpageflags.flags.active); + BIND(kpageflags, slab, int, kpageflags.flags.slab); + BIND(kpageflags, writeback, int, kpageflags.flags.writeback); + BIND(kpageflags, reclaim, int, kpageflags.flags.reclaim); + BIND(kpageflags, buddy, int, kpageflags.flags.buddy); + BIND(kpageflags, mmap, int, kpageflags.flags.mmap); + BIND(kpageflags, anon, int, kpageflags.flags.anon); + BIND(kpageflags, swapcache, int, kpageflags.flags.swapcache); + BIND(kpageflags, swapbacked, int, kpageflags.flags.swapbacked); + BIND(kpageflags, compound_head, int, kpageflags.flags.compound_head); + BIND(kpageflags, compound_tail, int, kpageflags.flags.compound_tail); + BIND(kpageflags, huge, int, kpageflags.flags.huge); + BIND(kpageflags, unevictable, int, kpageflags.flags.unevictable); + BIND(kpageflags, hwpoison, int, kpageflags.flags.hwpoison); + BIND(kpageflags, nopage, int, kpageflags.flags.nopage); + BIND(kpageflags, ksm, int, kpageflags.flags.ksm); + BIND(kpageflags, thp, int, kpageflags.flags.thp); + + if (run_query(sql_insert_kpageflags) != SQLITE_OK) { + sqlerror(sql, "inserting into kpageflags table"); + } + BIND(kpagecount, pfn, int64, *i); BIND(kpagecount, count, int, kpagecount); @@ -336,6 +438,42 @@ int create_tables(sqlite3* sql) { return SQLITE_ERROR; } + if (sqlite3_prepare(sql, + "CREATE TABLE IF NOT EXISTS kpageflags (" + " pfn INTEGER PRIMARY KEY NOT NULL," + " locked INTEGER NOT NULL," + " error INTEGER NOT NULL," + " referenced INTEGER NOT NULL," + " uptodate INTEGER NOT NULL," + " dirty INTEGER NOT NULL," + " lru INTEGER NOT NULL," + " active INTEGER NOT NULL," + " slab INTEGER NOT NULL," + " writeback INTEGER NOT NULL," + " reclaim INTEGER NOT NULL," + " buddy INTEGER NOT NULL," + " mmap INTEGER NOT NULL," + " anon INTEGER NOT NULL," + " swapcache INTEGER NOT NULL," + " swapbacked INTEGER NOT NULL," + " compound_head INTEGER NOT NULL," + " compound_tail INTEGER NOT NULL," + " huge INTEGER NOT NULL," + " unevictable INTEGER NOT NULL," + " hwpoison INTEGER NOT NULL," + " nopage INTEGER NOT NULL," + " ksm INTEGER NOT NULL," + " thp INTEGER NOT NULL" + ");", + -1, &sql_create_tables.get(), NULL) != SQLITE_OK) { + sqlerror(sql, "preparing kpageflags table creation"); + return SQLITE_ERROR; + } + if (sqlite3_step(sql_create_tables) != SQLITE_DONE) { + sqlerror(sql, "creating kpageflags table"); + return SQLITE_ERROR; + } + if (sqlite3_prepare(sql, "CREATE TABLE IF NOT EXISTS kpagecount (" " pfn INTEGER PRIMARY KEY NOT NULL," diff --git a/CoProcessing/Catalyst/Utilities/read_kpageflags.cxx b/CoProcessing/Catalyst/Utilities/read_kpageflags.cxx new file mode 100644 index 0000000000..d57515e059 --- /dev/null +++ b/CoProcessing/Catalyst/Utilities/read_kpageflags.cxx @@ -0,0 +1,50 @@ +#include "read_kpageflags.h" + +#include +#include +#include + +int read_kpageflags(int fd, uint64_t pfn, kpageflags_t* kpageflags) { + static const size_t KPAGEFLAGS_ENTRY_SIZE = sizeof(uint64_t); + + // Shifting by virt-addr-offset number of bytes and multiplying by the size + // of an address (the size of an entry in pagemap file) + off_t file_offset = pfn * KPAGEFLAGS_ENTRY_SIZE; + if (lseek(fd, file_offset, SEEK_SET) < 0) { + if (errno) { + perror("lseek failed"); + return -1; + } + return 1; + } + + union { + uint64_t data; + char bytes[KPAGEFLAGS_ENTRY_SIZE]; + } buf; + size_t sz = 0; + while (sz < KPAGEFLAGS_ENTRY_SIZE) { + errno = 0; + int csz = read(fd, (char*)buf.bytes + sz, KPAGEFLAGS_ENTRY_SIZE - sz); + if (csz < 0) { + if (errno == EAGAIN) { + continue; + } else { + perror("failed to read"); + return -1; + } + } else if (csz) { + sz += csz; + } else { + if (errno) { + perror("eof"); + return -1; + } + return 1; + } + } + + kpageflags->data = buf.data; + + return 0; +} diff --git a/CoProcessing/Catalyst/Utilities/read_kpageflags.h b/CoProcessing/Catalyst/Utilities/read_kpageflags.h new file mode 100644 index 0000000000..7eca082626 --- /dev/null +++ b/CoProcessing/Catalyst/Utilities/read_kpageflags.h @@ -0,0 +1,37 @@ +#include +#include + +struct kpageflags_t { + union { + uint64_t data; + struct { + uint64_t __unused : 41; + + unsigned thp : 1; + unsigned ksm : 1; + unsigned nopage : 1; + unsigned hwpoison : 1; + unsigned unevictable : 1; + unsigned huge : 1; + unsigned compound_tail : 1; + unsigned compound_head : 1; + unsigned swapbacked : 1; + unsigned swapcache : 1; + unsigned anon : 1; + unsigned mmap : 1; + unsigned buddy : 1; + unsigned reclaim : 1; + unsigned writeback : 1; + unsigned slab : 1; + unsigned active : 1; + unsigned lru : 1; + unsigned dirty : 1; + unsigned uptodate : 1; + unsigned referenced : 1; + unsigned error : 1; + unsigned locked : 1; + } flags; + }; +}; + +int read_kpageflags(int fd, uint64_t pfn, kpageflags_t* kpageflags); -- GitLab