diff options
-rw-r--r-- | buildrun.cxx | 38 | ||||
-rw-r--r-- | runtime/time.c | 12 |
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; |