diff --git a/sys/amd64/amd64/tsc.c b/sys/amd64/amd64/tsc.c index 847c1eb..6dce88b 100644 --- a/sys/amd64/amd64/tsc.c +++ b/sys/amd64/amd64/tsc.c @@ -49,7 +49,7 @@ __FBSDID("$FreeBSD$"); uint64_t tsc_freq; int tsc_is_broken; int tsc_is_invariant; -static eventhandler_tag tsc_levels_tag, tsc_pre_tag, tsc_post_tag; +static eventhandler_tag tsc_pre_tag, tsc_post_tag; SYSCTL_INT(_kern_timecounter, OID_AUTO, invariant_tsc, CTLFLAG_RDTUN, &tsc_is_invariant, 0, "Indicates whether the TSC is P-state invariant"); @@ -67,7 +67,6 @@ static void tsc_freq_changed(void *arg, const struct cf_level *level, static void tsc_freq_changing(void *arg, const struct cf_level *level, int *status); static unsigned tsc_get_timecount(struct timecounter *tc); -static void tsc_levels_changed(void *arg, int unit); static struct timecounter tsc_timecounter = { tsc_get_timecount, /* get_timecount */ @@ -100,15 +99,16 @@ init_TSC(void) * via tsc_freq_max(). This also will be updated if someone loads * a cpufreq driver after boot that discovers a new max frequency. */ - set_cputicker(rdtsc, tsc_freq, 1); + if (tsc_is_invariant) + set_cputicker(rdtsc, tsc_freq, 1); + else + set_cputicker(NULL, 0, 0); /* Register to find out about changes in CPU frequency. */ tsc_pre_tag = EVENTHANDLER_REGISTER(cpufreq_pre_change, tsc_freq_changing, NULL, EVENTHANDLER_PRI_FIRST); tsc_post_tag = EVENTHANDLER_REGISTER(cpufreq_post_change, tsc_freq_changed, NULL, EVENTHANDLER_PRI_FIRST); - tsc_levels_tag = EVENTHANDLER_REGISTER(cpufreq_levels_changed, - tsc_levels_changed, NULL, EVENTHANDLER_PRI_ANY); } void @@ -135,43 +135,6 @@ init_TSC_tc(void) } /* - * When cpufreq levels change, find out about the (new) max frequency. We - * use this to update CPU accounting in case it got a lower estimate at boot. - */ -static void -tsc_levels_changed(void *arg, int unit) -{ - device_t cf_dev; - struct cf_level *levels; - int count, error; - uint64_t max_freq; - - /* Only use values from the first CPU, assuming all are equal. */ - if (unit != 0) - return; - - /* Find the appropriate cpufreq device instance. */ - cf_dev = devclass_get_device(devclass_find("cpufreq"), unit); - if (cf_dev == NULL) { - printf("tsc_levels_changed() called but no cpufreq device?\n"); - return; - } - - /* Get settings from the device and find the max frequency. */ - count = 64; - levels = malloc(count * sizeof(*levels), M_TEMP, M_NOWAIT); - if (levels == NULL) - return; - error = CPUFREQ_LEVELS(cf_dev, levels, &count); - if (error == 0 && count != 0) { - max_freq = (uint64_t)levels[0].total_set.freq * 1000000; - set_cputicker(rdtsc, max_freq, 1); - } else - printf("tsc_levels_changed: no max freq found\n"); - free(levels, M_TEMP); -} - -/* * If the TSC timecounter is in use, veto the pending change. It may be * possible in the future to handle a dynamically-changing timecounter rate. */