summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/amd64/amd64/mp_machdep.c3
-rw-r--r--sys/amd64/include/apicvar.h3
-rw-r--r--sys/amd64/include/clock.h1
-rw-r--r--sys/i386/i386/mp_machdep.c3
-rw-r--r--sys/i386/include/apicvar.h6
-rw-r--r--sys/i386/include/clock.h1
-rw-r--r--sys/kern/kern_clock.c52
-rw-r--r--sys/pc98/cbus/clock.c21
-rw-r--r--sys/sys/kernel.h2
-rw-r--r--sys/sys/systm.h2
-rw-r--r--sys/x86/isa/clock.c66
-rw-r--r--sys/x86/x86/local_apic.c33
12 files changed, 85 insertions, 108 deletions
diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c
index 337c028..4a44aba 100644
--- a/sys/amd64/amd64/mp_machdep.c
+++ b/sys/amd64/amd64/mp_machdep.c
@@ -1112,9 +1112,6 @@ ipi_bitmap_handler(struct trapframe frame)
if (ipi_bitmap & (1 << IPI_STATCLOCK))
statclockintr(&frame);
-
- if (ipi_bitmap & (1 << IPI_PROFCLOCK))
- profclockintr(&frame);
}
/*
diff --git a/sys/amd64/include/apicvar.h b/sys/amd64/include/apicvar.h
index 91bba99..8dc04a9 100644
--- a/sys/amd64/include/apicvar.h
+++ b/sys/amd64/include/apicvar.h
@@ -123,8 +123,7 @@
#define IPI_PREEMPT 1
#define IPI_HARDCLOCK 2
#define IPI_STATCLOCK 3
-#define IPI_PROFCLOCK 4
-#define IPI_BITMAP_LAST IPI_PROFCLOCK
+#define IPI_BITMAP_LAST IPI_STATCLOCK
#define IPI_IS_BITMAPED(x) ((x) <= IPI_BITMAP_LAST)
#define IPI_STOP (APIC_IPI_INTS + 7) /* Stop CPU until restarted. */
diff --git a/sys/amd64/include/clock.h b/sys/amd64/include/clock.h
index 8af699e..d2d421f 100644
--- a/sys/amd64/include/clock.h
+++ b/sys/amd64/include/clock.h
@@ -27,7 +27,6 @@ struct trapframe;
int hardclockintr(struct trapframe *frame);
int statclockintr(struct trapframe *frame);
-int profclockintr(struct trapframe *frame);
/*
* Driver to clock driver interface.
diff --git a/sys/i386/i386/mp_machdep.c b/sys/i386/i386/mp_machdep.c
index 716c25e..0dfb357 100644
--- a/sys/i386/i386/mp_machdep.c
+++ b/sys/i386/i386/mp_machdep.c
@@ -1279,9 +1279,6 @@ ipi_bitmap_handler(struct trapframe frame)
if (ipi_bitmap & (1 << IPI_STATCLOCK))
statclockintr(&frame);
-
- if (ipi_bitmap & (1 << IPI_PROFCLOCK))
- profclockintr(&frame);
}
/*
diff --git a/sys/i386/include/apicvar.h b/sys/i386/include/apicvar.h
index bcb84a0..adfc1e8 100644
--- a/sys/i386/include/apicvar.h
+++ b/sys/i386/include/apicvar.h
@@ -124,8 +124,7 @@
#define IPI_PREEMPT 1
#define IPI_HARDCLOCK 2
#define IPI_STATCLOCK 3
-#define IPI_PROFCLOCK 4
-#define IPI_BITMAP_LAST IPI_PROFCLOCK
+#define IPI_BITMAP_LAST IPI_STATCLOCK
#define IPI_IS_BITMAPED(x) ((x) <= IPI_BITMAP_LAST)
#define IPI_STOP (APIC_IPI_INTS + 7) /* Stop CPU until restarted. */
@@ -152,8 +151,7 @@
#define IPI_PREEMPT 1
#define IPI_HARDCLOCK 2
#define IPI_STATCLOCK 3
-#define IPI_PROFCLOCK 4
-#define IPI_BITMAP_LAST IPI_PROFCLOCK
+#define IPI_BITMAP_LAST IPI_STATCLOCK
#define IPI_IS_BITMAPED(x) ((x) <= IPI_BITMAP_LAST)
#define IPI_STOP (APIC_IPI_INTS + 7) /* Stop CPU until restarted. */
diff --git a/sys/i386/include/clock.h b/sys/i386/include/clock.h
index c0c55ed..7a4a081 100644
--- a/sys/i386/include/clock.h
+++ b/sys/i386/include/clock.h
@@ -27,7 +27,6 @@ struct trapframe;
int hardclockintr(struct trapframe *frame);
int statclockintr(struct trapframe *frame);
-int profclockintr(struct trapframe *frame);
/*
* Driver to clock driver interface.
diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c
index da05cc1..a35e43b 100644
--- a/sys/kern/kern_clock.c
+++ b/sys/kern/kern_clock.c
@@ -374,6 +374,12 @@ int profprocs;
int ticks;
int psratio;
+int timer1hz;
+int timer2hz;
+static DPCPU_DEFINE(u_int, hard_cnt);
+static DPCPU_DEFINE(u_int, stat_cnt);
+static DPCPU_DEFINE(u_int, prof_cnt);
+
/*
* Initialize clock frequencies and start both clocks running.
*/
@@ -403,6 +409,52 @@ initclocks(dummy)
#endif
}
+void
+timer1clock(int usermode, uintfptr_t pc)
+{
+ u_int *cnt;
+
+ cnt = DPCPU_PTR(hard_cnt);
+ *cnt += hz;
+ if (*cnt >= timer1hz) {
+ *cnt -= timer1hz;
+ if (*cnt >= timer1hz)
+ *cnt = 0;
+ if (PCPU_GET(cpuid) == 0)
+ hardclock(usermode, pc);
+ else
+ hardclock_cpu(usermode);
+ }
+ if (timer2hz == 0)
+ timer2clock(usermode, pc);
+}
+
+void
+timer2clock(int usermode, uintfptr_t pc)
+{
+ u_int *cnt;
+ int t2hz = timer2hz ? timer2hz : timer1hz;
+
+ cnt = DPCPU_PTR(stat_cnt);
+ *cnt += stathz;
+ if (*cnt >= t2hz) {
+ *cnt -= t2hz;
+ if (*cnt >= t2hz)
+ *cnt = 0;
+ statclock(usermode);
+ }
+ if (profprocs == 0)
+ return;
+ cnt = DPCPU_PTR(prof_cnt);
+ *cnt += profhz;
+ if (*cnt >= t2hz) {
+ *cnt -= t2hz;
+ if (*cnt >= t2hz)
+ *cnt = 0;
+ profclock(usermode, pc);
+ }
+}
+
/*
* Each time the real-time timer fires, this function is called on all CPUs.
* Note that hardclock() calls hardclock_cpu() for the boot CPU, so only
diff --git a/sys/pc98/cbus/clock.c b/sys/pc98/cbus/clock.c
index 8c5a7d2..2f2c08c 100644
--- a/sys/pc98/cbus/clock.c
+++ b/sys/pc98/cbus/clock.c
@@ -129,10 +129,7 @@ int
hardclockintr(struct trapframe *frame)
{
- if (PCPU_GET(cpuid) == 0)
- hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
- else
- hardclock_cpu(TRAPF_USERMODE(frame));
+ timer1clock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
return (FILTER_HANDLED);
}
@@ -143,13 +140,6 @@ statclockintr(struct trapframe *frame)
return (FILTER_HANDLED);
}
-int
-profclockintr(struct trapframe *frame)
-{
-
- return (FILTER_HANDLED);
-}
-
static int
clkintr(struct trapframe *frame)
{
@@ -448,6 +438,7 @@ cpu_initclocks()
* timecounter to user a simpler algorithm.
*/
if (using_lapic_timer == LAPIC_CLOCK_NONE) {
+ timer1hz = hz;
intr_add_handler("clk", 0, (driver_filter_t *)clkintr, NULL,
NULL, INTR_TYPE_CLK, NULL);
i8254_intsrc = intr_lookup_source(0);
@@ -460,6 +451,14 @@ cpu_initclocks()
i8254_timecounter.tc_counter_mask = 0xffff;
set_i8254_freq(i8254_freq, hz);
}
+ if (using_lapic_timer != LAPIC_CLOCK_ALL) {
+ profhz = hz;
+ if (hz < 128)
+ stathz = hz;
+ else
+ stathz = hz / (hz / 128);
+ }
+ timer2hz = 0;
init_TSC_tc();
}
diff --git a/sys/sys/kernel.h b/sys/sys/kernel.h
index 1a9cb5c..53cf079 100644
--- a/sys/sys/kernel.h
+++ b/sys/sys/kernel.h
@@ -64,6 +64,8 @@ extern int stathz; /* statistics clock's frequency */
extern int profhz; /* profiling clock's frequency */
extern int profprocs; /* number of process's profiling */
extern int ticks;
+extern int timer1hz; /* timer 1 frequency */
+extern int timer2hz; /* timer 2 frequency */
#endif /* _KERNEL */
diff --git a/sys/sys/systm.h b/sys/sys/systm.h
index 1d861f0..8d245a3 100644
--- a/sys/sys/systm.h
+++ b/sys/sys/systm.h
@@ -240,6 +240,8 @@ void hardclock_cpu(int usermode);
void softclock(void *);
void statclock(int usermode);
void profclock(int usermode, uintfptr_t pc);
+void timer1clock(int usermode, uintfptr_t pc);
+void timer2clock(int usermode, uintfptr_t pc);
void startprofclock(struct proc *);
void stopprofclock(struct proc *);
diff --git a/sys/x86/isa/clock.c b/sys/x86/isa/clock.c
index 36dc36e..b0d49d5 100644
--- a/sys/x86/isa/clock.c
+++ b/sys/x86/isa/clock.c
@@ -87,8 +87,6 @@ __FBSDID("$FreeBSD$");
#define TIMER_DIV(x) ((i8254_freq + (x) / 2) / (x))
int clkintr_pending;
-static int pscnt = 1;
-static int psdiv = 1;
#ifndef TIMER_FREQ
#define TIMER_FREQ 1193182
#endif
@@ -134,10 +132,7 @@ int
hardclockintr(struct trapframe *frame)
{
- if (PCPU_GET(cpuid) == 0)
- hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
- else
- hardclock_cpu(TRAPF_USERMODE(frame));
+ timer1clock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
return (FILTER_HANDLED);
}
@@ -145,19 +140,7 @@ int
statclockintr(struct trapframe *frame)
{
- profclockintr(frame);
- statclock(TRAPF_USERMODE(frame));
- return (FILTER_HANDLED);
-}
-
-int
-profclockintr(struct trapframe *frame)
-{
-
- if (!using_atrtc_timer)
- hardclockintr(frame);
- if (profprocs != 0)
- profclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
+ timer2clock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
return (FILTER_HANDLED);
}
@@ -190,28 +173,11 @@ clkintr(struct trapframe *frame)
(*cyclic_clock_func[cpu])(frame);
#endif
- if (using_atrtc_timer) {
-#ifdef SMP
- if (smp_started)
- ipi_all_but_self(IPI_HARDCLOCK);
-#endif
- hardclockintr(frame);
- } else {
- if (--pscnt <= 0) {
- pscnt = psratio;
#ifdef SMP
- if (smp_started)
- ipi_all_but_self(IPI_STATCLOCK);
+ if (smp_started)
+ ipi_all_but_self(IPI_HARDCLOCK);
#endif
- statclockintr(frame);
- } else {
-#ifdef SMP
- if (smp_started)
- ipi_all_but_self(IPI_PROFCLOCK);
-#endif
- profclockintr(frame);
- }
- }
+ hardclockintr(frame);
#ifdef DEV_MCA
/* Reset clock interrupt by asserting bit 7 of port 0x61 */
@@ -295,20 +261,11 @@ rtcintr(struct trapframe *frame)
while (rtcin(RTC_INTR) & RTCIR_PERIOD) {
flag = 1;
- if (--pscnt <= 0) {
- pscnt = psdiv;
#ifdef SMP
- if (smp_started)
- ipi_all_but_self(IPI_STATCLOCK);
-#endif
- statclockintr(frame);
- } else {
-#ifdef SMP
- if (smp_started)
- ipi_all_but_self(IPI_PROFCLOCK);
+ if (smp_started)
+ ipi_all_but_self(IPI_STATCLOCK);
#endif
- profclockintr(frame);
- }
+ statclockintr(frame);
}
return(flag ? FILTER_HANDLED : FILTER_STRAY);
}
@@ -555,6 +512,7 @@ cpu_initclocks()
* timecounter to user a simpler algorithm.
*/
if (using_lapic_timer == LAPIC_CLOCK_NONE) {
+ timer1hz = hz;
intr_add_handler("clk", 0, (driver_filter_t *)clkintr, NULL,
NULL, INTR_TYPE_CLK, NULL);
i8254_intsrc = intr_lookup_source(0);
@@ -577,6 +535,7 @@ cpu_initclocks()
if (using_lapic_timer != LAPIC_CLOCK_ALL) {
using_atrtc_timer = tasc;
if (using_atrtc_timer) {
+ timer2hz = RTC_NOPROFRATE;
/* Enable periodic interrupts from the RTC. */
intr_add_handler("rtc", 8,
(driver_filter_t *)rtcintr, NULL, NULL,
@@ -588,6 +547,7 @@ cpu_initclocks()
stathz = hz;
else
stathz = hz / (hz / 128);
+ timer2hz = 0;
}
}
@@ -601,7 +561,7 @@ cpu_startprofclock(void)
if (using_lapic_timer == LAPIC_CLOCK_ALL || !using_atrtc_timer)
return;
atrtc_rate(RTCSA_PROF);
- psdiv = pscnt = psratio;
+ timer2hz = RTC_PROFRATE;
}
void
@@ -611,7 +571,7 @@ cpu_stopprofclock(void)
if (using_lapic_timer == LAPIC_CLOCK_ALL || !using_atrtc_timer)
return;
atrtc_rate(RTCSA_NOPROF);
- psdiv = pscnt = 1;
+ timer2hz = RTC_NOPROFRATE;
}
static int
diff --git a/sys/x86/x86/local_apic.c b/sys/x86/x86/local_apic.c
index 29b078e..f40026b 100644
--- a/sys/x86/x86/local_apic.c
+++ b/sys/x86/x86/local_apic.c
@@ -118,9 +118,6 @@ struct lapic {
u_int la_cluster_id:2;
u_int la_present:1;
u_long *la_timer_count;
- u_long la_hard_ticks;
- u_long la_stat_ticks;
- u_long la_prof_ticks;
/* Include IDT_SYSCALL to make indexing easier. */
int la_ioint_irqs[APIC_NUM_IOINTS + 1];
} static lapics[MAX_APIC_ID + 1];
@@ -493,12 +490,14 @@ lapic_setup_clock(enum lapic_clock srcsdes)
} else
lapic_timer_hz = hz;
lapic_timer_period = value / lapic_timer_hz;
+ timer1hz = lapic_timer_hz;
if (srcsdes == LAPIC_CLOCK_ALL) {
if (lapic_timer_hz < 128)
stathz = lapic_timer_hz;
else
stathz = lapic_timer_hz / (lapic_timer_hz / 128);
profhz = lapic_timer_hz;
+ timer2hz = 0;
}
/*
@@ -790,33 +789,7 @@ lapic_handle_timer(struct trapframe *frame)
(*cyclic_clock_func[cpu])(frame);
#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;
- if (PCPU_GET(cpuid) == 0)
- hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
- else
- hardclock_cpu(TRAPF_USERMODE(frame));
- }
- if (clockcoverage == LAPIC_CLOCK_ALL) {
-
- /* Fire statclock at stathz. */
- la->la_stat_ticks += stathz;
- if (la->la_stat_ticks >= lapic_timer_hz) {
- la->la_stat_ticks -= lapic_timer_hz;
- statclock(TRAPF_USERMODE(frame));
- }
-
- /* Fire profclock at profhz, but only when needed. */
- la->la_prof_ticks += profhz;
- if (la->la_prof_ticks >= lapic_timer_hz) {
- la->la_prof_ticks -= lapic_timer_hz;
- if (profprocs != 0)
- profclock(TRAPF_USERMODE(frame),
- TRAPF_PC(frame));
- }
- }
+ timer1clock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
critical_exit();
}
OpenPOWER on IntegriCloud