svn commit: r208494 - in head/sys: amd64/amd64 amd64/include
i386/i386 i386/include kern pc98/cbus sys x86/isa x86/x86
Andriy Gapon
avg at freebsd.org
Mon May 24 14:37:28 UTC 2010
on 24/05/2010 14:40 Alexander Motin said the following:
> Author: mav
> Date: Mon May 24 11:40:49 2010
> New Revision: 208494
> URL: http://svn.freebsd.org/changeset/base/208494
>
> Log:
> - Implement MI helper functions, dividing one or two timer interrupts with
> arbitrary frequencies into hardclock(), statclock() and profclock() calls.
> Same code with minor variations duplicated several times over the tree for
> different timer drivers and architectures.
> - Switch all x86 archs to new functions, simplifying the code and removing
> extra logic from timer drivers. Other archs are also welcome.
Alexander,
could you please describe the new code/KPI in greater detail, perhaps on a more
appropriate mailing list?
For me it is not immediately obvious why IPI_PROFCLOCK is gone now. I haven't
spent much time reverse engineering this change and perhaps it's easier for you
to describe the change.
Thanks!
> Modified:
> head/sys/amd64/amd64/mp_machdep.c
> head/sys/amd64/include/apicvar.h
> head/sys/amd64/include/clock.h
> head/sys/i386/i386/mp_machdep.c
> head/sys/i386/include/apicvar.h
> head/sys/i386/include/clock.h
> head/sys/kern/kern_clock.c
> head/sys/pc98/cbus/clock.c
> head/sys/sys/kernel.h
> head/sys/sys/systm.h
> head/sys/x86/isa/clock.c
> head/sys/x86/x86/local_apic.c
>
> Modified: head/sys/amd64/amd64/mp_machdep.c
> ==============================================================================
> --- head/sys/amd64/amd64/mp_machdep.c Mon May 24 11:14:40 2010 (r208493)
> +++ head/sys/amd64/amd64/mp_machdep.c Mon May 24 11:40:49 2010 (r208494)
> @@ -1112,9 +1112,6 @@ ipi_bitmap_handler(struct trapframe fram
>
> if (ipi_bitmap & (1 << IPI_STATCLOCK))
> statclockintr(&frame);
> -
> - if (ipi_bitmap & (1 << IPI_PROFCLOCK))
> - profclockintr(&frame);
> }
>
> /*
>
> Modified: head/sys/amd64/include/apicvar.h
> ==============================================================================
> --- head/sys/amd64/include/apicvar.h Mon May 24 11:14:40 2010 (r208493)
> +++ head/sys/amd64/include/apicvar.h Mon May 24 11:40:49 2010 (r208494)
> @@ -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. */
>
> Modified: head/sys/amd64/include/clock.h
> ==============================================================================
> --- head/sys/amd64/include/clock.h Mon May 24 11:14:40 2010 (r208493)
> +++ head/sys/amd64/include/clock.h Mon May 24 11:40:49 2010 (r208494)
> @@ -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.
>
> Modified: head/sys/i386/i386/mp_machdep.c
> ==============================================================================
> --- head/sys/i386/i386/mp_machdep.c Mon May 24 11:14:40 2010 (r208493)
> +++ head/sys/i386/i386/mp_machdep.c Mon May 24 11:40:49 2010 (r208494)
> @@ -1279,9 +1279,6 @@ ipi_bitmap_handler(struct trapframe fram
>
> if (ipi_bitmap & (1 << IPI_STATCLOCK))
> statclockintr(&frame);
> -
> - if (ipi_bitmap & (1 << IPI_PROFCLOCK))
> - profclockintr(&frame);
> }
>
> /*
>
> Modified: head/sys/i386/include/apicvar.h
> ==============================================================================
> --- head/sys/i386/include/apicvar.h Mon May 24 11:14:40 2010 (r208493)
> +++ head/sys/i386/include/apicvar.h Mon May 24 11:40:49 2010 (r208494)
> @@ -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. */
>
> Modified: head/sys/i386/include/clock.h
> ==============================================================================
> --- head/sys/i386/include/clock.h Mon May 24 11:14:40 2010 (r208493)
> +++ head/sys/i386/include/clock.h Mon May 24 11:40:49 2010 (r208494)
> @@ -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.
>
> Modified: head/sys/kern/kern_clock.c
> ==============================================================================
> --- head/sys/kern/kern_clock.c Mon May 24 11:14:40 2010 (r208493)
> +++ head/sys/kern/kern_clock.c Mon May 24 11:40:49 2010 (r208494)
> @@ -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
>
> Modified: head/sys/pc98/cbus/clock.c
> ==============================================================================
> --- head/sys/pc98/cbus/clock.c Mon May 24 11:14:40 2010 (r208493)
> +++ head/sys/pc98/cbus/clock.c Mon May 24 11:40:49 2010 (r208494)
> @@ -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();
> }
>
> Modified: head/sys/sys/kernel.h
> ==============================================================================
> --- head/sys/sys/kernel.h Mon May 24 11:14:40 2010 (r208493)
> +++ head/sys/sys/kernel.h Mon May 24 11:40:49 2010 (r208494)
> @@ -64,6 +64,8 @@ extern int stathz; /* statistics clock
> 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 */
>
>
> Modified: head/sys/sys/systm.h
> ==============================================================================
> --- head/sys/sys/systm.h Mon May 24 11:14:40 2010 (r208493)
> +++ head/sys/sys/systm.h Mon May 24 11:40:49 2010 (r208494)
> @@ -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 *);
>
> Modified: head/sys/x86/isa/clock.c
> ==============================================================================
> --- head/sys/x86/isa/clock.c Mon May 24 11:14:40 2010 (r208493)
> +++ head/sys/x86/isa/clock.c Mon May 24 11:40:49 2010 (r208494)
> @@ -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
>
> Modified: head/sys/x86/x86/local_apic.c
> ==============================================================================
> --- head/sys/x86/x86/local_apic.c Mon May 24 11:14:40 2010 (r208493)
> +++ head/sys/x86/x86/local_apic.c Mon May 24 11:40:49 2010 (r208494)
> @@ -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 srcsd
> } 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 *fra
> (*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();
> }
>
--
Andriy Gapon
More information about the svn-src-head
mailing list