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
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to