• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3  * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without modification,
6  * are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice, this list of
9  *    conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12  *    of conditions and the following disclaimer in the documentation and/or other materials
13  *    provided with the distribution.
14  *
15  * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16  *    to endorse or promote products derived from this software without specific prior written
17  *    permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 /**
33  * @defgroup los_perf Perf
34  * @ingroup kernel
35  */
36 
37 #ifndef _LOS_PERF_H
38 #define _LOS_PERF_H
39 
40 #include "los_typedef.h"
41 
42 #ifdef __cplusplus
43 #if __cplusplus
44 extern "C" {
45 #endif /* __cplusplus */
46 #endif /* __cplusplus */
47 
48 /**
49  * @ingroup los_perf
50  * Perf max sample filter task number.
51  */
52 #define PERF_MAX_FILTER_TSKS                32
53 
54 /**
55  * @ingroup los_perf
56  * Perf max sample event counter's number.
57  */
58 #define PERF_MAX_EVENT                      7
59 
60 /**
61  * @ingroup los_perf
62  * Perf max backtrace depth.
63  */
64 #define PERF_MAX_CALLCHAIN_DEPTH            10
65 
66 /**
67  * @ingroup los_perf
68  * Perf sample data buffer's water mark 1/N.
69  */
70 #define PERF_BUFFER_WATERMARK_ONE_N         2
71 
72 /**
73  * @ingroup los_perf
74  * Perf status.
75  */
76 enum PerfStatus {
77     PERF_UNINIT,   /* perf isn't inited */
78     PERF_STARTED,  /* perf is started */
79     PERF_STOPPED,  /* perf is stopped */
80 };
81 
82 /**
83  * @ingroup los_perf
84  * Define the type of the perf sample data buffer water mark hook function.
85  *
86  */
87 typedef VOID (*PERF_BUF_NOTIFY_HOOK)(VOID);
88 
89 /**
90  * @ingroup los_perf
91  * Define the type of the perf sample data buffer flush hook function.
92  *
93  */
94 typedef VOID (*PERF_BUF_FLUSH_HOOK)(VOID *addr, UINT32 size);
95 
96 /**
97  * @ingroup los_perf
98  * Perf error code: Bad status.
99  *
100  * Value: 0x02002000
101  *
102  * Solution: Follow the perf state machine.
103  */
104 #define LOS_ERRNO_PERF_STATUS_INVALID        LOS_ERRNO_OS_ERROR(LOS_MOD_PERF, 0x00)
105 
106 /**
107  * @ingroup los_perf
108  * Perf error code: Hardware pmu init failed.
109  *
110  * Value: 0x02002001
111  *
112  * Solution: Check the pmu hwi irq.
113  */
114 #define LOS_ERRNO_PERF_HW_INIT_ERROR         LOS_ERRNO_OS_ERROR(LOS_MOD_PERF, 0x01)
115 
116 /**
117  * @ingroup los_perf
118  * Perf error code: Hrtimer init failed for hrtimer timed pmu init.
119  *
120  * Value: 0x02002002
121  *
122  * Solution: Check the Hrtimer init.
123  */
124 #define LOS_ERRNO_PERF_TIMED_INIT_ERROR      LOS_ERRNO_OS_ERROR(LOS_MOD_PERF, 0x02)
125 
126 /**
127  * @ingroup los_perf
128  * Perf error code: Software pmu init failed.
129  *
130  * Value: 0x02002003
131  *
132  * Solution: Check the Perf software events init.
133  */
134 #define LOS_ERRNO_PERF_SW_INIT_ERROR         LOS_ERRNO_OS_ERROR(LOS_MOD_PERF, 0x03)
135 
136 /**
137  * @ingroup los_perf
138  * Perf error code: Perf buffer init failed.
139  *
140  * Value: 0x02002004
141  *
142  * Solution: Check the buffer init size.
143  */
144 #define LOS_ERRNO_PERF_BUF_ERROR             LOS_ERRNO_OS_ERROR(LOS_MOD_PERF, 0x04)
145 
146 /**
147  * @ingroup los_perf
148  * Perf error code: Perf pmu type error.
149  *
150  * Value: 0x02002005
151  *
152  * Solution: Check whether the corresponding pmu is enabled in the menuconfig.
153  */
154 #define LOS_ERRNO_PERF_INVALID_PMU           LOS_ERRNO_OS_ERROR(LOS_MOD_PERF, 0x05)
155 
156 /**
157  * @ingroup los_perf
158  * Perf error code: Perf pmu config error.
159  *
160  * Value: 0x02002006
161  *
162  * Solution: Check the config attr of event id and event period.
163  */
164 #define LOS_ERRNO_PERF_PMU_CONFIG_ERROR      LOS_ERRNO_OS_ERROR(LOS_MOD_PERF, 0x06)
165 
166 /**
167  * @ingroup los_perf
168  * Perf error code: Perf pmu config attr is NULL.
169  *
170  * Value: 0x02002007
171  *
172  * Solution: Check if the input params of attr is NULL.
173  */
174 #define LOS_ERRNO_PERF_CONFIG_NULL           LOS_ERRNO_OS_ERROR(LOS_MOD_PERF, 0x07)
175 
176 /**
177  * @ingroup los_perf
178  * Perf types
179  */
180 enum PerfEventType {
181     PERF_EVENT_TYPE_HW,      /* boards common hw events */
182     PERF_EVENT_TYPE_TIMED,   /* hrtimer timed events */
183     PERF_EVENT_TYPE_SW,      /* software trace events */
184     PERF_EVENT_TYPE_RAW,     /* boards special hw events, see enum PmuEventType in corresponding arch headfile */
185 
186     PERF_EVENT_TYPE_MAX
187 };
188 
189 /**
190  * @ingroup los_perf
191  * Common hardware pmu events
192  */
193 enum PmuHwId {
194     PERF_COUNT_HW_CPU_CYCLES = 0,      /* cpu cycle event */
195     PERF_COUNT_HW_INSTRUCTIONS,        /* instruction event */
196     PERF_COUNT_HW_DCACHE_REFERENCES,   /* dcache access event */
197     PERF_COUNT_HW_DCACHE_MISSES,       /* dcache miss event */
198     PERF_COUNT_HW_ICACHE_REFERENCES,   /* icache access event */
199     PERF_COUNT_HW_ICACHE_MISSES,       /* icache miss event */
200     PERF_COUNT_HW_BRANCH_INSTRUCTIONS, /* software change of pc event */
201     PERF_COUNT_HW_BRANCH_MISSES,       /* branch miss event */
202 
203     PERF_COUNT_HW_MAX,
204 };
205 
206 /**
207  * @ingroup los_perf
208  * Common hrtimer timed events
209  */
210 enum PmuTimedId {
211     PERF_COUNT_CPU_CLOCK = 0,      /* hrtimer timed event */
212 };
213 
214 /**
215  * @ingroup los_perf
216  * Common software pmu events
217  */
218 enum PmuSwId {
219     PERF_COUNT_SW_TASK_SWITCH = 1, /* task switch event */
220     PERF_COUNT_SW_IRQ_RESPONSE,    /* irq response event */
221     PERF_COUNT_SW_MEM_ALLOC,       /* memory alloc event */
222     PERF_COUNT_SW_MUX_PEND,        /* mutex pend event */
223 
224     PERF_COUNT_SW_MAX,
225 };
226 
227 /**
228  * @ingroup los_perf
229  * perf sample data types
230  * Config it through PerfConfigAttr->sampleType.
231  */
232 enum PerfSampleType {
233     PERF_RECORD_CPU       = 1U << 0, /* record current cpuid */
234     PERF_RECORD_TID       = 1U << 1, /* record current task id */
235     PERF_RECORD_TYPE      = 1U << 2, /* record event type */
236     PERF_RECORD_PERIOD    = 1U << 3, /* record event period */
237     PERF_RECORD_TIMESTAMP = 1U << 4, /* record timestamp */
238     PERF_RECORD_IP        = 1U << 5, /* record instruction pointer */
239     PERF_RECORD_CALLCHAIN = 1U << 6, /* record backtrace */
240     PERF_RECORD_PID       = 1U << 7, /* record current process id */
241 };
242 
243 /**
244  * @ingroup los_perf
245  * perf configuration sub event information
246  *
247  * This structure is used to config specific events attributes.
248  */
249 typedef struct {
250     UINT32 type;              /* enum PerfEventType */
251     struct {
252         UINT32 eventId;       /* the specific event corresponds to the PerfEventType */
253         UINT32 period;        /* event period, for every "period"th occurrence of the event a
254                                    sample will be recorded */
255     } events[PERF_MAX_EVENT]; /* perf event list */
256     UINT32 eventsNr;          /* total perf event number */
257     BOOL predivided;          /* whether to prescaler (once every 64 counts),
258                                   which only take effect on cpu cycle hardware event */
259 } PerfEventConfig;
260 
261 /**
262  * @ingroup los_perf
263  * perf configuration main information
264  *
265  * This structure is used to set perf sampling attributes, including events, tasks and other information.
266  */
267 typedef struct {
268     PerfEventConfig         eventsCfg;                      /* perf event config */
269     UINT32                  taskIds[PERF_MAX_FILTER_TSKS];  /* perf task filter list (allowlist) */
270     UINT32                  taskIdsNr;                      /* task numbers of task filter allowlist,
271                                                                  if set 0 perf will sample all tasks */
272     UINT32                  processIds[PERF_MAX_FILTER_TSKS];  /* perf process filter list (allowlist) */
273     UINT32                  processIdsNr;                      /* process numbers of process filter allowlist,
274                                                                  if set 0 perf will sample all processes */
275     UINT32                  sampleType;                     /* type of data to sample defined in PerfSampleType */
276     BOOL                    needSample;                     /* whether to sample data */
277 } PerfConfigAttr;
278 
279 /**
280  * @ingroup los_perf
281  * @brief Init perf.
282  *
283  * @par Description:
284  * <ul>
285  * <li>Used to initialize the perf module, including initializing the PMU, allocating memory,
286  * etc.,which is called during the phase of system initialization.</li>
287  * </ul>
288  * @attention
289  * <ul>
290  * <li>If buf is not NULL, user must ensure size is not bigger than buf's length.</li>
291  * </ul>
292  *
293  * @param  buf     [IN] Pointer of sample data buffer;Use the dynamically allocated memory if the pointer is NULL.
294  * @param  size    [IN] Length of sample data buffer.
295  *
296  * @retval #LOS_ERRNO_PERF_STATUS_INVALID              Perf in a wrong status.
297  * @retval #LOS_ERRNO_PERF_HW_INIT_ERROR               Perf hardware pmu init fail.
298  * @retval #LOS_ERRNO_PERF_TIMED_INIT_ERROR            Perf timed pmu init fail.
299  * @retval #LOS_ERRNO_PERF_SW_INIT_ERROR               Perf software pmu init fail.
300  * @retval #LOS_ERRNO_PERF_BUF_ERROR                   Perf buffer init fail.
301  * @retval #LOS_OK                                     Perf init success.
302  * @par Dependency:
303  * <ul>
304  * <li>los_perf.h: the header file that contains the API declaration.</li>
305  * </ul>
306  */
307 UINT32 LOS_PerfInit(VOID *buf, UINT32 size);
308 
309 /**
310  * @ingroup los_perf
311  * @brief Start perf sampling.
312  *
313  * @par Description
314  * Start perf sampling.
315  * @attention
316  * None.
317  *
318  * @param  sectionId          [IN] Set the section id for marking this piece of data in the perf sample data buffer.
319  * @retval None.
320  * @par Dependency:
321  * <ul>
322  * <li>los_perf.h: the header file that contains the API declaration.</li>
323  * </ul>
324  */
325 VOID LOS_PerfStart(UINT32 sectionId);
326 
327 /**
328  * @ingroup los_perf
329  * @brief Stop perf sampling.
330  *
331  * @par Description
332  * Stop perf sampling.
333  * @attention
334  * None.
335  *
336  * @param  None.
337  *
338  * @retval None.
339  * @par Dependency:
340  * <ul>
341  * <li>los_perf.h: the header file that contains the API declaration.</li>
342  * </ul>
343  */
344 VOID LOS_PerfStop(VOID);
345 
346 /**
347  * @ingroup los_perf
348  * @brief Config perf parameters.
349  *
350  * @par Description
351  * Config perf parameters before sample, for example, sample event, sample task, etc. This interface need to be called
352  * before LOS_PerfStart.
353  * @attention
354  * None.
355  *
356  * @param  attr                      [IN] Address of a perf event attr struct.
357  *
358  * @retval #LOS_ERRNO_PERF_STATUS_INVALID          Perf in a wrong status.
359  * @retval #LOS_ERRNO_PERF_CONFIG_NULL             Attr is NULL.
360  * @retval #LOS_ERRNO_PERF_INVALID_PMU             Config perf pmu with error type.
361  * @retval #LOS_ERRNO_PERF_PMU_CONFIG_ERROR        Config perf events fail with invalid event id or event period.
362  * @retval #LOS_OK                                 Config success.
363  * @par Dependency:
364  * <ul>
365  * <li>los_perf.h: the header file that contains the API declaration.</li>
366  * </ul>
367  */
368 UINT32 LOS_PerfConfig(PerfConfigAttr *attr);
369 
370 /**
371  * @ingroup los_perf
372  * @brief Read data from perf sample data buffer.
373  *
374  * @par Description
375  * Because perf sample data buffer is a ringbuffer, the data may be covered after user read ringbuffer.
376  * @attention
377  * None.
378  *
379  * @param  dest                      [IN] The destination address.
380  * @param  size                      [IN] Read size.
381  * @retval #UINT32                   The really read bytes.
382  * @par Dependency:
383  * <ul>
384  * <li>los_perf.h: the header file that contains the API declaration.</li>
385  * </ul>
386  */
387 UINT32 LOS_PerfDataRead(CHAR *dest, UINT32 size);
388 
389 /**
390  * @ingroup los_perf
391  * @brief Register perf sample data buffer water mark hook function.
392  *
393  * @par Description
394  * <ul>
395  * <li> Register perf sample data buffer water mark hook function.</li>
396  * <li> The registered hook will be called when buffer reaches the water mark./li>
397  * </ul>
398  * @attention
399  * None.
400  *
401  * @param  func                      [IN] Buffer water mark hook function.
402  *
403  * @retval None.
404  * @par Dependency:
405  * <ul>
406  * <li>los_perf.h: the header file that contains the API declaration.</li>
407  * </ul>
408  */
409 VOID LOS_PerfNotifyHookReg(const PERF_BUF_NOTIFY_HOOK func);
410 
411 /**
412  * @ingroup los_perf
413  * @brief Register perf sample data buffer flush hook function.
414  *
415  * @par Description
416  * <ul>
417  * <li> Register perf sample data buffer flush hook function.</li>
418  * <li> The flush hook will be called when the buffer be read or written.</li>
419  * </ul>
420  * @attention
421  * None.
422  *
423  * @param  func                      [IN] Buffer flush hook function.
424  *
425  * @retval None.
426  * @par Dependency:
427  * <ul>
428  * <li>los_perf.h: the header file that contains the API declaration.</li>
429  * </ul>
430  */
431 VOID LOS_PerfFlushHookReg(const PERF_BUF_FLUSH_HOOK func);
432 
433 #ifdef __cplusplus
434 #if __cplusplus
435 }
436 #endif /* __cplusplus */
437 #endif /* __cplusplus */
438 
439 #endif /* _LOS_PERF_H */
440