Date: Fri, 26 Mar 2010 02:29:15 +0000 (UTC) From: Marcel Moolenaar <marcel@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r205665 - in head/sys/ia64: ia64 include Message-ID: <201003260229.o2Q2TFS1008347@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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_ */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201003260229.o2Q2TFS1008347>