[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH, v3] reduce 'd' debug key's global impact
Given the abstraction you created, I decided it was best to put the x86 implementation of smp_send_state_dump() in the spurious-interrupt handler. Also I changed the keyhandler.c changes around a bunch and removed the needless CONFIG_SMP ifdefs. I checked the result in as xen-unstable:21309. Thanks, Keir On 06/05/2010 14:05, "Jan Beulich" <JBeulich@xxxxxxxxxx> wrote: > On large systems, dumping state may cause time management to get > stalled for so long a period that it wouldn't recover. Therefore alter > the state dumping logic to alternatively block each CPU as it prints > rather than one CPU for a very long time (using the alternative key > handling toggle introduced with an earlier patch). > > Further, instead of using on_selected_cpus(), which is unsafe when > the dumping happens from a hardware interrupt, introduce and use a > dedicated IPI sending function (which each architecture can implement > to its liking) > > Finally, don't print useless data (e.g. the hypervisor context of the > interrupt that is used for triggering the printing, but isn't part of > the context that's actually interesting). > > Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx> > > --- 2010-05-04.orig/xen/arch/ia64/linux-xen/smp.c 2010-05-06 > 14:52:45.000000000 +0200 > +++ 2010-05-04/xen/arch/ia64/linux-xen/smp.c 2010-05-06 11:20:40.000000000 > +0200 > @@ -94,6 +94,7 @@ static volatile struct call_data_struct > > #define IPI_CALL_FUNC 0 > #define IPI_CPU_STOP 1 > +#define IPI_STATE_DUMP 2 > > /* This needs to be cacheline aligned because it is written to by *other* > CPUs. */ > static DEFINE_PER_CPU(u64, ipi_operation) ____cacheline_aligned; > @@ -202,6 +203,10 @@ handle_IPI (int irq, void *dev_id, struc > stop_this_cpu(); > break; > > + case IPI_STATE_DUMP: > + dump_execstate(regs); > + break; > + > default: > printk(KERN_CRIT "Unknown IPI on CPU %d: %lu\n", this_cpu, which); > break; > @@ -479,6 +484,12 @@ smp_send_stop (void) > send_IPI_allbutself(IPI_CPU_STOP); > } > > +void > +smp_send_state_dump (unsigned int cpu) > +{ > + send_IPI_single(cpu, IPI_STATE_DUMP); > +} > + > int __init > setup_profiling_timer (unsigned int multiplier) > { > --- 2010-05-04.orig/xen/arch/x86/smp.c 2010-05-06 14:52:45.000000000 +0200 > +++ 2010-05-04/xen/arch/x86/smp.c 2010-05-06 11:21:07.000000000 +0200 > @@ -375,11 +375,24 @@ void smp_send_nmi_allbutself(void) > send_IPI_mask(&cpu_online_map, APIC_DM_NMI); > } > > +void smp_send_state_dump(unsigned int cpu) > +{ > + state_dump_pending(cpu) = 1; > + smp_send_event_check_cpu(cpu); > +} > + > fastcall void smp_event_check_interrupt(struct cpu_user_regs *regs) > { > struct cpu_user_regs *old_regs = set_irq_regs(regs); > ack_APIC_irq(); > perfc_incr(ipis); > + if ( unlikely(state_dump_pending(smp_processor_id())) ) > + { > + irq_enter(); > + state_dump_pending(smp_processor_id()) = 0; > + dump_execstate(regs); > + irq_exit(); > + } > set_irq_regs(old_regs); > } > > --- 2010-05-04.orig/xen/common/keyhandler.c 2010-05-04 13:21:53.000000000 > +0200 > +++ 2010-05-04/xen/common/keyhandler.c 2010-05-06 11:40:55.000000000 +0200 > @@ -71,19 +71,52 @@ static struct keyhandler show_handlers_k > .desc = "show this message" > }; > > -static void __dump_execstate(void *unused) > +#ifdef CONFIG_SMP > +static cpumask_t dump_execstate_mask; > +#endif > + > +void dump_execstate(struct cpu_user_regs *regs) > { > - dump_execution_state(); > - printk("*** Dumping CPU%d guest state: ***\n", smp_processor_id()); > + unsigned int cpu = smp_processor_id(); > + > + if ( !guest_mode(regs) ) > + { > + printk("\n*** Dumping CPU%u host state: ***\n", cpu); > + show_execution_state(regs); > + } > if ( is_idle_vcpu(current) ) > - printk("No guest context (CPU is idle).\n"); > + printk("No guest context (CPU%u is idle).\n", cpu); > else > + { > + printk("*** Dumping CPU%u guest state (d%d:v%d): ***\n", > + smp_processor_id(), current->domain->domain_id, > + current->vcpu_id); > show_execution_state(guest_cpu_user_regs()); > + } > + > +#ifdef CONFIG_SMP > + cpu_clear(cpu, dump_execstate_mask); > + if ( !alt_key_handling ) > + return; > + > + cpu = cycle_cpu(cpu, dump_execstate_mask); > + if ( cpu < NR_CPUS ) > + smp_send_state_dump(cpu); > + else > + { > + printk("\n"); > + > + console_end_sync(); > + watchdog_enable(); > + } > +#endif > } > > static void dump_registers(unsigned char key, struct cpu_user_regs *regs) > { > +#ifdef CONFIG_SMP > unsigned int cpu; > +#endif > > /* We want to get everything out that we possibly can. */ > watchdog_disable(); > @@ -91,17 +124,28 @@ static void dump_registers(unsigned char > > printk("'%c' pressed -> dumping registers\n", key); > > +#ifdef CONFIG_SMP > + if ( alt_key_handling ) > + dump_execstate_mask = cpu_online_map; > +#endif > + > /* Get local execution state out immediately, in case we get stuck. */ > - printk("\n*** Dumping CPU%d host state: ***\n", smp_processor_id()); > - __dump_execstate(NULL); > + dump_execstate(regs); > + > +#ifdef CONFIG_SMP > + if ( alt_key_handling ) > + return; > > for_each_online_cpu ( cpu ) > { > if ( cpu == smp_processor_id() ) > continue; > - printk("\n*** Dumping CPU%d host state: ***\n", cpu); > - on_selected_cpus(cpumask_of(cpu), __dump_execstate, NULL, 1); > + cpu_set(cpu, dump_execstate_mask); > + smp_send_state_dump(cpu); > + while ( cpu_isset(cpu, dump_execstate_mask) ) > + cpu_relax(); > } > +#endif > > printk("\n"); > > --- 2010-05-04.orig/xen/include/asm-ia64/linux-xen/asm/ptrace.h 2010-05-06 > 14:52:45.000000000 +0200 > +++ 2010-05-04/xen/include/asm-ia64/linux-xen/asm/ptrace.h 2010-05-04 > 13:22:27.000000000 +0200 > @@ -280,7 +280,7 @@ struct switch_stack { > # define ia64_task_regs(t) (((struct pt_regs *) ((char *) (t) + > IA64_STK_OFFSET)) - 1) > # define ia64_psr(regs) ((struct ia64_psr *) &(regs)->cr_ipsr) > #ifdef XEN > -# define guest_mode(regs) (ia64_psr(regs)->cpl != 0) > +# define guest_mode(regs) (ia64_psr(regs)->cpl && !ia64_psr(regs)->vm) > # define guest_kernel_mode(regs) (ia64_psr(regs)->cpl == CONFIG_CPL0_EMUL) > # define vmx_guest_kernel_mode(regs) (ia64_psr(regs)->cpl == 0) > # define regs_increment_iip(regs) \ > --- 2010-05-04.orig/xen/include/asm-x86/hardirq.h 2010-05-06 > 14:52:57.000000000 +0200 > +++ 2010-05-04/xen/include/asm-x86/hardirq.h 2010-05-06 14:54:55.000000000 > +0200 > @@ -9,6 +9,7 @@ typedef struct { > unsigned int __local_irq_count; > unsigned int __nmi_count; > bool_t __mwait_wakeup; > + bool_t __state_dump_pending; > } __cacheline_aligned irq_cpustat_t; > > #include <xen/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ > --- 2010-05-04.orig/xen/include/xen/irq_cpustat.h 2010-05-06 > 14:52:57.000000000 +0200 > +++ 2010-05-04/xen/include/xen/irq_cpustat.h 2010-05-06 14:54:49.000000000 > +0200 > @@ -27,5 +27,6 @@ extern irq_cpustat_t irq_stat[]; > #define local_irq_count(cpu) __IRQ_STAT((cpu), __local_irq_count) > #define nmi_count(cpu) __IRQ_STAT((cpu), __nmi_count) > #define mwait_wakeup(cpu) __IRQ_STAT((cpu), __mwait_wakeup) > +#define state_dump_pending(cpu) __IRQ_STAT((cpu), __state_dump_pending) > > #endif /* __irq_cpustat_h */ > --- 2010-05-04.orig/xen/include/xen/lib.h 2010-05-06 14:52:45.000000000 +0200 > +++ 2010-05-04/xen/include/xen/lib.h 2010-05-06 11:17:03.000000000 +0200 > @@ -111,4 +111,7 @@ extern int tainted; > extern char *print_tainted(char *str); > extern void add_taint(unsigned); > > +struct cpu_user_regs; > +void dump_execstate(struct cpu_user_regs *); > + > #endif /* __LIB_H__ */ > --- 2010-05-04.orig/xen/include/xen/smp.h 2010-05-04 13:22:06.000000000 +0200 > +++ 2010-05-04/xen/include/xen/smp.h 2010-05-06 10:44:43.000000000 +0200 > @@ -13,6 +13,8 @@ extern void smp_send_event_check_mask(co > #define smp_send_event_check_cpu(cpu) \ > smp_send_event_check_mask(cpumask_of(cpu)) > > +extern void smp_send_state_dump(unsigned int cpu); > + > /* > * Prepare machine for booting other CPUs. > */ > > _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |