All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jason Wang <jasowang@redhat.com>
To: mtosatti@redhat.com, avi@redhat.com, kvm@vger.kernel.org
Subject: [PATCH 3/3] test: Add test for kvmclock
Date: Sun, 26 Jul 2009 11:22:53 +0800	[thread overview]
Message-ID: <20090726032253.8068.62886.stgit@FreeLancer> (raw)
In-Reply-To: <20090726032237.8068.32553.stgit@FreeLancer>

This patch implements the following tests for kvmclock:
- A simple wall clock test to check whether a consistent value was
returned.
- A monotonic cycle test to check whether the kvmclock driver could
return monotnic cycles in SMP guests.
- A raw cycle test to check whether the hypervios could provide
monotonic cycles.

Signed-off-by: Jason Wang <jasowang@redhat.com>
---
 kvm/test/x86/kvmclock_test.c |  128 ++++++++++++++++++++++++++++++++++++++++++
 kvm/test/x86/unittests.cfg   |    4 +
 2 files changed, 132 insertions(+), 0 deletions(-)
 create mode 100644 kvm/test/x86/kvmclock_test.c

diff --git a/kvm/test/config-x86-common.mak b/kvm/test/config-x86-common.mak
index a6ee18c..3dfd450 100644
--- a/kvm/test/config-x86-common.mak
+++ b/kvm/test/config-x86-common.mak
@@ -25,7 +25,8 @@ FLATLIBS = lib/libcflat.a $(libgcc)
 tests-common = $(TEST_DIR)/vmexit.flat $(TEST_DIR)/tsc.flat \
                $(TEST_DIR)/smptest.flat  $(TEST_DIR)/port80.flat \
                $(TEST_DIR)/realmode.flat $(TEST_DIR)/msr.flat \
-               $(TEST_DIR)/hypercall.flat $(TEST_DIR)/sieve.flat
+               $(TEST_DIR)/hypercall.flat $(TEST_DIR)/sieve.flat \
+	       $(TEST_DIR)/kvmclock_test.flat
 
 tests_and_config = $(TEST_DIR)/*.flat $(TEST_DIR)/unittests.cfg
 
@@ -67,6 +68,9 @@ $(TEST_DIR)/xsave.flat: $(cstart.o) $(TEST_DIR)/idt.o $(TEST_DIR)/xsave.o
 $(TEST_DIR)/rmap_chain.flat: $(cstart.o) $(TEST_DIR)/rmap_chain.o \
 			     $(TEST_DIR)/vm.o
 
+$(TEST_DIR)/kvmclock_test.flat: $(cstart.o) $(TEST_DIR)/kvmclock.o \
+				$(TEST_DIR)/kvmclock_test.o
+
 arch_clean:
 	$(RM) $(TEST_DIR)/*.o $(TEST_DIR)/*.flat \
 	$(TEST_DIR)/.*.d $(TEST_DIR)/lib/.*.d $(TEST_DIR)/lib/*.o
diff --git a/kvm/test/x86/kvmclock_test.c b/kvm/test/x86/kvmclock_test.c
new file mode 100644
index 0000000..8530a89
--- /dev/null
+++ b/kvm/test/x86/kvmclock_test.c
@@ -0,0 +1,128 @@
+#include "libcflat.h"
+#include "smp.h"
+#include "kvmclock.h"
+
+#define TEST_LOOPS 100000000
+
+static inline int atomic_read(int *v)
+{
+    return (*(volatile int *)&(v));
+}
+
+static inline void atomic_dec(int *v)
+{
+    asm volatile("lock decl %0": "+m" (*v));
+}
+
+struct test_info {
+    struct spinlock lock; 
+    u64 loops;                /* test loops */
+    u64 warps;                /* warp count */
+    long long worst;          /* worst warp */
+    volatile cycle_t last;    /* last cycle seen by test */
+    int ncpus;                /* number of cpu in the test*/
+};
+
+struct test_info ti[2];
+
+static int wallclock_test()
+{
+    int i;
+    struct timespec ts, ts_last;
+    
+    kvm_get_wallclock(&ts_last);
+
+    for (i=0; i < 100; i++){
+	kvm_get_wallclock(&ts);
+	if (ts.nsec != ts_last.nsec || ts.sec != ts_last.sec){
+	    printf ("Inconsistent wall clock returned!\n");
+	    return 1;
+	}
+    }
+    return 0;
+}
+
+static void kvm_clock_test(void *data)
+{
+    struct test_info *hv_test_info = (struct test_info *)data;
+    int index = smp_id();
+    int i;
+    
+    for (i = 0; i < hv_test_info->loops; i++){
+	cycle_t t0, t1;
+	long long delta;
+
+	spin_lock(&hv_test_info->lock);
+	t1 = kvm_clock_read();
+	t0 = hv_test_info->last;
+	hv_test_info->last = kvm_clock_read();
+	spin_unlock(&hv_test_info->lock);
+
+	delta = t1 - t0;
+	if (delta < 0){
+	    spin_lock(&hv_test_info->lock);
+	    ++hv_test_info->warps;
+	    if (delta < hv_test_info->worst){
+		hv_test_info->worst = delta;
+		printf("Worst warp %lld %\n", hv_test_info->worst);
+	    }	   
+	    spin_unlock(&hv_test_info->lock);
+	}
+	
+	if (!((unsigned long)i & 31))
+	    asm volatile("rep; nop");
+    }
+
+    atomic_dec(&hv_test_info->ncpus);
+}
+
+static int cycle_test(int ncpus, int loops, struct test_info *ti)
+{
+    int i;
+
+    ti->ncpus = ncpus;
+    ti->loops = loops;
+    for (i = ncpus - 1; i >= 0; --i)
+	on_cpu_async(i, kvm_clock_test, (void *)ti);
+
+    /* Wait for the end of other vcpu */
+    while(!atomic_read(&ti->ncpus))
+	;
+    
+    printf("Total vcpus: %d\n", ncpus);
+    printf("Total loops: %lld\n", ti->loops * ncpus);
+    printf("Total warps: %lld\n", ti->warps);
+    printf("Worst warp:  %lld\n", ti->worst);
+
+    return ti->warps ? 1 : 0;
+}
+
+int main()
+{
+    int ncpus = cpu_count();
+    int nerr = 0, i;
+  
+    smp_init();
+
+    if (ncpus > MAX_CPU)
+	ncpus = MAX_CPU;
+    for (i = 0; i < ncpus; ++i)
+	on_cpu(i, kvm_clock_init, (void *)0);
+
+    printf("Wallclock test:\n");
+    nerr += wallclock_test();
+
+    pvclock_set_flags(PVCLOCK_TSC_STABLE_BIT);
+    printf("Monotonic cycle test:\n");
+    nerr += cycle_test(ncpus, TEST_LOOPS, &ti[0]);
+
+    pvclock_set_flags(PVCLOCK_TSC_STABLE_BIT 
+		      | PVCLOCK_CYCLE_RAW_TEST_BIT);
+    printf("Raw cycle test:\n");
+    nerr += cycle_test(ncpus, TEST_LOOPS, &ti[1]);
+
+    for (i = 0; i < ncpus; ++i)
+	on_cpu(i, kvm_clock_clear, (void *)0);
+
+    return nerr > 0 ? 1 : 0;
+}
diff --git a/kvm/test/x86/unittests.cfg b/kvm/test/x86/unittests.cfg
index f39c5bd..0d077ac 100644
--- a/kvm/test/x86/unittests.cfg
+++ b/kvm/test/x86/unittests.cfg
@@ -53,3 +53,7 @@ file = xsave.flat
 
 [rmap_chain]
 file = rmap_chain.flat
+
+[kvmclock]
+file = kvmclock_test.flat
+smp = 2


      parent reply	other threads:[~2010-07-26  3:22 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-07-26  3:22 [PATCH 1/3] test: Drop print.S Jason Wang
2009-07-26  3:22 ` [PATCH 2/3] test: Add kvmclock driver Jason Wang
2009-07-26  3:22 ` Jason Wang [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20090726032253.8068.62886.stgit@FreeLancer \
    --to=jasowang@redhat.com \
    --cc=avi@redhat.com \
    --cc=kvm@vger.kernel.org \
    --cc=mtosatti@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.