[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Minios-devel] [UNIKRAFT PATCH v5] plat/*: Make timer interrupt frequency selectable



Reviewed-by: Yuri Volchkov <yuri.volchkov@xxxxxxxxx>

Florian Schmidt <florian.schmidt@xxxxxxxxx> writes:

> Add new configuration options for choosing a timer interrupt frequency.
> The configured frequency is converted to the timer tick length which can
> be of use for other modules (e.g., preemptive schedulers).
>
> Previously, the tick was 100 Hz on KVM and 1000 Hz on Xen. The default
> value is now 100 Hz across both platforms.
>
> Signed-off-by: Costin Lupu <costin.lupu@xxxxxxxxx>
> Signed-off-by: Florian Schmidt <florian.schmidt@xxxxxxxxx>
> ---
>  include/uk/arch/time.h            |  6 ++++--
>  include/uk/plat/time.h            |  4 ++++
>  plat/Config.uk                    |  8 ++++++++
>  plat/kvm/x86/tscclock.c           | 29 ++++++++++++++++++-----------
>  plat/linuxu/include/linuxu/time.h |  3 ++-
>  plat/linuxu/time.c                |  2 --
>  plat/xen/x86/arch_time.c          |  2 +-
>  7 files changed, 37 insertions(+), 17 deletions(-)
>
> diff --git a/include/uk/arch/time.h b/include/uk/arch/time.h
> index 262fd3b1..ac207887 100644
> --- a/include/uk/arch/time.h
> +++ b/include/uk/arch/time.h
> @@ -57,12 +57,14 @@ typedef __s64 __snsec;
>  #define __SNSEC_MAX (__S64_MAX)
>  #define __SNSEC_MIN (__S64_MIN)
>  
> -#define ukarch_time_nsec_to_sec(ns)      ((ns) / 1000000000ULL)
> +#define UKARCH_NSEC_PER_SEC 1000000000ULL
> +
> +#define ukarch_time_nsec_to_sec(ns)      ((ns) / UKARCH_NSEC_PER_SEC)
>  #define ukarch_time_nsec_to_msec(ns)     ((ns) / 1000000ULL)
>  #define ukarch_time_nsec_to_usec(ns)     ((ns) / 1000UL)
>  #define ukarch_time_subsec(ns)           ((ns) % 1000000000ULL)
>  
> -#define ukarch_time_sec_to_nsec(sec)     ((sec)  * 1000000000UL)
> +#define ukarch_time_sec_to_nsec(sec)     ((sec)  * UKARCH_NSEC_PER_SEC)
>  #define ukarch_time_msec_to_nsec(msec)   ((msec) * 1000000UL)
>  #define ukarch_time_usec_to_nsec(usec)   ((usec) * 1000UL)
>  
> diff --git a/include/uk/plat/time.h b/include/uk/plat/time.h
> index 202e0f99..b402ec24 100644
> --- a/include/uk/plat/time.h
> +++ b/include/uk/plat/time.h
> @@ -47,6 +47,10 @@ void ukplat_time_fini(void);
>  
>  __nsec ukplat_monotonic_clock(void);
>  
> +/* Time tick length */
> +#define UKPLAT_TIME_TICK_NSEC  (UKARCH_NSEC_PER_SEC / CONFIG_HZ)
> +#define UKPLAT_TIME_TICK_MSEC  
> ukarch_time_nsec_to_msec(UKPLAT_TIME_TICK_NSEC)
> +
>  #ifdef __cplusplus
>  }
>  #endif
> diff --git a/plat/Config.uk b/plat/Config.uk
> index b776c451..8a878eb0 100644
> --- a/plat/Config.uk
> +++ b/plat/Config.uk
> @@ -17,3 +17,11 @@ config EARLY_PRINT_PL011_UART_ADDR
>               Pl011 serial address used by early debug console.
>  
>  endmenu
> +
> +config HZ
> +     int
> +     prompt "Timer frequency (Hz)"
> +     default 100
> +     help
> +             Configure the timer interrupt frequency.
> +             Only change this if you know what you're doing.
> diff --git a/plat/kvm/x86/tscclock.c b/plat/kvm/x86/tscclock.c
> index f3fa55a2..86db814a 100644
> --- a/plat/kvm/x86/tscclock.c
> +++ b/plat/kvm/x86/tscclock.c
> @@ -60,8 +60,6 @@
>  #include <uk/assert.h>
>  #include <uk/bitops.h>
>  
> -#define NSEC_PER_SEC         1000000000ULL
> -
>  #define TIMER_CNTR           0x40
>  #define TIMER_MODE           0x43
>  #define TIMER_SEL0           0x00
> @@ -84,6 +82,15 @@
>  #define      RTC_STATUS_A         0x0a
>  #define      RTC_UIP              (1<<7)
>  
> +/*
> + * Compile-time check to make sure we don't tick faster than the PIT can go.
> + * This is really only a basic sanity check. We'll run into serious issues 
> WAY
> + * earlier.
> + */
> +#if TIMER_HZ / CONFIG_HZ < 1
> +#error Timer tick frequency (CONFIG_HZ) cannot be higher than PIT frequency!
> +#endif
> +
>  /* RTC wall time offset at monotonic time base. */
>  static __u64 rtc_epochoffset;
>  
> @@ -103,11 +110,11 @@ static __u32 tsc_mult;
>   *
>   * Calculated as:
>   *
> - *     f = NSEC_PER_SEC / TIMER_HZ   (0.31) fixed point.
> - *     pit_mult = 1 / f              (1.32) fixed point.
> + *     f = UKARCH_NSEC_PER_SEC / TIMER_HZ   (0.31) fixed point.
> + *     pit_mult = 1 / f                     (1.32) fixed point.
>   */
>  static const __u32 pit_mult =
> -     (1ULL << 63) / ((NSEC_PER_SEC << 31) / TIMER_HZ);
> +     (1ULL << 63) / ((UKARCH_NSEC_PER_SEC << 31) / TIMER_HZ);
>  
>  
>  /*
> @@ -131,7 +138,7 @@ static void i8254_delay(unsigned int n)
>  {
>       unsigned int cur_tick, initial_tick;
>       int remaining;
> -     const unsigned long timer_rval = TIMER_HZ / 100;
> +     const unsigned long timer_rval = TIMER_HZ / CONFIG_HZ;
>  
>       initial_tick = i8254_gettick();
>  
> @@ -211,10 +218,10 @@ int tscclock_init(void)
>  {
>       __u64 tsc_freq, rtc_boot;
>  
> -     /* Initialise i8254 timer channel 0 to mode 2 at 100 Hz */
> +     /* Initialise i8254 timer channel 0 to mode 2 at CONFIG_HZ frequency */
>       outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
> -     outb(TIMER_CNTR, (TIMER_HZ / 100) & 0xff);
> -     outb(TIMER_CNTR, (TIMER_HZ / 100) >> 8);
> +     outb(TIMER_CNTR, (TIMER_HZ / CONFIG_HZ) & 0xff);
> +     outb(TIMER_CNTR, (TIMER_HZ / CONFIG_HZ) >> 8);
>  
>       /*
>        * Read RTC "time at boot". This must be done just before tsc_base is
> @@ -238,9 +245,9 @@ int tscclock_init(void)
>       /*
>        * Calculate TSC scaling multiplier.
>        *
> -      * (0.32) tsc_mult = NSEC_PER_SEC (32.32) / tsc_freq (32.0)
> +      * (0.32) tsc_mult = UKARCH_NSEC_PER_SEC (32.32) / tsc_freq (32.0)
>        */
> -     tsc_mult = (NSEC_PER_SEC << 32) / tsc_freq;
> +     tsc_mult = (UKARCH_NSEC_PER_SEC << 32) / tsc_freq;
>  
>       /*
>        * Monotonic time begins at tsc_base (first read of TSC before
> diff --git a/plat/linuxu/include/linuxu/time.h 
> b/plat/linuxu/include/linuxu/time.h
> index 2df881ec..c1a875af 100644
> --- a/plat/linuxu/include/linuxu/time.h
> +++ b/plat/linuxu/include/linuxu/time.h
> @@ -35,9 +35,10 @@
>  #ifndef __LINUXU_TIME_H__
>  #define __LINUXU_TIME_H__
>  
> +#include <uk/plat/time.h>
>  #include <linuxu/signal.h>
>  
> -#define TIMER_INTVAL_MSEC    10
> +#define TIMER_INTVAL_NSEC    UKPLAT_TIME_TICK_NSEC
>  #define TIMER_SIGNUM         SIGALRM
>  
>  
> diff --git a/plat/linuxu/time.c b/plat/linuxu/time.c
> index ead07f59..13439ad5 100644
> --- a/plat/linuxu/time.c
> +++ b/plat/linuxu/time.c
> @@ -40,8 +40,6 @@
>  #include <linuxu/syscall.h>
>  #include <linuxu/time.h>
>  
> -#define TIMER_INTVAL_NSEC    ukarch_time_msec_to_nsec(TIMER_INTVAL_MSEC)
> -
>  static k_timer_t timerid;
>  
>  
> diff --git a/plat/xen/x86/arch_time.c b/plat/xen/x86/arch_time.c
> index 95d7b103..a4b77b93 100644
> --- a/plat/xen/x86/arch_time.c
> +++ b/plat/xen/x86/arch_time.c
> @@ -233,7 +233,7 @@ void time_block_until(__snsec until)
>  static void timer_handler(evtchn_port_t ev __unused,
>               struct __regs *regs __unused, void *ign __unused)
>  {
> -     __nsec until = ukplat_monotonic_clock() + ukarch_time_msec_to_nsec(1);
> +     __nsec until = ukplat_monotonic_clock() + UKPLAT_TIME_TICK_NSEC;
>  
>       HYPERVISOR_set_timer_op(until);
>  }
> -- 
> 2.20.1
>

-- 
Yuri Volchkov
Software Specialist

NEC Europe Ltd
Kurfürsten-Anlage 36
D-69115 Heidelberg

_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.