[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] SMP timer and irq fixes for 2.6. Merge x86/64 time.c with i386.
ChangeSet 1.1452, 2005/04/05 13:07:37+01:00, kaf24@xxxxxxxxxxxxxxxxxxxx SMP timer and irq fixes for 2.6. Merge x86/64 time.c with i386. Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c | 65 - b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/time.c | 126 -- b/linux-2.6.11-xen-sparse/arch/xen/i386/mm/hypervisor.c | 4 b/linux-2.6.11-xen-sparse/arch/xen/x86_64/kernel/Makefile | 4 linux-2.6.11-xen-sparse/arch/xen/x86_64/kernel/time.c | 840 -------------- 5 files changed, 91 insertions(+), 948 deletions(-) diff -Nru a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c --- a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c 2005-04-05 09:03:31 -04:00 +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c 2005-04-05 09:03:31 -04:00 @@ -437,21 +437,23 @@ int cpucount; -static irqreturn_t local_debug_interrupt(int irq, void *dev_id, - struct pt_regs *regs) +static irqreturn_t ldebug_interrupt( + int irq, void *dev_id, struct pt_regs *regs) { - return IRQ_HANDLED; } -static struct irqaction local_irq_debug = { - local_debug_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "ldebug", - NULL, NULL -}; +static DEFINE_PER_CPU(int, ldebug_irq); +static char ldebug_name[NR_IRQS][15]; -void local_setup_debug(void) +void ldebug_setup(void) { - (void)setup_irq(bind_virq_to_irq(VIRQ_DEBUG), &local_irq_debug); + int cpu = smp_processor_id(); + + per_cpu(ldebug_irq, cpu) = bind_virq_to_irq(VIRQ_DEBUG); + sprintf(ldebug_name[cpu], "ldebug%d", cpu); + BUG_ON(request_irq(per_cpu(ldebug_irq, cpu), ldebug_interrupt, + SA_INTERRUPT, ldebug_name[cpu], NULL)); } @@ -472,7 +474,7 @@ while (!cpu_isset(smp_processor_id(), smp_commenced_mask)) rep_nop(); local_setup_timer(); - local_setup_debug(); /* XXX */ + ldebug_setup(); smp_intr_init(); local_irq_enable(); /* @@ -1329,36 +1331,27 @@ } extern irqreturn_t smp_reschedule_interrupt(int, void *, struct pt_regs *); - -static struct irqaction reschedule_irq = { - smp_reschedule_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "reschedule", - NULL, NULL -}; - -extern irqreturn_t smp_invalidate_interrupt(int, void *, struct pt_regs *); - -static struct irqaction invalidate_irq = { - smp_invalidate_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "invalidate", - NULL, NULL -}; - extern irqreturn_t smp_call_function_interrupt(int, void *, struct pt_regs *); -static struct irqaction call_function_irq = { - smp_call_function_interrupt, SA_INTERRUPT, CPU_MASK_NONE, - "call_function", NULL, NULL -}; +static DEFINE_PER_CPU(int, resched_irq); +static DEFINE_PER_CPU(int, callfunc_irq); +static char resched_name[NR_IRQS][15]; +static char callfunc_name[NR_IRQS][15]; void __init smp_intr_init(void) { + int cpu = smp_processor_id(); - (void)setup_irq( - bind_ipi_on_cpu_to_irq(smp_processor_id(), RESCHEDULE_VECTOR), - &reschedule_irq); - (void)setup_irq( - bind_ipi_on_cpu_to_irq(smp_processor_id(), INVALIDATE_TLB_VECTOR), - &invalidate_irq); - (void)setup_irq( - bind_ipi_on_cpu_to_irq(smp_processor_id(), CALL_FUNCTION_VECTOR), - &call_function_irq); + per_cpu(resched_irq, cpu) = + bind_ipi_on_cpu_to_irq(cpu, RESCHEDULE_VECTOR); + sprintf(resched_name[cpu], "resched%d", cpu); + BUG_ON(request_irq(per_cpu(resched_irq, cpu), smp_reschedule_interrupt, + SA_INTERRUPT, resched_name[cpu], NULL)); + + per_cpu(callfunc_irq, cpu) = + bind_ipi_on_cpu_to_irq(cpu, CALL_FUNCTION_VECTOR); + sprintf(callfunc_name[cpu], "callfunc%d", cpu); + BUG_ON(request_irq(per_cpu(callfunc_irq, cpu), + smp_call_function_interrupt, + SA_INTERRUPT, callfunc_name[cpu], NULL)); } diff -Nru a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/time.c b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/time.c --- a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/time.c 2005-04-05 09:03:31 -04:00 +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/time.c 2005-04-05 09:03:31 -04:00 @@ -77,6 +77,15 @@ EXPORT_SYMBOL(jiffies_64); +#if defined(__x86_64__) +unsigned long vxtime_hz = PIT_TICK_RATE; +struct vxtime_data __vxtime __section_vxtime; /* for vsyscalls */ +volatile unsigned long __jiffies __section_jiffies = INITIAL_JIFFIES; +unsigned long __wall_jiffies __section_wall_jiffies = INITIAL_JIFFIES; +struct timespec __xtime __section_xtime; +struct timezone __sys_tz __section_sys_tz; +#endif + unsigned long cpu_khz; /* Detected as we calibrate the TSC */ extern unsigned long wall_jiffies; @@ -111,8 +120,8 @@ static long last_update_from_xen; /* UTC seconds when last read Xen clock. */ /* Keep track of last time we did processing/updating of jiffies and xtime. */ -u64 processed_system_time; /* System time (ns) at last processing. */ -DEFINE_PER_CPU(u64, processed_system_time); +static u64 processed_system_time; /* System time (ns) at last processing. */ +static DEFINE_PER_CPU(u64, processed_system_time); #define NS_PER_TICK (1000000000ULL/HZ) @@ -379,37 +388,49 @@ struct pt_regs *regs) { time_t wtm_sec, sec; - s64 delta, nsec; + s64 delta, delta_cpu, nsec; long sec_diff, wtm_nsec; + int cpu = smp_processor_id(); do { __get_time_values_from_xen(); - delta = (s64)(shadow_system_time + - ((s64)cur_timer->get_offset() * - (s64)NSEC_PER_USEC) - - processed_system_time); + delta = delta_cpu = (s64)shadow_system_time + + ((s64)cur_timer->get_offset() * (s64)NSEC_PER_USEC); + delta -= processed_system_time; + delta_cpu -= per_cpu(processed_system_time, cpu); } while (!TIME_VALUES_UP_TO_DATE); - if (unlikely(delta < 0)) { - printk("Timer ISR: Time went backwards: %lld %lld %lld %lld\n", - delta, shadow_system_time, + if (unlikely(delta < 0) || unlikely(delta_cpu < 0)) { + printk("Timer ISR/%d: Time went backwards: " + "delta=%lld cpu_delta=%lld shadow=%lld " + "off=%lld processed=%lld cpu_processed=%lld\n", + cpu, delta, delta_cpu, shadow_system_time, ((s64)cur_timer->get_offset() * (s64)NSEC_PER_USEC), - processed_system_time); + processed_system_time, + per_cpu(processed_system_time, cpu)); return; } - /* Process elapsed jiffies since last call. */ + /* System-wide jiffy work. */ while (delta >= NS_PER_TICK) { delta -= NS_PER_TICK; processed_system_time += NS_PER_TICK; do_timer(regs); + } + + /* Local CPU jiffy work. */ + while (delta_cpu >= NS_PER_TICK) { + delta_cpu -= NS_PER_TICK; + per_cpu(processed_system_time, cpu) += NS_PER_TICK; update_process_times(user_mode(regs)); - if (regs) - profile_tick(CPU_PROFILING, regs); + profile_tick(CPU_PROFILING, regs); } + if (cpu != 0) + return; + /* * Take synchronised time from Xen once a minute if we're not * synchronised ourselves, and we haven't chosen to keep an independent @@ -617,10 +638,10 @@ #endif /* Dynamically-mapped IRQ. */ -static int TIMER_IRQ; +static DEFINE_PER_CPU(int, timer_irq); static struct irqaction irq_timer = { - timer_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "timer", + timer_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "timer0", NULL, NULL }; @@ -642,14 +663,23 @@ set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec); processed_system_time = shadow_system_time; + per_cpu(processed_system_time, 0) = processed_system_time; if (timer_tsc_init.init(NULL) != 0) BUG(); printk(KERN_INFO "Using %s for high-res timesource\n",cur_timer->name); - TIMER_IRQ = bind_virq_to_irq(VIRQ_TIMER); +#if defined(__x86_64__) + vxtime.mode = VXTIME_TSC; + vxtime.quot = (1000000L << 32) / vxtime_hz; + vxtime.tsc_quot = (1000L << 32) / cpu_khz; + vxtime.hz = vxtime_hz; + sync_core(); + rdtscll(vxtime.last_tsc); +#endif - (void)setup_irq(TIMER_IRQ, &irq_timer); + per_cpu(timer_irq, 0) = bind_virq_to_irq(VIRQ_TIMER); + (void)setup_irq(per_cpu(timer_irq, 0), &irq_timer); } /* Convert jiffies to system time. Call with xtime_lock held for reading. */ @@ -719,6 +749,7 @@ /* Reset our own concept of passage of system time. */ processed_system_time = shadow_system_time; + per_cpu(processed_system_time, 0) = processed_system_time; /* Accept a warp in UTC (wall-clock) time. */ last_seen_tv.tv_sec = 0; @@ -728,63 +759,20 @@ } #ifdef CONFIG_SMP - -static irqreturn_t local_timer_interrupt(int irq, void *dev_id, - struct pt_regs *regs) -{ - s64 delta; - int cpu = smp_processor_id(); - - do { _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |