summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--buildrun.cxx38
-rw-r--r--runtime/time.c12
2 files changed, 43 insertions, 7 deletions
diff --git a/buildrun.cxx b/buildrun.cxx
index 48f27a3a..3091c511 100644
--- a/buildrun.cxx
+++ b/buildrun.cxx
@@ -90,6 +90,43 @@ output_autoconf(systemtap_session& s, ofstream& o, const char *autoconf_c,
o << "; fi >> $@" << endl;
}
+void output_cpu_khz (systemtap_session& s, ofstream& o)
+{
+ // PR10493: search cpu_khz in Module.symvers
+ string kernel_export_file = s.kernel_build_tree + "/Module.symvers";
+ char *line = NULL, *name = NULL, *module = NULL, *type = NULL;
+ size_t len = 0;
+ unsigned long address;
+ int ret;
+ FILE *sym = fopen(kernel_export_file.c_str(),"r");
+
+ if (sym == NULL)
+ return;
+ while (!feof(sym))
+ {
+ if (getline(&line, &len, sym) < 0)
+ break;
+ ret = sscanf(line, "%lx %as %as %as", &address, &name, &module, &type);
+ if (name == NULL || module == NULL || type == NULL)
+ continue;
+ if (ret == 4) {
+ // cpu_khz is kernel EXPORT_SYMBOL'd
+ if (!strcmp(name, "cpu_khz") && !strcmp(module, "vmlinux")
+ && strstr(type, "EXPORT_SYMBOL")) // match all to avoid corrupt file
+ {
+ o << "\t";
+ if (s.verbose < 4)
+ o << "@";
+ o << "echo \"#define STAPCONF_CPU_KHZ 1\"";
+ o << ">> $@" << endl;
+ break;
+ }
+ }
+ }
+ if (sym)
+ fclose(sym);
+}
+
int
compile_pass (systemtap_session& s)
{
@@ -167,6 +204,7 @@ compile_pass (systemtap_session& s)
output_autoconf(s, o, "autoconf-trace-printk.c", "STAPCONF_TRACE_PRINTK", NULL);
output_autoconf(s, o, "autoconf-regset.c", "STAPCONF_REGSET", NULL);
output_autoconf(s, o, "autoconf-utrace-regset.c", "STAPCONF_UTRACE_REGSET", NULL);
+ output_cpu_khz(s, o);
#if 0
/* NB: For now, the performance hit of probe_kernel_read/write (vs. our
diff --git a/runtime/time.c b/runtime/time.c
index d588370f..5caa73cc 100644
--- a/runtime/time.c
+++ b/runtime/time.c
@@ -71,18 +71,16 @@ static unsigned int
__stp_get_freq(void)
{
// If we can get the actual frequency of HW counter, we use it.
-#if defined (__i386__) || defined (__x86_64__)
-#ifdef STAPCONF_TSC_KHZ
- return tsc_khz;
-#else /*STAPCONF_TSC_KHZ*/
- return cpu_khz;
-#endif /*STAPCONF_TSC_KHZ*/
-#elif defined (__ia64__)
+#if defined (__ia64__)
return local_cpu_data->itc_freq / 1000;
#elif defined (__s390__) || defined (__s390x__) || defined (__arm__)
// We don't need to find the cpu freq on s390 as the
// TOD clock is always a fix freq. (see: POO pg 4-36.)
return 0;
+#elif (defined (__i386__) || defined (__x86_64__)) && defined(STAPCONF_TSC_KHZ)
+ return tsc_khz;
+#elif (defined (__i386__) || defined (__x86_64__)) && defined(STAPCONF_CPU_KHZ)
+ return cpu_khz;
#else /* __i386__ || __x86_64__ || __ia64__ || __s390__ || __s390x__ || __arm__*/
// If we don't know the actual frequency, we estimate it.
cycles_t beg, mid, end;