diff options
-rw-r--r-- | .rootkeys | 3 | ||||
-rw-r--r-- | xen/arch/x86/idle0_task.c | 3 | ||||
-rw-r--r-- | xen/arch/x86/irq.c | 4 | ||||
-rw-r--r-- | xen/arch/x86/setup.c | 39 | ||||
-rw-r--r-- | xen/arch/x86/time.c | 79 | ||||
-rw-r--r-- | xen/common/domain.c | 6 | ||||
-rw-r--r-- | xen/common/kernel.c | 9 | ||||
-rw-r--r-- | xen/common/lib.c | 80 | ||||
-rw-r--r-- | xen/common/sched_bvt.c | 1 | ||||
-rw-r--r-- | xen/common/schedule.c | 13 | ||||
-rw-r--r-- | xen/common/softirq.c | 78 | ||||
-rw-r--r-- | xen/common/timer.c | 338 | ||||
-rw-r--r-- | xen/include/asm-x86/processor.h | 23 | ||||
-rw-r--r-- | xen/include/xen/interrupt.h | 117 | ||||
-rw-r--r-- | xen/include/xen/lib.h | 26 | ||||
-rw-r--r-- | xen/include/xen/sched.h | 4 | ||||
-rw-r--r-- | xen/include/xen/time.h | 21 | ||||
-rw-r--r-- | xen/include/xen/timer.h | 81 | ||||
-rw-r--r-- | xen/include/xen/tqueue.h | 125 |
19 files changed, 91 insertions, 959 deletions
@@ -342,7 +342,6 @@ 3ddb79bdB9RNMnkQnUyZ5C9hhMSQQw xen/common/slab.c 3ddb79bd0gVQYmL2zvuJnldvD0AGxQ xen/common/softirq.c 3e7f358awXBC3Vw-wFRwPw18qL1khg xen/common/string.c -3ddb79bdQqFHtHRGEO2dsxGgo6eAhw xen/common/timer.c 403a3edbejm33XLTGMuinKEwQBrOIg xen/common/trace.c 3ddb79bd3zgV33PHdt-cgh3sxcb1hw xen/common/vsprintf.c 3ddb79c0ppNeJtjC4va8j41ADCnchA xen/drivers/Makefile @@ -500,9 +499,7 @@ 3ddb79c2iIcESrDAB8samy_yAh6olQ xen/include/xen/spinlock.h 3e7f358aMtFMUVvN_Zjg5qvEJIqEBA xen/include/xen/string.h 3ddb79c0BnA20PbgmuMPSGIBljNRQw xen/include/xen/time.h -3ddb79c2HFkXuRxi1CriJtSFmY6Ybw xen/include/xen/timer.h 3ddb79c2_m8lT9jDKse_tePj7zcnNQ xen/include/xen/timex.h -3ddb79c2e2C14HkndNEJlYwXaPrF5A xen/include/xen/tqueue.h 403a3edbG9K5uZjuY19_LORbQGmFbA xen/include/xen/trace.h 3ddb79c1-kVvF8cVa0k3ZHDdBMj01Q xen/include/xen/types.h 3e8827bdaqPeZAWGVOwswgY9bWSx4g xen/include/xen/version.h diff --git a/xen/arch/x86/idle0_task.c b/xen/arch/x86/idle0_task.c index b956fdff40..bb40dde8bf 100644 --- a/xen/arch/x86/idle0_task.c +++ b/xen/arch/x86/idle0_task.c @@ -11,5 +11,4 @@ struct task_struct idle0_task = IDLE0_TASK(idle0_task); * section. Since TSS's are completely CPU-local, we want them * on exact cacheline boundaries, to eliminate cacheline ping-pong. */ -struct tss_struct init_tss[NR_CPUS] __cacheline_aligned = { [0 ... NR_CPUS-1] = INIT_TSS }; - +struct tss_struct init_tss[NR_CPUS] __cacheline_aligned; diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c index f3daf15305..56da0f73ec 100644 --- a/xen/arch/x86/irq.c +++ b/xen/arch/x86/irq.c @@ -179,7 +179,7 @@ static inline void wait_on_irq(int cpu) * already executing in one.. */ if (!irqs_running()) - if (local_bh_count(cpu) || !spin_is_locked(&global_bh_lock)) + if (local_bh_count(cpu)) break; /* Duh, we have to loop. Release the lock to avoid deadlocks */ @@ -193,7 +193,7 @@ static inline void wait_on_irq(int cpu) continue; if (global_irq_lock) continue; - if (!local_bh_count(cpu) && spin_is_locked(&global_bh_lock)) + if (!local_bh_count(cpu)) continue; if (!test_and_set_bit(0,&global_irq_lock)) break; diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index a4e470984f..92b90dc282 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -257,6 +257,9 @@ void __init cpu_init(void) panic("CPU#%d already initialized!!!\n", nr); printk("Initializing CPU#%d\n", nr); + t->bitmap = INVALID_IO_BITMAP_OFFSET; + memset(t->io_bitmap, ~0, sizeof(t->io_bitmap)); + /* Set up GDT and IDT. */ SET_GDT_ENTRIES(current, DEFAULT_GDT_ENTRIES); SET_GDT_ADDRESS(current, DEFAULT_GDT_ADDRESS); @@ -294,31 +297,6 @@ static void __init do_initcalls(void) (*call)(); } -/* - * IBM-compatible BIOSes place drive info tables at initial interrupt - * vectors 0x41 and 0x46. These are in the for of 16-bit-mode far ptrs. - */ -struct drive_info_struct { unsigned char dummy[32]; } drive_info; -void get_bios_driveinfo(void) -{ - unsigned long seg, off, tab1, tab2; - - off = (unsigned long)*(unsigned short *)(4*0x41+0); - seg = (unsigned long)*(unsigned short *)(4*0x41+2); - tab1 = (seg<<4) + off; - - off = (unsigned long)*(unsigned short *)(4*0x46+0); - seg = (unsigned long)*(unsigned short *)(4*0x46+2); - tab2 = (seg<<4) + off; - - printk("Reading BIOS drive-info tables at 0x%05lx and 0x%05lx\n", - tab1, tab2); - - memcpy(drive_info.dummy+ 0, (char *)tab1, 16); - memcpy(drive_info.dummy+16, (char *)tab2, 16); -} - - unsigned long pci_mem_start = 0x10000000; void __init start_of_day(void) @@ -326,8 +304,6 @@ void __init start_of_day(void) extern void trap_init(void); extern void init_IRQ(void); extern void time_init(void); - extern void timer_bh(void); - extern void init_timervecs(void); extern void ac_timer_init(void); extern void initialize_keytable(); extern void initialize_keyboard(void); @@ -348,12 +324,6 @@ void __init start_of_day(void) if ( opt_watchdog ) nmi_watchdog = NMI_LOCAL_APIC; - /* - * We do this early, but tables are in the lowest 1MB (usually - * 0xfe000-0xfffff). Therefore they're unlikely to ever get clobbered. - */ - get_bios_driveinfo(); - /* Tell the PCI layer not to allocate too close to the RAM area.. */ low_mem_size = ((max_page << PAGE_SHIFT) + 0xfffff) & ~0xfffff; if ( low_mem_size > pci_mem_start ) pci_mem_start = low_mem_size; @@ -380,14 +350,11 @@ void __init start_of_day(void) if ( smp_found_config ) get_smp_config(); #endif - domain_init(); scheduler_init(); trap_init(); init_IRQ(); /* installs simple interrupt wrappers. Starts HZ clock. */ time_init(); /* installs software handler for HZ clock. */ softirq_init(); - init_timervecs(); - init_bh(TIMER_BH, timer_bh); init_apic_mappings(); /* make APICs addressable in our pagetables. */ #ifndef CONFIG_SMP diff --git a/xen/arch/x86/time.c b/xen/arch/x86/time.c index 9cd6da1955..092bb78765 100644 --- a/xen/arch/x86/time.c +++ b/xen/arch/x86/time.c @@ -6,11 +6,6 @@ * * File: i386/time.c * Author: Rolf Neugebar & Keir Fraser - * - * Environment: Xen Hypervisor - * Description: modified version of Linux' time.c - * implements system and wall clock time. - * based on freebsd's implementation. */ /* @@ -37,15 +32,13 @@ #include <asm/fixmap.h> #include <asm/mc146818rtc.h> -extern rwlock_t xtime_lock; -extern unsigned long wall_jiffies; - /* GLOBAL */ unsigned long cpu_khz; /* Detected as we calibrate the TSC */ unsigned long ticks_per_usec; /* TSC ticks per microsecond. */ spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED; int timer_ack = 0; int do_timer_lists_from_pit = 0; +unsigned long volatile jiffies; /* PRIVATE */ static unsigned int rdtsc_bitshift; /* Which 32 bits of TSC do we use? */ @@ -54,12 +47,14 @@ static u32 st_scale_f; /* Cycles -> ns, fractional part */ static u32 st_scale_i; /* Cycles -> ns, integer part */ static u32 tsc_irq; /* CPU0's TSC at last 'time update' */ static s_time_t stime_irq; /* System time at last 'time update' */ +static unsigned long wc_sec, wc_usec; /* UTC time at last 'time update'. */ +static rwlock_t time_lock = RW_LOCK_UNLOCKED; static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { u64 full_tsc; - write_lock(&xtime_lock); + write_lock(&time_lock); #ifdef CONFIG_X86_IO_APIC if ( timer_ack ) @@ -80,13 +75,21 @@ static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) rdtscll(full_tsc); tsc_irq = (u32)(full_tsc >> rdtsc_bitshift); - /* Updates xtime (wallclock time). */ - do_timer(regs); + /* Update jiffies counter. */ + (*(unsigned long *)&jiffies)++; + + /* Update wall time. */ + wc_usec += 1000000/HZ; + if ( wc_usec >= 1000000 ) + { + wc_usec -= 1000000; + wc_sec++; + } /* Updates system time (nanoseconds since boot). */ stime_irq += MILLISECS(1000/HZ); - write_unlock(&xtime_lock); + write_unlock(&time_lock); /* Rough hack to allow accurate timers to sort-of-work with no APIC. */ if ( do_timer_lists_from_pit ) @@ -253,7 +256,7 @@ s_time_t get_s_time(void) s_time_t now; unsigned long flags; - read_lock_irqsave(&xtime_lock, flags); + read_lock_irqsave(&time_lock, flags); now = stime_irq + get_time_delta(); @@ -265,7 +268,7 @@ s_time_t get_s_time(void) prev_now = now; } - read_unlock_irqrestore(&xtime_lock, flags); + read_unlock_irqrestore(&time_lock, flags); return now; } @@ -275,7 +278,7 @@ void update_dom_time(shared_info_t *si) { unsigned long flags; - read_lock_irqsave(&xtime_lock, flags); + read_lock_irqsave(&time_lock, flags); si->time_version1++; wmb(); @@ -284,19 +287,13 @@ void update_dom_time(shared_info_t *si) si->tsc_timestamp.tsc_bitshift = rdtsc_bitshift; si->tsc_timestamp.tsc_bits = tsc_irq; si->system_time = stime_irq; - si->wc_sec = xtime.tv_sec; - si->wc_usec = xtime.tv_usec; - si->wc_usec += (jiffies - wall_jiffies) * (1000000 / HZ); - while ( si->wc_usec >= 1000000 ) - { - si->wc_usec -= 1000000; - si->wc_sec++; - } + si->wc_sec = wc_sec; + si->wc_usec = wc_usec; wmb(); si->time_version2++; - read_unlock_irqrestore(&xtime_lock, flags); + read_unlock_irqrestore(&time_lock, flags); } @@ -306,23 +303,21 @@ void do_settime(unsigned long secs, unsigned long usecs, u64 system_time_base) s64 delta; long _usecs = (long)usecs; - write_lock_irq(&xtime_lock); + write_lock_irq(&time_lock); delta = (s64)(stime_irq - system_time_base); - _usecs += (long)(delta/1000); - _usecs -= (jiffies - wall_jiffies) * (1000000 / HZ); - - while ( _usecs < 0 ) + _usecs += (long)(delta/1000); + while ( _usecs >= 1000000 ) { - _usecs += 1000000; - secs--; - } + _usecs -= 1000000; + secs++; + } - xtime.tv_sec = secs; - xtime.tv_usec = _usecs; + wc_sec = secs; + wc_usec = _usecs; - write_unlock_irq(&xtime_lock); + write_unlock_irq(&time_lock); update_dom_time(current->shared_info); } @@ -350,17 +345,13 @@ int __init init_xen_time() tsc_irq = (u32)(full_tsc >> rdtsc_bitshift); /* Wallclock time starts as the initial RTC time. */ - xtime.tv_sec = get_cmos_time(); + wc_sec = get_cmos_time(); printk("Time init:\n"); - printk(".... System Time: %lldns\n", - NOW()); - printk(".... cpu_freq: %08X:%08X\n", - (u32)(cpu_freq>>32), (u32)cpu_freq); - printk(".... scale: %08X:%08X\n", - (u32)(scale>>32), (u32)scale); - printk(".... Wall Clock: %lds %ldus\n", - xtime.tv_sec, xtime.tv_usec); + printk(".... System Time: %lldns\n", NOW()); + printk(".... cpu_freq: %08X:%08X\n", (u32)(cpu_freq>>32),(u32)cpu_freq); + printk(".... scale: %08X:%08X\n", (u32)(scale>>32),(u32)scale); + printk(".... Wall Clock: %lds %ldus\n", wc_sec, wc_usec); return 0; } diff --git a/xen/common/domain.c b/xen/common/domain.c index f42d24655b..878bc35392 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -1057,9 +1057,3 @@ int construct_dom0(struct task_struct *p, return 0; } - - -void __init domain_init(void) -{ - printk("Initialising domains\n"); -} diff --git a/xen/common/kernel.c b/xen/common/kernel.c index d749a795a2..8ba7f7e3af 100644 --- a/xen/common/kernel.c +++ b/xen/common/kernel.c @@ -49,8 +49,6 @@ unsigned int opt_ser_baud = 0; unsigned char opt_com1[30] = "", opt_com2[30] = ""; /* opt_dom0_mem: Kilobytes of memory allocated to domain 0. */ unsigned int opt_dom0_mem = 16000; -/* opt_ifname: Name of physical network interface to use. */ -unsigned char opt_ifname[10] = "eth0"; /* opt_noht: If true, Hyperthreading is ignored. */ int opt_noht=0; /* opt_noacpi: If true, ACPI tables are not parsed. */ @@ -80,7 +78,7 @@ char opt_leveltrigger[30] = "", opt_edgetrigger[30] = ""; static struct { unsigned char *name; - enum { OPT_IP, OPT_STR, OPT_UINT, OPT_BOOL } type; + enum { OPT_STR, OPT_UINT, OPT_BOOL } type; void *var; } opts[] = { { "console", OPT_STR, &opt_console }, @@ -88,7 +86,6 @@ static struct { { "com1", OPT_STR, &opt_com1 }, { "com2", OPT_STR, &opt_com2 }, { "dom0_mem", OPT_UINT, &opt_dom0_mem }, - { "ifname", OPT_STR, &opt_ifname }, { "noht", OPT_BOOL, &opt_noht }, { "noacpi", OPT_BOOL, &opt_noacpi }, { "nosmp", OPT_BOOL, &opt_nosmp }, @@ -137,10 +134,6 @@ void cmain(unsigned long magic, multiboot_info_t *mbi) if ( strcmp(opts[i].name, cmdline ) != 0 ) continue; switch ( opts[i].type ) { - case OPT_IP: - if ( opt != NULL ) - *(unsigned long *)opts[i].var = str_to_quad(opt); - break; case OPT_STR: if ( opt != NULL ) strcpy(opts[i].var, opt); diff --git a/xen/common/lib.c b/xen/common/lib.c index b2057ead2b..256ec34294 100644 --- a/xen/common/lib.c +++ b/xen/common/lib.c @@ -31,26 +31,6 @@ _L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L, /* 224-239 */ _L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L}; /* 240-255 */ -unsigned long str_to_quad(unsigned char *s) -{ - unsigned long quad = 0; - do { - quad <<= 8; - quad |= simple_strtol(s, (char **)&s, 10); - } - while ( *s++ == '.' ); - return quad; -} - - -unsigned char *quad_to_str(unsigned long q, unsigned char *s) -{ - sprintf(s, "%ld.%ld.%ld.%ld", - (q>>24)&255, (q>>16)&255, (q>>8)&255, (q>>0)&255); - return s; -} - - /* a couple of 64 bit operations ported from freebsd */ /*- @@ -409,63 +389,3 @@ __udivdi3(a, b) } #endif /* BITS_PER_LONG == 32 */ - - -/* HASH/RANDOMISATION FUNCTION - * Based on lookup2.c, by Bob Jenkins, December 1996, Public Domain. - * You can use this free for any purpose. It has no warranty. - * See http://burlteburtle.net/bob/hash/evahash.html - */ - -#define mix(a,b,c) \ - do { \ - a -= b; a -= c; a ^= (c>>13); \ - b -= c; b -= a; b ^= (a<< 8); \ - c -= a; c -= b; c ^= ((b&0xffffffff)>>13); \ - a -= b; a -= c; a ^= ((c&0xffffffff)>>12); \ - b -= c; b -= a; b = (b ^ (a<<16)) & 0xffffffff; \ - c -= a; c -= b; c = (c ^ (b>> 5)) & 0xffffffff; \ - a -= b; a -= c; a = (a ^ (c>> 3)) & 0xffffffff; \ - b -= c; b -= a; b = (b ^ (a<<10)) & 0xffffffff; \ - c -= a; c -= b; c = (c ^ (b>>15)) & 0xffffffff; \ - } while ( 0 ) - -u32 hash(unsigned char *k, unsigned long len) -{ - u32 a, b, c, l; - - l = len; - a = b = 0x9e3779b9; /* the golden ratio; an arbitrary value */ - c = 0xa5a5a5a5; /* another arbitrary value (KAF, 13/5/03) */ - - while ( l >= 12 ) - { - a += (k[0] + ((u32)k[1]<<8) + ((u32)k[2]<<16) + ((u32)k[3]<<24)); - b += (k[4] + ((u32)k[5]<<8) + ((u32)k[6]<<16) + ((u32)k[7]<<24)); - c += (k[8] + ((u32)k[9]<<8) + ((u32)k[10]<<16) + ((u32)k[11]<<24)); - mix(a,b,c); - k += 12; l -= 12; - } - - c += len; - switch ( l ) - { - case 11: c+=((u32)k[10]<<24); - case 10: c+=((u32)k[9]<<16); - case 9 : c+=((u32)k[8]<<8); - /* the first byte of c is reserved for the length */ - case 8 : b+=((u32)k[7]<<24); - case 7 : b+=((u32)k[6]<<16); - case 6 : b+=((u32)k[5]<<8); - case 5 : b+=k[4]; - case 4 : a+=((u32)k[3]<<24); - case 3 : a+=((u32)k[2]<<16); - case 2 : a+=((u32)k[1]<<8); - case 1 : a+=k[0]; - /* case 0: nothing left to add */ - } - - mix(a,b,c); - - return c; -} diff --git a/xen/common/sched_bvt.c b/xen/common/sched_bvt.c index dd8e70db59..c667333618 100644 --- a/xen/common/sched_bvt.c +++ b/xen/common/sched_bvt.c @@ -23,7 +23,6 @@ #include <xen/time.h> #include <xen/ac_timer.h> #include <xen/interrupt.h> -#include <xen/timer.h> #include <xen/perfc.h> #include <xen/sched-if.h> #include <xen/slab.h> diff --git a/xen/common/schedule.c b/xen/common/schedule.c index 116ee14574..a4a1c6a68d 100644 --- a/xen/common/schedule.c +++ b/xen/common/schedule.c @@ -23,7 +23,6 @@ #include <xen/time.h> #include <xen/ac_timer.h> #include <xen/interrupt.h> -#include <xen/timer.h> #include <xen/perfc.h> #include <xen/sched-if.h> #include <hypervisor-ifs/sched_ctl.h> @@ -583,8 +582,6 @@ void __init scheduler_init(void) { int i; - printk("Initialising schedulers\n"); - for ( i = 0; i < NR_CPUS; i++ ) { INIT_LIST_HEAD(&schedule_data[i].runqueue); @@ -613,9 +610,8 @@ void __init scheduler_init(void) for ( i = 0; schedulers[i] != NULL; i++ ) { - ops = *schedulers[i]; /* fetch operations structure */ - - if(strcmp(ops.opt_name, opt_sched) == 0) + ops = *schedulers[i]; + if ( strcmp(ops.opt_name, opt_sched) == 0 ) break; } @@ -623,9 +619,6 @@ void __init scheduler_init(void) printk("Could not find scheduler: %s\n", opt_sched); printk("Using scheduler: %s (%s)\n", ops.name, ops.opt_name); - - if ( ops.do_schedule == NULL) - panic("Chosen scheduler has NULL do_schedule!"); if ( SCHED_OP(init_scheduler) < 0 ) panic("Initialising scheduler failed!"); @@ -637,8 +630,6 @@ void __init scheduler_init(void) */ void schedulers_start(void) { - printk("Start schedulers\n"); - s_timer_fn(0); smp_call_function((void *)s_timer_fn, NULL, 1, 1); diff --git a/xen/common/softirq.c b/xen/common/softirq.c index 3924fbf56e..c8bbdb95ed 100644 --- a/xen/common/softirq.c +++ b/xen/common/softirq.c @@ -15,7 +15,6 @@ #include <xen/sched.h> #include <xen/interrupt.h> #include <xen/init.h> -#include <xen/tqueue.h> irq_cpustat_t irq_stat[NR_CPUS]; @@ -196,85 +195,8 @@ void tasklet_kill(struct tasklet_struct *t) clear_bit(TASKLET_STATE_SCHED, &t->state); } - - -/* Old style BHs */ - -static void (*bh_base[32])(void); -struct tasklet_struct bh_task_vec[32]; - -spinlock_t global_bh_lock = SPIN_LOCK_UNLOCKED; - -static void bh_action(unsigned long nr) -{ - int cpu = smp_processor_id(); - - if ( !spin_trylock(&global_bh_lock) ) - goto resched; - - if ( !hardirq_trylock(cpu) ) - goto resched_unlock; - - if ( likely(bh_base[nr] != NULL) ) - bh_base[nr](); - - hardirq_endlock(cpu); - spin_unlock(&global_bh_lock); - return; - - resched_unlock: - spin_unlock(&global_bh_lock); - resched: - mark_bh(nr); -} - -void init_bh(int nr, void (*routine)(void)) -{ - bh_base[nr] = routine; - mb(); -} - -void remove_bh(int nr) -{ - tasklet_kill(bh_task_vec+nr); - bh_base[nr] = NULL; -} - void __init softirq_init() { - int i; - - for ( i = 0; i < 32; i++) - tasklet_init(bh_task_vec+i, bh_action, i); - open_softirq(TASKLET_SOFTIRQ, tasklet_action, NULL); open_softirq(HI_SOFTIRQ, tasklet_hi_action, NULL); } - -void __run_task_queue(task_queue *list) -{ - struct list_head head, *next; - unsigned long flags; - void (*f) (void *); - struct tq_struct *p; - void *data; - - spin_lock_irqsave(&tqueue_lock, flags); - list_add(&head, list); - list_del_init(list); - spin_unlock_irqrestore(&tqueue_lock, flags); - - next = head.next; - while ( next != &head ) - { - p = list_entry(next, struct tq_struct, list); - next = next->next; - f = p->routine; - data = p->data; - wmb(); - p->sync = 0; - if ( likely(f != NULL) ) - f(data); - } -} - diff --git a/xen/common/timer.c b/xen/common/timer.c deleted file mode 100644 index bc3a491236..0000000000 --- a/xen/common/timer.c +++ /dev/null @@ -1,338 +0,0 @@ -/* - * linux/kernel/timer.c - * - * Kernel internal timers, kernel timekeeping, basic process system calls - * - * Copyright (C) 1991, 1992 Linus Torvalds - * - * 1997-01-28 Modified by Finn Arne Gangstad to make timers scale better. - * - * 1997-09-10 Updated NTP code according to technical memorandum Jan '96 - * "A Kernel Model for Precision Timekeeping" by Dave Mills - * 1998-12-24 Fixed a xtime SMP race (we need the xtime_lock rw spinlock to - * serialize accesses to xtime/lost_ticks). - * Copyright (C) 1998 Andrea Arcangeli - * 1999-03-10 Improved NTP compatibility by Ulrich Windl - */ - -#include <xen/config.h> -#include <xen/mm.h> -#include <xen/time.h> -#include <xen/timer.h> -#include <xen/timex.h> -#include <xen/tqueue.h> -#include <xen/delay.h> -#include <xen/interrupt.h> - -#include <xen/event.h> - -#include <asm/uaccess.h> - -struct timeval xtime __attribute__ ((aligned (16))); -unsigned long volatile jiffies; - -/* - * Event timer code - */ -#define TVN_BITS 6 -#define TVR_BITS 8 -#define TVN_SIZE (1 << TVN_BITS) -#define TVR_SIZE (1 << TVR_BITS) -#define TVN_MASK (TVN_SIZE - 1) -#define TVR_MASK (TVR_SIZE - 1) - -struct timer_vec { - int index; - struct list_head vec[TVN_SIZE]; -}; - -struct timer_vec_root { - int index; - struct list_head vec[TVR_SIZE]; -}; - -static struct timer_vec tv5; -static struct timer_vec tv4; -static struct timer_vec tv3; -static struct timer_vec tv2; -static struct timer_vec_root tv1; - -static struct timer_vec * const tvecs[] = { - (struct timer_vec *)&tv1, &tv2, &tv3, &tv4, &tv5 -}; - -#define NOOF_TVECS (sizeof(tvecs) / sizeof(tvecs[0])) - -void init_timervecs (void) -{ - int i; - - for (i = 0; i < TVN_SIZE; i++) { - INIT_LIST_HEAD(tv5.vec + i); - INIT_LIST_HEAD(tv4.vec + i); - INIT_LIST_HEAD(tv3.vec + i); - INIT_LIST_HEAD(tv2.vec + i); - } - for (i = 0; i < TVR_SIZE; i++) - INIT_LIST_HEAD(tv1.vec + i); -} - -static unsigned long timer_jiffies; - -static inline void internal_add_timer(struct timer_list *timer) -{ - /* - * must be cli-ed when calling this - */ - unsigned long expires = timer->expires; - unsigned long idx = expires - timer_jiffies; - struct list_head * vec; - - if (idx < TVR_SIZE) { - int i = expires & TVR_MASK; - vec = tv1.vec + i; - } else if (idx < 1 << (TVR_BITS + TVN_BITS)) { - int i = (expires >> TVR_BITS) & TVN_MASK; - vec = tv2.vec + i; - } else if (idx < 1 << (TVR_BITS + 2 * TVN_BITS)) { - int i = (expires >> (TVR_BITS + TVN_BITS)) & TVN_MASK; - vec = tv3.vec + i; - } else if (idx < 1 << (TVR_BITS + 3 * TVN_BITS)) { - int i = (expires >> (TVR_BITS + 2 * TVN_BITS)) & TVN_MASK; - vec = tv4.vec + i; - } else if ((signed long) idx < 0) { - /* can happen if you add a timer with expires == jiffies, - * or you set a timer to go off in the past - */ - vec = tv1.vec + tv1.index; - } else if (idx <= 0xffffffffUL) { - int i = (expires >> (TVR_BITS + 3 * TVN_BITS)) & TVN_MASK; - vec = tv5.vec + i; - } else { - /* Can only get here on architectures with 64-bit jiffies */ - INIT_LIST_HEAD(&timer->list); - return; - } - /* - * Timers are FIFO! - */ - list_add(&timer->list, vec->prev); -} - -/* Initialize both explicitly - let's try to have them in the same cache line */ -spinlock_t timerlist_lock = SPIN_LOCK_UNLOCKED; - -#ifdef CONFIG_SMP -volatile struct timer_list * volatile running_timer; -#define timer_enter(t) do { running_timer = t; mb(); } while (0) -#define timer_exit() do { running_timer = NULL; } while (0) -#define timer_is_running(t) (running_timer == t) -#define timer_synchronize(t) while (timer_is_running(t)) barrier() -#else -#define timer_enter(t) do { } while (0) -#define timer_exit() do { } while (0) -#endif - -void add_timer(struct timer_list *timer) -{ - unsigned long flags; - - spin_lock_irqsave(&timerlist_lock, flags); - if (timer_pending(timer)) - goto bug; - internal_add_timer(timer); - spin_unlock_irqrestore(&timerlist_lock, flags); - return; - bug: - spin_unlock_irqrestore(&timerlist_lock, flags); - printk("bug: kernel timer added twice at %p.\n", - __builtin_return_address(0)); -} - -static inline int detach_timer (struct timer_list *timer) -{ - if (!timer_pending(timer)) - return 0; - list_del(&timer->list); - return 1; -} - -int mod_timer(struct timer_list *timer, unsigned long expires) -{ - int ret; - unsigned long flags; - - spin_lock_irqsave(&timerlist_lock, flags); - timer->expires = expires; - ret = detach_timer(timer); - internal_add_timer(timer); - spin_unlock_irqrestore(&timerlist_lock, flags); - return ret; -} - -int del_timer(struct timer_list * timer) -{ - int ret; - unsigned long flags; - - spin_lock_irqsave(&timerlist_lock, flags); - ret = detach_timer(timer); - timer->list.next = timer->list.prev = NULL; - spin_unlock_irqrestore(&timerlist_lock, flags); - return ret; -} - -#ifdef CONFIG_SMP -void sync_timers(void) -{ - spin_unlock_wait(&global_bh_lock); -} - -/* - * SMP specific function to delete periodic timer. - * Caller must disable by some means restarting the timer - * for new. Upon exit the timer is not queued and handler is not running - * on any CPU. It returns number of times, which timer was deleted - * (for reference counting). - */ - -int del_timer_sync(struct timer_list * timer) -{ - int ret = 0; - - for (;;) { - unsigned long flags; - int running; - - spin_lock_irqsave(&timerlist_lock, flags); - ret += detach_timer(timer); - timer->list.next = timer->list.prev = 0; - running = timer_is_running(timer); - spin_unlock_irqrestore(&timerlist_lock, flags); - - if (!running) - break; - - timer_synchronize(timer); - } - - return ret; -} -#endif - - -static inline void cascade_timers(struct timer_vec *tv) -{ - /* cascade all the timers from tv up one level */ - struct list_head *head, *curr, *next; - - head = tv->vec + tv->index; - curr = head->next; - /* - * We are removing _all_ timers from the list, so we don't have to - * detach them individually, just clear the list afterwards. - */ - while (curr != head) { - struct timer_list *tmp; - - tmp = list_entry(curr, struct timer_list, list); - next = curr->next; - list_del(curr); /* not needed */ - internal_add_timer(tmp); - curr = next; - } - INIT_LIST_HEAD(head); - tv->index = (tv->index + 1) & TVN_MASK; -} - -static inline void run_timer_list(void) -{ - spin_lock_irq(&timerlist_lock); - while ((long)(jiffies - timer_jiffies) >= 0) { - struct list_head *head, *curr; - if (!tv1.index) { - int n = 1; - do { - cascade_timers(tvecs[n]); - } while (tvecs[n]->index == 1 && ++n < NOOF_TVECS); - } - repeat: - head = tv1.vec + tv1.index; - curr = head->next; - if (curr != head) { - struct timer_list *timer; - void (*fn)(unsigned long); - unsigned long data; - - timer = list_entry(curr, struct timer_list, list); - fn = timer->function; - data= timer->data; - - detach_timer(timer); - timer->list.next = timer->list.prev = NULL; - timer_enter(timer); - spin_unlock_irq(&timerlist_lock); - fn(data); - spin_lock_irq(&timerlist_lock); - timer_exit(); - goto repeat; - } - ++timer_jiffies; - tv1.index = (tv1.index + 1) & TVR_MASK; - } - spin_unlock_irq(&timerlist_lock); -} - -spinlock_t tqueue_lock = SPIN_LOCK_UNLOCKED; - -static void update_wall_time(unsigned long ticks) -{ - do { - ticks--; - xtime.tv_usec += 1000000/HZ; - } while (ticks); - - if (xtime.tv_usec >= 1000000) { - xtime.tv_usec -= 1000000; - xtime.tv_sec++; - } -} - -/* jiffies at the most recent update of wall time */ -unsigned long wall_jiffies; - -/* - * This spinlock protect us from races in SMP while playing with xtime. -arca - */ -rwlock_t xtime_lock = RW_LOCK_UNLOCKED; - -static inline void update_times(void) -{ - unsigned long ticks; - - /* - * update_times() is run from the raw timer_bh handler so we - * just know that the irqs are locally enabled and so we don't - * need to save/restore the flags of the local CPU here. -arca - */ - write_lock_irq(&xtime_lock); - - ticks = jiffies - wall_jiffies; - if (ticks) { - wall_jiffies += ticks; - update_wall_time(ticks); - } - write_unlock_irq(&xtime_lock); -} - -void timer_bh(void) -{ - update_times(); - run_timer_list(); -} - -void do_timer(struct pt_regs *regs) -{ - (*(unsigned long *)&jiffies)++; - mark_bh(TIMER_BH); -} diff --git a/xen/include/asm-x86/processor.h b/xen/include/asm-x86/processor.h index 54a82a3a16..b1b10493f6 100644 --- a/xen/include/asm-x86/processor.h +++ b/xen/include/asm-x86/processor.h @@ -340,33 +340,10 @@ long set_fast_trap(struct task_struct *p, int idx); { {0} } /* io permissions */ \ } -#define INIT_TSS { \ - 0,0, /* back_link, __blh */ \ - 0, /* esp0 */ \ - 0, 0, /* ss0 */ \ - 0,0,0,0,0,0, /* stack1, stack2 */ \ - 0, /* cr3 */ \ - 0,0, /* eip,eflags */ \ - 0,0,0,0, /* eax,ecx,edx,ebx */ \ - 0,0,0,0, /* esp,ebp,esi,edi */ \ - 0,0,0,0,0,0, /* es,cs,ss */ \ - 0,0,0,0,0,0, /* ds,fs,gs */ \ - 0,0, /* ldt */ \ - 0, INVALID_IO_BITMAP_OFFSET, /* tace, bitmap */ \ - { [0 ... IO_BITMAP_SIZE] = ~0UL }, /* ioperm */ \ -} - #elif defined(__x86_64__) #define INIT_THREAD { 0 } -#define INIT_TSS { \ - 0,0, \ - 0,0,0,0,{0},0,0, \ - 0, INVALID_IO_BITMAP_OFFSET, \ - { [0 ... IO_BITMAP_SIZE] = ~0UL } \ -} - #endif /* __x86_64__ */ struct mm_struct { diff --git a/xen/include/xen/interrupt.h b/xen/include/xen/interrupt.h index 884c14d13a..25f2272fd7 100644 --- a/xen/include/xen/interrupt.h +++ b/xen/include/xen/interrupt.h @@ -1,4 +1,3 @@ -/* interrupt.h */ #ifndef _LINUX_INTERRUPT_H #define _LINUX_INTERRUPT_H @@ -11,39 +10,24 @@ #include <asm/atomic.h> #include <asm/ptrace.h> -/* For 2.6.x compatibility */ -typedef void irqreturn_t; -#define IRQ_NONE -#define IRQ_HANDLED -#define IRQ_RETVAL(x) - struct irqaction { - void (*handler)(int, void *, struct pt_regs *); - unsigned long flags; - unsigned long mask; - const char *name; - void *dev_id; - struct irqaction *next; -}; - -enum { - TIMER_BH = 0, - SCSI_BH + void (*handler)(int, void *, struct pt_regs *); + unsigned long flags; + unsigned long mask; + const char *name; + void *dev_id; + struct irqaction *next; }; #include <asm/hardirq.h> #include <asm/softirq.h> - enum { - HI_SOFTIRQ=0, - NET_RX_SOFTIRQ, - AC_TIMER_SOFTIRQ, - TASKLET_SOFTIRQ, - BLKDEV_RESPONSE_SOFTIRQ, - NET_TX_SOFTIRQ, - NEW_TLBFLUSH_CLOCK_PERIOD_SOFTIRQ + HI_SOFTIRQ=0, + AC_TIMER_SOFTIRQ, + TASKLET_SOFTIRQ, + NEW_TLBFLUSH_CLOCK_PERIOD_SOFTIRQ }; /* softirq mask and active fields moved to irq_cpustat_t in @@ -52,8 +36,8 @@ enum struct softirq_action { - void (*action)(struct softirq_action *); - void *data; + void (*action)(struct softirq_action *); + void *data; }; asmlinkage void do_softirq(void); @@ -63,8 +47,6 @@ extern void softirq_init(void); extern void FASTCALL(cpu_raise_softirq(unsigned int cpu, unsigned int nr)); extern void FASTCALL(raise_softirq(unsigned int nr)); - - /* Tasklets --- multithreaded analogue of BHs. Main feature differing them of generic softirqs: tasklet @@ -87,11 +69,11 @@ extern void FASTCALL(raise_softirq(unsigned int nr)); struct tasklet_struct { - struct tasklet_struct *next; - unsigned long state; - atomic_t count; - void (*func)(unsigned long); - unsigned long data; + struct tasklet_struct *next; + unsigned long state; + atomic_t count; + void (*func)(unsigned long); + unsigned long data; }; #define DECLARE_TASKLET(name, func, data) \ @@ -103,13 +85,13 @@ struct tasklet_struct name = { NULL, 0, ATOMIC_INIT(1), func, data } enum { - TASKLET_STATE_SCHED, /* Tasklet is scheduled for execution */ - TASKLET_STATE_RUN /* Tasklet is running (SMP only) */ + TASKLET_STATE_SCHED, /* Tasklet is scheduled for execution */ + TASKLET_STATE_RUN /* Tasklet is running (SMP only) */ }; struct tasklet_head { - struct tasklet_struct *list; + struct tasklet_struct *list; } __attribute__ ((__aligned__(SMP_CACHE_BYTES))); extern struct tasklet_head tasklet_vec[NR_CPUS]; @@ -118,18 +100,18 @@ extern struct tasklet_head tasklet_hi_vec[NR_CPUS]; #ifdef CONFIG_SMP static inline int tasklet_trylock(struct tasklet_struct *t) { - return !test_and_set_bit(TASKLET_STATE_RUN, &(t)->state); + return !test_and_set_bit(TASKLET_STATE_RUN, &(t)->state); } static inline void tasklet_unlock(struct tasklet_struct *t) { - smp_mb__before_clear_bit(); - clear_bit(TASKLET_STATE_RUN, &(t)->state); + smp_mb__before_clear_bit(); + clear_bit(TASKLET_STATE_RUN, &(t)->state); } static inline void tasklet_unlock_wait(struct tasklet_struct *t) { - while (test_bit(TASKLET_STATE_RUN, &(t)->state)) { barrier(); } + while (test_bit(TASKLET_STATE_RUN, &(t)->state)) { barrier(); } } #else #define tasklet_trylock(t) 1 @@ -141,46 +123,46 @@ extern void FASTCALL(__tasklet_schedule(struct tasklet_struct *t)); static inline void tasklet_schedule(struct tasklet_struct *t) { - if (!test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) - __tasklet_schedule(t); + if (!test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) + __tasklet_schedule(t); } extern void FASTCALL(__tasklet_hi_schedule(struct tasklet_struct *t)); static inline void tasklet_hi_schedule(struct tasklet_struct *t) { - if (!test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) - __tasklet_hi_schedule(t); + if (!test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) + __tasklet_hi_schedule(t); } static inline void tasklet_disable_nosync(struct tasklet_struct *t) { - atomic_inc(&t->count); - smp_mb__after_atomic_inc(); + atomic_inc(&t->count); + smp_mb__after_atomic_inc(); } static inline void tasklet_disable(struct tasklet_struct *t) { - tasklet_disable_nosync(t); - tasklet_unlock_wait(t); - smp_mb(); + tasklet_disable_nosync(t); + tasklet_unlock_wait(t); + smp_mb(); } static inline void tasklet_enable(struct tasklet_struct *t) { - smp_mb__before_atomic_dec(); - if (atomic_dec_and_test(&t->count) && - test_bit(TASKLET_STATE_SCHED, &t->state)) - __tasklet_schedule(t); + smp_mb__before_atomic_dec(); + if (atomic_dec_and_test(&t->count) && + test_bit(TASKLET_STATE_SCHED, &t->state)) + __tasklet_schedule(t); } static inline void tasklet_hi_enable(struct tasklet_struct *t) { - smp_mb__before_atomic_dec(); - if (atomic_dec_and_test(&t->count) && - test_bit(TASKLET_STATE_SCHED, &t->state)) - __tasklet_hi_schedule(t); + smp_mb__before_atomic_dec(); + if (atomic_dec_and_test(&t->count) && + test_bit(TASKLET_STATE_SCHED, &t->state)) + __tasklet_hi_schedule(t); } extern void tasklet_kill(struct tasklet_struct *t); @@ -205,23 +187,6 @@ static void name (unsigned long dummy) \ #endif /* CONFIG_SMP */ - -/* Old BH definitions */ - -extern struct tasklet_struct bh_task_vec[]; - -/* It is exported _ONLY_ for wait_on_irq(). */ -extern spinlock_t global_bh_lock; - -static inline void mark_bh(int nr) -{ - tasklet_hi_schedule(bh_task_vec+nr); -} - -extern void init_bh(int nr, void (*routine)(void)); -extern void remove_bh(int nr); - - /* * Autoprobing for irqs: * diff --git a/xen/include/xen/lib.h b/xen/include/xen/lib.h index 5c55bf869c..d4899efe6a 100644 --- a/xen/include/xen/lib.h +++ b/xen/include/xen/lib.h @@ -3,6 +3,7 @@ #include <stdarg.h> #include <xen/types.h> +#include <xen/string.h> #ifndef NDEBUG #define ASSERT(_p) if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s", #_p , __LINE__, __FILE__); *(int*)0=0; } @@ -13,29 +14,9 @@ #define reserve_bootmem(_p,_l) \ printk("Memory Reservation 0x%lx, %lu bytes\n", (_p), (_l)) -/* lib.c */ -#include <xen/string.h> - -/* JWS - pulled over linux string library ({asm,linux}/string.h) -int memcmp(const void * cs,const void * ct,size_t count); -void * memcpy(void * dest,const void *src,size_t count); -int strncmp(const char * cs,const char * ct,size_t count); -int strcmp(const char * cs,const char * ct); -char * strcpy(char * dest,const char *src); -char * strncpy(char * dest,const char *src,size_t count); -void * memset(void * s,int c,size_t count); -size_t strnlen(const char * s, size_t count); -size_t strlen(const char * s); -char * strchr(const char *,int); -char * strstr(const char * s1,const char * s2); -*/ - -unsigned long str_to_quad(unsigned char *s); -unsigned char *quad_to_str(unsigned long q, unsigned char *s); - /* kernel.c */ #define printk printf -void printf (const char *format, ...); +void printf(const char *format, ...); void panic(const char *format, ...); /* vsprintf.c */ @@ -50,7 +31,4 @@ long simple_strtol(const char *cp,char **endp,unsigned int base); unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base); long long simple_strtoll(const char *cp,char **endp,unsigned int base); -/* Produce a 32-bit hash from a key string 'k' of length 'len' bytes. */ -u32 hash(unsigned char *k, unsigned long len); - #endif /* __LIB_H__ */ diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index 2895f1f460..1eb0aa8bda 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -24,12 +24,8 @@ extern unsigned long volatile jiffies; extern rwlock_t tasklist_lock; -extern struct timeval xtime; - #include <xen/spinlock.h> -extern struct mm_struct init_mm; - #define _HYP_EVENT_NEED_RESCHED 0 #define _HYP_EVENT_DIE 1 diff --git a/xen/include/xen/time.h b/xen/include/xen/time.h index 367d0e4585..e73d43805e 100644 --- a/xen/include/xen/time.h +++ b/xen/include/xen/time.h @@ -27,14 +27,10 @@ #ifndef __XEN_TIME_H__ #define __XEN_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 <xen/types.h> #include <hypervisor-ifs/hypervisor-if.h> -/* - * Init time - */ extern int init_xen_time(); @@ -49,22 +45,13 @@ extern int init_xen_time(); s_time_t get_s_time(void); -#define NOW() ((s_time_t)get_s_time()) -#define SECONDS(_s) (((s_time_t)(_s)) * 1000000000ULL ) -#define MILLISECS(_ms) (((s_time_t)(_ms)) * 1000000ULL ) -#define MICROSECS(_us) (((s_time_t)(_us)) * 1000ULL ) -#define Time_Max ((s_time_t) 0x7fffffffffffffffLL) -#define FOREVER Time_Max +#define NOW() ((s_time_t)get_s_time()) +#define SECONDS(_s) (((s_time_t)(_s)) * 1000000000ULL ) +#define MILLISECS(_ms) (((s_time_t)(_ms)) * 1000000ULL ) +#define MICROSECS(_us) (((s_time_t)(_us)) * 1000ULL ) -/* Wall Clock Time */ -struct timeval { - long tv_sec; /* seconds */ - long tv_usec; /* microseconds */ -}; - extern void update_dom_time(shared_info_t *si); extern void do_settime(unsigned long secs, unsigned long usecs, u64 system_time_base); -extern void do_timer(struct pt_regs *regs); #endif /* __XEN_TIME_H__ */ diff --git a/xen/include/xen/timer.h b/xen/include/xen/timer.h deleted file mode 100644 index f837df65c4..0000000000 --- a/xen/include/xen/timer.h +++ /dev/null @@ -1,81 +0,0 @@ -#ifndef _LINUX_TIMER_H -#define _LINUX_TIMER_H - -#include <xen/config.h> -#include <xen/list.h> - -/* - * In Linux 2.4, static timers have been removed from the kernel. - * Timers may be dynamically created and destroyed, and should be initialized - * by a call to init_timer() upon creation. - * - * 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; /* jiffies */ - unsigned long data; - void (*function)(unsigned long); -}; - -extern void add_timer(struct timer_list * timer); -extern int del_timer(struct timer_list * timer); - -#ifdef CONFIG_SMP -extern int del_timer_sync(struct timer_list * timer); -extern void sync_timers(void); -#else -#define del_timer_sync(t) del_timer(t) -#define sync_timers() do { } while (0) -#endif - -/* - * mod_timer is a more efficient way to update the expire field of an - * active timer (if the timer is inactive it will be activated) - * mod_timer(a,b) is equivalent to del_timer(a); a->expires = b; add_timer(a). - * If the timer is known to be not pending (ie, in the handler), mod_timer - * is less efficient than a->expires = b; add_timer(a). - */ -int mod_timer(struct timer_list *timer, unsigned long expires); - -extern void it_real_fn(unsigned long); - -static inline void init_timer(struct timer_list * timer) -{ - timer->list.next = timer->list.prev = NULL; -} - -static inline int timer_pending (const struct timer_list * timer) -{ - return timer->list.next != NULL; -} - -/* - * These inlines deal with timer wrapping correctly. You are - * strongly encouraged to use them - * 1. Because people otherwise forget - * 2. Because if the timer wrap changes in future you wont have to - * alter your driver code. - * - * time_after(a,b) returns true if the time a is after time b. - * - * Do this with "<0" and ">=0" to only test the sign of the result. A - * good compiler would generate better code (and a really good compiler - * wouldn't care). Gcc is currently neither. - */ -#define time_after(a,b) ((long)(b) - (long)(a) < 0) -#define time_before(a,b) time_after(b,a) - -#define time_after_eq(a,b) ((long)(a) - (long)(b) >= 0) -#define time_before_eq(a,b) time_after_eq(b,a) - -#endif diff --git a/xen/include/xen/tqueue.h b/xen/include/xen/tqueue.h deleted file mode 100644 index 81dba4912f..0000000000 --- a/xen/include/xen/tqueue.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * tqueue.h --- task queue handling for Linux. - * - * Mostly based on a proposed bottom-half replacement code written by - * Kai Petzke, wpp@marie.physik.tu-berlin.de. - * - * Modified for use in the Linux kernel by Theodore Ts'o, - * tytso@mit.edu. Any bugs are my fault, not Kai's. - * - * The original comment follows below. - */ - -#ifndef _LINUX_TQUEUE_H -#define _LINUX_TQUEUE_H - -#include <xen/spinlock.h> -#include <xen/list.h> -#include <asm/bitops.h> -#include <asm/system.h> - -/* - * New proposed "bottom half" handlers: - * (C) 1994 Kai Petzke, wpp@marie.physik.tu-berlin.de - * - * Advantages: - * - Bottom halfs are implemented as a linked list. You can have as many - * of them, as you want. - * - No more scanning of a bit field is required upon call of a bottom half. - * - Support for chained bottom half lists. The run_task_queue() function can be - * used as a bottom half handler. This is for example useful for bottom - * halfs, which want to be delayed until the next clock tick. - * - * Notes: - * - Bottom halfs are called in the reverse order that they were linked into - * the list. - */ - -struct tq_struct { - struct list_head list; /* linked list of active bh's */ - unsigned long sync; /* must be initialized to zero */ - void (*routine)(void *); /* function to call */ - void *data; /* argument to function */ -}; - -/* - * Emit code to initialise a tq_struct's routine and data pointers - */ -#define PREPARE_TQUEUE(_tq, _routine, _data) \ - do { \ - (_tq)->routine = _routine; \ - (_tq)->data = _data; \ - } while (0) - -/* - * Emit code to initialise all of a tq_struct - */ -#define INIT_TQUEUE(_tq, _routine, _data) \ - do { \ - INIT_LIST_HEAD(&(_tq)->list); \ - (_tq)->sync = 0; \ - PREPARE_TQUEUE((_tq), (_routine), (_data)); \ - } while (0) - -typedef struct list_head task_queue; - -#define DECLARE_TASK_QUEUE(q) LIST_HEAD(q) -#define TQ_ACTIVE(q) (!list_empty(&q)) - -extern task_queue tq_disk; - -/* - * To implement your own list of active bottom halfs, use the following - * two definitions: - * - * DECLARE_TASK_QUEUE(my_tqueue); - * struct tq_struct my_task = { - * routine: (void (*)(void *)) my_routine, - * data: &my_data - * }; - * - * To activate a bottom half on a list, use: - * - * queue_task(&my_task, &my_tqueue); - * - * To later run the queued tasks use - * - * run_task_queue(&my_tqueue); - * - * This allows you to do deferred processing. For example, you could - * have a task queue called tq_timer, which is executed within the timer - * interrupt. - */ - -extern spinlock_t tqueue_lock; - -/* - * Queue a task on a tq. Return non-zero if it was successfully - * added. - */ -static inline int queue_task(struct tq_struct *bh_pointer, task_queue *bh_list) -{ - int ret = 0; - if (!test_and_set_bit(0,&bh_pointer->sync)) { - unsigned long flags; - spin_lock_irqsave(&tqueue_lock, flags); - list_add_tail(&bh_pointer->list, bh_list); - spin_unlock_irqrestore(&tqueue_lock, flags); - ret = 1; - } - return ret; -} - -/* - * Call all "bottom halfs" on a given list. - */ - -extern void __run_task_queue(task_queue *list); - -static inline void run_task_queue(task_queue *list) -{ - if (TQ_ACTIVE(*list)) - __run_task_queue(list); -} - -#endif /* _LINUX_TQUEUE_H */ |