Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 27 Dec 2007 23:54:04 GMT
From:      John Birrell <jb@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 131823 for review
Message-ID:  <200712272354.lBRNs4ja062454@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=131823

Change 131823 by jb@jb_freebsd1 on 2007/12/27 23:53:59

	The HPET on my Dell 531S is not per-cpu, so the HPET isn't much use
	as a cyclic timer interrupt source. We need interrupts on each CPU
	and cyclic timers can be enabled on one CPU and not on others.
	
	Hook the cyclic timer into the APIC timer interrupt at it's fastest
	rate rather than at hardclock.
	
	Use the presence of the (now) per-cpu cyclic timer hook to indicate
	if the cyclic timer is enabled.
	
	XXX More code is required to allow the cyclic timer fire interval to
	be set -- like the hz, stathz and profhz counters -- to avoid calling
	the cyclic function earlier than required.

Affected files ...

.. //depot/projects/dtrace/src/sys/amd64/amd64/local_apic.c#12 edit
.. //depot/projects/dtrace/src/sys/cddl/amd64/cyclic_machdep.c#3 edit

Differences ...

==== //depot/projects/dtrace/src/sys/amd64/amd64/local_apic.c#12 (text+ko) ====

@@ -68,7 +68,7 @@
 
 #ifdef KDTRACE_HOOKS
 #include <sys/dtrace_bsd.h>
-cyclic_clock_func_t	lapic_cyclic_clock_func;
+cyclic_clock_func_t	lapic_cyclic_clock_func[MAXCPU];
 #endif
 
 /* Sanity checks on IDT vectors. */
@@ -674,7 +674,18 @@
 	(*la->la_timer_count)++;
 	critical_enter();
 
-	/* Fire hardclock at hz. */
+#ifdef KDTRACE_HOOKS
+	/*
+	 * If the DTrace hooks are configured and a callback function
+	 * has been registered, then call it to process the high speed
+	 * timers.
+	 */
+	int cpu = PCPU_GET(cpuid);
+	if (lapic_cyclic_clock_func[cpu] != NULL)
+		(*lapic_cyclic_clock_func[cpu])();
+#endif
+
+/* Fire hardclock at hz. */
 	la->la_hard_ticks += hz;
 	if (la->la_hard_ticks >= lapic_timer_hz) {
 		la->la_hard_ticks -= lapic_timer_hz;
@@ -682,19 +693,6 @@
 			hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
 		else
 			hardclock_cpu(TRAPF_USERMODE(frame));
-
-#ifdef KDTRACE_HOOKS
-		/*
-		 * If the DTrace hooks are configured and a callback
-		 * function has been registered, then call it to process
-		 * the high speed timers. If this function is registered
-		 * here, then there mustn't be a High Performance Event
-		 * Timer (HPET) on the CPU. A HPET provides higher
-		 * performance timer interrupts.
-		 */
-		if (lapic_cyclic_clock_func != NULL)
-			(*lapic_cyclic_clock_func)();
-#endif
 	}
 
 	/* Fire statclock at stathz. */

==== //depot/projects/dtrace/src/sys/cddl/amd64/cyclic_machdep.c#3 (text+ko) ====

@@ -55,7 +55,6 @@
 };
 
 static hrtime_t resolution;
-static int	hpet_present	= 0;
 static void	*cyclic_lock_ih;
 static void	*cyclic_low_ih;
 
@@ -104,8 +103,6 @@
 	/* Default the resolution. */
 	resolution = ticks * 1000000;
 
-	/* XXX Need to check here if the HPET is available. */
-
 	/*
 	 * Add a software interrupt handlers for low priority cyclic
 	 * events.
@@ -117,18 +114,16 @@
 
 	/* Register the cyclic backend. */
 	cyclic_init(&be, resolution);
-
-	/* If the HPET isn't present, use the slow method. */
-	if (!hpet_present)
-		/* Register the cyclic clock callback function. */
-		lapic_cyclic_clock_func = cyclic_clock;
 }
 
 static void
 cyclic_machdep_uninit(void)
 {
-	/* Reset the cyclic clock callback hook. */
-	lapic_cyclic_clock_func = NULL;
+	int i;
+
+	for (i = 0; i < mp_maxid; i++)
+		/* Reset the cyclic clock callback hook. */
+		lapic_cyclic_clock_func[i] = NULL;
 
 	/* De-register the cyclic backend. */
 	cyclic_uninit();
@@ -140,30 +135,30 @@
 
 static cyb_arg_t configure(cpu_t *c)
 {
-	/* XXX Configure the HPET if it is present. */
 
 	return (NULL);
 }
 
 static void unconfigure(cyb_arg_t arg)
 {
-	/* XXX Unconfigure the HPET if it is present. */
 
 }
 
 static void enable(cyb_arg_t arg)
 {
-	/* XXX Enable the HPET if it is present. */
+	/* Register the cyclic clock callback function. */
+	lapic_cyclic_clock_func[curcpu] = cyclic_clock;
 }
 
 static void disable(cyb_arg_t arg)
 {
-	/* XXX Disable the HPET if it is present. */
+	/* Reset the cyclic clock callback function. */
+	lapic_cyclic_clock_func[curcpu] = NULL;
 }
 
 static void reprogram(cyb_arg_t arg, hrtime_t interval)
 {
-	/* XXX Reprogram the HPET if it is present. */
+	/* XXX */
 }
 
 static void softint(cyb_arg_t arg, cyc_level_t level)



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