diff --git a/.rootkeys b/.rootkeys index 0b14af45da..2de4168cb5 100644 --- a/.rootkeys +++ b/.rootkeys @@ -369,6 +369,15 @@ 40dc4076St6AmPTmQPrtQ6LGHPxGmw tools/python/xen/lowlevel/xu/__init__.py 40dc4076pVeE1kEEWzcUaNZin65kCA tools/python/xen/lowlevel/xu/domain_controller.h 40dc4076CwBYRTUQDdbdU1L6KcLgSw tools/python/xen/lowlevel/xu/xu.c +40fcefb2qm13BbRZBydAatOavaS0fQ tools/python/xen/sv/DomInfo.py +40fcefb2-RIU8GB67mJMRzybME9bxw tools/python/xen/sv/DomList.py +40fcefb23FfQn-ZBCbcHqA0cPGqQxw tools/python/xen/sv/GenTabbed.py +40fcefb2QZAn3u3sX-M7NXBjOv5HGg tools/python/xen/sv/HTMLBase.py +40fcefb2vnfDbl4w_yCTedROPuqs0g tools/python/xen/sv/Main.py +40fcefb24h-04WaHag-Tg4nxWPhTig tools/python/xen/sv/NodeInfo.py +40fcefb2Sif__6AqrANeBQZZfvP-6w tools/python/xen/sv/TabView.py +40fcefb2DqteqCCZYDCvvh4Q5jBd0w tools/python/xen/sv/__init__.py +40fcefb4rnaZNjqsBu7A5V2rlLyqRw tools/python/xen/sv/util.py 40d8915cyoVA0hJxiBFNymL7YvDaRg tools/python/xen/util/Brctl.py 40dfd40aGqGkiopOOgJxSF4iCbHM0Q tools/python/xen/util/__init__.py 4055ee4dwy4l0MghZosxoiu6zmhc9Q tools/python/xen/util/console_client.py @@ -417,33 +426,6 @@ 40c9c469yrm31i60pGKslTi2Zgpotg tools/python/xen/xend/server/messages.py 40c9c46925x-Rjb0Cv2f1-l2jZrPYg tools/python/xen/xend/server/netif.py 40c9c469ZqILEQ8x6yWy0_51jopiCg tools/python/xen/xend/server/params.py -40fcefb2qm13BbRZBydAatOavaS0fQ tools/python/xen/xend/sv/DomInfo.py -40fcefb2-RIU8GB67mJMRzybME9bxw tools/python/xen/xend/sv/DomList.py -40fcefb23FfQn-ZBCbcHqA0cPGqQxw tools/python/xen/xend/sv/GenTabbed.py -40fcefb2QZAn3u3sX-M7NXBjOv5HGg tools/python/xen/xend/sv/HTMLBase.py -40fcefb2vnfDbl4w_yCTedROPuqs0g tools/python/xen/xend/sv/Main.py -40fcefb2K1xqVVT4D-p7nL2GzS4scg tools/python/xen/xend/sv/Main.rpy -40fcefb24h-04WaHag-Tg4nxWPhTig tools/python/xen/xend/sv/NodeInfo.py -40fcefb2Sif__6AqrANeBQZZfvP-6w tools/python/xen/xend/sv/TabView.py -40fcefb23s0sQlDfl4sPP0Un8oZGhg tools/python/xen/xend/sv/XendClientDeferred.py -40fcefb2DqteqCCZYDCvvh4Q5jBd0w tools/python/xen/xend/sv/__init__.py -40fcefb2Nhe-sT74KBB_3mYQg9Dl4Q tools/python/xen/xend/sv/images/internet copy.jpg -40fcefb2QmVa4xdjdnSTXEdF2fZCDA tools/python/xen/xend/sv/images/internet.jpg -40fcefb2g8Ez5jJIPHGN_KX7GtxV4w tools/python/xen/xend/sv/images/internet.psd -40fcefb3wXQMsl9WkgQAVtdrupm4sw tools/python/xen/xend/sv/images/left-end-highlight.jpg -40fcefb3K6ESt5sQhD9aCQRscQIlXQ tools/python/xen/xend/sv/images/left-end-no-highlight.jpg -40fcefb3BUT98zPzW8kAFKuxGdh4XA tools/python/xen/xend/sv/images/middle-highlight.jpg -40fcefb38OTgsUKHBpwshLLIsiIaCA tools/python/xen/xend/sv/images/middle-no-highlight.jpg -40fcefb32SPtrw36c4S6YGFlLvkKuw tools/python/xen/xend/sv/images/orb_01.jpg -40fcefb3Ok5qkX3iM7ZEPVkRInrUpg tools/python/xen/xend/sv/images/orb_02.jpg -40fcefb3JnT5XeKTuVF4yUMGOtuNZg tools/python/xen/xend/sv/images/right-end-highlight.jpg -40fcefb3-DuYOS7noo2W7b_0p7TOUg tools/python/xen/xend/sv/images/right-end-no-highlight.jpg -40fcefb3qNbAZR5FYGPAZ9sFPVMTDA tools/python/xen/xend/sv/images/seperator-left-highlight.jpg -40fcefb3dgsa24WLk_BJeYQHrDLuOg tools/python/xen/xend/sv/images/seperator-right-highlight.jpg -40fcefb3FtiX4Pd2kT8wDlp8u8xRhQ tools/python/xen/xend/sv/images/seperator.jpg -40fcefb3yMSrZvApO9ToIi-iQwnchA tools/python/xen/xend/sv/images/xen.png -40fcefb3zGC9XNBkSwTEobCoq8YClA tools/python/xen/xend/sv/inc/style.css -40fcefb4rnaZNjqsBu7A5V2rlLyqRw tools/python/xen/xend/sv/util.py 40c9c469LNxLVizOUpOjEaTKKCm8Aw tools/python/xen/xend/sxp.py 40d05079aFRp6NQdo5wIh5Ly31c0cg tools/python/xen/xm/__init__.py 40cf2937gKQcATgXKGtNeWb1PDH5nA tools/python/xen/xm/create.py @@ -452,6 +434,21 @@ 40cf2937isyS250zyd0Q2GuEDoNXfQ tools/python/xen/xm/main.py 40cf2937PSslwBliN1g7ofDy2H_RhA tools/python/xen/xm/opts.py 40cf2937Z8WCNOnO2FcWdubvEAF9QQ tools/python/xen/xm/shutdown.py +40fcefb2K1xqVVT4D-p7nL2GzS4scg tools/sv/Main.rpy +40ffbcb66Dj5F-1kCK9BcgSqCWkt1w tools/sv/Makefile +40fcefb3wXQMsl9WkgQAVtdrupm4sw tools/sv/images/left-end-highlight.jpg +40fcefb3K6ESt5sQhD9aCQRscQIlXQ tools/sv/images/left-end-no-highlight.jpg +40fcefb3BUT98zPzW8kAFKuxGdh4XA tools/sv/images/middle-highlight.jpg +40fcefb38OTgsUKHBpwshLLIsiIaCA tools/sv/images/middle-no-highlight.jpg +40fcefb32SPtrw36c4S6YGFlLvkKuw tools/sv/images/orb_01.jpg +40fcefb3Ok5qkX3iM7ZEPVkRInrUpg tools/sv/images/orb_02.jpg +40fcefb3JnT5XeKTuVF4yUMGOtuNZg tools/sv/images/right-end-highlight.jpg +40fcefb3-DuYOS7noo2W7b_0p7TOUg tools/sv/images/right-end-no-highlight.jpg +40fcefb3qNbAZR5FYGPAZ9sFPVMTDA tools/sv/images/seperator-left-highlight.jpg +40fcefb3dgsa24WLk_BJeYQHrDLuOg tools/sv/images/seperator-right-highlight.jpg +40fcefb3FtiX4Pd2kT8wDlp8u8xRhQ tools/sv/images/seperator.jpg +40fcefb3yMSrZvApO9ToIi-iQwnchA tools/sv/images/xen.png +40fcefb3zGC9XNBkSwTEobCoq8YClA tools/sv/inc/style.css 403a3edbrr8RE34gkbR40zep98SXbg tools/xentrace/Makefile 40a107afN60pFdURgBv9KwEzgRl5mQ tools/xentrace/formats 4050c413PhhLNAYk3TEwP37i_iLw9Q tools/xentrace/xentrace.8 diff --git a/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/time.c b/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/time.c index f342466a8b..276a61f695 100644 --- a/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/time.c +++ b/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/time.c @@ -87,14 +87,11 @@ EXPORT_SYMBOL(i8253_lock); struct timer_opts *cur_timer = &timer_none; -/* These are peridically updated in shared_info, and then copied here. */ -static u32 shadow_tsc_stamp; -static u64 shadow_system_time; -static u32 shadow_time_version; -static struct timeval shadow_tv; +extern u64 shadow_system_time; +extern void __get_time_values_from_xen(void); /* Keep track of last time we did processing/updating of jiffies and xtime. */ -static u64 processed_system_time; /* System time (ns) at last processing. */ +u64 processed_system_time; /* System time (ns) at last processing. */ #define NS_PER_TICK (1000000000ULL/HZ) @@ -214,24 +211,6 @@ unsigned long long monotonic_clock(void) EXPORT_SYMBOL(monotonic_clock); -/* - * Reads a consistent set of time-base values from Xen, into a shadow data - * area. Must be called with the xtime_lock held for writing. - */ -static void __get_time_values_from_xen(void) -{ - do { - shadow_time_version = HYPERVISOR_shared_info->time_version2; - rmb(); - shadow_tv.tv_sec = HYPERVISOR_shared_info->wc_sec; - shadow_tv.tv_usec = HYPERVISOR_shared_info->wc_usec; - shadow_tsc_stamp = HYPERVISOR_shared_info->tsc_timestamp.tsc_bits; - shadow_system_time = HYPERVISOR_shared_info->system_time; - rmb(); - } - while ( shadow_time_version != HYPERVISOR_shared_info->time_version1 ); -} - /* * timer_interrupt() needs to keep up the real-time clock, * as well as call the "do_timer()" routine every clocktick @@ -239,8 +218,6 @@ static void __get_time_values_from_xen(void) static inline void do_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - s64 delta; - unsigned long ticks = 0; #ifdef CONFIG_X86_IO_APIC if (timer_ack) { @@ -258,23 +235,8 @@ static inline void do_timer_interrupt(int irq, void *dev_id, } #endif - __get_time_values_from_xen(); - - delta = (s64)(shadow_system_time - processed_system_time); - if (delta < 0) { - printk("Timer ISR: Time went backwards: %lld\n", delta); - return; - } - - /* Process elapsed jiffies since last call. */ - while (delta >= NS_PER_TICK) { - ticks++; - delta -= NS_PER_TICK; - processed_system_time += NS_PER_TICK; - - if (regs) - do_timer_interrupt_hook(regs); - } + if (regs) + do_timer_interrupt_hook(regs); #if 0 /* XEN PRIV */ /* @@ -325,6 +287,8 @@ static inline void do_timer_interrupt(int irq, void *dev_id, */ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { + s64 delta; + /* * Here we are in the timer irq handler. We just have irqs locally * disabled but we don't know if the timer_bh is running on the other @@ -334,10 +298,22 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) */ write_seqlock(&xtime_lock); + __get_time_values_from_xen(); + + delta = (s64)(shadow_system_time - processed_system_time); + if (delta < 0) { + printk("Timer ISR: Time went backwards: %lld\n", delta); + goto out; + } + + if (delta < NS_PER_TICK) + goto out; + cur_timer->mark_offset(); do_timer_interrupt(irq, NULL, regs); + out: write_sequnlock(&xtime_lock); return IRQ_HANDLED; } @@ -447,7 +423,7 @@ void __init time_init(void) #endif xtime.tv_sec = HYPERVISOR_shared_info->wc_sec; wall_to_monotonic.tv_sec = -xtime.tv_sec; - xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ); + xtime.tv_nsec = HYPERVISOR_shared_info->wc_usec * 1000; wall_to_monotonic.tv_nsec = -xtime.tv_nsec; cur_timer = select_timer(); diff --git a/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/timers/timer_tsc.c b/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/timers/timer_tsc.c index fb878535ff..eca23fd677 100644 --- a/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/timers/timer_tsc.c +++ b/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/timers/timer_tsc.c @@ -34,12 +34,9 @@ int tsc_disable __initdata = 0; extern spinlock_t i8253_lock; static int use_tsc; -/* Number of usecs that the last interrupt was delayed */ -static int delay_at_last_interrupt; -static unsigned long last_tsc_low; /* lsb 32 bits of Time Stamp Counter */ -static unsigned long last_tsc_high; /* msb 32 bits of Time Stamp Counter */ static unsigned long long monotonic_base; +static u32 monotonic_offset; static seqlock_t monotonic_lock = SEQLOCK_UNLOCKED; /* convert from cycles(64bits) => nanoseconds (64bits) @@ -85,15 +82,19 @@ static unsigned long fast_gettimeoffset_quotient; /* These are peridically updated in shared_info, and then copied here. */ static u32 shadow_tsc_stamp; -static u64 shadow_system_time; +u64 shadow_system_time; static u32 shadow_time_version; static struct timeval shadow_tv; +static unsigned int rdtsc_bitshift; +extern u64 processed_system_time; + +#define NS_PER_TICK (1000000000ULL/HZ) /* * Reads a consistent set of time-base values from Xen, into a shadow data * area. Must be called with the xtime_lock held for writing. */ -static void __get_time_values_from_xen(void) +void __get_time_values_from_xen(void) { do { shadow_time_version = HYPERVISOR_shared_info->time_version2; @@ -120,16 +121,16 @@ static unsigned long get_offset_tsc(void) rdtsc(eax,edx); /* .. relative to previous jiffy (32 bits is enough) */ - eax -= last_tsc_low; /* tsc_low delta */ + eax -= (shadow_tsc_stamp << rdtsc_bitshift) & 0xffffffff; /* - * Time offset = (tsc_low delta) * fast_gettimeoffset_quotient - * = (tsc_low delta) * (usecs_per_clock) - * = (tsc_low delta) * (usecs_per_jiffy / clocks_per_jiffy) + * Time offset = (tsc_low delta) * fast_gettimeoffset_quotient + * = (tsc_low delta) * (usecs_per_clock) + * = (tsc_low delta) * (usecs_per_jiffy / clocks_per_jiffy) * * Using a mull instead of a divl saves up to 31 clock cycles * in the critical path. - */ + */ __asm__("mull %2" :"=a" (eax), "=d" (edx) @@ -137,7 +138,7 @@ static unsigned long get_offset_tsc(void) "0" (eax)); /* our adjusted time offset in microseconds */ - return delay_at_last_interrupt + edx; + return edx; } static unsigned long long monotonic_clock_tsc(void) @@ -148,7 +149,7 @@ static unsigned long long monotonic_clock_tsc(void) /* atomically read monotonic base & last_offset */ do { seq = read_seqbegin(&monotonic_lock); - last_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low; + last_offset = monotonic_offset << rdtsc_bitshift; base = monotonic_base; } while (read_seqretry(&monotonic_lock, seq)); @@ -186,122 +187,25 @@ unsigned long long sched_clock(void) static void mark_offset_tsc(void) { - unsigned long lost,delay; - unsigned long delta = last_tsc_low; -#if 0 - int count; - int countmp; - static int count1 = 0; -#endif - unsigned long long this_offset, last_offset; - static int lost_count = 0; - + s64 delta; + unsigned int ticks = 0; + write_seqlock(&monotonic_lock); - last_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low; - /* - * It is important that these two operations happen almost at - * the same time. We do the RDTSC stuff first, since it's - * faster. To avoid any inconsistencies, we need interrupts - * disabled locally. - */ - /* - * Interrupts are just disabled locally since the timer irq - * has the SA_INTERRUPT flag set. -arca - */ - - /* read Pentium cycle counter */ + delta = (s64)(shadow_system_time - processed_system_time); - rdtsc(last_tsc_low, last_tsc_high); - -#if 0 - spin_lock(&i8253_lock); - outb_p(0x00, PIT_MODE); /* latch the count ASAP */ - - count = inb_p(PIT_CH0); /* read the latched count */ - count |= inb(PIT_CH0) << 8; - - /* - * VIA686a test code... reset the latch if count > max + 1 - * from timer_pit.c - cjb - */ - if (count > LATCH) { - outb_p(0x34, PIT_MODE); - outb_p(LATCH & 0xff, PIT_CH0); - outb(LATCH >> 8, PIT_CH0); - count = LATCH - 1; + /* Process elapsed jiffies since last call. */ + while (delta >= NS_PER_TICK) { + ticks++; + delta -= NS_PER_TICK; + processed_system_time += NS_PER_TICK; } + jiffies_64 += ticks - 1; - spin_unlock(&i8253_lock); - - if (pit_latch_buggy) { - /* get center value of last 3 time lutch */ - if ((count2 >= count && count >= count1) - || (count1 >= count && count >= count2)) { - count2 = count1; count1 = count; - } else if ((count1 >= count2 && count2 >= count) - || (count >= count2 && count2 >= count1)) { - countmp = count;count = count2; - count2 = count1;count1 = countmp; - } else { - count2 = count1; count1 = count; count = count1; - } - } -#endif - - /* lost tick compensation */ - delta = last_tsc_low - delta; - { - register unsigned long eax, edx; - eax = delta; - __asm__("mull %2" - :"=a" (eax), "=d" (edx) - :"rm" (fast_gettimeoffset_quotient), - "0" (eax)); - delta = edx; - } - delta += delay_at_last_interrupt; - lost = delta/(1000000/HZ); - delay = delta%(1000000/HZ); - if (lost >= 2) { - jiffies_64 += lost-1; - - /* sanity check to ensure we're not always losing ticks */ - if (lost_count++ > 100) { - printk(KERN_WARNING "Losing too many ticks!\n"); - printk(KERN_WARNING "TSC cannot be used as a timesource. \n"); - printk(KERN_WARNING "Possible reasons for this are:\n"); - printk(KERN_WARNING " You're running with Speedstep,\n"); - printk(KERN_WARNING " You don't have DMA enabled for your hard disk (see hdparm),\n"); - printk(KERN_WARNING " Incorrect TSC synchronization on an SMP system (see dmesg).\n"); - printk(KERN_WARNING "Falling back to a sane timesource now.\n"); - - clock_fallback(); - } - /* ... but give the TSC a fair chance */ - if (lost_count > 25) - cpufreq_delayed_get(); - } else - lost_count = 0; /* update the monotonic base value */ - this_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low; - monotonic_base += cycles_2_ns(this_offset - last_offset); + monotonic_base = shadow_system_time; + monotonic_offset = shadow_tsc_stamp; write_sequnlock(&monotonic_lock); - -#if 0 - /* calculate delay_at_last_interrupt */ - count = ((LATCH-1) - count) * TICK_SIZE; - delay_at_last_interrupt = (count + LATCH/2) / LATCH; -#else - delay_at_last_interrupt = 0; -#endif - - /* catch corner case where tick rollover occured - * between tsc and pit reads (as noted when - * usec delta is > 90% # of usecs/tick) - */ - if (lost && abs(delay - delay_at_last_interrupt) > (900000/HZ)) - jiffies_64++; } static void delay_tsc(unsigned long loops) @@ -410,7 +314,7 @@ static unsigned long cpu_khz_ref = 0; static int time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, - void *data) + void *data) { struct cpufreq_freqs *freq = data; @@ -486,9 +390,12 @@ static int __init init_tsc(char* override) "0" (eax), "1" (edx)); } + rdtsc_bitshift = HYPERVISOR_shared_info->tsc_timestamp.tsc_bitshift; + set_cyc2ns_scale(cpu_khz/1000); __get_time_values_from_xen(); + processed_system_time = shadow_system_time; rdtscll(alarm); diff --git a/linux-2.6.7-xen-sparse/drivers/xen/net/network.c b/linux-2.6.7-xen-sparse/drivers/xen/net/network.c index 51646e9c8f..9381595a2d 100644 --- a/linux-2.6.7-xen-sparse/drivers/xen/net/network.c +++ b/linux-2.6.7-xen-sparse/drivers/xen/net/network.c @@ -275,6 +275,9 @@ static void network_alloc_rx_buffers(struct net_device *dev) } while ( (++i - np->rx_resp_cons) != NETIF_RX_RING_SIZE ); + if ( unlikely(nr_pfns == 0) ) + return; + /* * We may have allocated buffers which have entries outstanding in the page * update queue -- make sure we flush those first! diff --git a/tools/Makefile b/tools/Makefile index 58934639bb..e8cdd96672 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -16,6 +16,7 @@ install: all $(MAKE) -C xentrace install $(MAKE) -C python install $(MAKE) -C xfrd install + $(MAKE) -C sv install dist: $(TARGET) $(MAKE) prefix=`pwd`/../../install dist=yes install diff --git a/tools/python/setup.py b/tools/python/setup.py index 82d8a93bb4..7adae6cc94 100644 --- a/tools/python/setup.py +++ b/tools/python/setup.py @@ -42,7 +42,7 @@ setup(name = 'xen', 'xen.util', 'xen.xend', 'xen.xend.server', - 'xen.xend.sv', + 'xen.sv', 'xen.xm', ], ext_package = "xen.lowlevel", diff --git a/tools/python/xen/xend/sv/DomInfo.py b/tools/python/xen/sv/DomInfo.py similarity index 58% rename from tools/python/xen/xend/sv/DomInfo.py rename to tools/python/xen/sv/DomInfo.py index 3c5642a770..42abdee799 100755 --- a/tools/python/xen/xend/sv/DomInfo.py +++ b/tools/python/xen/sv/DomInfo.py @@ -1,20 +1,20 @@ -from HTMLBase import HTMLBase -from XendClientDeferred import server +from xen.xend.XendClient import aserver as server from xen.xend import PrettyPrint -from xen.xend.sv.util import * -from xen.xend.sv.GenTabbed import * +from xen.sv.HTMLBase import HTMLBase +from xen.sv.util import * +from xen.sv.GenTabbed import * class DomInfo( GenTabbed ): - def __init__( self, urlWriter, callback ): + def __init__( self, urlWriter ): self.dom = 0; def tabUrlWriter( tab ): return urlWriter( "mod=info&dom=%s%s" % ( self.dom, tab ) ) - GenTabbed.__init__( self, tabUrlWriter, [ 'General', 'SXP', 'Devices' ], [ DomGenTab, DomSXPTab, NullTab ], callback ) + GenTabbed.__init__( self, tabUrlWriter, [ 'General', 'SXP', 'Devices' ], [ DomGenTab, DomSXPTab, NullTab ] ) def write_BODY( self, request ): dom = request.args.get('dom') @@ -43,7 +43,8 @@ class DomGenTab( GeneralTab ): GeneralTab.__init__( self, "General Domain Info", {}, titles ) - def write_BODY( self, request, callback ): + def write_BODY( self, request ): + dom = request.args.get('dom') if dom is None or len(dom) != 1: @@ -52,14 +53,9 @@ class DomGenTab( GeneralTab ): else: self.dom = dom[0] - deferred = getDomInfoHash( self.dom ) - deferred.addCallback( self.continue_BODY, request, callback ) - - def continue_BODY( self, dict, request, callback ): - - self.dict = dict + self.dict = getDomInfoHash( self.dom ) - GeneralTab.write_BODY( self, request, callback ) + GeneralTab.write_BODY( self, request ) class DomSXPTab( PreTab ): @@ -67,21 +63,8 @@ class DomSXPTab( PreTab ): self.dom = 0 PreTab.__init__( self, "" ) - def fn( self, x, request ): - class tmp: - def __init__( self ): - self.str = "" - def write( self, str ): - self.str = self.str + str - temp = tmp() - PrettyPrint.prettyprint( x, out=temp ) - self.source = temp.str - return request - - def fn2( self, request, callback ): - PreTab.write_BODY( self, request, callback ) - - def write_BODY( self, request, callback ): + + def write_BODY( self, request ): dom = request.args.get('dom') if dom is None or len(dom) != 1: @@ -90,10 +73,10 @@ class DomSXPTab( PreTab ): else: self.dom = dom[0] - deferred = server.xend_domain( self.dom ) + domInfo = server.xend_domain( self.dom ) - deferred.addCallback( self.fn, request ) - deferred.addCallback( self.fn2, callback ) - def errback( x ): - print ">err ", x - deferred.addErrback( errback ) \ No newline at end of file + self.source = sxp2string( domInfo ) + + PreTab.write_BODY( self, request ) + + diff --git a/tools/python/xen/sv/DomList.py b/tools/python/xen/sv/DomList.py new file mode 100755 index 0000000000..ee55957ba6 --- /dev/null +++ b/tools/python/xen/sv/DomList.py @@ -0,0 +1,62 @@ +from xen.xend.XendClient import server +from xen.xend import sxp + +from xen.sv.HTMLBase import HTMLBase +from xen.sv.util import * + +class DomList( HTMLBase ): + + isLeaf = True + + def __init__( self, urlWriter ): + HTMLBase.__init__(self) + self.urlWriter = urlWriter + + def write_BODY( self, request, head=True, long=True ): + + domains = server.xend_domains() + + request.write( "\n\n" ) + + if head: + request.write( "" ) + self.write_DOMAIN_HEAD( request, long ) + request.write( "" ) + + odd = True + + for domain in domains: + if odd: + request.write( "\n" ) + odd = False + else: + request.write( "\n" ) + odd = True + self.write_DOMAIN( request, getDomInfoHash( domain ), long ) + request.write( "\n" ) + + request.write( "
\n" ) + + def write_DOMAIN( self, request, domInfoHash, long=True ): + request.write( "%(dom)-4d\n" % domInfoHash ) + + url = self.urlWriter( "mod=info&dom=%(dom)-4d" % domInfoHash ) + + request.write( "%s\n" % ( url, domInfoHash['name'] ) ) + if long: + request.write( "%(mem)7d\n" % domInfoHash ) + request.write( "%(cpu)3d\n" % domInfoHash ) + request.write( "%(state)5s\n" % domInfoHash ) + if long: + request.write( "%(cpu_time)7.1f\n" % domInfoHash ) + + def write_DOMAIN_HEAD( self, request, long=True ): + request.write( "Domain\n" ) + request.write( "Name\n" ) + if long: + request.write( "Memory / Mb\n" ) + request.write( "CPU\n" ) + request.write( "State\n" ) + if long: + request.write( "CPU time / s\n" ) + diff --git a/tools/python/xen/xend/sv/GenTabbed.py b/tools/python/xen/sv/GenTabbed.py similarity index 82% rename from tools/python/xen/xend/sv/GenTabbed.py rename to tools/python/xen/sv/GenTabbed.py index 4f34a0692c..bfbe5b04cf 100755 --- a/tools/python/xen/xend/sv/GenTabbed.py +++ b/tools/python/xen/sv/GenTabbed.py @@ -1,17 +1,16 @@ import types -from HTMLBase import HTMLBase -from TabView import TabView +from xen.sv.HTMLBase import HTMLBase +from xen.sv.TabView import TabView class GenTabbed( HTMLBase ): - def __init__( self, urlWriter, tabStrings, tabObjects, callback ): + def __init__( self, urlWriter, tabStrings, tabObjects ): HTMLBase.__init__(self) self.tab = 0; self.tabStrings = tabStrings self.tabObjects = tabObjects self.urlWriter = urlWriter - self.callback = callback def write_BODY( self, request, urlWriter = None ): tab = request.args.get('tab') @@ -34,29 +33,23 @@ class GenTabbed( HTMLBase ): request.write( "

Bad Tab

" ) self.finish_BODY( request ) else: - render_tab.write_BODY( request, self.finish_BODY ) + render_tab.write_BODY( request ) - def finish_BODY( self, request ): - request.write( "" ) - self.callback( request ) - class PreTab( HTMLBase ): def __init__( self, source ): HTMLBase.__init__( self ) self.source = source - def write_BODY( self, request, callback ): + def write_BODY( self, request ): request.write( "
" )
         
         request.write( self.source )
         
         request.write( "
" ) - - callback( request ) class GeneralTab( HTMLBase ): @@ -66,7 +59,7 @@ class GeneralTab( HTMLBase ): self.dict = dict self.titles = titles - def write_BODY( self, request, callback ): + def write_BODY( self, request ): request.write( "

%s

" % self.title ) @@ -87,17 +80,14 @@ class GeneralTab( HTMLBase ): writeAttr( niceName, attr ) request.write( "" ) - - callback( request ) - + class NullTab( HTMLBase ): def __init__( self ): HTMLBase.__init__( self ) self.title = "Null Tab" - def write_BODY( self, request, callback ): + def write_BODY( self, request ): request.write( "

%s

" % self.title ) - callback( request ) - - \ No newline at end of file + + diff --git a/tools/python/xen/xend/sv/HTMLBase.py b/tools/python/xen/sv/HTMLBase.py similarity index 58% rename from tools/python/xen/xend/sv/HTMLBase.py rename to tools/python/xen/sv/HTMLBase.py index e127dedac6..4479d7e455 100755 --- a/tools/python/xen/xend/sv/HTMLBase.py +++ b/tools/python/xen/sv/HTMLBase.py @@ -1,27 +1,25 @@ -from twisted.web import server, resource -from twisted.internet import reactor +from twisted.web.resource import Resource + +class HTMLBase( Resource ): -class HTMLBase( resource.Resource ): - isLeaf = True - + def __init__( self ): - resource.Resource.__init__(self) - + Resource.__init__(self) + def render_GET( self, request ): self.write_TOP( request ) - return self.write_BODY( request, self.finish_render_GET ) - - def finish_render_GET( self, request ): + self.write_BODY( request ) self.write_BOTTOM( request ) request.finish() + return '' def write_BODY( self, request ): - request.write( "BODY" ) + request.write( "BODY" ) def write_TOP( self, request ): request.write( 'Xen' ) request.write( '' ) def write_BOTTOM( self, request ): - request.write( "" ) \ No newline at end of file + request.write( "" ) diff --git a/tools/python/xen/xend/sv/Main.py b/tools/python/xen/sv/Main.py similarity index 71% rename from tools/python/xen/xend/sv/Main.py rename to tools/python/xen/sv/Main.py index 366e8a8124..6b9bbfae05 100755 --- a/tools/python/xen/xend/sv/Main.py +++ b/tools/python/xen/sv/Main.py @@ -1,12 +1,5 @@ -from twisted.web import resource -from twisted.web.server import NOT_DONE_YET - -from xen.xend.XendClient import server as XendServer -from xen.xend import sxp - -from HTMLBase import HTMLBase - -from xen.xend.sv import DomList, NodeInfo, DomInfo +from xen.sv.HTMLBase import HTMLBase +from xen.sv import DomList, NodeInfo, DomInfo class Main( HTMLBase ): @@ -21,10 +14,8 @@ class Main( HTMLBase ): def mainUrlWriter( self, s ): return "Main.rpy?%s" % s - def write_BODY( self, request, callback ): + def write_BODY( self, request ): - self.callback = callback - request.write( "\n\n" ) request.write( "\n" ) request.write( " " ) @@ -37,11 +28,8 @@ class Main( HTMLBase ): request.write( "

Node details

" ) request.write( "

Domains summary

" ) - DomList.DomList( self.mainUrlWriter, self.continue_BODY ).write_BODY( request, True, False ) + DomList.DomList( self.mainUrlWriter ).write_BODY( request, True, False ) - return NOT_DONE_YET - - def continue_BODY( self, request ): request.write( " " ) request.write( "
 
" ) request.write( "  " ) @@ -56,18 +44,14 @@ class Main( HTMLBase ): if mod is None or len(mod) != 1: request.write( '

Please select a module

' ) - self.finish_BODY( request ) elif mod[0] == 'info': - DomInfo.DomInfo( self.mainUrlWriter, self.finish_BODY ).write_BODY( request ) + DomInfo.DomInfo( self.mainUrlWriter ).write_BODY( request ) elif mod[0] == 'list': - DomList.DomList( self.mainUrlWriter, self.finish_BODY ).write_BODY( request ) + DomList.DomList( self.mainUrlWriter ).write_BODY( request ) elif mod[0] == 'node': - NodeInfo.NodeInfo( self.mainUrlWriter, self.finish_BODY ).write_BODY( request ) + NodeInfo.NodeInfo( self.mainUrlWriter ).write_BODY( request ) else: request.write( '

Invalid module. Please select another

' ) - self.finish_BODY( request ) - - def finish_BODY( self, request ): request.write( " " ) request.write( " " ) @@ -77,5 +61,3 @@ class Main( HTMLBase ): request.write( "\n" ) - self.callback( request ) - \ No newline at end of file diff --git a/tools/python/xen/xend/sv/NodeInfo.py b/tools/python/xen/sv/NodeInfo.py similarity index 71% rename from tools/python/xen/xend/sv/NodeInfo.py rename to tools/python/xen/sv/NodeInfo.py index 7d69f4eb50..68d050b3bb 100755 --- a/tools/python/xen/xend/sv/NodeInfo.py +++ b/tools/python/xen/sv/NodeInfo.py @@ -1,24 +1,27 @@ -from xen.xend import XendDmesg -from xen.xend import XendNode +from xen.xend.XendClient import server -from xen.xend.sv.util import * -from xen.xend.sv.GenTabbed import * -from xen.xend.sv.HTMLBase import HTMLBase +from xen.sv.util import * +from xen.sv.GenTabbed import * class NodeInfo( GenTabbed ): - def __init__( self, urlWriter, callback ): + def __init__( self, urlWriter ): def newUrlWriter( url ): return urlWriter( "mod=node%s" % url ) - GenTabbed.__init__( self, newUrlWriter, [ 'General', 'Dmesg' ], [ NodeGeneralTab, NodeDmesgTab ], callback ) + GenTabbed.__init__( self, newUrlWriter, [ 'General', 'Dmesg' ], [ NodeGenTab, NodeDmesgTab ] ) +class NodeGenTab( PreTab ): + def __init__( self ): + text = sxp2string( server.xend_node() ) + PreTab.__init__( self, text ) + class NodeGeneralTab( GeneralTab ): def __init__( self ): - nodeInfo = XendNode.instance().info() + nodeInfo = server.xend_node() dictNodeInfo = {} @@ -42,6 +45,6 @@ class NodeGeneralTab( GeneralTab ): class NodeDmesgTab( PreTab ): def __init__( self ): - self.xd = XendDmesg.instance() - PreTab.__init__( self, self.xd.info()[0] ) - \ No newline at end of file + dmesg = server.xend_node_dmesg() + PreTab.__init__( self, dmesg[ 1 ] ) + diff --git a/tools/python/xen/xend/sv/TabView.py b/tools/python/xen/sv/TabView.py similarity index 97% rename from tools/python/xen/xend/sv/TabView.py rename to tools/python/xen/sv/TabView.py index 70c485c329..cada51c4e8 100755 --- a/tools/python/xen/xend/sv/TabView.py +++ b/tools/python/xen/sv/TabView.py @@ -1,4 +1,4 @@ -from xen.xend.sv.HTMLBase import HTMLBase +from xen.sv.HTMLBase import HTMLBase class TabView( HTMLBase ): diff --git a/tools/python/xen/xend/sv/__init__.py b/tools/python/xen/sv/__init__.py similarity index 100% rename from tools/python/xen/xend/sv/__init__.py rename to tools/python/xen/sv/__init__.py diff --git a/tools/python/xen/xend/sv/util.py b/tools/python/xen/sv/util.py similarity index 79% rename from tools/python/xen/xend/sv/util.py rename to tools/python/xen/sv/util.py index 06b7017b0b..47d3519011 100755 --- a/tools/python/xen/xend/sv/util.py +++ b/tools/python/xen/sv/util.py @@ -1,12 +1,9 @@ -from xen.xend.sv.XendClientDeferred import server +from xen.xend.XendClient import server from xen.xend import sxp +from xen.xend import PrettyPrint def getDomInfoHash( domain ): - deferred = server.xend_domain( int( domain ) ) - deferred.addCallback( procDomInfo, domain ) - return deferred - -def procDomInfo( domInfo, domain ): + domInfo = server.xend_domain( int( domain ) ) d = {} d['dom'] = int( domain ) d['name'] = sxp.child_value( domInfo, 'name' ) @@ -19,7 +16,20 @@ def procDomInfo( domInfo, domain ): if( sxp.child_value( domInfo, 'start_time' ) ): d['start_time'] = float( sxp.child_value( domInfo, 'start_time' ) ) return d + +def sxp2hash( sxp ): + pass +def sxp2string( sxp ): + class tmp: + def __init__( self ): + self.str = "" + def write( self, str ): + self.str = self.str + str + temp = tmp() + PrettyPrint.prettyprint( sxp, out=temp ) + return temp.str + def bigTimeFormatter( time ): weeks = time // 604800 remainder = time % 604800 @@ -61,4 +71,4 @@ def hyperthreadFormatter( threads ): if int( threads ) > 1: return "Yes (%d)" % threads else: - return "No" \ No newline at end of file + return "No" diff --git a/tools/python/xen/xend/XendClient.py b/tools/python/xen/xend/XendClient.py index b5ebf557f1..52b8702b28 100644 --- a/tools/python/xen/xend/XendClient.py +++ b/tools/python/xen/xend/XendClient.py @@ -121,12 +121,12 @@ class XendRequest: data = None if method == "POST" and url.path.endswith('/'): url.path = url.path[:-1] - + self.headers = hdr self.data = data self.url = url self.method = method - + class XendClientProtocol: """Abstract class for xend clients. """ @@ -134,18 +134,18 @@ class XendClientProtocol: def xendRequest(self, url, method, args=None): """Make a request to xend. Implement in a subclass. - + @param url: xend request url @param method: http method: POST or GET @param args: request arguments (dict) """ raise NotImplementedError() - + def xendGet(self, url, args=None): """Make a xend request using HTTP GET. Requests using GET are usually 'safe' and may be repeated without nasty side-effects. - + @param url: xend request url @param data: request arguments (dict) """ @@ -156,7 +156,7 @@ class XendClientProtocol: Requests using POST potentially cause side-effects, and should not be repeated unless you really want to repeat the side effect. - + @param url: xend request url @param args: request arguments (dict) """ @@ -198,7 +198,7 @@ class SynchXendClientProtocol(XendClientProtocol): """A synchronous xend client. This will make a request, wait for the reply and return the result. """ - + def xendRequest(self, url, method, args=None): """Make a request to xend. @@ -244,10 +244,10 @@ class AsynchXendClient(http.HTTPClient): def handleStatus(self, version, status, message): return self.protocol.handleStatus(version, status, message) - + def handleResponse(self, data): return self.protocol.handleResponse(data) - + class AsynchXendClientProtocol(XendClientProtocol): """An asynchronous xend client. Uses twisted to connect to xend and make the request. It does not block waiting for the result, @@ -255,6 +255,46 @@ class AsynchXendClientProtocol(XendClientProtocol): Uses AsynchXendClient to manage the connection. """ + def __init__(self): + self.err = None + + def xendRequest(self, url, method, args=None): + """Make a request to xend. The returned deferred is called when + the result is available. + + @param url: xend request url + @param method: http method: POST or GET + @param args: request arguments (dict) + @return: deferred + """ + request = XendRequest(url, method, args) + self.deferred = Deferred() + clientCreator = ClientCreator(reactor, AsynchXendClient, self, request) + clientCreator.connectTCP(url.host, url.port) + return self.deferred + + def callErrback(self, err): + if not self.deferred.called: + self.err = err + self.deferred.errback(err) + return err + + def callCallback(self, val): + if not self.deferred.called: + self.deferred.callback(val) + return val + + def handleException(self, err): + return self.callErrback(err) + + def handleResponse(self, data): + if self.err: return self.err + val = XendClientProtocol.handleResponse(self, data) + if isinstance(val, Exception): + self.callErrback(val) + else: + self.callCallback(val) + return val def __init__(self): self.err = None @@ -365,17 +405,20 @@ class Xend: def xend_node(self): return self.xendGet(self.nodeurl()) + + def xend_node_dmesg(self): + return self.xendGet(self.dmesgurl()) def xend_node_cpu_rrobin_slice_set(self, slice): return self.xendPost(self.nodeurl(), {'op' : 'cpu_rrobin_slice_set', 'slice' : slice }) - + def xend_node_cpu_bvt_slice_set(self, ctx_allow): return self.xendPost(self.nodeurl(), {'op' : 'cpu_bvt_slice_set', 'ctx_allow' : ctx_allow }) - + def xend_node_cpu_fbvt_slice_set(self, ctx_allow): return self.xendPost(self.nodeurl(), {'op' : 'cpu_fbvt_slice_set', @@ -442,7 +485,7 @@ class Xend: 'warp' : warp, 'warpl' : warpl, 'warpu' : warpu }) - + def xend_domain_cpu_fbvt_set(self, id, mcuadv, warp, warpl, warpu): return self.xendPost(self.domainurl(id), {'op' : 'cpu_fbvt_set', @@ -450,7 +493,6 @@ class Xend: 'warp' : warp, 'warpl' : warpl, 'warpu' : warpu }) - def xend_domain_cpu_atropos_set(self, id, period, slice, latency, xtratime): return self.xendPost(self.domainurl(id), @@ -459,20 +501,20 @@ class Xend: 'slice' : slice, 'latency' : latency, 'xtratime': xtratime }) - + def xend_domain_vifs(self, id): return self.xendGet(self.domainurl(id), { 'op' : 'vifs' }) - + def xend_domain_vif(self, id, vif): return self.xendGet(self.domainurl(id), { 'op' : 'vif', 'vif' : vif }) - + def xend_domain_vbds(self, id): return self.xendGet(self.domainurl(id), {'op' : 'vbds'}) - + def xend_domain_vbd(self, id, vbd): return self.xendGet(self.domainurl(id), {'op' : 'vbd', @@ -488,7 +530,7 @@ class Xend: {'op' : 'device_destroy', 'type' : type, 'index' : idx }) - + def xend_consoles(self): return self.xendGet(self.consoleurl()) @@ -517,7 +559,6 @@ class Xend: def xend_dmesg(self): return self.xendGet(self.dmesgurl()) - def xendmain(srv, asynch, fn, args): if asynch: @@ -549,15 +590,15 @@ def xendmain(srv, asynch, fn, args): def main(argv): """Call an API function: - + python XendClient.py fn args... The leading 'xend_' on the function can be omitted. Example: - > python XendClient.py domains +python XendClient.py domains (0 8) - > python XendClient.py domain 0 +python XendClient.py domain 0 (domain (id 0) (name Domain-0) (memory 128)) """ global DEBUG @@ -588,3 +629,4 @@ if __name__ == "__main__": main(sys.argv) else: server = Xend() + aserver = Xend( AsynchXendClientProtocol() ) diff --git a/tools/python/xen/xend/server/SrvServer.py b/tools/python/xen/xend/server/SrvServer.py index 1ce3446058..d1aed29c6b 100644 --- a/tools/python/xen/xend/server/SrvServer.py +++ b/tools/python/xen/xend/server/SrvServer.py @@ -44,12 +44,8 @@ def create(port=None, interface=None, bridge=0): if bridge or xroot.rebooted: Vifctl.network('start') root = resource.Resource() - sv = static.File( "/usr/lib/python2.2/site-packages/xen/xend/sv/" ) - sv.indexNames=['Main.rpy'] - sv.processors={'.rpy':script.ResourceScript} xend = SrvRoot() root.putChild('xend', xend) - root.putChild('sv', sv) site = server.Site(root) reactor.listenTCP(port, site, interface=interface) diff --git a/tools/python/xen/xend/sv/DomList.py b/tools/python/xen/xend/sv/DomList.py deleted file mode 100755 index 8fa74dff93..0000000000 --- a/tools/python/xen/xend/sv/DomList.py +++ /dev/null @@ -1,101 +0,0 @@ -from twisted.web import resource -from twisted.web.server import NOT_DONE_YET - -from XendClientDeferred import server as XendServer -from xen.xend import sxp - -from xen.xend.sv.HTMLBase import HTMLBase -from xen.xend.sv.util import * - -from twisted.internet import reactor - -class DomList( HTMLBase ): - - isLeaf = True - - def __init__( self, urlWriter, callback ): - HTMLBase.__init__(self) - self.urlWriter = urlWriter - self.head = None - self.long = None - self.rendered_domains = {} - self.domCount = 0 - self.callback = callback - - def write_BODY( self, request, head=True, long=True ): - deferred = XendServer.xend_domains() - deferred.addCallback( self.get_domain_info, request ) - deferred.addErrback( self.errback ) - - self.head = head - self.long = long - - def errback( self, err ): - print 'errback>', err - - def get_domain_info( self, domains, request ): - - self.domCount = len( domains ) - - for domain in domains: - deferred = getDomInfoHash( domain ) - deferred.addCallback( self.render_domain, request ) - deferred.addErrback( self.errback ) - - def render_domain( self, domInfoHash, request ): - - domStr = "%(dom)-4d\n" % domInfoHash - - url = self.urlWriter( "mod=info&dom=%(dom)-4d" % domInfoHash ) - - domStr += "%s\n" % ( url, domInfoHash['name'] ) - - if self.long: - domStr += "%(mem)7d\n" % domInfoHash - domStr += "%(cpu)3d\n" % domInfoHash - - domStr += "%(state)5s\n" % domInfoHash - - if self.long: - domStr += "%(cpu_time)7.1f\n" % domInfoHash - - self.rendered_domains[ domInfoHash[ 'dom' ] ] = domStr - self.domCount -= 1 - - if self.domCount == 0: - self.finish_write_BODY( request ) - - def finish_write_BODY( self, request ): - - request.write( "\n\n" ) - - if self.head: - request.write( "" ) - self.write_DOMAIN_HEAD( request, self.long ) - request.write( "" ) - - odd = True - for domain in self.rendered_domains.values(): - if odd: - request.write( "\n" ) - odd = False - else: - request.write( "\n" ) - odd = True - request.write( domain ) - request.write( "\n" ) - - request.write( "
\n" ) - - self.callback( request ) - - def write_DOMAIN_HEAD( self, request, long=True ): - request.write( "Domain\n" ) - request.write( "Name\n" ) - if long: - request.write( "Memory / Mb\n" ) - request.write( "CPU\n" ) - request.write( "State\n" ) - if long: - request.write( "CPU time / s\n" ) - diff --git a/tools/python/xen/xend/sv/Main.rpy b/tools/python/xen/xend/sv/Main.rpy deleted file mode 100755 index 90698027a6..0000000000 --- a/tools/python/xen/xend/sv/Main.rpy +++ /dev/null @@ -1,3 +0,0 @@ -from xen.xend.sv.Main import * - -resource = Main() \ No newline at end of file diff --git a/tools/python/xen/xend/sv/XendClientDeferred.py b/tools/python/xen/xend/sv/XendClientDeferred.py deleted file mode 100755 index 9f8a16d129..0000000000 --- a/tools/python/xen/xend/sv/XendClientDeferred.py +++ /dev/null @@ -1,363 +0,0 @@ -# Copyright (C) 2004 Tom Wilkie -# Copyright (C) 2004 Mike Wray -"""Client API for the HTTP interface on xend. -Callable as a script - see main(). - -This API is the 'control-plane' for xend. -The 'data-plane' is done separately. For example, consoles -are accessed via sockets on xend, but the list of consoles -is accessible via this API. - -This one is similar to mikes, but works in an async fashion -""" -import sys -import httplib -import types -from StringIO import StringIO -import urlparse - -from xen.xend.encode import * -from xen.xend.sxp import * -from xen.xend.PrettyPrint import prettyprint - -from twisted.protocols.http import HTTPClient -from twisted.internet.protocol import ClientCreator -from twisted.internet.defer import Deferred -from twisted.internet import reactor - -DEBUG = 0 - -class XendRequest( HTTPClient ): - def __init__(self, deferred, urls): - self.urls = urls - self.deferred = deferred - - def connectionMade(self): - self.sendCommand('GET', self.urls[2]) - self.sendHeader('Host', '%s:%d' % (self.urls[0], self.urls[1]) ) - self.endHeaders() - - def handleResponse(self, data): - self.deferred.callback( data ) - -def process_SXP( sexp ): - pin = Parser() - pin.input(sexp) - pin.input_eof() - return pin.get_val() - -def xend_request(url, method, data=None): - """Make a request to xend. - - url xend request url - method http method: POST or GET - data request argument data (dict) - """ - urlinfo = urlparse.urlparse(url) - (uproto, ulocation, upath, uparam, uquery, ufrag) = urlinfo - (hdr, args) = encode_data(data) - if data and method == 'GET': - upath += '?' + args - args = None - if method == "POST" and upath.endswith('/'): - upath = upath[:-1] - - deferred = Deferred() - - clientCreator = ClientCreator( reactor, XendRequest, deferred, (ulocation, 8000, upath) ) - clientCreator.connectTCP( ulocation, 8000 ) - - deferred.addCallback( process_SXP ) - - return deferred - -class XendError(RuntimeError): - pass - -class Foo(httplib.HTTPResponse): - - def begin(self): - fin = self.fp - while(1): - buf = fin.readline() - print "***", buf - if buf == '': - print - sys.exit() - - -def sxprio(sxpr): - """Convert an sxpr to a string. - """ - io = StringIO() - sxp.show(sxpr, out=io) - print >> io - io.seek(0) - return io - -def fileof(val): - """Converter for passing configs. - Handles lists, files directly. - Assumes a string is a file name and passes its contents. - """ - if isinstance(val, types.ListType): - return sxprio(val) - if isinstance(val, types.StringType): - return file(val) - if hasattr(val, 'readlines'): - return val - -# todo: need to sort of what urls/paths are using for objects. -# e.g. for domains at the moment return '0'. -# should probably return abs path w.r.t. server, e.g. /xend/domain/0. -# As an arg, assume abs path is obj uri, otherwise just id. - -# Function to convert to full url: Xend.uri(path), e.g. -# maps /xend/domain/0 to http://wray-m-3.hpl.hp.com:8000/xend/domain/0 -# And should accept urls for ids? - -def urljoin(location, root, prefix='', rest=''): - prefix = str(prefix) - rest = str(rest) - base = 'http://' + location + root + prefix - url = urlparse.urljoin(base, rest) - return url - -def nodeurl(location, root, id=''): - return urljoin(location, root, 'node/', id) - -def domainurl(location, root, id=''): - return urljoin(location, root, 'domain/', id) - -def consoleurl(location, root, id=''): - return urljoin(location, root, 'console/', id) - -def deviceurl(location, root, id=''): - return urljoin(location, root, 'device/', id) - -def vneturl(location, root, id=''): - return urljoin(location, root, 'vnet/', id) - -def eventurl(location, root, id=''): - return urljoin(location, root, 'event/', id) - -def xend_get(url, args=None): - """Make a xend request using GET. - Requests using GET are 'safe' and may be repeated without - nasty side-effects. - """ - return xend_request(url, "GET", args) - -def xend_call(url, data): - """Make xend request using POST. - Requests using POST potentially cause side-effects and should - not be repeated unless it really is wanted to do the side - effect again. - """ - return xend_request(url, "POST", data) - -class Xend: - - """Default location of the xend server.""" - SRV_DEFAULT = "localhost" - - """Default path to the xend root on the server.""" - ROOT_DEFAULT = "/xend/" - - def __init__(self, srv=None, root=None): - self.bind(srv, root) - - def bind(self, srv=None, root=None): - """Bind to a given server. - - srv server location (host:port) - root server xend root path - """ - if srv is None: srv = self.SRV_DEFAULT - if root is None: root = self.ROOT_DEFAULT - if not root.endswith('/'): root += '/' - self.location = srv - self.root = root - - def nodeurl(self, id=''): - return nodeurl(self.location, self.root, id) - - def domainurl(self, id=''): - return domainurl(self.location, self.root, id) - - def consoleurl(self, id=''): - return consoleurl(self.location, self.root, id) - - def deviceurl(self, id=''): - return deviceurl(self.location, self.root, id) - - def vneturl(self, id=''): - return vneturl(self.location, self.root, id) - - def eventurl(self, id=''): - return eventurl(self.location, self.root, id) - - def xend(self): - return xend_get(urljoin(self.location, self.root)) - - def xend_node(self): - return xend_get(self.nodeurl()) - - def xend_node_cpu_rrobin_slice_set(self, slice): - return xend_call(self.nodeurl(), - {'op' : 'cpu_rrobin_slice_set', - 'slice' : slice }) - - def xend_node_cpu_bvt_slice_set(self, ctx_allow): - return xend_call(self.nodeurl(), - {'op' : 'cpu_bvt_slice_set', - 'ctx_allow' : ctx_allow }) - - def xend_node_cpu_fbvt_slice_set(self, ctx_allow): - return xend_call(self.nodeurl(), - {'op' : 'cpu_fbvt_slice_set', - 'ctx_allow' : ctx_allow }) - - def xend_domains(self): - return xend_get(self.domainurl()) - - def xend_domain_create(self, conf): - return xend_call(self.domainurl(), - {'op' : 'create', - 'config' : fileof(conf) }) - - def xend_domain(self, id): - return xend_get(self.domainurl(id)) - - def xend_domain_unpause(self, id): - return xend_call(self.domainurl(id), - {'op' : 'unpause'}) - - def xend_domain_pause(self, id): - return xend_call(self.domainurl(id), - {'op' : 'pause'}) - - def xend_domain_shutdown(self, id, reason): - return xend_call(self.domainurl(id), - {'op' : 'shutdown', - 'reason' : reason }) - - def xend_domain_destroy(self, id): - return xend_call(self.domainurl(id), - {'op' : 'destroy'}) - - def xend_domain_save(self, id, filename): - return xend_call(self.domainurl(id), - {'op' : 'save', - 'file' : filename}) - - def xend_domain_restore(self, id, filename): - return xend_call(self.domainurl(id), - {'op' : 'restore', - 'file' : filename }) - - def xend_domain_migrate(self, id, dst): - return xend_call(self.domainurl(id), - {'op' : 'migrate', - 'destination': dst}) - - def xend_domain_pincpu(self, id, cpu): - return xend_call(self.domainurl(id), - {'op' : 'pincpu', - 'cpu' : cpu}) - - def xend_domain_cpu_bvt_set(self, id, mcuadv, warp, warpl, warpu): - return xend_call(self.domainurl(id), - {'op' : 'cpu_bvt_set', - 'mcuadv' : mcuadv, - 'warp' : warp, - 'warpl' : warpl, - 'warpu' : warpu }) - - def xend_domain_cpu_fbvt_set(self, id, mcuadv, warp, warpl, warpu): - return xend_call(self.domainurl(id), - {'op' : 'cpu_fbvt_set', - 'mcuadv' : mcuadv, - 'warp' : warp, - 'warpl' : warpl, - 'warpu' : warpu }) - - - def xend_domain_cpu_atropos_set(self, id, period, slice, latency, xtratime): - return xend_call(self.domainurl(id), - {'op' : 'cpu_atropos_set', - 'period' : period, - 'slice' : slice, - 'latency' : latency, - 'xtratime': xtratime }) - - def xend_domain_vifs(self, id): - return xend_get(self.domainurl(id), - { 'op' : 'vifs' }) - - def xend_domain_vif_ip_add(self, id, vif, ipaddr): - return xend_call(self.domainurl(id), - {'op' : 'vif_ip_add', - 'vif' : vif, - 'ip' : ipaddr }) - - def xend_domain_vbds(self, id): - return xend_get(self.domainurl(id), - {'op' : 'vbds'}) - - def xend_domain_vbd(self, id, vbd): - return xend_get(self.domainurl(id), - {'op' : 'vbd', - 'vbd' : vbd}) - - def xend_consoles(self): - return xend_get(self.consoleurl()) - - def xend_console(self, id): - return xend_get(self.consoleurl(id)) - - def xend_vnets(self): - return xend_get(self.vneturl()) - - def xend_vnet_create(self, conf): - return xend_call(self.vneturl(), - {'op': 'create', 'config': fileof(conf) }) - - def xend_vnet(self, id): - return xend_get(self.vneturl(id)) - - def xend_vnet_delete(self, id): - return xend_call(self.vneturl(id), - {'op': 'delete'}) - - def xend_event_inject(self, sxpr): - val = xend_call(self.eventurl(), - {'op': 'inject', 'event': fileof(sxpr) }) - -def main(argv): - """Call an API function: - - python XendClient.py fn args... - - The leading 'xend_' on the function can be omitted. - Example: - - > python XendClient.py domains - (domain 0 8) - > python XendClient.py domain 0 - (domain (id 0) (name Domain-0) (memory 128)) - """ - server = Xend() - fn = argv[1] - if not fn.startswith('xend'): - fn = 'xend_' + fn - args = argv[2:] - deferred = getattr(server, fn)(*args) - deferred.addCallback( prettyprint ) - reactor.run() - print - -if __name__ == "__main__": - main(sys.argv) -else: - server = Xend() diff --git a/tools/python/xen/xend/sv/images/internet copy.jpg b/tools/python/xen/xend/sv/images/internet copy.jpg deleted file mode 100755 index 92eafeb9fe..0000000000 Binary files a/tools/python/xen/xend/sv/images/internet copy.jpg and /dev/null differ diff --git a/tools/python/xen/xend/sv/images/internet.jpg b/tools/python/xen/xend/sv/images/internet.jpg deleted file mode 100755 index 74a03c3a78..0000000000 Binary files a/tools/python/xen/xend/sv/images/internet.jpg and /dev/null differ diff --git a/tools/python/xen/xend/sv/images/internet.psd b/tools/python/xen/xend/sv/images/internet.psd deleted file mode 100644 index a2e9d1754f..0000000000 Binary files a/tools/python/xen/xend/sv/images/internet.psd and /dev/null differ diff --git a/tools/sv/Main.rpy b/tools/sv/Main.rpy new file mode 100755 index 0000000000..6b75ea9431 --- /dev/null +++ b/tools/sv/Main.rpy @@ -0,0 +1,3 @@ +from xen.sv.Main import Main + +resource = Main() diff --git a/tools/sv/Makefile b/tools/sv/Makefile new file mode 100755 index 0000000000..0321a566f3 --- /dev/null +++ b/tools/sv/Makefile @@ -0,0 +1,39 @@ +sv_insdir := $(prefix)/var/xen/sv + +all: + +install: + # make parent directory + mkdir -p $(sv_insdir) + + # copy Main.rpy file - references xen.sv.Main class + install -m0644 Main.rpy $(sv_insdir) + + # make images folder + mkdir -p $(sv_insdir)/images + + # copy images + install -m0644 images/xen.png $(sv_insdir)/images + install -m0644 images/orb_01.jpg $(sv_insdir)/images + install -m0644 images/orb_02.jpg $(sv_insdir)/images + + install -m0644 images/left-end-highlight.jpg $(sv_insdir)/images + install -m0644 images/left-end-no-highlight.jpg $(sv_insdir)/images + install -m0644 images/right-end-highlight.jpg $(sv_insdir)/images + install -m0644 images/right-end-no-highlight.jpg $(sv_insdir)/images + + install -m0644 images/middle-highlight.jpg $(sv_insdir)/images + install -m0644 images/middle-no-highlight.jpg $(sv_insdir)/images + + install -m0644 images/seperator.jpg $(sv_insdir)/images + install -m0644 images/seperator-left-highlight.jpg $(sv_insdir)/images + install -m0644 images/seperator-right-highlight.jpg $(sv_insdir)/images + + # make include folder + mkdir -p $(sv_insdir)/inc + + # copy stylesheet + install -m0644 inc/style.css $(sv_insdir)/inc + +clean: + diff --git a/tools/python/xen/xend/sv/images/left-end-highlight.jpg b/tools/sv/images/left-end-highlight.jpg similarity index 100% rename from tools/python/xen/xend/sv/images/left-end-highlight.jpg rename to tools/sv/images/left-end-highlight.jpg diff --git a/tools/python/xen/xend/sv/images/left-end-no-highlight.jpg b/tools/sv/images/left-end-no-highlight.jpg similarity index 100% rename from tools/python/xen/xend/sv/images/left-end-no-highlight.jpg rename to tools/sv/images/left-end-no-highlight.jpg diff --git a/tools/python/xen/xend/sv/images/middle-highlight.jpg b/tools/sv/images/middle-highlight.jpg similarity index 100% rename from tools/python/xen/xend/sv/images/middle-highlight.jpg rename to tools/sv/images/middle-highlight.jpg diff --git a/tools/python/xen/xend/sv/images/middle-no-highlight.jpg b/tools/sv/images/middle-no-highlight.jpg similarity index 100% rename from tools/python/xen/xend/sv/images/middle-no-highlight.jpg rename to tools/sv/images/middle-no-highlight.jpg diff --git a/tools/python/xen/xend/sv/images/orb_01.jpg b/tools/sv/images/orb_01.jpg similarity index 100% rename from tools/python/xen/xend/sv/images/orb_01.jpg rename to tools/sv/images/orb_01.jpg diff --git a/tools/python/xen/xend/sv/images/orb_02.jpg b/tools/sv/images/orb_02.jpg similarity index 100% rename from tools/python/xen/xend/sv/images/orb_02.jpg rename to tools/sv/images/orb_02.jpg diff --git a/tools/python/xen/xend/sv/images/right-end-highlight.jpg b/tools/sv/images/right-end-highlight.jpg similarity index 100% rename from tools/python/xen/xend/sv/images/right-end-highlight.jpg rename to tools/sv/images/right-end-highlight.jpg diff --git a/tools/python/xen/xend/sv/images/right-end-no-highlight.jpg b/tools/sv/images/right-end-no-highlight.jpg similarity index 100% rename from tools/python/xen/xend/sv/images/right-end-no-highlight.jpg rename to tools/sv/images/right-end-no-highlight.jpg diff --git a/tools/python/xen/xend/sv/images/seperator-left-highlight.jpg b/tools/sv/images/seperator-left-highlight.jpg similarity index 100% rename from tools/python/xen/xend/sv/images/seperator-left-highlight.jpg rename to tools/sv/images/seperator-left-highlight.jpg diff --git a/tools/python/xen/xend/sv/images/seperator-right-highlight.jpg b/tools/sv/images/seperator-right-highlight.jpg similarity index 100% rename from tools/python/xen/xend/sv/images/seperator-right-highlight.jpg rename to tools/sv/images/seperator-right-highlight.jpg diff --git a/tools/python/xen/xend/sv/images/seperator.jpg b/tools/sv/images/seperator.jpg similarity index 100% rename from tools/python/xen/xend/sv/images/seperator.jpg rename to tools/sv/images/seperator.jpg diff --git a/tools/python/xen/xend/sv/images/xen.png b/tools/sv/images/xen.png similarity index 100% rename from tools/python/xen/xend/sv/images/xen.png rename to tools/sv/images/xen.png diff --git a/tools/python/xen/xend/sv/inc/style.css b/tools/sv/inc/style.css similarity index 100% rename from tools/python/xen/xend/sv/inc/style.css rename to tools/sv/inc/style.css diff --git a/tools/xfrd/Makefile b/tools/xfrd/Makefile index 6e9b4b6681..e62fd9f1d4 100644 --- a/tools/xfrd/Makefile +++ b/tools/xfrd/Makefile @@ -35,6 +35,8 @@ XFRD_PROG_OBJ += $(UTIL_LIB) # Define to use stubs, undefine to use the real Xen functions. #CPPFLAGS += -D _XEN_XFR_STUB_ +CC := gcc + CFLAGS += -g CFLAGS += -Wall CFALGS += -Werror @@ -67,7 +69,7 @@ XFRD_LIBS += $(CURL_LIBS) all: xfrd xfrd: $(XFRD_PROG_OBJ) - $(CC) -o $@ $^ $(XFRD_LIBS) + $(CC) -shared -o $@ $^ $(XFRD_LIBS) .PHONY: install install: xfrd diff --git a/xen/arch/x86/memory.c b/xen/arch/x86/memory.c index 960bf5aaf4..cd7ae9b2c6 100644 --- a/xen/arch/x86/memory.c +++ b/xen/arch/x86/memory.c @@ -164,9 +164,8 @@ static void __invalidate_shadow_ldt(struct domain *d) } -static inline void invalidate_shadow_ldt(void) +static inline void invalidate_shadow_ldt(struct domain *d) { - struct domain *d = current; if ( d->mm.shadow_ldt_mapcnt != 0 ) __invalidate_shadow_ldt(d); } @@ -387,7 +386,7 @@ static void put_page_from_l1e(l1_pgentry_t l1e) if ( unlikely(((page->type_and_flags & PGT_type_mask) == PGT_ldt_page)) && unlikely(((page->type_and_flags & PGT_count_mask) != 0)) ) - invalidate_shadow_ldt(); + invalidate_shadow_ldt(page->u.domain); put_page(page); } } @@ -748,7 +747,7 @@ static int do_extended_command(unsigned long ptr, unsigned long val) okay = get_page_and_type_from_pagenr(pfn, PGT_l2_page_table, d); if ( likely(okay) ) { - invalidate_shadow_ldt(); + invalidate_shadow_ldt(d); percpu_info[cpu].deferred_ops &= ~DOP_FLUSH_TLB; old_base_pfn = pagetable_val(d->mm.pagetable) >> PAGE_SHIFT; @@ -795,7 +794,7 @@ static int do_extended_command(unsigned long ptr, unsigned long val) else if ( (d->mm.ldt_ents != ents) || (d->mm.ldt_base != ptr) ) { - invalidate_shadow_ldt(); + invalidate_shadow_ldt(d); d->mm.ldt_base = ptr; d->mm.ldt_ents = ents; load_LDT(d); diff --git a/xen/common/memory.c b/xen/common/memory.c index d925e05adc..039d0b0e3c 100644 --- a/xen/common/memory.c +++ b/xen/common/memory.c @@ -80,15 +80,13 @@ void __init init_frametable(void *frametable_vstart, unsigned long nr_pages) void add_to_domain_alloc_list(unsigned long ps, unsigned long pe) { - struct pfn_info *pf; unsigned long i; unsigned long flags; spin_lock_irqsave(&free_list_lock, flags); for ( i = ps >> PAGE_SHIFT; i < (pe >> PAGE_SHIFT); i++ ) { - pf = list_entry(&frame_table[i].list, struct pfn_info, list); - list_add_tail(&pf->list, &free_list); + list_add_tail(&frame_table[i].list, &free_list); free_pfns++; } spin_unlock_irqrestore(&free_list_lock, flags); diff --git a/xen/common/sched_bvt.c b/xen/common/sched_bvt.c index b67aa72d92..3baf8cb9c4 100644 --- a/xen/common/sched_bvt.c +++ b/xen/common/sched_bvt.c @@ -25,6 +25,7 @@ #include #include #include +#include /* all per-domain BVT-specific scheduling info is stored here */ struct bvt_dom_info @@ -145,24 +146,6 @@ void bvt_free_task(struct domain *p) } -void bvt_wake_up(struct domain *p) -{ - struct bvt_dom_info *inf = BVT_INFO(p); - - ASSERT(inf != NULL); - - - /* set the BVT parameters */ - if (inf->avt < CPU_SVT(p->processor)) - inf->avt = CPU_SVT(p->processor); - - /* deal with warping here */ - inf->warpback = 1; - inf->warped = NOW(); - __calc_evt(inf); - __add_to_runqueue_head(p); -} - /* * Block the currently-executing domain until a pertinent event occurs. */ @@ -433,10 +416,47 @@ int bvt_init_scheduler() return 0; } -static void bvt_pause(struct domain *p) +static void bvt_sleep(struct domain *d) { - if( __task_on_runqueue(p) ) - __del_from_runqueue(p); + if ( test_bit(DF_RUNNING, &d->flags) ) + cpu_raise_softirq(d->processor, SCHEDULE_SOFTIRQ); + else if ( __task_on_runqueue(d) ) + __del_from_runqueue(d); +} + +void bvt_wake(struct domain *d) +{ + struct bvt_dom_info *inf = BVT_INFO(d); + struct domain *curr; + s_time_t now, min_time; + int cpu = d->processor; + + /* If on the runqueue already then someone has done the wakeup work. */ + if ( unlikely(__task_on_runqueue(d)) ) + return; + + __add_to_runqueue_head(d); + + now = NOW(); + + /* Set the BVT parameters. */ + if ( inf->avt < CPU_SVT(cpu) ) + inf->avt = CPU_SVT(cpu); + + /* Deal with warping here. */ + inf->warpback = 1; + inf->warped = now; + __calc_evt(inf); + + curr = schedule_data[cpu].curr; + + /* Currently-running domain should run at least for ctx_allow. */ + min_time = curr->lastschd + curr->min_slice; + + if ( is_idle_task(curr) || (min_time <= now) ) + cpu_raise_softirq(cpu, SCHEDULE_SOFTIRQ); + else if ( schedule_data[cpu].s_timer.expires > (min_time + TIME_SLOP) ) + mod_ac_timer(&schedule_data[cpu].s_timer, min_time); } struct scheduler sched_bvt_def = { @@ -448,7 +468,6 @@ struct scheduler sched_bvt_def = { .alloc_task = bvt_alloc_task, .add_task = bvt_add_task, .free_task = bvt_free_task, - .wake_up = bvt_wake_up, .do_block = bvt_do_block, .do_schedule = bvt_do_schedule, .control = bvt_ctl, @@ -456,6 +475,7 @@ struct scheduler sched_bvt_def = { .dump_settings = bvt_dump_settings, .dump_cpu_state = bvt_dump_cpu_state, .dump_runq_el = bvt_dump_runq_el, - .pause = bvt_pause, + .sleep = bvt_sleep, + .wake = bvt_wake, }; diff --git a/xen/common/sched_fair_bvt.c b/xen/common/sched_fair_bvt.c index a7aa0335cf..04ae055b43 100644 --- a/xen/common/sched_fair_bvt.c +++ b/xen/common/sched_fair_bvt.c @@ -26,11 +26,12 @@ #include #include #include +#include #include /* For tracing - TODO - put all the defines in some common hearder file */ #define TRC_SCHED_FBVT_DO_SCHED 0x00020000 - +#define TRC_SCHED_FBVT_DO_SCHED_UPDATE 0x00020001 /* all per-domain BVT-specific scheduling info is stored here */ struct fbvt_dom_info @@ -38,8 +39,7 @@ struct fbvt_dom_info unsigned long mcu_advance; /* inverse of weight */ u32 avt; /* actual virtual time */ u32 evt; /* effective virtual time */ - u32 time_slept; /* records amount of time slept, used for scheduling */ - u32 vtb; /* virtual time bonus */ + u32 time_slept; /* amount of time slept */ int warpback; /* warp? */ long warp; /* virtual time warp */ long warpl; /* warp limit */ @@ -50,18 +50,23 @@ struct fbvt_dom_info struct fbvt_cpu_info { - unsigned long svt; /* XXX check this is unsigned long! */ + unsigned long svt; /* XXX check this is unsigned long! */ + u32 vtb; /* virtual time bonus */ + u32 r_time; /* last time to run */ }; -#define FBVT_INFO(p) ((struct fbvt_dom_info *)(p)->sched_priv) +#define FBVT_INFO(p) ((struct fbvt_dom_info *)(p)->sched_priv) #define CPU_INFO(cpu) ((struct fbvt_cpu_info *)(schedule_data[cpu]).sched_priv) #define CPU_SVT(cpu) (CPU_INFO(cpu)->svt) +#define LAST_VTB(cpu) (CPU_INFO(cpu)->vtb) +#define R_TIME(cpu) (CPU_INFO(cpu)->r_time) #define MCU (s32)MICROSECS(100) /* Minimum unit */ #define MCU_ADVANCE 10 /* default weight */ #define TIME_SLOP (s32)MICROSECS(50) /* allow time to slip a bit */ static s32 ctx_allow = (s32)MILLISECS(5); /* context switch allowance */ +static s32 max_vtb = (s32)MILLISECS(5); /* SLAB cache for struct fbvt_dom_info objects */ static kmem_cache_t *dom_info_cache; @@ -132,8 +137,7 @@ void fbvt_add_task(struct domain *p) inf->avt = CPU_SVT(p->processor); inf->evt = CPU_SVT(p->processor); /* Set some default values here. */ - inf->vtb = 0; - inf->time_slept = 0; + inf->time_slept = 0; inf->warpback = 0; inf->warp = 0; inf->warpl = 0; @@ -153,43 +157,6 @@ void fbvt_free_task(struct domain *p) kmem_cache_free( dom_info_cache, p->sched_priv ); } - -void fbvt_wake_up(struct domain *p) -{ - struct fbvt_dom_info *inf = FBVT_INFO(p); - s32 io_warp; - - ASSERT(inf != NULL); - - - /* set the BVT parameters */ - if (inf->avt < CPU_SVT(p->processor)) - { - /* - *We want IO bound processes to gain - *dispatch precedence. It is especially for - *device driver domains. Therefore AVT should not be updated - *to SVT but to a value marginally smaller. - *Since frequently sleeping domains have high time_slept - *values, the virtual time can be determined as: - *SVT - const * TIME_SLEPT - */ - - io_warp = (int)(0.5 * inf->time_slept); - if(io_warp > 1000) io_warp = 1000; - - ASSERT(inf->time_slept + CPU_SVT(p->processor) > inf->avt + io_warp); - inf->time_slept += CPU_SVT(p->processor) - inf->avt - io_warp; - inf->avt = CPU_SVT(p->processor) - io_warp; - } - - /* deal with warping here */ - inf->warpback = 1; - inf->warped = NOW(); - __calc_evt(inf); - __add_to_runqueue_head(p); -} - /* * Block the currently-executing domain until a pertinent event occurs. */ @@ -206,6 +173,8 @@ int fbvt_ctl(struct sched_ctl_cmd *cmd) if ( cmd->direction == SCHED_INFO_PUT ) { ctx_allow = params->ctx_allow; + /* The max_vtb should be of the order o the ctx_allow */ + max_vtb = ctx_allow; } else { @@ -217,7 +186,7 @@ int fbvt_ctl(struct sched_ctl_cmd *cmd) /* Adjust scheduling parameter for a given domain. */ int fbvt_adjdom(struct domain *p, - struct sched_adjdom_cmd *cmd) + struct sched_adjdom_cmd *cmd) { struct fbvt_adjdom *params = &cmd->u.fbvt; unsigned long flags; @@ -285,10 +254,11 @@ static task_slice_t fbvt_do_schedule(s_time_t now) s32 ranfor; /* assume we never run longer than 2.1s! */ s32 mcus; u32 next_evt, next_prime_evt, min_avt; - struct fbvt_dom_info *prev_inf = FBVT_INFO(prev), - *p_inf = NULL, - *next_inf = NULL, - *next_prime_inf = NULL; + u32 sl_decrement; + struct fbvt_dom_info *prev_inf = FBVT_INFO(prev); + struct fbvt_dom_info *p_inf = NULL; + struct fbvt_dom_info *next_inf = NULL; + struct fbvt_dom_info *next_prime_inf = NULL; task_slice_t ret; ASSERT(prev->sched_priv != NULL); @@ -299,18 +269,26 @@ static task_slice_t fbvt_do_schedule(s_time_t now) ranfor = (s32)(now - prev->lastschd); /* Calculate mcu and update avt. */ mcus = (ranfor + MCU - 1) / MCU; - if(mcus * prev_inf->mcu_advance < prev_inf->vtb) - { - ASSERT(prev_inf->time_slept >= mcus * prev_inf->mcu_advance); - prev_inf->time_slept -= mcus * prev_inf->mcu_advance; - } - else - { - prev_inf->avt += mcus * prev_inf->mcu_advance - prev_inf->vtb; - - ASSERT(prev_inf->time_slept >= prev_inf->vtb); - prev_inf->time_slept -= prev_inf->vtb; - } + + TRACE_3D(TRC_SCHED_FBVT_DO_SCHED_UPDATE, prev->domain, + mcus, LAST_VTB(cpu)); + + sl_decrement = mcus * LAST_VTB(cpu) / R_TIME(cpu); + prev_inf->time_slept -= sl_decrement; + prev_inf->avt += mcus * prev_inf->mcu_advance - sl_decrement; + + /*if(mcus * prev_inf->mcu_advance < LAST_VTB(cpu)) + { + ASSERT(prev_inf->time_slept >= mcus * prev_inf->mcu_advance); + prev_inf->time_slept -= mcus * prev_inf->mcu_advance; + } + else + { + prev_inf->avt += mcus * prev_inf->mcu_advance - LAST_VTB(cpu); + + ASSERT(prev_inf->time_slept >= LAST_VTB(cpu)); + prev_inf->time_slept -= LAST_VTB(cpu); + }*/ __calc_evt(prev_inf); @@ -399,7 +377,7 @@ static task_slice_t fbvt_do_schedule(s_time_t now) } - /* + /* * In here we decide on Virtual Time Bonus. The idea is, for the * domains that have large time_slept values to be allowed to run * for longer. Thus regaining the share of CPU originally allocated. @@ -407,8 +385,9 @@ static task_slice_t fbvt_do_schedule(s_time_t now) * domains earlier in virtual time). Together this should give quite * good control both for CPU and IO-bound domains. */ - next_inf->vtb = (int)(0.2 * next_inf->time_slept); - if(next_inf->vtb > 1000) next_inf->vtb = 1000; + LAST_VTB(cpu) = (int)(0.2 * next_inf->time_slept); + if(LAST_VTB(cpu) / next_inf->mcu_advance > max_vtb / MCU) + LAST_VTB(cpu) = max_vtb * next_inf->mcu_advance / MCU; /* work out time for next run through scheduler */ @@ -431,15 +410,17 @@ static task_slice_t fbvt_do_schedule(s_time_t now) * 'next_prime's evt. Take context switch allowance into account. */ ASSERT(next_prime_inf->evt >= next_inf->evt); - - r_time = ((next_prime_inf->evt + next_inf->vtb - next_inf->evt)/next_inf->mcu_advance) + + ASSERT(LAST_VTB(cpu) >= 0); + + r_time = MCU * ((next_prime_inf->evt + LAST_VTB(cpu) - next_inf->evt)/next_inf->mcu_advance) + ctx_allow; - + ASSERT(r_time >= ctx_allow); sched_done: - - TRACE_2D(TRC_SCHED_FBVT_DO_SCHED, next->domain, r_time); + R_TIME(cpu) = r_time / MCU; + TRACE_3D(TRC_SCHED_FBVT_DO_SCHED, next->domain, r_time, LAST_VTB(cpu)); next->min_slice = ctx_allow; ret.task = next; ret.time = r_time; @@ -452,8 +433,8 @@ static void fbvt_dump_runq_el(struct domain *p) { struct fbvt_dom_info *inf = FBVT_INFO(p); - printk("mcua=0x%04lX ev=0x%08X av=0x%08X sl=0x%08X vtb=0x%08X ", - inf->mcu_advance, inf->evt, inf->avt, inf->time_slept, inf->vtb); + printk("mcua=%04lu ev=%08u av=%08u sl=%08u", + inf->mcu_advance, inf->evt, inf->avt, inf->time_slept); } static void fbvt_dump_settings(void) @@ -497,30 +478,85 @@ int fbvt_init_scheduler() return 0; } -static void fbvt_pause(struct domain *p) +static void fbvt_sleep(struct domain *d) { - if( __task_on_runqueue(p) ) - { - __del_from_runqueue(p); - } + if ( test_bit(DF_RUNNING, &d->flags) ) + cpu_raise_softirq(d->processor, SCHEDULE_SOFTIRQ); + else if ( __task_on_runqueue(d) ) + __del_from_runqueue(d); } -static void fbvt_unpause(struct domain *p) +static void fbvt_wake(struct domain *d) { - struct fbvt_dom_info *inf = FBVT_INFO(p); + struct fbvt_dom_info *inf = FBVT_INFO(d); + struct domain *curr; + s_time_t now, min_time; + int cpu = d->processor; + s32 io_warp; - if ( p->domain == IDLE_DOMAIN_ID ) + /* If on the runqueue already then someone has done the wakeup work. */ + if ( unlikely(__task_on_runqueue(d)) ) + return; + + __add_to_runqueue_head(d); + + now = NOW(); + +#if 0 + /* + * XXX KAF: This was fbvt_unpause(). Not sure if it's the right thing + * to do, in light of the stuff that fbvt_wake_up() does. + * e.g., setting 'inf->avt = CPU_SVT(cpu);' would make the later test + * 'inf->avt < CPU_SVT(cpu)' redundant! + */ + if ( d->domain == IDLE_DOMAIN_ID ) { inf->avt = inf->evt = ~0U; } else { /* Set avt to system virtual time. */ - inf->avt = CPU_SVT(p->processor); + inf->avt = CPU_SVT(cpu); /* Set some default values here. */ - inf->vtb = 0; - __calc_evt(inf); + LAST_VTB(cpu) = 0; + __calc_evt(inf); } +#endif + + /* Set the BVT parameters. */ + if ( inf->avt < CPU_SVT(cpu) ) + { + /* + * We want IO bound processes to gain dispatch precedence. It is + * especially for device driver domains. Therefore AVT + * not be updated to SVT but to a value marginally smaller. + * Since frequently sleeping domains have high time_slept + * values, the virtual time can be determined as: + * SVT - const * TIME_SLEPT + */ + io_warp = (int)(0.5 * inf->time_slept); + if ( io_warp > 1000 ) + io_warp = 1000; + + ASSERT(inf->time_slept + CPU_SVT(cpu) > inf->avt + io_warp); + inf->time_slept += CPU_SVT(cpu) - inf->avt - io_warp; + inf->avt = CPU_SVT(cpu) - io_warp; + } + + /* Deal with warping here. */ + inf->warpback = 1; + inf->warped = now; + __calc_evt(inf); + + curr = schedule_data[cpu].curr; + + /* Currently-running domain should run at least for ctx_allow. */ + min_time = curr->lastschd + curr->min_slice; + + if ( is_idle_task(curr) || (min_time <= now) ) + cpu_raise_softirq(cpu, SCHEDULE_SOFTIRQ); + else if ( schedule_data[cpu].s_timer.expires > (min_time + TIME_SLOP) ) + mod_ac_timer(&schedule_data[cpu].s_timer, min_time); } struct scheduler sched_fbvt_def = { @@ -532,7 +568,6 @@ struct scheduler sched_fbvt_def = { .alloc_task = fbvt_alloc_task, .add_task = fbvt_add_task, .free_task = fbvt_free_task, - .wake_up = fbvt_wake_up, .do_block = fbvt_do_block, .do_schedule = fbvt_do_schedule, .control = fbvt_ctl, @@ -540,7 +575,7 @@ struct scheduler sched_fbvt_def = { .dump_settings = fbvt_dump_settings, .dump_cpu_state = fbvt_dump_cpu_state, .dump_runq_el = fbvt_dump_runq_el, - .pause = fbvt_pause, - .unpause = fbvt_unpause, + .sleep = fbvt_sleep, + .wake = fbvt_wake, }; diff --git a/xen/common/sched_rrobin.c b/xen/common/sched_rrobin.c index b553476163..09aa6aba86 100644 --- a/xen/common/sched_rrobin.c +++ b/xen/common/sched_rrobin.c @@ -8,8 +8,11 @@ #include #include #include +#include #include +#define TIME_SLOP (s32)MICROSECS(50) /* allow time to slip a bit */ + static s_time_t rr_slice = MILLISECS(10); static task_slice_t rr_do_schedule(s_time_t now) @@ -33,7 +36,7 @@ static task_slice_t rr_do_schedule(s_time_t now) static int rr_ctl(struct sched_ctl_cmd *cmd) { - if(cmd->direction == SCHED_INFO_PUT) + if ( cmd->direction == SCHED_INFO_PUT ) { rr_slice = cmd->u.rrobin.slice; } @@ -50,10 +53,37 @@ static void rr_dump_settings() printk("rr_slice = %llu ", rr_slice); } -static void rr_pause(struct domain *p) +static void rr_sleep(struct domain *d) { - if ( __task_on_runqueue(p) ) - __del_from_runqueue(p); + if ( test_bit(DF_RUNNING, &d->flags) ) + cpu_raise_softirq(d->processor, SCHEDULE_SOFTIRQ); + else if ( __task_on_runqueue(d) ) + __del_from_runqueue(d); +} + +void rr_wake(struct domain *d) +{ + struct domain *curr; + s_time_t now, min_time; + int cpu = d->processor; + + /* If on the runqueue already then someone has done the wakeup work. */ + if ( unlikely(__task_on_runqueue(d)) ) + return; + + __add_to_runqueue_head(d); + + now = NOW(); + + curr = schedule_data[cpu].curr; + + /* Currently-running domain should run at least for ctx_allow. */ + min_time = curr->lastschd + curr->min_slice; + + if ( is_idle_task(curr) || (min_time <= now) ) + cpu_raise_softirq(cpu, SCHEDULE_SOFTIRQ); + else if ( schedule_data[cpu].s_timer.expires > (min_time + TIME_SLOP) ) + mod_ac_timer(&schedule_data[cpu].s_timer, min_time); } struct scheduler sched_rrobin_def = { @@ -61,11 +91,11 @@ struct scheduler sched_rrobin_def = { .opt_name = "rrobin", .sched_id = SCHED_RROBIN, - .wake_up = __add_to_runqueue_head, .do_schedule = rr_do_schedule, .control = rr_ctl, .dump_settings = rr_dump_settings, - .pause = rr_pause, + .sleep = rr_sleep, + .wake = rr_wake, }; diff --git a/xen/common/schedule.c b/xen/common/schedule.c index f31fab94fc..eb99f0f0b8 100644 --- a/xen/common/schedule.c +++ b/xen/common/schedule.c @@ -73,7 +73,7 @@ schedule_data_t schedule_data[NR_CPUS]; */ extern struct scheduler sched_bvt_def, sched_fbvt_def, sched_rrobin_def, sched_atropos_def; static struct scheduler *schedulers[] = { &sched_bvt_def, - &sched_fbvt_def, + &sched_fbvt_def, &sched_rrobin_def, &sched_atropos_def, NULL}; @@ -178,12 +178,7 @@ void domain_sleep(struct domain *d) spin_lock_irqsave(&schedule_lock[cpu], flags); if ( likely(!domain_runnable(d)) ) - { - if ( test_bit(DF_RUNNING, &d->flags) ) - cpu_raise_softirq(cpu, SCHEDULE_SOFTIRQ); - else if ( __task_on_runqueue(d) ) - __del_from_runqueue(d); - } + SCHED_OP(sleep, d); spin_unlock_irqrestore(&schedule_lock[cpu], flags); /* Synchronous. */ @@ -198,53 +193,19 @@ void domain_wake(struct domain *d) { unsigned long flags; int cpu = d->processor; - struct domain *curr; - s_time_t now, min_time; spin_lock_irqsave(&schedule_lock[cpu], flags); - - if ( likely(domain_runnable(d)) && likely(!__task_on_runqueue(d)) ) + if ( likely(domain_runnable(d)) ) { - TRACE_2D(TRC_SCHED_WAKE,d->domain, d); - SCHED_OP(wake_up, d); + TRACE_2D(TRC_SCHED_WAKE, d->domain, d); + SCHED_OP(wake, d); #ifdef WAKE_HISTO - p->wokenup = NOW(); + d->wokenup = NOW(); #endif - - now = NOW(); - curr = schedule_data[cpu].curr; - - /* Currently-running domain should run at least for ctx_allow. */ - min_time = curr->lastschd + curr->min_slice; - - if ( is_idle_task(curr) || (min_time <= now) ) - cpu_raise_softirq(cpu, SCHEDULE_SOFTIRQ); - else if ( schedule_data[cpu].s_timer.expires > (min_time + TIME_SLOP) ) - mod_ac_timer(&schedule_data[cpu].s_timer, min_time); } - spin_unlock_irqrestore(&schedule_lock[cpu], flags); } -/* - * Pausing a domain. - */ -void pause_domain(struct domain *domain) -{ - domain_sleep(domain); - SCHED_OP(pause, domain); -} - - -/* - * Unpauseing a domain - */ -void unpause_domain(struct domain *domain) -{ - SCHED_OP(unpause, domain); - domain_wake(domain); -} - /* Block the currently-executing domain until a pertinent event occurs. */ long do_block(void) { diff --git a/xen/include/xen/sched-if.h b/xen/include/xen/sched-if.h index c547d8f28a..05fdce847d 100644 --- a/xen/include/xen/sched-if.h +++ b/xen/include/xen/sched-if.h @@ -39,7 +39,8 @@ struct scheduler void (*add_task) (struct domain *); void (*free_task) (struct domain *); void (*rem_task) (struct domain *); - void (*wake_up) (struct domain *); + void (*sleep) (struct domain *); + void (*wake) (struct domain *); void (*do_block) (struct domain *); task_slice_t (*do_schedule) (s_time_t); int (*control) (struct sched_ctl_cmd *); @@ -49,8 +50,6 @@ struct scheduler void (*dump_cpu_state) (int); void (*dump_runq_el) (struct domain *); int (*prn_state) (int); - void (*pause) (struct domain *); - void (*unpause) (struct domain *); }; /* per CPU scheduler information */ diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index d75257bf7c..bcfab27b65 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -210,8 +210,6 @@ int sched_id(); void init_idle_task(void); void domain_wake(struct domain *d); void domain_sleep(struct domain *d); -void pause_domain(struct domain *d); -void unpause_domain(struct domain *d); void __enter_scheduler(void); @@ -262,14 +260,14 @@ static inline void domain_pause(struct domain *d) { ASSERT(d != current); atomic_inc(&d->pausecnt); - pause_domain(d); + domain_sleep(d); } static inline void domain_unpause(struct domain *d) { ASSERT(d != current); if ( atomic_dec_and_test(&d->pausecnt) ) - unpause_domain(d); + domain_wake(d); } static inline void domain_unblock(struct domain *d) @@ -282,13 +280,13 @@ static inline void domain_pause_by_systemcontroller(struct domain *d) { ASSERT(d != current); if ( !test_and_set_bit(DF_CTRLPAUSE, &d->flags) ) - pause_domain(d); + domain_sleep(d); } static inline void domain_unpause_by_systemcontroller(struct domain *d) { if ( test_and_clear_bit(DF_CTRLPAUSE, &d->flags) ) - unpause_domain(d); + domain_wake(d); }