summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2010-09-14 08:48:06 +0000
committermav <mav@FreeBSD.org>2010-09-14 08:48:06 +0000
commit6c05aa4db6d1ea20da8eca83a1214b74821b32d8 (patch)
treead6e771c5b5091a633bf1f813ca1f742162ecb96 /sys/kern
parent5864d6e457c81a0a80b2ab3b57ee852e6f62efcb (diff)
downloadFreeBSD-src-6c05aa4db6d1ea20da8eca83a1214b74821b32d8.zip
FreeBSD-src-6c05aa4db6d1ea20da8eca83a1214b74821b32d8.tar.gz
Make kern_tc.c provide minimum frequency of tc_ticktock() calls, required
to handle current timecounter wraps. Make kern_clocksource.c to honor that requirement, scheduling sleeps on first CPU for no more then specified period. Allow other CPUs to sleep up to 1/4 second (for any case).
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/kern_clock.c4
-rw-r--r--sys/kern/kern_clocksource.c6
-rw-r--r--sys/kern/kern_tc.c9
-rw-r--r--sys/kern/kern_timeout.c4
4 files changed, 16 insertions, 7 deletions
diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c
index 7fb70d0..192ec60 100644
--- a/sys/kern/kern_clock.c
+++ b/sys/kern/kern_clock.c
@@ -457,7 +457,7 @@ hardclock(int usermode, uintfptr_t pc)
atomic_add_int((volatile int *)&ticks, 1);
hardclock_cpu(usermode);
- tc_ticktock();
+ tc_ticktock(1);
cpu_tick_calibration();
/*
* If no separate statistics clock is available, run it from here.
@@ -538,7 +538,7 @@ hardclock_anycpu(int cnt, int usermode)
if (newticks > 0) {
/* Dangerous and no need to call these things concurrently. */
if (atomic_cmpset_acq_int(&global_hardclock_run, 0, 1)) {
- tc_ticktock();
+ tc_ticktock(newticks);
#ifdef DEVICE_POLLING
/* This is very short and quick. */
hardclock_device_poll();
diff --git a/sys/kern/kern_clocksource.c b/sys/kern/kern_clocksource.c
index 7654ace..e366ef9 100644
--- a/sys/kern/kern_clocksource.c
+++ b/sys/kern/kern_clocksource.c
@@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$");
#include <sys/smp.h>
#include <sys/sysctl.h>
#include <sys/timeet.h>
+#include <sys/timetc.h>
#include <machine/atomic.h>
#include <machine/clock.h>
@@ -247,7 +248,10 @@ getnextcpuevent(struct bintime *event, int idle)
state = DPCPU_PTR(timerstate);
*event = state->nexthard;
if (idle) { /* If CPU is idle - ask callouts for how long. */
- skip = callout_tickstofirst() - 1;
+ skip = 4;
+ if (curcpu == CPU_FIRST() && tc_min_ticktock_freq > skip)
+ skip = tc_min_ticktock_freq;
+ skip = callout_tickstofirst(hz / skip) - 1;
CTR2(KTR_SPARE2, "skip at %d: %d", curcpu, skip);
tmp = hardperiod;
bintime_mul(&tmp, skip);
diff --git a/sys/kern/kern_tc.c b/sys/kern/kern_tc.c
index 811b24f..7a34a52 100644
--- a/sys/kern/kern_tc.c
+++ b/sys/kern/kern_tc.c
@@ -87,6 +87,8 @@ static struct timehands *volatile timehands = &th0;
struct timecounter *timecounter = &dummy_timecounter;
static struct timecounter *timecounters = &dummy_timecounter;
+int tc_min_ticktock_freq = 1;
+
time_t time_second = 1;
time_t time_uptime = 1;
@@ -482,6 +484,8 @@ tc_windup(void)
if (th->th_counter != timecounter) {
th->th_counter = timecounter;
th->th_offset_count = ncount;
+ tc_min_ticktock_freq = max(1, timecounter->tc_frequency /
+ (((uint64_t)timecounter->tc_counter_mask + 1) / 3));
}
/*-
@@ -767,11 +771,12 @@ static int tc_tick;
SYSCTL_INT(_kern_timecounter, OID_AUTO, tick, CTLFLAG_RD, &tc_tick, 0, "");
void
-tc_ticktock(void)
+tc_ticktock(int cnt)
{
static int count;
- if (++count < tc_tick)
+ count += cnt;
+ if (count < tc_tick)
return;
count = 0;
tc_windup();
diff --git a/sys/kern/kern_timeout.c b/sys/kern/kern_timeout.c
index 5697792..89fe544 100644
--- a/sys/kern/kern_timeout.c
+++ b/sys/kern/kern_timeout.c
@@ -280,7 +280,7 @@ callout_tick(void)
}
int
-callout_tickstofirst(void)
+callout_tickstofirst(int limit)
{
struct callout_cpu *cc;
struct callout *c;
@@ -291,7 +291,7 @@ callout_tickstofirst(void)
cc = CC_SELF();
mtx_lock_spin_flags(&cc->cc_lock, MTX_QUIET);
curticks = cc->cc_ticks;
- while( skip < ncallout && skip < hz/8 ) {
+ while( skip < ncallout && skip < limit ) {
sc = &cc->cc_callwheel[ (curticks+skip) & callwheelmask ];
/* search scanning ticks */
TAILQ_FOREACH( c, sc, c_links.tqe ){
OpenPOWER on IntegriCloud