1
0
mirror of https://git.FreeBSD.org/src.git synced 2025-01-20 15:43:16 +00:00

When using i8254 as the only kernel timer source:

- Interpolate stat/prof clock using clkintr() in a similar fashion to
  local APIC timer, since statclock usually run slower.

- Liberate hardclockintr() from taking the burden of handling both stat
  and prof clock interrupt. Instead, send IPIs within clkintr() to handle
  those.
This commit is contained in:
Ariff Abdullah 2009-06-09 07:26:52 +00:00
parent 2b9a8a330f
commit b65cb1db3c
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=193814
2 changed files with 62 additions and 14 deletions

View File

@ -93,6 +93,9 @@ static int i8254_ticked;
static int using_atrtc_timer;
static int using_lapic_timer;
static u_int stat_ticks = 0;
static u_int prof_ticks = 0;
/* Values for timerX_state: */
#define RELEASED 0
#define RELEASE_PENDING 1
@ -122,8 +125,6 @@ hardclockintr(struct trapframe *frame)
hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
else
hardclock_cpu(TRAPF_USERMODE(frame));
if (!using_atrtc_timer)
statclockintr(frame);
return (FILTER_HANDLED);
}
@ -131,8 +132,6 @@ int
statclockintr(struct trapframe *frame)
{
if (profprocs != 0)
profclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
statclock(TRAPF_USERMODE(frame));
return (FILTER_HANDLED);
}
@ -166,6 +165,30 @@ clkintr(struct trapframe *frame)
ipi_all_but_self(IPI_HARDCLOCK);
#endif
hardclockintr(frame);
if (!using_atrtc_timer) {
prof_ticks += profhz;
if (prof_ticks >= hz) {
prof_ticks -= hz;
if (profprocs != 0) {
#ifdef SMP
if (smp_started)
ipi_all_but_self(IPI_PROFCLOCK);
#endif
profclockintr(frame);
}
}
stat_ticks += stathz;
if (stat_ticks >= hz) {
stat_ticks -= hz;
#ifdef SMP
if (smp_started)
ipi_all_but_self(IPI_STATCLOCK);
#endif
statclockintr(frame);
}
}
return (FILTER_HANDLED);
}
@ -500,7 +523,8 @@ cpu_initclocks()
INTR_TYPE_CLK, NULL);
atrtc_enable_intr();
} else {
profhz = stathz = hz;
profhz = min(RTC_PROFRATE, hz);
stathz = min(RTC_NOPROFRATE, hz);
}
}
@ -511,7 +535,7 @@ void
cpu_startprofclock(void)
{
if (using_lapic_timer)
if (using_lapic_timer || !using_atrtc_clock)
return;
atrtc_rate(RTCSA_PROF);
psdiv = pscnt = psratio;
@ -521,7 +545,7 @@ void
cpu_stopprofclock(void)
{
if (using_lapic_timer)
if (using_lapic_timer || !using_atrtc_clock)
return;
atrtc_rate(RTCSA_NOPROF);
psdiv = pscnt = 1;

View File

@ -108,6 +108,9 @@ static int i8254_ticked;
static int using_atrtc_timer;
static int using_lapic_timer;
static u_int stat_ticks = 0;
static u_int prof_ticks = 0;
/* Values for timerX_state: */
#define RELEASED 0
#define RELEASE_PENDING 1
@ -137,8 +140,6 @@ hardclockintr(struct trapframe *frame)
hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
else
hardclock_cpu(TRAPF_USERMODE(frame));
if (!using_atrtc_timer)
statclockintr(frame);
return (FILTER_HANDLED);
}
@ -146,8 +147,6 @@ int
statclockintr(struct trapframe *frame)
{
if (profprocs != 0)
profclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
statclock(TRAPF_USERMODE(frame));
return (FILTER_HANDLED);
}
@ -193,6 +192,30 @@ clkintr(struct trapframe *frame)
ipi_all_but_self(IPI_HARDCLOCK);
#endif
hardclockintr(frame);
if (!using_atrtc_timer) {
prof_ticks += profhz;
if (prof_ticks >= hz) {
prof_ticks -= hz;
if (profprocs != 0) {
#ifdef SMP
if (smp_started)
ipi_all_but_self(IPI_PROFCLOCK);
#endif
profclockintr(frame);
}
}
stat_ticks += stathz;
if (stat_ticks >= hz) {
stat_ticks -= hz;
#ifdef SMP
if (smp_started)
ipi_all_but_self(IPI_STATCLOCK);
#endif
statclockintr(frame);
}
}
#ifdef DEV_MCA
/* Reset clock interrupt by asserting bit 7 of port 0x61 */
if (MCA_system)
@ -549,7 +572,8 @@ cpu_initclocks()
INTR_TYPE_CLK, NULL);
atrtc_enable_intr();
} else {
profhz = stathz = hz;
profhz = min(RTC_PROFRATE, hz);
stathz = min(RTC_NOPROFRATE, hz);
}
}
@ -560,7 +584,7 @@ void
cpu_startprofclock(void)
{
if (using_lapic_timer)
if (using_lapic_timer || !using_atrtc_timer)
return;
atrtc_rate(RTCSA_PROF);
psdiv = pscnt = psratio;
@ -570,7 +594,7 @@ void
cpu_stopprofclock(void)
{
if (using_lapic_timer)
if (using_lapic_timer || !using_atrtc_timer)
return;
atrtc_rate(RTCSA_NOPROF);
psdiv = pscnt = 1;