summaryrefslogtreecommitdiff
path: root/mali_kbase/debug/mali_kbase_debug_ktrace.h
blob: 7c988f4bcb660c7ba6a573de02af0b5cd9e24231 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/*
 *
 * (C) COPYRIGHT 2020-2022 ARM Limited. All rights reserved.
 *
 * This program is free software and is provided to you under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation, and any use by you of this program is subject to the terms
 * of such GNU license.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, you can access it online at
 * http://www.gnu.org/licenses/gpl-2.0.html.
 *
 */

/*
 * DOC: Kbase's own trace, 'KTrace'
 *
 * Low overhead trace specific to kbase, aimed at:
 * - common use-cases for tracing kbase specific functionality to do with
 *   running work on the GPU
 * - easy 1-line addition of new types of trace
 *
 * KTrace can be recorded in one or more of the following targets:
 * - KBASE_KTRACE_TARGET_RBUF: low overhead ringbuffer protected by an
 *   irq-spinlock, output available via dev_dbg() and debugfs file
 * - KBASE_KTRACE_TARGET_FTRACE: ftrace based tracepoints under 'mali' events
 */

#ifndef _KBASE_DEBUG_KTRACE_H_
#define _KBASE_DEBUG_KTRACE_H_

#if KBASE_KTRACE_TARGET_FTRACE
#include "mali_linux_trace.h"
#endif

#if MALI_USE_CSF
#include "debug/backend/mali_kbase_debug_ktrace_csf.h"
#else
#include "debug/backend/mali_kbase_debug_ktrace_jm.h"
#endif

/**
 * kbase_ktrace_init - initialize kbase ktrace.
 * @kbdev: kbase device
 * Return: 0 if successful or a negative error code on failure.
 */
int kbase_ktrace_init(struct kbase_device *kbdev);

/**
 * kbase_ktrace_term - terminate kbase ktrace.
 * @kbdev: kbase device
 */
void kbase_ktrace_term(struct kbase_device *kbdev);

/**
 * kbase_ktrace_hook_wrapper - wrapper so that dumping ktrace can be done via a
 *                             callback.
 * @param: kbase device, cast to void pointer
 */
void kbase_ktrace_hook_wrapper(void *param);

#if IS_ENABLED(CONFIG_DEBUG_FS)
/**
 * kbase_ktrace_debugfs_init - initialize kbase ktrace for debugfs usage, if
 *                             the selected targets support it.
 * @kbdev: kbase device
 *
 * There is no matching 'term' call, debugfs_remove_recursive() is sufficient.
 */
void kbase_ktrace_debugfs_init(struct kbase_device *kbdev);
#endif /* CONFIG_DEBUG_FS */

/*
 * KTrace target for internal ringbuffer
 */
#if KBASE_KTRACE_TARGET_RBUF
/**
 * kbasep_ktrace_initialized - Check whether kbase ktrace is initialized
 *
 * @ktrace: ktrace of kbase device.
 *
 * Return: true if ktrace has been initialized.
 */
static inline bool kbasep_ktrace_initialized(struct kbase_ktrace *ktrace)
{
	return ktrace->rbuf != NULL;
}

/**
 * kbasep_ktrace_add - internal function to add trace to the ringbuffer.
 * @kbdev:    kbase device
 * @code:     ktrace code
 * @kctx:     kbase context, or NULL if no context
 * @flags:    flags about the message
 * @info_val: generic information about @code to add to the trace
 *
 * PRIVATE: do not use directly. Use KBASE_KTRACE_ADD() instead.
 */
void kbasep_ktrace_add(struct kbase_device *kbdev, enum kbase_ktrace_code code,
		struct kbase_context *kctx, kbase_ktrace_flag_t flags,
		u64 info_val);

/**
 * kbasep_ktrace_clear - clear the trace ringbuffer
 * @kbdev: kbase device
 *
 * PRIVATE: do not use directly. Use KBASE_KTRACE_CLEAR() instead.
 */
void kbasep_ktrace_clear(struct kbase_device *kbdev);

/**
 * kbasep_ktrace_dump - dump ktrace ringbuffer to dev_dbg(), then clear it
 * @kbdev: kbase device
 *
 * PRIVATE: do not use directly. Use KBASE_KTRACE_DUMP() instead.
 */
void kbasep_ktrace_dump(struct kbase_device *kbdev);

/**
 * kbasep_ktrace_copy - copy ktrace buffer.
 * Elements in the buffer will be ordered from earliest to latest.
 * Precondition: ktrace lock must be held.
 *
 * @kbdev: kbase device
 * @msgs: a region of memory of size data_size that the ktrace buffer will be copied to
 * @num_msgs: the size of data. 
 * Return: The number of elements copied.
 */
 u32 kbasep_ktrace_copy(struct kbase_device* kbdev, struct kbase_ktrace_msg* msgs, u32 num_msgs);

#define KBASE_KTRACE_RBUF_ADD(kbdev, code, kctx, info_val)     \
	kbasep_ktrace_add(kbdev, KBASE_KTRACE_CODE(code), kctx, 0, \
			info_val) \

#define KBASE_KTRACE_RBUF_CLEAR(kbdev) \
	kbasep_ktrace_clear(kbdev)

#define KBASE_KTRACE_RBUF_DUMP(kbdev) \
	kbasep_ktrace_dump(kbdev)

#else /* KBASE_KTRACE_TARGET_RBUF */

#define KBASE_KTRACE_RBUF_ADD(kbdev, code, kctx, info_val) \
	do { \
		CSTD_UNUSED(kbdev); \
		CSTD_NOP(code); \
		CSTD_UNUSED(kctx); \
		CSTD_UNUSED(info_val); \
		CSTD_NOP(0); \
	} while (0)

#define KBASE_KTRACE_RBUF_CLEAR(kbdev) \
	do { \
		CSTD_UNUSED(kbdev); \
		CSTD_NOP(0); \
	} while (0)
#define KBASE_KTRACE_RBUF_DUMP(kbdev) \
	do { \
		CSTD_UNUSED(kbdev); \
		CSTD_NOP(0); \
	} while (0)
#endif /* KBASE_KTRACE_TARGET_RBUF */

/*
 * KTrace target for Linux's ftrace
 */
#if KBASE_KTRACE_TARGET_FTRACE

#define KBASE_KTRACE_FTRACE_ADD(kbdev, code, kctx, info_val) \
	trace_mali_##code(kctx, info_val)

#else /* KBASE_KTRACE_TARGET_FTRACE */
#define KBASE_KTRACE_FTRACE_ADD(kbdev, code, kctx, info_val) \
	do { \
		CSTD_UNUSED(kbdev); \
		CSTD_NOP(code); \
		CSTD_UNUSED(kctx); \
		CSTD_UNUSED(info_val); \
		CSTD_NOP(0); \
	} while (0)
#endif /* KBASE_KTRACE_TARGET_FTRACE */

/* No 'clear' implementation for ftrace yet */
#define KBASE_KTRACE_FTRACE_CLEAR(kbdev) \
	do { \
		CSTD_UNUSED(kbdev); \
		CSTD_NOP(0); \
	} while (0)

/* No 'dump' implementation for ftrace yet */
#define KBASE_KTRACE_FTRACE_DUMP(kbdev) \
	do { \
		CSTD_UNUSED(kbdev); \
		CSTD_NOP(0); \
	} while (0)

/*
 * Master set of macros to route KTrace to any of the targets
 */

/**
 * KBASE_KTRACE_ADD - Add trace values
 * @kbdev:    kbase device
 * @code:     trace code
 * @kctx:     kbase context, or NULL if no context
 * @info_val: generic information about @code to add to the trace
 *
 * Note: Any functions called through this macro will still be evaluated in
 * Release builds (CONFIG_MALI_DEBUG not defined). Therefore, when
 * KBASE_KTRACE_ENABLE == 0 any functions called to get the parameters supplied
 * to this macro must:
 * a) be static or static inline, and
 * b) just return 0 and have no other statements present in the body.
 */
#define KBASE_KTRACE_ADD(kbdev, code, kctx, info_val) \
	do { \
		/* capture values that could come from non-pure function calls */ \
		u64 __info_val = info_val; \
		KBASE_KTRACE_RBUF_ADD(kbdev, code, kctx, __info_val); \
		KBASE_KTRACE_FTRACE_ADD(kbdev, code, kctx, __info_val); \
	} while (0)

/**
 * KBASE_KTRACE_CLEAR - Clear the trace, if applicable to the target(s)
 * @kbdev:    kbase device
 */
#define KBASE_KTRACE_CLEAR(kbdev) \
	do { \
		KBASE_KTRACE_RBUF_CLEAR(kbdev); \
		KBASE_KTRACE_FTRACE_CLEAR(kbdev); \
	} while (0)

/**
 * KBASE_KTRACE_DUMP - Dump the trace, if applicable to the target(s)
 * @kbdev:    kbase device
 */
#define KBASE_KTRACE_DUMP(kbdev) \
	do { \
		KBASE_KTRACE_RBUF_DUMP(kbdev); \
		KBASE_KTRACE_FTRACE_DUMP(kbdev); \
	} while (0)

#endif /* _KBASE_DEBUG_KTRACE_H_ */