changeset 7cab06691984 in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=7cab06691984
description:
        kvm: Set the perf exclude_host attribute if available

        The performance counting framework in Linux 3.2 and onwards supports
        an attribute to exclude events generated by the host when running
        KVM. Setting this attribute allows us to get more reliable
        measurements of the guest machine. For example, on a highly loaded
        system, the instruction counts from the guest can be severely
        distorted by the host kernel (e.g., by page fault handlers).

        This changeset introduces a check for the attribute and enables it in
        the KVM CPU if present.

diffstat:

 SConstruct               |  41 +++++++++++++++++++++++++++++++++++++++--
 src/cpu/kvm/base.cc      |  12 ++++++++++++
 src/cpu/kvm/perfevent.hh |  35 +++++++++++++++++++++++++++++++++++
 3 files changed, 86 insertions(+), 2 deletions(-)

diffs (158 lines):

diff -r d70124a5d594 -r 7cab06691984 SConstruct
--- a/SConstruct        Tue Nov 26 17:51:07 2013 +0100
+++ b/SConstruct        Tue Oct 15 10:09:23 2013 +0200
@@ -794,12 +794,35 @@
     context.Result(ret)
     return ret
 
+# Add a custom Check function to test for structure members.
+def CheckMember(context, include, decl, member, include_quotes="<>"):
+    context.Message("Checking for member %s in %s..." %
+                    (member, decl))
+    text = """
+#include %(header)s
+int main(){
+  %(decl)s test;
+  (void)test.%(member)s;
+  return 0;
+};
+""" % { "header" : include_quotes[0] + include + include_quotes[1],
+        "decl" : decl,
+        "member" : member,
+        }
+
+    ret = context.TryCompile(text, extension=".cc")
+    context.Result(ret)
+    return ret
+
 # Platform-specific configuration.  Note again that we assume that all
 # builds under a given build root run on the same host platform.
 conf = Configure(main,
                  conf_dir = joinpath(build_root, '.scons_config'),
                  log_file = joinpath(build_root, 'scons_config.log'),
-                 custom_tests = { 'CheckLeading' : CheckLeading })
+                 custom_tests = {
+        'CheckLeading' : CheckLeading,
+        'CheckMember' : CheckMember,
+        })
 
 # Check for leading underscores.  Don't really need to worry either
 # way so don't need to check the return code.
@@ -964,6 +987,12 @@
     return host_isa in isa_comp_table.get(isa, [])
 
 
+# Check if the exclude_host attribute is available. We want this to
+# get accurate instruction counts in KVM.
+main['HAVE_PERF_ATTR_EXCLUDE_HOST'] = conf.CheckMember(
+    'linux/perf_event.h', 'struct perf_event_attr', 'exclude_host')
+
+
 ######################################################################
 #
 # Finish the configuration
@@ -1065,7 +1094,8 @@
 
 # These variables get exported to #defines in config/*.hh (see src/SConscript).
 export_vars += ['USE_FENV', 'SS_COMPATIBLE_FP', 'TARGET_ISA', 'CP_ANNOTATE',
-                'USE_POSIX_CLOCK', 'PROTOCOL', 'HAVE_PROTOBUF']
+                'USE_POSIX_CLOCK', 'PROTOCOL', 'HAVE_PROTOBUF',
+                'HAVE_PERF_ATTR_EXCLUDE_HOST']
 
 ###################################################
 #
@@ -1243,6 +1273,13 @@
                 "target ISA combination"
             env['USE_KVM'] = False
 
+    # Warn about missing optional functionality
+    if env['USE_KVM']:
+        if not main['HAVE_PERF_ATTR_EXCLUDE_HOST']:
+            print "Warning: perf_event headers lack support for the " \
+                "exclude_host attribute. KVM instruction counts will " \
+                "be inaccurate."
+
     # Save sticky variable settings back to current variables file
     sticky_vars.Save(current_vars_file, env)
 
diff -r d70124a5d594 -r 7cab06691984 src/cpu/kvm/base.cc
--- a/src/cpu/kvm/base.cc       Tue Nov 26 17:51:07 2013 +0100
+++ b/src/cpu/kvm/base.cc       Tue Oct 15 10:09:23 2013 +0200
@@ -1133,6 +1133,12 @@
     cfgCycles.disabled(true)
         .pinned(true);
 
+    // Try to exclude the host. We set both exclude_hv and
+    // exclude_host since different architectures use slightly
+    // different APIs in the kernel.
+    cfgCycles.exclude_hv(true)
+        .exclude_host(true);
+
     if (perfControlledByTimer) {
         // We need to configure the cycles counter to send overflows
         // since we are going to use it to trigger timer signals that
@@ -1206,6 +1212,12 @@
     PerfKvmCounterConfig cfgInstructions(PERF_TYPE_HARDWARE,
                                          PERF_COUNT_HW_INSTRUCTIONS);
 
+    // Try to exclude the host. We set both exclude_hv and
+    // exclude_host since different architectures use slightly
+    // different APIs in the kernel.
+    cfgInstructions.exclude_hv(true)
+        .exclude_host(true);
+
     if (period) {
         // Setup a sampling counter if that has been requested.
         cfgInstructions.wakeupEvents(1)
diff -r d70124a5d594 -r 7cab06691984 src/cpu/kvm/perfevent.hh
--- a/src/cpu/kvm/perfevent.hh  Tue Nov 26 17:51:07 2013 +0100
+++ b/src/cpu/kvm/perfevent.hh  Tue Oct 15 10:09:23 2013 +0200
@@ -45,6 +45,8 @@
 
 #include <inttypes.h>
 
+#include "config/have_perf_attr_exclude_host.hh"
+
 /**
  * PerfEvent counter configuration.
  */
@@ -125,6 +127,39 @@
         return *this;
     }
 
+    /**
+     * Exclude the events from the host (i.e., only include events
+     * from the guest system).
+     *
+     * Intel CPUs seem to support this attribute from Linux 3.2 and
+     * onwards. Non-x86 architectures currently ignore this attribute
+     * (Linux 3.12-rc5).
+     *
+     * @warn This attribute is ignored if it isn't present in the
+     * kernel headers or if the kernel doesn't support it.
+     *
+     * @param val true to exclude host events
+     */
+    PerfKvmCounterConfig &exclude_host(bool val) {
+#if HAVE_PERF_ATTR_EXCLUDE_HOST == 1
+        attr.exclude_host = val;
+#endif
+        return *this;
+    }
+
+    /**
+     * Exclude the hyper visor (i.e., only include events from the
+     * guest system).
+     *
+     * @warn This is attribute only seems to be ignored on Intel.
+     *
+     * @param val true to exclude host events
+     */
+    PerfKvmCounterConfig &exclude_hv(bool val) {
+        attr.exclude_hv = val;
+        return *this;
+    }
+
     /** Underlying perf_event_attr structure describing the counter */
     struct perf_event_attr attr;
 };
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to