Do a bit of rude hackery to get clock interrupts on all CPUs. This

is partly based on the Alpha system which duplicates the clock to
each cpu, instead of doing a clock roundrobin like on i386.  This means
we get hz * ncpu clocks per second and so we have to seperate clock
sampling from actual 'do the work' clock processing.  The BSP runs the
complete processing, the rest just sample state etc.

Using the on-cpu interval timer is not ideal as it will drift.  There
is more to be done here, we should use an external clock source.
This commit is contained in:
peter 2002-10-04 01:00:35 +00:00
parent cfe8b263a0
commit 8fd35a03b5
4 changed files with 44 additions and 11 deletions

View File

@ -78,10 +78,9 @@ int tickfixinterval;
int adjkerntz; /* local offset from GMT in seconds */
int disable_rtc_set; /* disable resettodr() if != 0 */
int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */
u_int64_t itm_reload; /* reload ticks for clock */
static int beeping = 0;
extern u_int64_t itc_frequency;
#ifndef SMP
static timecounter_get_t ia64_get_timecount;
@ -192,7 +191,8 @@ cpu_initclocks()
tc_init(&ia64_timecounter);
#endif
ia64_set_itm(ia64_get_itc() + (itc_frequency + hz/2) / hz);
itm_reload = (itc_frequency + hz/2) / hz;
ia64_set_itm(ia64_get_itc() + itm_reload);
ia64_set_itv(255); /* highest priority class */
stathz = 128;

View File

@ -48,6 +48,7 @@
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/smp.h>
#include <sys/sysctl.h>
#include <machine/clock.h>
#include <machine/cpu.h>
@ -83,6 +84,14 @@ dummy_perf(unsigned long vector, struct trapframe *framep)
void (*perf_irq)(unsigned long, struct trapframe *) = dummy_perf;
static unsigned int ints[MAXCPU];
static unsigned int clks[MAXCPU];
static unsigned int asts[MAXCPU];
static unsigned int rdvs[MAXCPU];
SYSCTL_OPAQUE(_debug, OID_AUTO, ints, CTLFLAG_RW, &ints, sizeof(ints), "IU","");
SYSCTL_OPAQUE(_debug, OID_AUTO, clks, CTLFLAG_RW, &clks, sizeof(clks), "IU","");
SYSCTL_OPAQUE(_debug, OID_AUTO, asts, CTLFLAG_RW, &asts, sizeof(asts), "IU","");
SYSCTL_OPAQUE(_debug, OID_AUTO, rdvs, CTLFLAG_RW, &rdvs, sizeof(rdvs), "IU","");
static u_int schedclk2;
@ -115,16 +124,33 @@ interrupt(u_int64_t vector, struct trapframe *framep)
intrcnt[INTRCNT_CLOCK]++;
#endif
critical_enter();
handleclock(framep);
/* divide hz (1024) by 8 to get stathz (128) */
if((++schedclk2 & 0x7) == 0)
statclock((struct clockframe *)framep);
#ifdef SMP
clks[PCPU_GET(cpuid)]++;
/* Only the BSP runs the real clock */
if (PCPU_GET(cpuid) == 0) {
#endif
handleclock(framep);
/* divide hz (1024) by 8 to get stathz (128) */
if ((++schedclk2 & 0x7) == 0)
statclock((struct clockframe *)framep);
#ifdef SMP
} else {
ia64_set_itm(ia64_get_itc() + itm_reload);
mtx_lock_spin(&sched_lock);
hardclock_process(curthread, TRAPF_USERMODE(framep));
if ((schedclk2 & 0x7) == 0)
statclock_process(curkse, TRAPF_PC(framep),
TRAPF_USERMODE(framep));
mtx_unlock_spin(&sched_lock);
}
#endif
critical_exit();
#ifdef SMP
} else if (vector == ipi_vector[IPI_AST]) {
asts[PCPU_GET(cpuid)]++;
CTR1(KTR_SMP, "IPI_AST, cpuid=%d", PCPU_GET(cpuid));
} else if (vector == ipi_vector[IPI_RENDEZVOUS]) {
rdvs[PCPU_GET(cpuid)]++;
CTR1(KTR_SMP, "IPI_RENDEZVOUS, cpuid=%d", PCPU_GET(cpuid));
smp_rendezvous_action();
} else if (vector == ipi_vector[IPI_STOP]) {
@ -146,8 +172,10 @@ interrupt(u_int64_t vector, struct trapframe *framep)
CTR1(KTR_SMP, "IPI_TEST, cpuid=%d", PCPU_GET(cpuid));
mp_ipi_test++;
#endif
} else
} else {
ints[PCPU_GET(cpuid)]++;
ia64_dispatch_intr(framep, vector);
}
out:
atomic_subtract_int(&td->td_intr_nesting_level, 1);
@ -185,8 +213,6 @@ static int ia64_sapic_count;
static struct mtx ia64_intrs_lock;
static struct ia64_intr *ia64_intrs[256];
static void ithds_init(void *dummy);
static void
ithds_init(void *dummy)
{
@ -198,6 +224,7 @@ SYSINIT(ithds_init, SI_SUB_INTR, SI_ORDER_SECOND, ithds_init, NULL);
void
ia64_add_sapic(struct sapic *sa)
{
ia64_sapics[ia64_sapic_count++] = sa;
}

View File

@ -732,6 +732,7 @@ ia64_init(u_int64_t arg1, u_int64_t arg2)
breakpoint();
}
#endif
ia64_set_tpr(0);
}
int

View File

@ -116,6 +116,11 @@ ia64_ap_startup(void)
PCPU_SET(switchticks, ticks);
mtx_lock_spin(&sched_lock);
/* kick off the clock on this AP */
ia64_set_itm(ia64_get_itc() + itm_reload);
ia64_set_itv(255);
ia64_set_tpr(0);
cpu_throw();
panic("ia64_ap_startup: cpu_throw() returned");
}