summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xSConstruct41
-rw-r--r--src/cpu/kvm/base.cc12
-rw-r--r--src/cpu/kvm/perfevent.hh35
3 files changed, 86 insertions, 2 deletions
diff --git a/SConstruct b/SConstruct
index 5b57c1ce6..cdd44a871 100755
--- a/SConstruct
+++ b/SConstruct
@@ -794,12 +794,35 @@ def CheckLeading(context):
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 @@ def is_isa_kvm_compatible(isa):
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 @@ sticky_vars.AddVariables(
# 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 @@ for variant_path in variant_paths:
"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 --git a/src/cpu/kvm/base.cc b/src/cpu/kvm/base.cc
index a8e115da7..d25e145a5 100644
--- a/src/cpu/kvm/base.cc
+++ b/src/cpu/kvm/base.cc
@@ -1133,6 +1133,12 @@ BaseKvmCPU::setupCounters()
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 @@ BaseKvmCPU::setupInstCounter(uint64_t period)
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 --git a/src/cpu/kvm/perfevent.hh b/src/cpu/kvm/perfevent.hh
index eed900994..b1b0da283 100644
--- a/src/cpu/kvm/perfevent.hh
+++ b/src/cpu/kvm/perfevent.hh
@@ -45,6 +45,8 @@
#include <inttypes.h>
+#include "config/have_perf_attr_exclude_host.hh"
+
/**
* PerfEvent counter configuration.
*/
@@ -125,6 +127,39 @@ class PerfKvmCounterConfig
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;
};