WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

Re: [Xen-devel] [PATCH, v3] reduce 'd' debug key's global impact

To: Jan Beulich <JBeulich@xxxxxxxxxx>, "xen-devel@xxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: Re: [Xen-devel] [PATCH, v3] reduce 'd' debug key's global impact
From: Keir Fraser <keir.fraser@xxxxxxxxxxxxx>
Date: Thu, 6 May 2010 17:36:25 +0100
Cc:
Delivery-date: Thu, 06 May 2010 09:37:49 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <4BE2DAC50200007800001912@xxxxxxxxxxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
Thread-index: AcrtHNYBvfleGDyyTROY50b7zoZ3tQAHW6x9
Thread-topic: [Xen-devel] [PATCH, v3] reduce 'd' debug key's global impact
User-agent: Microsoft-Entourage/12.24.0.100205
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

<Prev in Thread] Current Thread [Next in Thread>