From owner-svn-src-head@FreeBSD.ORG Mon May 24 14:37:28 2010 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 7530C1065674; Mon, 24 May 2010 14:37:28 +0000 (UTC) (envelope-from avg@freebsd.org) Received: from citadel.icyb.net.ua (citadel.icyb.net.ua [212.40.38.140]) by mx1.freebsd.org (Postfix) with ESMTP id CD7868FC13; Mon, 24 May 2010 14:37:26 +0000 (UTC) Received: from porto.topspin.kiev.ua (porto-e.starpoint.kiev.ua [212.40.38.100]) by citadel.icyb.net.ua (8.8.8p3/ICyb-2.3exp) with ESMTP id RAA01500; Mon, 24 May 2010 17:37:24 +0300 (EEST) (envelope-from avg@freebsd.org) Received: from localhost.topspin.kiev.ua ([127.0.0.1]) by porto.topspin.kiev.ua with esmtp (Exim 4.34 (FreeBSD)) id 1OGYmR-000BlE-Uk; Mon, 24 May 2010 17:37:24 +0300 Message-ID: <4BFA8F22.6040402@freebsd.org> Date: Mon, 24 May 2010 17:37:22 +0300 From: Andriy Gapon User-Agent: Thunderbird 2.0.0.24 (X11/20100321) MIME-Version: 1.0 To: Alexander Motin References: <201005241140.o4OBeova088506@svn.freebsd.org> In-Reply-To: <201005241140.o4OBeova088506@svn.freebsd.org> X-Enigmail-Version: 0.96.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit Cc: svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org Subject: Re: svn commit: r208494 - in head/sys: amd64/amd64 amd64/include i386/i386 i386/include kern pc98/cbus sys x86/isa x86/x86 X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 24 May 2010 14:37:28 -0000 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