Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost
[cris-mirror.git] / arch / powerpc / platforms / powernv / opal-tracepoints.c
blob1ab7d26c0a2cd972674d299339928b0475b2ff91
1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/percpu.h>
3 #include <linux/jump_label.h>
4 #include <asm/trace.h>
5 #include <asm/asm-prototypes.h>
7 #ifdef HAVE_JUMP_LABEL
8 struct static_key opal_tracepoint_key = STATIC_KEY_INIT;
10 int opal_tracepoint_regfunc(void)
12 static_key_slow_inc(&opal_tracepoint_key);
13 return 0;
16 void opal_tracepoint_unregfunc(void)
18 static_key_slow_dec(&opal_tracepoint_key);
20 #else
22 * We optimise OPAL calls by placing opal_tracepoint_refcount
23 * directly in the TOC so we can check if the opal tracepoints are
24 * enabled via a single load.
27 /* NB: reg/unreg are called while guarded with the tracepoints_mutex */
28 extern long opal_tracepoint_refcount;
30 int opal_tracepoint_regfunc(void)
32 opal_tracepoint_refcount++;
33 return 0;
36 void opal_tracepoint_unregfunc(void)
38 opal_tracepoint_refcount--;
40 #endif
43 * Since the tracing code might execute OPAL calls we need to guard against
44 * recursion.
46 static DEFINE_PER_CPU(unsigned int, opal_trace_depth);
48 void __trace_opal_entry(unsigned long opcode, unsigned long *args)
50 unsigned long flags;
51 unsigned int *depth;
53 local_irq_save(flags);
55 depth = this_cpu_ptr(&opal_trace_depth);
57 if (*depth)
58 goto out;
60 (*depth)++;
61 preempt_disable();
62 trace_opal_entry(opcode, args);
63 (*depth)--;
65 out:
66 local_irq_restore(flags);
69 void __trace_opal_exit(long opcode, unsigned long retval)
71 unsigned long flags;
72 unsigned int *depth;
74 local_irq_save(flags);
76 depth = this_cpu_ptr(&opal_trace_depth);
78 if (*depth)
79 goto out;
81 (*depth)++;
82 trace_opal_exit(opcode, retval);
83 preempt_enable();
84 (*depth)--;
86 out:
87 local_irq_restore(flags);