Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/powerpc/platforms/powernv/opal-tracepoints.c
26481 views
1
// SPDX-License-Identifier: GPL-2.0
2
#include <linux/percpu.h>
3
#include <linux/jump_label.h>
4
#include <asm/trace.h>
5
6
#ifdef CONFIG_JUMP_LABEL
7
struct static_key opal_tracepoint_key = STATIC_KEY_INIT;
8
9
int opal_tracepoint_regfunc(void)
10
{
11
static_key_slow_inc(&opal_tracepoint_key);
12
return 0;
13
}
14
15
void opal_tracepoint_unregfunc(void)
16
{
17
static_key_slow_dec(&opal_tracepoint_key);
18
}
19
#else
20
/*
21
* We optimise OPAL calls by placing opal_tracepoint_refcount
22
* directly in the TOC so we can check if the opal tracepoints are
23
* enabled via a single load.
24
*/
25
26
/* NB: reg/unreg are called while guarded with the tracepoints_mutex */
27
extern long opal_tracepoint_refcount;
28
29
int opal_tracepoint_regfunc(void)
30
{
31
opal_tracepoint_refcount++;
32
return 0;
33
}
34
35
void opal_tracepoint_unregfunc(void)
36
{
37
opal_tracepoint_refcount--;
38
}
39
#endif
40
41
/*
42
* Since the tracing code might execute OPAL calls we need to guard against
43
* recursion.
44
*/
45
static DEFINE_PER_CPU(unsigned int, opal_trace_depth);
46
47
void __trace_opal_entry(unsigned long opcode, unsigned long *args)
48
{
49
unsigned long flags;
50
unsigned int *depth;
51
52
local_irq_save(flags);
53
54
depth = this_cpu_ptr(&opal_trace_depth);
55
56
if (*depth)
57
goto out;
58
59
(*depth)++;
60
preempt_disable();
61
trace_opal_entry(opcode, args);
62
(*depth)--;
63
64
out:
65
local_irq_restore(flags);
66
}
67
68
void __trace_opal_exit(long opcode, unsigned long retval)
69
{
70
unsigned long flags;
71
unsigned int *depth;
72
73
local_irq_save(flags);
74
75
depth = this_cpu_ptr(&opal_trace_depth);
76
77
if (*depth)
78
goto out;
79
80
(*depth)++;
81
trace_opal_exit(opcode, retval);
82
preempt_enable();
83
(*depth)--;
84
85
out:
86
local_irq_restore(flags);
87
}
88
89