From mboxrd@z Thu Jan 1 00:00:00 1970 From: Takuya Yoshikawa Subject: [PATCH v2 1/3 kvm-unit-tests] Add dirty logging performance test Date: Sun, 15 Jan 2012 12:43:18 +0900 Message-ID: <20120115124318.cb372f8c784309695bef7d9e@gmail.com> References: <20120115124131.3b460d1d85194edaa251e635@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Cc: kvm@vger.kernel.org To: avi@redhat.com, mtosatti@redhat.com Return-path: Received: from mail-tul01m020-f174.google.com ([209.85.214.174]:37653 "EHLO mail-tul01m020-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753517Ab2AODnX (ORCPT ); Sat, 14 Jan 2012 22:43:23 -0500 Received: by obcva7 with SMTP id va7so3537237obc.19 for ; Sat, 14 Jan 2012 19:43:22 -0800 (PST) In-Reply-To: <20120115124131.3b460d1d85194edaa251e635@gmail.com> Sender: kvm-owner@vger.kernel.org List-ID: Can be used to check how long it takes to get dirty log according to the number of dirty pages as follows: $ ./api/dirty-log-perf rip 804a3fa rip 804a3fa get dirty log: 80824 ns for 1 dirty pages rip 804a3fa get dirty log: 60077 ns for 2 dirty pages rip 804a3fa get dirty log: 51745 ns for 4 dirty pages ... rip 804a3fa get dirty log: 2008468 ns for 65536 dirty pages rip 804a3fa get dirty log: 3402165 ns for 131072 dirty pages rip 804a3fa get dirty log: 5614625 ns for 262144 dirty pages Signed-off-by: Takuya Yoshikawa --- api/dirty-log-perf.cc | 93 +++++++++++++++++++++++++++++++++++++++++++++++++ config-x86-common.mak | 5 ++- 2 files changed, 97 insertions(+), 1 deletions(-) create mode 100644 api/dirty-log-perf.cc diff --git a/api/dirty-log-perf.cc b/api/dirty-log-perf.cc new file mode 100644 index 0000000..b9e9796 --- /dev/null +++ b/api/dirty-log-perf.cc @@ -0,0 +1,93 @@ +#include "kvmxx.hh" +#include "memmap.hh" +#include "identity.hh" +#include +#include +#include +#include + +namespace { + +const int page_size = 4096; +const int64_t nr_total_pages = 256 * 1024; + +// Return the current time in nanoseconds. +uint64_t time_ns() +{ + struct timespec ts; + + clock_gettime(CLOCK_MONOTONIC, &ts); + return ts.tv_sec * (uint64_t)1000000000 + ts.tv_nsec; +} + +// Update nr_to_write pages selected from nr_pages pages. +void write_mem(void* slot_head, int64_t nr_to_write, int64_t nr_pages) +{ + char* var = static_cast(slot_head); + int64_t interval = nr_pages / nr_to_write; + + for (int64_t i = 0; i < nr_to_write; ++i) { + ++(*var); + var += interval * page_size; + } +} + +using boost::ref; +using std::tr1::bind; + +// Let the guest update nr_to_write pages selected from nr_pages pages. +void do_guest_write(kvm::vcpu& vcpu, void* slot_head, + int64_t nr_to_write, int64_t nr_pages) +{ + identity::vcpu guest_write_thread(vcpu, bind(write_mem, ref(slot_head), + nr_to_write, nr_pages)); + vcpu.run(); +} + +// Check how long it takes to update dirty log. +void check_dirty_log(kvm::vcpu& vcpu, mem_slot& slot, void* slot_head) +{ + slot.set_dirty_logging(true); + slot.update_dirty_log(); + + for (int64_t i = 1; i <= nr_total_pages; i *= 2) { + do_guest_write(vcpu, slot_head, i, nr_total_pages); + + uint64_t start_ns = time_ns(); + slot.update_dirty_log(); + uint64_t end_ns = time_ns(); + + printf("get dirty log: %10lld ns for %10lld dirty pages\n", + end_ns - start_ns, i); + } + + slot.set_dirty_logging(false); +} + +} + +int main(int ac, char **av) +{ + kvm::system sys; + kvm::vm vm(sys); + mem_map memmap(vm); + + void* mem_head; + int64_t mem_size = nr_total_pages * page_size; + if (posix_memalign(&mem_head, page_size, mem_size)) { + printf("dirty-log-perf: Could not allocate guest memory.\n"); + exit(1); + } + uint64_t mem_addr = reinterpret_cast(mem_head); + + identity::hole hole(mem_head, mem_size); + identity::vm ident_vm(vm, memmap, hole); + kvm::vcpu vcpu(vm, 0); + + mem_slot slot(memmap, mem_addr, mem_size, mem_head); + + // pre-allocate shadow pages + do_guest_write(vcpu, mem_head, nr_total_pages, nr_total_pages); + check_dirty_log(vcpu, slot, mem_head); + return 0; +} diff --git a/config-x86-common.mak b/config-x86-common.mak index 1cbc7c6..a093b8d 100644 --- a/config-x86-common.mak +++ b/config-x86-common.mak @@ -39,6 +39,7 @@ tests-common = $(TEST_DIR)/vmexit.flat $(TEST_DIR)/tsc.flat \ ifdef API tests-common += api/api-sample tests-common += api/dirty-log +tests-common += api/dirty-log-perf endif tests_and_config = $(TEST_DIR)/*.flat $(TEST_DIR)/unittests.cfg @@ -93,7 +94,7 @@ arch_clean: api/%.o: CFLAGS += -m32 -api/%: LDLIBS += -lstdc++ -lboost_thread-mt -lpthread +api/%: LDLIBS += -lstdc++ -lboost_thread-mt -lpthread -lrt api/%: LDFLAGS += -m32 api/libapi.a: api/kvmxx.o api/identity.o api/exception.o api/memmap.o @@ -102,3 +103,5 @@ api/libapi.a: api/kvmxx.o api/identity.o api/exception.o api/memmap.o api/api-sample: api/api-sample.o api/libapi.a api/dirty-log: api/dirty-log.o api/libapi.a + +api/dirty-log-perf: api/dirty-log-perf.o api/libapi.a -- 1.7.5.4