aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/pseries/lpar.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms/pseries/lpar.c')
-rw-r--r--arch/powerpc/platforms/pseries/lpar.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index cf79b46d8f88..568b503d68bd 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -680,6 +680,13 @@ EXPORT_SYMBOL(arch_free_page);
680/* NB: reg/unreg are called while guarded with the tracepoints_mutex */ 680/* NB: reg/unreg are called while guarded with the tracepoints_mutex */
681extern long hcall_tracepoint_refcount; 681extern long hcall_tracepoint_refcount;
682 682
683/*
684 * Since the tracing code might execute hcalls we need to guard against
685 * recursion. One example of this are spinlocks calling H_YIELD on
686 * shared processor partitions.
687 */
688static DEFINE_PER_CPU(unsigned int, hcall_trace_depth);
689
683void hcall_tracepoint_regfunc(void) 690void hcall_tracepoint_regfunc(void)
684{ 691{
685 hcall_tracepoint_refcount++; 692 hcall_tracepoint_refcount++;
@@ -692,12 +699,42 @@ void hcall_tracepoint_unregfunc(void)
692 699
693void __trace_hcall_entry(unsigned long opcode, unsigned long *args) 700void __trace_hcall_entry(unsigned long opcode, unsigned long *args)
694{ 701{
702 unsigned long flags;
703 unsigned int *depth;
704
705 local_irq_save(flags);
706
707 depth = &__get_cpu_var(hcall_trace_depth);
708
709 if (*depth)
710 goto out;
711
712 (*depth)++;
695 trace_hcall_entry(opcode, args); 713 trace_hcall_entry(opcode, args);
714 (*depth)--;
715
716out:
717 local_irq_restore(flags);
696} 718}
697 719
698void __trace_hcall_exit(long opcode, unsigned long retval, 720void __trace_hcall_exit(long opcode, unsigned long retval,
699 unsigned long *retbuf) 721 unsigned long *retbuf)
700{ 722{
723 unsigned long flags;
724 unsigned int *depth;
725
726 local_irq_save(flags);
727
728 depth = &__get_cpu_var(hcall_trace_depth);
729
730 if (*depth)
731 goto out;
732
733 (*depth)++;
701 trace_hcall_exit(opcode, retval, retbuf); 734 trace_hcall_exit(opcode, retval, retbuf);
735 (*depth)--;
736
737out:
738 local_irq_restore(flags);
702} 739}
703#endif 740#endif