kvm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Amos Kong <akong@redhat.com>
To: autotest@test.kernel.org
Cc: lmr@redhat.com, glommer@redhat.com, zamsden@redhat.com,
	kvm@vger.kernel.org
Subject: [Autotest PATCH] KVM-test: TSC drift test
Date: Thu, 21 Apr 2011 15:33:02 +0800	[thread overview]
Message-ID: <20110421073302.12433.13463.stgit@t> (raw)

This case is used to test the drift between host and guest.
Use taskset to make tsc program execute in a single cpu.
If the drift ratio bigger than 10%, then fail this case.

Signed-off-by: Amos Kong <akong@redhat.com>
---
 client/tests/kvm/deps/get_tsc.c        |   27 ++++++++++
 client/tests/kvm/tests/tsc_drift.py    |   88 ++++++++++++++++++++++++++++++++
 client/tests/kvm/tests_base.cfg.sample |    5 ++
 3 files changed, 120 insertions(+), 0 deletions(-)
 create mode 100644 client/tests/kvm/deps/get_tsc.c
 create mode 100644 client/tests/kvm/tests/tsc_drift.py

diff --git a/client/tests/kvm/deps/get_tsc.c b/client/tests/kvm/deps/get_tsc.c
new file mode 100644
index 0000000..e91a41f
--- /dev/null
+++ b/client/tests/kvm/deps/get_tsc.c
@@ -0,0 +1,27 @@
+/*
+ * Programme to get cpu's TSC(time stamp counter)
+ * Copyright(C) 2009 Redhat, Inc.
+ * Amos Kong <akong@redhat.com>
+ * Dec 9, 2009
+ *
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdint.h>
+
+typedef unsigned long long u64;
+
+u64 rdtsc(void)
+{
+	unsigned tsc_lo, tsc_hi;
+
+	asm volatile("rdtsc" : "=a"(tsc_lo), "=d"(tsc_hi));
+	return tsc_lo | (u64)tsc_hi << 32;
+}
+
+int main(void)
+{
+	printf("%lld\n", rdtsc());
+	return 0;
+}
diff --git a/client/tests/kvm/tests/tsc_drift.py b/client/tests/kvm/tests/tsc_drift.py
new file mode 100644
index 0000000..de2fb76
--- /dev/null
+++ b/client/tests/kvm/tests/tsc_drift.py
@@ -0,0 +1,88 @@
+import time, os, logging, commands, re
+from autotest_lib.client.common_lib import error
+from autotest_lib.client.bin import local_host
+import kvm_test_utils
+
+
+def run_tsc_drift(test, params, env):
+    """
+    Check the TSC(time stamp counter) frequency of guest and host whether match
+    or not
+
+    1) Computer average tsc frequency of host's cpus by C the program
+    2) Copy the C code to the guest, complie and run it to get tsc
+       frequency of guest's vcpus
+    3) Sleep sometimes and get the TSC of host and guest again
+    4) Compute the TSC frequency of host and guest
+    5) Compare the frequency deviation between host and guest with standard
+
+    @param test: Kvm test object
+    @param params: Dictionary with the test parameters.
+    @param env: Dictionary with test environment.
+    """
+    drift_threshold = float(params.get("drift_threshold"))
+    interval = float(params.get("interval"))
+    cpu_chk_cmd = params.get("cpu_chk_cmd")
+    tsc_freq_path = os.path.join(test.bindir, 'deps/get_tsc.c')
+    host_freq = 0
+
+    def get_tsc(machine="host", i=0):
+        cmd = "taskset -c %s /tmp/get_tsc" % i
+        if machine == "host":
+            s, o = commands.getstatusoutput(cmd)
+        else:
+            s, o = session.cmd_status_output(cmd)
+        if s != 0:
+            logging.debug(o)
+            raise error.TestError("Fail to get tsc of host, ncpu: %d" % i)
+        return float(re.findall("(\d+)",o)[0])
+
+    vm = env.get_vm(params["main_vm"])
+    vm.verify_alive()
+    timeout = float(params.get("login_timeout", 240))
+    session = vm.wait_for_login(timeout=timeout)
+
+    commands.getoutput("gcc %s -o /tmp/get_tsc" % tsc_freq_path)
+    ncpu = local_host.LocalHost().get_num_cpu()
+
+    logging.info("Interval is %s" % interval)
+    logging.info("Determine the TSC frequency in the host")
+    for i in range(ncpu):
+        tsc1 = get_tsc("host", i)
+        time.sleep(interval)
+        tsc2 = get_tsc("host", i)
+
+        delta = tsc2 - tsc1
+        logging.info("Host TSC delta for cpu %s is %s" % (i, delta))
+        if delta < 0:
+            raise error.TestError("Host TSC for cpu %s warps %s" % (i, delta))
+
+        host_freq += delta / ncpu
+    logging.info("Average frequency of host's cpus: %s" % host_freq)
+
+    vm.copy_files_to(tsc_freq_path,'/tmp/get_tsc.c')
+    session.cmd("gcc /tmp/get_tsc.c -o /tmp/get_tsc")
+
+    s, guest_ncpu = session.cmd_status_output(cpu_chk_cmd)
+
+    success = True
+    for i in range(int(guest_ncpu)):
+        tsc1 = get_tsc("guest", i)
+        time.sleep(interval)
+        tsc2 = get_tsc("guest", i)
+
+        delta = tsc2 - tsc1
+        logging.info("Guest TSC delta for vcpu %s is %s" % (i, delta))
+        if delta < 0:
+            logging.error("Guest TSC for vcpu %s warps %s" % (i, delta))
+
+        ratio = 100 * (delta - host_freq) / host_freq
+        logging.info("TSC drift ratio for vcpu %s is %s" % (i, ratio))
+        if abs(ratio) > drift_threshold:
+            logging.error("TSC drift found for vcpu %s ratio %s" % (i, ratio))
+            success = False
+
+    if not success:
+        raise error.TestFail("TSC drift found for the guest, please check the "
+                             "log for details")
+    session.close()
diff --git a/client/tests/kvm/tests_base.cfg.sample b/client/tests/kvm/tests_base.cfg.sample
index ceafebe..8e70746 100644
--- a/client/tests/kvm/tests_base.cfg.sample
+++ b/client/tests/kvm/tests_base.cfg.sample
@@ -331,6 +331,11 @@ variants:
                         drift_threshold = 10
                         drift_threshold_single = 3
 
+    - tsc_drift:
+        type = tsc_drift
+        drift_threshold = 10
+        interval = 30
+
     - balloon_check:  install setup unattended_install.cdrom
         type = balloon_check
         extra_params += " -balloon virtio"


             reply	other threads:[~2011-04-21  7:33 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-04-21  7:33 Amos Kong [this message]
2011-04-29  5:42 ` [Autotest PATCH] KVM-test: TSC drift test Lucas Meneghel Rodrigues
2011-05-06 15:00   ` Amos Kong
2011-07-26 18:45 ` [Autotest] " Lucas Meneghel Rodrigues

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=20110421073302.12433.13463.stgit@t \
    --to=akong@redhat.com \
    --cc=autotest@test.kernel.org \
    --cc=glommer@redhat.com \
    --cc=kvm@vger.kernel.org \
    --cc=lmr@redhat.com \
    --cc=zamsden@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).