diff options
author | kib <kib@FreeBSD.org> | 2012-06-23 09:33:06 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2012-06-23 09:33:06 +0000 |
commit | 497817697cfb819824b7ae8619a5094ace1b3698 (patch) | |
tree | e776dfcefe80b16e0aa0a27d0fdb364391c6c4b8 /sys/kern/kern_tc.c | |
parent | e19c8fe0ffaebe2cb325b0d14102166d51b7429d (diff) | |
download | FreeBSD-src-497817697cfb819824b7ae8619a5094ace1b3698.zip FreeBSD-src-497817697cfb819824b7ae8619a5094ace1b3698.tar.gz |
Stop updating the struct vdso_timehands from even handler executed in
the scheduled task from tc_windup(). Do it directly from tc_windup in
interrupt context [1].
Establish the permanent mapping of the shared page into the kernel
address space, avoiding the potential need to sleep waiting for
allocation of sf buffer during vdso_timehands update. As a
consequence, shared_page_write_start() and shared_page_write_end()
functions are not needed anymore.
Guess and memorize the pointers to native host and compat32 sysentvec
during initialization, to avoid the need to get shared_page_alloc_sx
lock during the update.
In tc_fill_vdso_timehands(), do not loop waiting for timehands
generation to stabilize, since vdso_timehands is written in the same
interrupt context which wrote timehands.
Requested by: mav [1]
MFC after: 29 days
Diffstat (limited to 'sys/kern/kern_tc.c')
-rw-r--r-- | sys/kern/kern_tc.c | 62 |
1 files changed, 21 insertions, 41 deletions
diff --git a/sys/kern/kern_tc.c b/sys/kern/kern_tc.c index 0b8fefe..4a75af5 100644 --- a/sys/kern/kern_tc.c +++ b/sys/kern/kern_tc.c @@ -31,7 +31,6 @@ __FBSDID("$FreeBSD$"); #include <sys/systm.h> #include <sys/timeffc.h> #include <sys/timepps.h> -#include <sys/taskqueue.h> #include <sys/timetc.h> #include <sys/timex.h> #include <sys/vdso.h> @@ -121,12 +120,8 @@ SYSCTL_INT(_kern_timecounter, OID_AUTO, stepwarnings, CTLFLAG_RW, ×tepwarnings, 0, "Log time steps"); static void tc_windup(void); -static void tc_windup_push_vdso(void *ctx, int pending); static void cpu_tick_calibrate(int); -static struct task tc_windup_push_vdso_task = TASK_INITIALIZER(0, - tc_windup_push_vdso, 0); - static int sysctl_kern_boottime(SYSCTL_HANDLER_ARGS) { @@ -1367,7 +1362,7 @@ tc_windup(void) #endif timehands = th; - taskqueue_enqueue_fast(taskqueue_fast, &tc_windup_push_vdso_task); + timekeep_push_vdso(); } /* Report or change the active timecounter hardware. */ @@ -1394,7 +1389,7 @@ sysctl_kern_timecounter_hardware(SYSCTL_HANDLER_ARGS) (void)newtc->tc_get_timecount(newtc); timecounter = newtc; - EVENTHANDLER_INVOKE(tc_windup); + timekeep_push_vdso(); return (0); } return (EINVAL); @@ -1865,7 +1860,7 @@ sysctl_fast_gettime(SYSCTL_HANDLER_ARGS) if (error != 0) return (error); vdso_th_enable = old_vdso_th_enable; - EVENTHANDLER_INVOKE(tc_windup); + timekeep_push_vdso(); return (0); } SYSCTL_PROC(_kern_timecounter, OID_AUTO, fast_gettime, @@ -1877,19 +1872,15 @@ tc_fill_vdso_timehands(struct vdso_timehands *vdso_th) { struct timehands *th; uint32_t enabled; - int gen; - do { - th = timehands; - gen = th->th_generation; - vdso_th->th_algo = VDSO_TH_ALGO_1; - vdso_th->th_scale = th->th_scale; - vdso_th->th_offset_count = th->th_offset_count; - vdso_th->th_counter_mask = th->th_counter->tc_counter_mask; - vdso_th->th_offset = th->th_offset; - vdso_th->th_boottime = boottimebin; - enabled = cpu_fill_vdso_timehands(vdso_th); - } while (gen == 0 || timehands->th_generation != gen); + th = timehands; + vdso_th->th_algo = VDSO_TH_ALGO_1; + vdso_th->th_scale = th->th_scale; + vdso_th->th_offset_count = th->th_offset_count; + vdso_th->th_counter_mask = th->th_counter->tc_counter_mask; + vdso_th->th_offset = th->th_offset; + vdso_th->th_boottime = boottimebin; + enabled = cpu_fill_vdso_timehands(vdso_th); if (!vdso_th_enable) enabled = 0; return (enabled); @@ -1901,30 +1892,19 @@ tc_fill_vdso_timehands32(struct vdso_timehands32 *vdso_th32) { struct timehands *th; uint32_t enabled; - int gen; - do { - th = timehands; - gen = th->th_generation; - vdso_th32->th_algo = VDSO_TH_ALGO_1; - *(uint64_t *)&vdso_th32->th_scale[0] = th->th_scale; - vdso_th32->th_offset_count = th->th_offset_count; - vdso_th32->th_counter_mask = th->th_counter->tc_counter_mask; - vdso_th32->th_offset.sec = th->th_offset.sec; - *(uint64_t *)&vdso_th32->th_offset.frac[0] = th->th_offset.frac; - vdso_th32->th_boottime.sec = boottimebin.sec; - *(uint64_t *)&vdso_th32->th_boottime.frac[0] = boottimebin.frac; - enabled = cpu_fill_vdso_timehands32(vdso_th32); - } while (gen == 0 || timehands->th_generation != gen); + th = timehands; + vdso_th32->th_algo = VDSO_TH_ALGO_1; + *(uint64_t *)&vdso_th32->th_scale[0] = th->th_scale; + vdso_th32->th_offset_count = th->th_offset_count; + vdso_th32->th_counter_mask = th->th_counter->tc_counter_mask; + vdso_th32->th_offset.sec = th->th_offset.sec; + *(uint64_t *)&vdso_th32->th_offset.frac[0] = th->th_offset.frac; + vdso_th32->th_boottime.sec = boottimebin.sec; + *(uint64_t *)&vdso_th32->th_boottime.frac[0] = boottimebin.frac; + enabled = cpu_fill_vdso_timehands32(vdso_th32); if (!vdso_th_enable) enabled = 0; return (enabled); } #endif - -static void -tc_windup_push_vdso(void *ctx, int pending) -{ - - EVENTHANDLER_INVOKE(tc_windup); -} |