From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Jan Beulich" Subject: [PATCH, v2] reduce 'd' debug key's global impact Date: Wed, 05 May 2010 16:34:41 +0100 Message-ID: <4BE1AC3102000078000016B3@vpn.id2.novell.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=__Part5379F401.0__=" Return-path: List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xensource.com Errors-To: xen-devel-bounces@lists.xensource.com To: xen-devel@lists.xensource.com List-Id: xen-devel@lists.xenproject.org This is a MIME message. If you are reading this text, you may want to consider changing to a mail reader or gateway that understands how to properly handle MIME multipart messages. --=__Part5379F401.0__= Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: quoted-printable Content-Disposition: inline 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). Also 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 --- 2010-05-04.orig/xen/arch/ia64/linux-xen/smp.c 2010-05-05 = 16:42:36.000000000 +0200 +++ 2010-05-04/xen/arch/ia64/linux-xen/smp.c 2010-05-04 13:22:27.0000000= 00 +0200 @@ -189,7 +189,7 @@ handle_IPI (int irq, void *dev_id, struc * At this point the structure may = be gone unless * wait is true. */ - (*func)(info); + (*func)(info ?: regs); =20 /* Notify the sending CPU that the = task is done. */ mb(); --- 2010-05-04.orig/xen/arch/x86/smp.c 2010-05-05 16:42:36.000000000 = +0200 +++ 2010-05-04/xen/arch/x86/smp.c 2010-05-04 13:22:27.000000000 = +0200 @@ -395,7 +395,7 @@ static void __smp_call_function_interrup =20 if ( call_data.wait ) { - (*func)(info); + (*func)(info ?: get_irq_regs()); mb(); atomic_inc(&call_data.finished); } @@ -403,7 +403,7 @@ static void __smp_call_function_interrup { mb(); atomic_inc(&call_data.started); - (*func)(info); + (*func)(info ?: get_irq_regs()); } =20 irq_exit(); --- 2010-05-04.orig/xen/common/keyhandler.c 2010-05-04 13:21:53.0000000= 00 +0200 +++ 2010-05-04/xen/common/keyhandler.c 2010-05-05 16:49:24.000000000 = +0200 @@ -71,14 +71,44 @@ static struct keyhandler show_handlers_k .desc =3D "show this message" }; =20 -static void __dump_execstate(void *unused) +static cpumask_t dump_execstate_mask; + +static void __dump_execstate(void *_regs) { - dump_execution_state(); - printk("*** Dumping CPU%d guest state: ***\n", smp_processor_id()); + struct cpu_user_regs *regs =3D _regs; + unsigned int cpu =3D 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()); + } + + if ( !alt_key_handling ) + return; + + cpu =3D cycle_cpu(cpu, dump_execstate_mask); + if ( cpu < NR_CPUS ) + { + cpu_clear(cpu, dump_execstate_mask); + on_selected_cpus(cpumask_of(cpu), __dump_execstate, NULL, 0); + } + else + { + printk("\n"); + + console_end_sync(); + watchdog_enable(); + } } =20 static void dump_registers(unsigned char key, struct cpu_user_regs *regs) @@ -91,15 +121,20 @@ static void dump_registers(unsigned char =20 printk("'%c' pressed -> dumping registers\n", key); =20 + if ( alt_key_handling ) + cpus_andnot(dump_execstate_mask, cpu_online_map, + cpumask_of_cpu(smp_processor_id())); + /* 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); + + if ( alt_key_handling ) + return; =20 for_each_online_cpu ( cpu ) { if ( cpu =3D=3D smp_processor_id() ) continue; - printk("\n*** Dumping CPU%d host state: ***\n", cpu); on_selected_cpus(cpumask_of(cpu), __dump_execstate, NULL, 1); } =20 --- 2010-05-04.orig/xen/include/asm-ia64/linux-xen/asm/ptrace.h 2010-05-05 = 16:42:36.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 !=3D 0) +# define guest_mode(regs) (ia64_psr(regs)->cpl && !ia64_psr(r= egs)->vm) # define guest_kernel_mode(regs) (ia64_psr(regs)->cpl =3D=3D = CONFIG_CPL0_EMUL) # define vmx_guest_kernel_mode(regs) (ia64_psr(regs)->cpl =3D=3D 0) # define regs_increment_iip(regs) \ --=__Part5379F401.0__= Content-Type: text/plain; name="dump-exec-state.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="dump-exec-state.patch" On large systems, dumping state may cause time management to get=0Astalled = for so long a period that it wouldn't recover. Therefore alter=0Athe state = dumping logic to alternatively block each CPU as it prints=0Arather than = one CPU for a very long time (using the alternative key=0Ahandling toggle = introduced with an earlier patch). Also don't print=0Auseless data (e.g. = the hypervisor context of the interrupt that is=0Aused for triggering the = printing, but isn't part of the context that's=0Aactually interesting).=0A= =0ASigned-off-by: Jan Beulich =0A=0A--- 2010-05-04.ori= g/xen/arch/ia64/linux-xen/smp.c 2010-05-05 16:42:36.000000000 +0200=0A+++ = 2010-05-04/xen/arch/ia64/linux-xen/smp.c 2010-05-04 13:22:27.0000000= 00 +0200=0A@@ -189,7 +189,7 @@ handle_IPI (int irq, void *dev_id, struc=0A = * At this point the structure may = be gone unless=0A * wait is true.=0A = */=0A- = (*func)(info);=0A+ (*func)(info ?: = regs);=0A =0A /* Notify the sending CPU = that the task is done. */=0A mb();=0A--- = 2010-05-04.orig/xen/arch/x86/smp.c 2010-05-05 16:42:36.000000000 = +0200=0A+++ 2010-05-04/xen/arch/x86/smp.c 2010-05-04 13:22:27.0000000= 00 +0200=0A@@ -395,7 +395,7 @@ static void __smp_call_function_interrup=0A = =0A if ( call_data.wait )=0A {=0A- (*func)(info);=0A+ = (*func)(info ?: get_irq_regs());=0A mb();=0A atomic_inc(&c= all_data.finished);=0A }=0A@@ -403,7 +403,7 @@ static void __smp_call_f= unction_interrup=0A {=0A mb();=0A atomic_inc(&call_data= .started);=0A- (*func)(info);=0A+ (*func)(info ?: get_irq_reg= s());=0A }=0A =0A irq_exit();=0A--- 2010-05-04.orig/xen/common/keyh= andler.c 2010-05-04 13:21:53.000000000 +0200=0A+++ 2010-05-04/xen/co= mmon/keyhandler.c 2010-05-05 16:49:24.000000000 +0200=0A@@ -71,14 = +71,44 @@ static struct keyhandler show_handlers_k=0A .desc =3D "show = this message"=0A };=0A =0A-static void __dump_execstate(void *unused)=0A+st= atic cpumask_t dump_execstate_mask;=0A+=0A+static void __dump_execstate(voi= d *_regs)=0A {=0A- dump_execution_state();=0A- printk("*** Dumping = CPU%d guest state: ***\n", smp_processor_id());=0A+ struct cpu_user_regs= *regs =3D _regs;=0A+ unsigned int cpu =3D smp_processor_id();=0A+=0A+ = if ( !guest_mode(regs) )=0A+ {=0A+ printk("\n*** Dumping CPU%u = host state: ***\n", cpu);=0A+ show_execution_state(regs);=0A+ = }=0A if ( is_idle_vcpu(current) )=0A- printk("No guest context = (CPU is idle).\n");=0A+ printk("No guest context (CPU%u is = idle).\n", cpu);=0A else=0A+ {=0A+ printk("*** Dumping CPU%u = guest state (d%d:v%d): ***\n",=0A+ smp_processor_id(), = current->domain->domain_id,=0A+ current->vcpu_id);=0A = show_execution_state(guest_cpu_user_regs());=0A+ }=0A+=0A+ if ( = !alt_key_handling )=0A+ return;=0A+=0A+ cpu =3D cycle_cpu(cpu, = dump_execstate_mask);=0A+ if ( cpu < NR_CPUS )=0A+ {=0A+ = cpu_clear(cpu, dump_execstate_mask);=0A+ on_selected_cpus(cpumask_of= (cpu), __dump_execstate, NULL, 0);=0A+ }=0A+ else=0A+ {=0A+ = printk("\n");=0A+=0A+ console_end_sync();=0A+ watchdog_enabl= e();=0A+ }=0A }=0A =0A static void dump_registers(unsigned char key, = struct cpu_user_regs *regs)=0A@@ -91,15 +121,20 @@ static void dump_registe= rs(unsigned char=0A =0A printk("'%c' pressed -> dumping registers\n", = key);=0A =0A+ if ( alt_key_handling )=0A+ cpus_andnot(dump_execst= ate_mask, cpu_online_map,=0A+ cpumask_of_cpu(smp_process= or_id()));=0A+=0A /* Get local execution state out immediately, in = case we get stuck. */=0A- printk("\n*** Dumping CPU%d host state: = ***\n", smp_processor_id());=0A- __dump_execstate(NULL);=0A+ = __dump_execstate(regs);=0A+=0A+ if ( alt_key_handling )=0A+ = return;=0A =0A for_each_online_cpu ( cpu )=0A {=0A if ( = cpu =3D=3D smp_processor_id() )=0A continue;=0A- = printk("\n*** Dumping CPU%d host state: ***\n", cpu);=0A on_selecte= d_cpus(cpumask_of(cpu), __dump_execstate, NULL, 1);=0A }=0A =0A--- = 2010-05-04.orig/xen/include/asm-ia64/linux-xen/asm/ptrace.h 2010-05-05 = 16:42:36.000000000 +0200=0A+++ 2010-05-04/xen/include/asm-ia64/linux-xen/as= m/ptrace.h 2010-05-04 13:22:27.000000000 +0200=0A@@ -280,7 +280,7 @@ = struct switch_stack {=0A # define ia64_task_regs(t) (((struct = pt_regs *) ((char *) (t) + IA64_STK_OFFSET)) - 1)=0A # define ia64_psr(regs= ) ((struct ia64_psr *) &(regs)->cr_ipsr)=0A #ifdef = XEN=0A-# define guest_mode(regs) (ia64_psr(regs)->cpl !=3D = 0)=0A+# define guest_mode(regs) (ia64_psr(regs)->cpl && !ia64_psr(r= egs)->vm)=0A # define guest_kernel_mode(regs) (ia64_psr(regs)->cpl = =3D=3D CONFIG_CPL0_EMUL)=0A # define vmx_guest_kernel_mode(regs) = (ia64_psr(regs)->cpl =3D=3D 0)=0A # define regs_increment_iip(regs) = \=0A --=__Part5379F401.0__= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel --=__Part5379F401.0__=--