Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 13 Jul 2012 14:02:05 +0000 (UTC)
From:      Davide Italiano <davide@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r238425 - in projects/calloutng/sys: kern sys
Message-ID:  <201207131402.q6DE25Qk072736@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: davide
Date: Fri Jul 13 14:02:05 2012
New Revision: 238425
URL: http://svn.freebsd.org/changeset/base/238425

Log:
  Fix an issue related to old periodic timers. The code in kern_clocksource.c
  uses interrupt to keep track of time, and this time may not match with
  binuptime(). In order to address such incoerency, switch periodic timers to
  binuptime(). While here, modify callout_process() so that it takes present
  time as argument avoiding to call binuptime() twice even though it's not
  strictly needed.
  
  Reviewed by:		mav

Modified:
  projects/calloutng/sys/kern/kern_clock.c
  projects/calloutng/sys/kern/kern_clocksource.c
  projects/calloutng/sys/kern/kern_timeout.c
  projects/calloutng/sys/sys/callout.h

Modified: projects/calloutng/sys/kern/kern_clock.c
==============================================================================
--- projects/calloutng/sys/kern/kern_clock.c	Fri Jul 13 13:24:33 2012	(r238424)
+++ projects/calloutng/sys/kern/kern_clock.c	Fri Jul 13 14:02:05 2012	(r238425)
@@ -425,6 +425,7 @@ initclocks(dummy)
 void
 hardclock_cpu(int usermode)
 {
+	struct bintime now;
 	struct pstats *pstats;
 	struct thread *td = curthread;
 	struct proc *p = td->td_proc;
@@ -459,7 +460,8 @@ hardclock_cpu(int usermode)
 	if (td->td_intr_frame != NULL)
 		PMC_SOFT_CALL_TF( , , clock, hard, td->td_intr_frame);
 #endif
-	callout_process();
+	binuptime(&now);
+	callout_process(&now);
 }
 
 /*

Modified: projects/calloutng/sys/kern/kern_clocksource.c
==============================================================================
--- projects/calloutng/sys/kern/kern_clocksource.c	Fri Jul 13 13:24:33 2012	(r238424)
+++ projects/calloutng/sys/kern/kern_clocksource.c	Fri Jul 13 14:02:05 2012	(r238425)
@@ -239,7 +239,7 @@ handleevents(struct bintime *now, int fa
 	if (bintime_cmp(now, &state->nextcall, >=) &&
 		(state->nextcall.sec != -1)) {
 		state->nextcall.sec = -1;
-		callout_process();
+		callout_process(now);
 	}
 
 #ifdef KDTRACE_HOOKS
@@ -363,13 +363,12 @@ timercb(struct eventtimer *et, void *arg
 		next = &state->nexttick;
 	} else
 		next = &nexttick;
-	if (periodic) {
-		now = *next;	/* Ex-next tick time becomes present time. */
+	binuptime(&now); 
+	if (periodic) { 
+		*next = now;
 		bintime_add(next, &timerperiod); /* Next tick in 1 period. */
-	} else {
-		binuptime(&now);	/* Get present time from hardware. */
-		next->sec = -1;		/* Next tick is not scheduled yet. */
-	}
+	} else
+		next->sec = -1;	/* Next tick is not scheduled yet. */
 	state->now = now;
 	CTR4(KTR_SPARE2, "intr at %d:    now  %d.%08x%08x",
 	    curcpu, (int)(now.sec), (u_int)(now.frac >> 32),
@@ -720,11 +719,7 @@ cpu_initclocks_ap(void)
 	state = DPCPU_PTR(timerstate);
 	binuptime(&now);
 	ET_HW_LOCK(state);
-	if ((timer->et_flags & ET_FLAGS_PERCPU) == 0 && periodic) {
-		state->now = nexttick;
-		bintime_sub(&state->now, &timerperiod);
-	} else
-		state->now = now;
+	state->now = now;
 	hardclock_sync(curcpu);
 	handleevents(&state->now, 2);
 	if (timer->et_flags & ET_FLAGS_PERCPU)

Modified: projects/calloutng/sys/kern/kern_timeout.c
==============================================================================
--- projects/calloutng/sys/kern/kern_timeout.c	Fri Jul 13 13:24:33 2012	(r238424)
+++ projects/calloutng/sys/kern/kern_timeout.c	Fri Jul 13 14:02:05 2012	(r238425)
@@ -349,9 +349,9 @@ get_bucket(struct bintime *bt)
 }
 
 void
-callout_process(void)
+callout_process(struct bintime *now)
 {
-	struct bintime max, min, next, now, tmp_max, tmp_min;
+	struct bintime max, min, next, tmp_max, tmp_min;
 	struct callout *tmp;
 	struct callout_cpu *cc;
 	struct callout_tailq *sc;
@@ -364,10 +364,9 @@ callout_process(void)
 	need_softclock = 0;
 	cc = CC_SELF();
 	mtx_lock_spin_flags(&cc->cc_lock, MTX_QUIET);
-	binuptime(&now);
 	cpu = curcpu;
 	first = callout_hash(&cc->cc_lastscan);
-	last = callout_hash(&now);
+	last = callout_hash(now);
 	/* 
 	 * Check if we wrapped around the entire wheel from the last scan.
 	 * In case, we need to scan entirely the wheel for pending callouts.
@@ -380,7 +379,7 @@ callout_process(void)
 		TAILQ_FOREACH(tmp, sc, c_links.tqe) {
 			next = tmp->c_time;
 			bintime_sub(&next, &tmp->c_precision);
-			if (bintime_cmp(&next, &now, <=)) {
+			if (bintime_cmp(&next, now, <=)) {
 				/* 
 				 * Consumer told us the callout may be run
 				 * directly from hardware interrupt context.
@@ -445,7 +444,7 @@ callout_process(void)
 	if (max.sec == TIME_T_MAX) { 
 		next.sec = 0;	
 		next.frac = (uint64_t)1 << (64 - 2);	
-		bintime_add(&next, &now);
+		bintime_add(&next, now);
 	} else {
 		/*
 		 * Now that we found something to aggregate, schedule an  
@@ -461,7 +460,7 @@ callout_process(void)
 	cc->cc_firstevent = next;
 	if (callout_new_inserted != NULL) 
 		(*callout_new_inserted)(cpu, next);
-	cc->cc_lastscan = now;
+	cc->cc_lastscan = *now;
 	mtx_unlock_spin_flags(&cc->cc_lock, MTX_QUIET);
 	/*
 	 * swi_sched acquires the thread lock, so we don't want to call it

Modified: projects/calloutng/sys/sys/callout.h
==============================================================================
--- projects/calloutng/sys/sys/callout.h	Fri Jul 13 13:24:33 2012	(r238424)
+++ projects/calloutng/sys/sys/callout.h	Fri Jul 13 14:02:05 2012	(r238425)
@@ -113,7 +113,7 @@ int	callout_schedule_on(struct callout *
     callout_schedule_on((c), (on_tick), PCPU_GET(cpuid))
 #define	callout_stop(c)		_callout_stop_safe(c, 0)
 int	_callout_stop_safe(struct callout *, int);
-void	callout_process(void);
+void	callout_process(struct bintime *);
 extern void (*callout_new_inserted)(int cpu, struct bintime bt);
 
 #endif



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201207131402.q6DE25Qk072736>