svn commit: r205665 - in head/sys/ia64: ia64 include
Marcel Moolenaar
marcel at FreeBSD.org
Fri Mar 26 02:29:15 UTC 2010
Author: marcel
Date: Fri Mar 26 02:29:15 2010
New Revision: 205665
URL: http://svn.freebsd.org/changeset/base/205665
Log:
Only use the interval timer for clock interrupts on the BSP and
have the BSP use IPIs to trigger clock interrupts on the APs.
This allows us to run on hardware configurations for which the
ITC has non-uniform frequencies across CPUs.
While here, change the clock XIV to type IPI so as to protect
the interrupt delivery against CPU re-balancing once that's
implemented.
Modified:
head/sys/ia64/ia64/clock.c
head/sys/ia64/ia64/mp_machdep.c
head/sys/ia64/include/pcpu.h
Modified: head/sys/ia64/ia64/clock.c
==============================================================================
--- head/sys/ia64/ia64/clock.c Fri Mar 26 01:57:12 2010 (r205664)
+++ head/sys/ia64/ia64/clock.c Fri Mar 26 02:29:15 2010 (r205665)
@@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$");
#include <machine/intr.h>
#include <machine/intrcnt.h>
#include <machine/md_var.h>
+#include <machine/smp.h>
SYSCTL_NODE(_debug, OID_AUTO, clock, CTLFLAG_RW, 0, "clock statistics");
@@ -91,58 +92,61 @@ ia64_ih_clock(struct thread *td, u_int x
int count;
PCPU_INC(md.stats.pcs_nclks);
- intrcnt[INTRCNT_CLOCK]++;
- itc = ia64_get_itc();
-
- adj = PCPU_GET(md.clockadj);
- clk = PCPU_GET(md.clock);
-
- delta = itc - clk;
- count = 0;
- while (delta >= ia64_clock_reload) {
- /* Only the BSP runs the real clock */
- if (PCPU_GET(cpuid) == 0)
+ if (PCPU_GET(cpuid) == 0) {
+ /*
+ * Clock processing on the BSP.
+ */
+ intrcnt[INTRCNT_CLOCK]++;
+
+ itc = ia64_get_itc();
+
+ adj = PCPU_GET(md.clockadj);
+ clk = PCPU_GET(md.clock);
+
+ delta = itc - clk;
+ count = 0;
+ while (delta >= ia64_clock_reload) {
+#ifdef SMP
+ ipi_all_but_self(ia64_clock_xiv);
+#endif
hardclock(TRAPF_USERMODE(tf), TRAPF_PC(tf));
- else
- hardclock_cpu(TRAPF_USERMODE(tf));
+ if (profprocs != 0)
+ profclock(TRAPF_USERMODE(tf), TRAPF_PC(tf));
+ statclock(TRAPF_USERMODE(tf));
+ delta -= ia64_clock_reload;
+ clk += ia64_clock_reload;
+ if (adj != 0)
+ adjust_ticks++;
+ count++;
+ }
+ ia64_set_itm(ia64_get_itc() + ia64_clock_reload - adj);
+ ia64_srlz_d();
+ if (count > 0) {
+ adjust_lost += count - 1;
+ if (delta > (ia64_clock_reload >> 3)) {
+ if (adj == 0)
+ adjust_edges++;
+ adj = ia64_clock_reload >> 4;
+ } else
+ adj = 0;
+ } else {
+ adj = 0;
+ adjust_excess++;
+ }
+ PCPU_SET(md.clock, clk);
+ PCPU_SET(md.clockadj, adj);
+ } else {
+ /*
+ * Clock processing on the BSP.
+ */
+ hardclock_cpu(TRAPF_USERMODE(tf));
if (profprocs != 0)
profclock(TRAPF_USERMODE(tf), TRAPF_PC(tf));
statclock(TRAPF_USERMODE(tf));
- delta -= ia64_clock_reload;
- clk += ia64_clock_reload;
- if (adj != 0)
- adjust_ticks++;
- count++;
}
- ia64_set_itm(ia64_get_itc() + ia64_clock_reload - adj);
- ia64_srlz_d();
- if (count > 0) {
- adjust_lost += count - 1;
- if (delta > (ia64_clock_reload >> 3)) {
- if (adj == 0)
- adjust_edges++;
- adj = ia64_clock_reload >> 4;
- } else
- adj = 0;
- } else {
- adj = 0;
- adjust_excess++;
- }
- PCPU_SET(md.clock, clk);
- PCPU_SET(md.clockadj, adj);
- return (0);
-}
-void
-pcpu_initclock(void)
-{
-
- PCPU_SET(md.clockadj, 0);
- PCPU_SET(md.clock, ia64_get_itc());
- ia64_set_itm(PCPU_GET(md.clock) + ia64_clock_reload);
- ia64_set_itv(ia64_clock_xiv);
- ia64_srlz_d();
+ return (0);
}
/*
@@ -154,7 +158,7 @@ cpu_initclocks()
{
u_long itc_freq;
- ia64_clock_xiv = ia64_xiv_alloc(PI_REALTIME, IA64_XIV_IRQ,
+ ia64_clock_xiv = ia64_xiv_alloc(PI_REALTIME, IA64_XIV_IPI,
ia64_ih_clock);
if (ia64_clock_xiv == 0)
panic("No XIV for clock interrupts");
@@ -169,7 +173,11 @@ cpu_initclocks()
tc_init(&ia64_timecounter);
#endif
- pcpu_initclock();
+ PCPU_SET(md.clockadj, 0);
+ PCPU_SET(md.clock, ia64_get_itc());
+ ia64_set_itm(PCPU_GET(md.clock) + ia64_clock_reload);
+ ia64_set_itv(ia64_clock_xiv);
+ ia64_srlz_d();
}
void
Modified: head/sys/ia64/ia64/mp_machdep.c
==============================================================================
--- head/sys/ia64/ia64/mp_machdep.c Fri Mar 26 01:57:12 2010 (r205664)
+++ head/sys/ia64/ia64/mp_machdep.c Fri Mar 26 02:29:15 2010 (r205665)
@@ -206,9 +206,8 @@ ia64_ap_startup(void)
CTR1(KTR_SMP, "SMP: cpu%d launched", PCPU_GET(cpuid));
- /* kick off the clock on this AP */
- pcpu_initclock();
-
+ /* Mask interval timer interrupts on APs. */
+ ia64_set_itv(0x10000);
ia64_set_tpr(0);
ia64_srlz_d();
enable_intr();
Modified: head/sys/ia64/include/pcpu.h
==============================================================================
--- head/sys/ia64/include/pcpu.h Fri Mar 26 01:57:12 2010 (r205664)
+++ head/sys/ia64/include/pcpu.h Fri Mar 26 02:29:15 2010 (r205665)
@@ -91,8 +91,6 @@ __curthread(void)
#define PCPU_PTR(member) (&pcpup->pc_ ## member)
#define PCPU_SET(member,value) (pcpup->pc_ ## member = (value))
-void pcpu_initclock(void);
-
#endif /* _KERNEL */
#endif /* !_MACHINE_PCPU_H_ */
More information about the svn-src-head
mailing list