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:
parent
cfe8b263a0
commit
8fd35a03b5
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -732,6 +732,7 @@ ia64_init(u_int64_t arg1, u_int64_t arg2)
|
||||
breakpoint();
|
||||
}
|
||||
#endif
|
||||
ia64_set_tpr(0);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -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");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user