xref: /linux/drivers/hwtracing/coresight/coresight-trace-id.h (revision 3a39d672e7f48b8d6b91a09afa4b55352773b4b5)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Copyright(C) 2022 Linaro Limited. All rights reserved.
4  * Author: Mike Leach <mike.leach@linaro.org>
5  */
6 
7 #ifndef _CORESIGHT_TRACE_ID_H
8 #define _CORESIGHT_TRACE_ID_H
9 
10 /*
11  * Coresight trace ID allocation API
12  *
13  * With multi cpu systems, and more additional trace sources a scalable
14  * trace ID reservation system is required.
15  *
16  * The system will allocate Ids on a demand basis, and allow them to be
17  * released when done.
18  *
19  * In order to ensure that a consistent cpu / ID matching is maintained
20  * throughout a perf cs_etm event session - a session in progress flag will be
21  * maintained for each sink, and IDs are cleared when all the perf sessions
22  * complete. This allows the same CPU to be re-allocated its prior ID when
23  * events are scheduled in and out.
24  *
25  *
26  * Trace ID maps will be created and initialised to prevent architecturally
27  * reserved IDs from being allocated.
28  *
29  * API permits multiple maps to be maintained - for large systems where
30  * different sets of cpus trace into different independent sinks.
31  */
32 
33 #include <linux/bitops.h>
34 #include <linux/types.h>
35 
36 /* ID 0 is reserved */
37 #define CORESIGHT_TRACE_ID_RES_0 0
38 
39 /* ID 0x70 onwards are reserved */
40 #define CORESIGHT_TRACE_ID_RES_TOP 0x70
41 
42 /* check an ID is in the valid range */
43 #define IS_VALID_CS_TRACE_ID(id)	\
44 	((id > CORESIGHT_TRACE_ID_RES_0) && (id < CORESIGHT_TRACE_ID_RES_TOP))
45 
46 /**
47  * Read and optionally allocate a CoreSight trace ID and associate with a CPU.
48  *
49  * Function will read the current trace ID for the associated CPU,
50  * allocating an new ID if one is not currently allocated.
51  *
52  * Numeric ID values allocated use legacy allocation algorithm if possible,
53  * otherwise any available ID is used.
54  *
55  * @cpu: The CPU index to allocate for.
56  *
57  * return: CoreSight trace ID or -EINVAL if allocation impossible.
58  */
59 int coresight_trace_id_get_cpu_id(int cpu);
60 
61 /**
62  * Version of coresight_trace_id_get_cpu_id() that allows the ID map to operate
63  * on to be provided.
64  */
65 int coresight_trace_id_get_cpu_id_map(int cpu, struct coresight_trace_id_map *id_map);
66 
67 /**
68  * Release an allocated trace ID associated with the CPU.
69  *
70  * This will release the CoreSight trace ID associated with the CPU.
71  *
72  * @cpu: The CPU index to release the associated trace ID.
73  */
74 void coresight_trace_id_put_cpu_id(int cpu);
75 
76 /**
77  * Version of coresight_trace_id_put_cpu_id() that allows the ID map to operate
78  * on to be provided.
79  */
80 void coresight_trace_id_put_cpu_id_map(int cpu, struct coresight_trace_id_map *id_map);
81 
82 /**
83  * Read the current allocated CoreSight Trace ID value for the CPU.
84  *
85  * Fast read of the current value that does not allocate if no ID allocated
86  * for the CPU.
87  *
88  * Used in perf context  where it is known that the value for the CPU will not
89  * be changing, when perf starts and event on a core and outputs the Trace ID
90  * for the CPU as a packet in the data file. IDs cannot change during a perf
91  * session.
92  *
93  * This function does not take the lock protecting the ID lists, avoiding
94  * locking dependency issues with perf locks.
95  *
96  * @cpu: The CPU index to read.
97  *
98  * return: current value, will be 0 if unallocated.
99  */
100 int coresight_trace_id_read_cpu_id(int cpu);
101 
102 /**
103  * Version of coresight_trace_id_read_cpu_id() that allows the ID map to operate
104  * on to be provided.
105  */
106 int coresight_trace_id_read_cpu_id_map(int cpu, struct coresight_trace_id_map *id_map);
107 
108 /**
109  * Allocate a CoreSight trace ID for a system component.
110  *
111  * Unconditionally allocates a Trace ID, without associating the ID with a CPU.
112  *
113  * Used to allocate IDs for system trace sources such as STM.
114  *
115  * return: Trace ID or -EINVAL if allocation is impossible.
116  */
117 int coresight_trace_id_get_system_id(void);
118 
119 /**
120  * Release an allocated system trace ID.
121  *
122  * Unconditionally release a trace ID allocated to a system component.
123  *
124  * @id: value of trace ID allocated.
125  */
126 void coresight_trace_id_put_system_id(int id);
127 
128 /* notifiers for perf session start and stop */
129 
130 /**
131  * Notify the Trace ID allocator that a perf session is starting.
132  *
133  * Increase the perf session reference count - called by perf when setting up a
134  * trace event.
135  *
136  * Perf sessions never free trace IDs to ensure that the ID associated with a
137  * CPU cannot change during their and other's concurrent sessions. Instead,
138  * this refcount is used so that the last event to finish always frees all IDs.
139  */
140 void coresight_trace_id_perf_start(struct coresight_trace_id_map *id_map);
141 
142 /**
143  * Notify the ID allocator that a perf session is stopping.
144  *
145  * Decrease the perf session reference count. If this causes the count to go to
146  * zero, then all Trace IDs will be released.
147  */
148 void coresight_trace_id_perf_stop(struct coresight_trace_id_map *id_map);
149 
150 #endif /* _CORESIGHT_TRACE_ID_H */
151