2010-11-11 07:57:44

by Subrata Modak

[permalink] [raw]
Subject: Re: [PATCH] powerpc: Fix hcall tracepoint recursion

I tested and reported back the results. The patch works fine. Can you
please find out if it has been committed to Linus tree and if yes, then
the commit id please ?

Regards--
Subrata

On Fri, 2010-10-22 at 15:22 +0800, Li Zefan wrote:
> Anton Blanchard wrote:
> > Hi,
> >
> >> This is a dead loop:
> >>
> >> trace_hcall_entry() -> trace_clock_global() -> trace_hcall_entry() ..
> >>
> >> And this is a PPC specific bug. Hope some ppc guys will fix it?
> >> Or we kill trace_clock_global() if no one actually uses it..
> >
> > Nasty! How does the patch below look? I had to disable irqs otherwise
> > we would sometimes drop valid events (if we take an interrupt anywhere
> > in the region where depth is elevated, then the entire interrupt will
> > be blocked from calling hcall tracepoints.
> >
>
> Thanks!
>
> Subrata, could you test the patch below?
>
> > Anton
> > --
> >
> > Subject: [PATCH] powerpc: Fix hcall tracepoint recursion
> >
> > Spinlocks on shared processor partitions use H_YIELD to notify the
> > hypervisor we are waiting on another virtual CPU. Unfortunately this means
> > the hcall tracepoints can recurse.
> >
> > The patch below adds a percpu depth and checks it on both the entry and
> > exit hcall tracepoints.
> >
> > Signed-off-by: Anton Blanchard <[email protected]>
> > ---
> >
> > Index: powerpc.git/arch/powerpc/platforms/pseries/lpar.c
> > ===================================================================
> > --- powerpc.git.orig/arch/powerpc/platforms/pseries/lpar.c 2010-10-21 17:32:00.980003644 +1100
> > +++ powerpc.git/arch/powerpc/platforms/pseries/lpar.c 2010-10-21 17:34:54.942681273 +1100
> > @@ -701,6 +701,13 @@ EXPORT_SYMBOL(arch_free_page);
> > /* NB: reg/unreg are called while guarded with the tracepoints_mutex */
> > extern long hcall_tracepoint_refcount;
> >
> > +/*
> > + * Since the tracing code might execute hcalls we need to guard against
> > + * recursion. One example of this are spinlocks calling H_YIELD on
> > + * shared processor partitions.
> > + */
> > +static DEFINE_PER_CPU(unsigned int, hcall_trace_depth);
> > +
> > void hcall_tracepoint_regfunc(void)
> > {
> > hcall_tracepoint_refcount++;
> > @@ -713,12 +720,42 @@ void hcall_tracepoint_unregfunc(void)
> >
> > void __trace_hcall_entry(unsigned long opcode, unsigned long *args)
> > {
> > + unsigned long flags;
> > + unsigned int *depth;
> > +
> > + local_irq_save(flags);
> > +
> > + depth = &__get_cpu_var(hcall_trace_depth);
> > +
> > + if (*depth)
> > + goto out;
> > +
> > + (*depth)++;
> > trace_hcall_entry(opcode, args);
> > + (*depth)--;
> > +
> > +out:
> > + local_irq_restore(flags);
> > }
> >
> > void __trace_hcall_exit(long opcode, unsigned long retval,
> > unsigned long *retbuf)
> > {
> > + unsigned long flags;
> > + unsigned int *depth;
> > +
> > + local_irq_save(flags);
> > +
> > + depth = &__get_cpu_var(hcall_trace_depth);
> > +
> > + if (*depth)
> > + goto out;
> > +
> > + (*depth)++;
> > trace_hcall_exit(opcode, retval, retbuf);
> > + (*depth)--;
> > +
> > +out:
> > + local_irq_restore(flags);
> > }
> > #endif
> >
> >