diff options
author | rn@wyvis.camb.intel-research.net <rn@wyvis.camb.intel-research.net> | 2003-01-30 19:35:24 +0000 |
---|---|---|
committer | rn@wyvis.camb.intel-research.net <rn@wyvis.camb.intel-research.net> | 2003-01-30 19:35:24 +0000 |
commit | 9062553a0dc188eaf5f0fa001dbe92e64a7d64e9 (patch) | |
tree | 8a21d6af1b57302389695fc71fa61a01813dda5e /xen-2.4.16/include | |
parent | 22a857bde9b89547d682aa92bb226096119b0223 (diff) | |
download | xen-9062553a0dc188eaf5f0fa001dbe92e64a7d64e9.tar.gz xen-9062553a0dc188eaf5f0fa001dbe92e64a7d64e9.tar.bz2 xen-9062553a0dc188eaf5f0fa001dbe92e64a7d64e9.zip |
bitkeeper revision 1.14.1.1 (3e397e7cPGmZK7y5LLOGYa43nTQMUw)
added time and accurate timer support
partially there for better scheduler (most of the infrastructure should be there)
Diffstat (limited to 'xen-2.4.16/include')
-rw-r--r-- | xen-2.4.16/include/asm-i386/apic.h | 3 | ||||
-rw-r--r-- | xen-2.4.16/include/asm-i386/time.h | 80 | ||||
-rw-r--r-- | xen-2.4.16/include/hypervisor-ifs/hypervisor-if.h | 57 | ||||
-rw-r--r-- | xen-2.4.16/include/xeno/ac_timer.h | 65 | ||||
-rw-r--r-- | xen-2.4.16/include/xeno/sched.h | 73 | ||||
-rw-r--r-- | xen-2.4.16/include/xeno/time.h | 61 | ||||
-rw-r--r-- | xen-2.4.16/include/xeno/timer.h | 9 |
7 files changed, 267 insertions, 81 deletions
diff --git a/xen-2.4.16/include/asm-i386/apic.h b/xen-2.4.16/include/asm-i386/apic.h index 86dd0fbc66..1f5670943b 100644 --- a/xen-2.4.16/include/asm-i386/apic.h +++ b/xen-2.4.16/include/asm-i386/apic.h @@ -55,17 +55,14 @@ static inline void ack_APIC_irq(void) } extern int get_maxlvt(void); -extern void clear_local_APIC(void); extern void connect_bsp_APIC (void); extern void disconnect_bsp_APIC (void); extern void disable_local_APIC (void); extern int verify_local_APIC (void); -extern void cache_APIC_registers (void); extern void sync_Arb_IDs (void); extern void init_bsp_APIC (void); extern void setup_local_APIC (void); extern void init_apic_mappings (void); -extern void smp_local_timer_interrupt (struct pt_regs * regs); extern void setup_APIC_clocks (void); extern int APIC_init_uniprocessor (void); diff --git a/xen-2.4.16/include/asm-i386/time.h b/xen-2.4.16/include/asm-i386/time.h new file mode 100644 index 0000000000..9e2f77727d --- /dev/null +++ b/xen-2.4.16/include/asm-i386/time.h @@ -0,0 +1,80 @@ +/* -*- Mode:C; c-basic-offset:4; tab-width:4 -*- + **************************************************************************** + * (C) 2002 - Rolf Neugebauer - Intel Research Cambridge + **************************************************************************** + * + * File: time.h + * Author: Rolf Neugebauer (neugebar@dcs.gla.ac.uk) + * Changes: + * + * Date: Nov 2002 + * + * Environment: Xen Hypervisor + * Description: Architecture dependent definition of time variables + * + **************************************************************************** + * $Id: h-insert.h,v 1.4 2002/11/08 16:03:55 rn Exp $ + **************************************************************************** + */ + +#ifndef _ASM_TIME_H_ +#define _ASM_TIME_H_ + +#include <asm/types.h> +#include <asm/msr.h> + +/* + * Cycle Counter Time + */ +typedef u64 cc_time_t; +static inline cc_time_t get_cc_time() +{ + u64 ret; + rdtscll(ret); + return ret; +} + +/* + * System Time + */ +typedef s64 s_time_t; /* System time */ +extern u32 stime_pcc; /* cycle counter value at last timer irq */ +extern s_time_t stime_now; /* time in ns at last timer IRQ */ +extern u32 stime_scale; /* scale factur for converting cc to ns */ + + +/* + * This is the Nemesis implementation. + * The variables are all set in apic.c + * Every timer IRQ time_now and time_pcc is set to the current values + * At callibration time_scale is set + */ +static s_time_t get_s_time(void) +{ + u32 delta, low, pcc; + s_time_t now; + s_time_t incr; + + /* read two values (pcc, now) "atomically" */ +again: + pcc = stime_pcc; + now = stime_now; + if (stime_pcc != pcc) goto again; + + /* only use bottom 32bits of TSC. This should be sufficient */ + rdtscl(low); + delta = low - pcc; + + incr = ((s_time_t)(stime_scale) * delta) >> 10; + return now + incr; +} + +/* update time variables once in a while */ +extern void update_time(void); + +/* + * Domain Virtual Time + */ +typedef u64 dv_time_t; + +#endif /* _ASM_TIME_H_ */ diff --git a/xen-2.4.16/include/hypervisor-ifs/hypervisor-if.h b/xen-2.4.16/include/hypervisor-ifs/hypervisor-if.h index 1e3705e9ac..82a4d9eb2d 100644 --- a/xen-2.4.16/include/hypervisor-ifs/hypervisor-if.h +++ b/xen-2.4.16/include/hypervisor-ifs/hypervisor-if.h @@ -60,12 +60,12 @@ typedef struct #define __HYPERVISOR_set_guest_stack 4 #define __HYPERVISOR_net_update 5 #define __HYPERVISOR_fpu_taskswitch 6 -#define __HYPERVISOR_yield 7 -#define __HYPERVISOR_exit 8 -#define __HYPERVISOR_dom0_op 9 -#define __HYPERVISOR_network_op 10 -#define __HYPERVISOR_set_debugreg 11 -#define __HYPERVISOR_get_debugreg 12 +#define __HYPERVISOR_sched_op 7 +#define __HYPERVISOR_exit 10 +#define __HYPERVISOR_dom0_op 11 +#define __HYPERVISOR_network_op 12 +#define __HYPERVISOR_set_debugreg 13 +#define __HYPERVISOR_get_debugreg 14 #define TRAP_INSTR "int $0x82" @@ -142,36 +142,33 @@ typedef struct shared_info_st { */ unsigned long failsafe_address; - /* - * CPU ticks since start of day. - * `wall_time' counts CPU ticks in real time. - * `domain_time' counts CPU ticks during which this domain has run. - */ - unsigned long ticks_per_ms; /* CPU ticks per millisecond */ - /* - * Current wall_time can be found by rdtsc. Only possible use of - * variable below is that it provides a timestamp for last update - * of domain_time. + /* + * Time: + * The following abstractions are exposed: System Time, Wall Clock + * Time, Domain Virtual Time. Domains can access Cycle counter time + * directly. */ - unsigned long long wall_time; - unsigned long long domain_time; - /* - * Timeouts for points at which guest OS would like a callback. - * This will probably be backed up by a timer heap in the guest OS. - * In Linux we use timeouts to update 'jiffies'. + /* System Time */ + long long system_time; /* in ns */ + unsigned long st_timestamp; /* cyclecounter at last update */ + unsigned long ticks_per_ms; /* CPU ticks per millisecond */ + /* Wall Clock Time */ + long tv_sec; /* essentially a struct timeval */ + long tv_usec; + long long wc_timestamp; /* system time at last update */ + + /* Domain Virtual Time */ + unsigned long long domain_time; + + /* + * Timeout values: + * Allow a domain to specify a timeout value in system time and + * domain virtual time. */ unsigned long long wall_timeout; unsigned long long domain_timeout; - /* - * Real-Time Clock. This shows time, in seconds, since 1.1.1980. - * The timestamp shows the CPU 'wall time' when RTC was last read. - * Thus it allows a mapping between 'real time' and 'wall time'. - */ - unsigned long rtc_time; - unsigned long long rtc_timestamp; - } shared_info_t; /* diff --git a/xen-2.4.16/include/xeno/ac_timer.h b/xen-2.4.16/include/xeno/ac_timer.h new file mode 100644 index 0000000000..f78082cb6b --- /dev/null +++ b/xen-2.4.16/include/xeno/ac_timer.h @@ -0,0 +1,65 @@ +/* -*- Mode:C; c-basic-offset:4; tab-width:4 -*- + **************************************************************************** + * (C) 2002 - Rolf Neugebauer - Intel Research Cambridge + **************************************************************************** + * + * File: ac_timer.h + * Author: Rolf Neugebauer (neugebar@dcs.gla.ac.uk) + * Changes: + * + * Date: Nov 2002 + * + * Environment: Xen Hypervisor + * Description: Accurate timer for the Hypervisor + * + **************************************************************************** + * $Id: h-insert.h,v 1.4 2002/11/08 16:03:55 rn Exp $ + **************************************************************************** + */ + +#ifndef _AC_TIMER_H_ +#define _AC_TIMER_H_ + +#include <time.h> /* include notion of time */ + +/* + * The Xen Hypervisor provides two types of timers: + * + * - Linux style, jiffy based timers for legacy code and coarse grain timeouts + * These are defined in ./include/xeno/timer.h and implemented in + * ./common/timer.c. Unlike in Linux they are executed not on a periodic + * timer interrupt but "occasionally" with somewhat lesser accuracy. + * + * - accurate timers defined in this file and implemented in + * ./common/ac_timer.c. These are implemented using a programmable timer + * interrupt and are thus as accurate as the hardware allows. Where possible + * we use the local APIC for this purpose. However, this fact is hidden + * behind a architecture independent layer. + * accurate timers are programmed using system time. + * + * The interface to accurate timers is very similar to Linux timers with the + * exception that the expires value is not expressed in jiffies but in ns from + * boot time. Its implementation however, is entirely different. + */ + +struct ac_timer { + struct list_head timer_list; + s_time_t expires; /* system time time out value */ + unsigned long data; + void (*function)(unsigned long); +}; + +/* interface for "clients" */ +extern int add_ac_timer(struct ac_timer *timer); +extern int rem_ac_timer(struct ac_timer *timer); +extern int mod_ac_timer(struct ac_timer *timer, s_time_t new_time); +static inline void init_ac_timer(struct ac_timer *timer) +{ + //timer->next = NULL; +} + +/* interface used by programmable timer, implemented hardware dependent */ +extern int reprogram_ac_timer(s_time_t timeout); +extern void do_ac_timer(void); + +#endif /* _AC_TIMER_H_ */ diff --git a/xen-2.4.16/include/xeno/sched.h b/xen-2.4.16/include/xeno/sched.h index 295335bd16..02cf6fa5e1 100644 --- a/xen-2.4.16/include/xeno/sched.h +++ b/xen-2.4.16/include/xeno/sched.h @@ -42,7 +42,8 @@ extern struct mm_struct init_mm; struct task_struct { int processor; - int state, hyp_events; + int state; + int hyp_events; unsigned int domain; /* An unsafe pointer into a shared data area. */ @@ -85,11 +86,24 @@ struct task_struct { unsigned long flags; }; +/* + * domain states + * TASK_RUNNING: Domain is runable and should be on a run queue + * TASK_INTERRUPTIBLE: Domain is blocked by may be woken up by an event + * or expiring timer + * TASK_UNINTERRUPTIBLE: Domain is blocked but may not be woken up by an + * arbitrary event or timer. + * TASK_WAIT: Domains CPU allocation expired. + * TASK_STOPPED: not really used in Xen + * TASK_DYING: Domain is about to cross over to the land of the dead. + */ + #define TASK_RUNNING 0 #define TASK_INTERRUPTIBLE 1 #define TASK_UNINTERRUPTIBLE 2 -#define TASK_STOPPED 4 -#define TASK_DYING 8 +#define TASK_WAIT 4 +#define TASK_DYING 16 +/* #define TASK_STOPPED 8 not really used */ #define SCHED_YIELD 0x10 @@ -150,52 +164,23 @@ extern void free_irq(unsigned int, void *); extern unsigned long wait_init_idle; #define init_idle() clear_bit(smp_processor_id(), &wait_init_idle); + + +/* + * Scheduler functions (in schedule.c) + */ #define set_current_state(_s) do { current->state = (_s); } while (0) #define MAX_SCHEDULE_TIMEOUT LONG_MAX +void scheduler_init(void); +void start_scheduler(void); +void sched_add_domain(struct task_struct *p); +void sched_rem_domain(struct task_struct *p); +int wake_up(struct task_struct *p); long schedule_timeout(long timeout); -asmlinkage void schedule(void); - +long do_yield(void); void reschedule(struct task_struct *p); +asmlinkage void schedule(void); -typedef struct schedule_data_st -{ - spinlock_t lock; - struct list_head runqueue; - struct task_struct *prev, *curr; -} __cacheline_aligned schedule_data_t; -extern schedule_data_t schedule_data[NR_CPUS]; - -static inline void __add_to_runqueue(struct task_struct * p) -{ - list_add(&p->run_list, &schedule_data[p->processor].runqueue); -} - - -static inline void __move_last_runqueue(struct task_struct * p) -{ - list_del(&p->run_list); - list_add_tail(&p->run_list, &schedule_data[p->processor].runqueue); -} - - -static inline void __move_first_runqueue(struct task_struct * p) -{ - list_del(&p->run_list); - list_add(&p->run_list, &schedule_data[p->processor].runqueue); -} - -static inline void __del_from_runqueue(struct task_struct * p) -{ - list_del(&p->run_list); - p->run_list.next = NULL; -} - -static inline int __task_on_runqueue(struct task_struct *p) -{ - return (p->run_list.next != NULL); -} - -int wake_up(struct task_struct *p); #define signal_pending(_p) ((_p)->hyp_events || \ (_p)->shared_info->events) diff --git a/xen-2.4.16/include/xeno/time.h b/xen-2.4.16/include/xeno/time.h index 33837c5009..5bb717fb2d 100644 --- a/xen-2.4.16/include/xeno/time.h +++ b/xen-2.4.16/include/xeno/time.h @@ -1,13 +1,61 @@ -/****************************************************************************** - * time.h +/* -*- Mode:C; c-basic-offset:4; tab-width:4 -*- + **************************************************************************** + * (C) 2002 - Rolf Neugebauer - Intel Research Cambridge + **************************************************************************** + * + * File: time.h + * Author: Rolf Neugebauer (neugebar@dcs.gla.ac.uk) + * Changes: + * + * Date: Nov 2002 + * + * Environment: Xen Hypervisor + * Description: This file provides a one stop shop for all time related + * issues within the hypervisor. + * + * The Hypervisor provides the following notions of time: + * Cycle Counter Time, System Time, Wall Clock Time, and + * Domain Virtual Time. + * + **************************************************************************** + * $Id: h-insert.h,v 1.4 2002/11/08 16:03:55 rn Exp $ + **************************************************************************** */ + + #ifndef __XENO_TIME_H__ #define __XENO_TIME_H__ +#include <asm/ptrace.h> /* XXX Only used for do_timer which should be moved */ +#include <asm/time.h> /* pull in architecture specific time definition */ #include <xeno/types.h> -#include <asm/ptrace.h> +/* + * Cycle Counter Time (defined in asm/time.h) + */ + + +/* + * System Time + * 64 bit value containing the nanoseconds elapsed since boot time. + * This value is adjusted by frequency drift. + * NOW() returns the current time. + * The other macros are for convenience to approximate short intervals + * of real time into system time + */ +#define NOW() ((s_time_t)get_s_time()) +#define SECONDS(_s) (((s_time_t)(_s)) * 1000000000UL ) +#define TENTHS(_ts) (((s_time_t)(_ts)) * 100000000UL ) +#define HUNDREDTHS(_hs) (((s_time_t)(_hs)) * 10000000UL ) +#define MILLISECS(_ms) (((s_time_t)(_ms)) * 1000000UL ) +#define MICROSECS(_us) (((s_time_t)(_us)) * 1000UL ) +#define Time_Max ((s_time_t) 0x7fffffffffffffffLL) +#define FOREVER Time_Max + +/* + * Wall Clock Time + */ struct timeval { long tv_sec; /* seconds */ long tv_usec; /* microseconds */ @@ -25,6 +73,13 @@ extern void get_fast_time(struct timeval *tv); extern void (*do_get_fast_time)(struct timeval *); #endif +/* + * Domain Virtual Time (defined in asm/time.h) + */ +/* XXX Interface for getting and setting still missing */ + + +/* XXX move this */ extern void do_timer(struct pt_regs *regs); #endif /* __XENO_TIME_H__ */ diff --git a/xen-2.4.16/include/xeno/timer.h b/xen-2.4.16/include/xeno/timer.h index c4f01ada59..dcde75b182 100644 --- a/xen-2.4.16/include/xeno/timer.h +++ b/xen-2.4.16/include/xeno/timer.h @@ -12,10 +12,17 @@ * The "data" field enables use of a common timeout function for several * timeouts. You can use this field to distinguish between the different * invocations. + * + * RN: Unlike the Linux timers, which are executed at the periodic timer + * interrupt, in Xen, the timer list is only checked "occasionally", thus + * its accuracy might be somewhat worse than under Linux. However, the + * hypervisor should be purely event-driven and, in fact, in the current + * implementation, timers are only used for watchdog purpose at a very + * coarse granularity anyway. Thus this is not a problem. */ struct timer_list { struct list_head list; - unsigned long expires; + unsigned long expires; /* jiffies */ unsigned long data; void (*function)(unsigned long); }; |