Skip to content

Commit f9d81a6

Browse files
Suzuki K Poulosegregkh
authored andcommitted
coresight: perf: Allow tracing on hotplugged CPUs
At the moment, if there is no CPU specified for a given event, we use cpu_online_mask and try to build path for each of the CPUs in the mask. This could prevent any CPU that is turned online later to be used for the tracing. This patch changes to use the cpu_present_mask and tries to build path for as much CPUs as possible ignoring the failures in building path for some of the CPUs. If ever we try to trace on those CPUs, we fail the operation. Based on a patch from Mathieu Poirier. Cc: Mathieu Poirier <[email protected]> Signed-off-by: Suzuki K Poulose <[email protected]> Signed-off-by: Mathieu Poirier <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent c48fb3b commit f9d81a6

File tree

1 file changed

+29
-15
lines changed

1 file changed

+29
-15
lines changed

drivers/hwtracing/coresight/coresight-etm-perf.c

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -127,11 +127,9 @@ static void free_event_data(struct work_struct *work)
127127

128128
event_data = container_of(work, struct etm_event_data, work);
129129
mask = &event_data->mask;
130-
/*
131-
* First deal with the sink configuration. See comment in
132-
* etm_setup_aux() about why we take the first available path.
133-
*/
134-
if (event_data->snk_config) {
130+
131+
/* Free the sink buffers, if there are any */
132+
if (event_data->snk_config && !WARN_ON(cpumask_empty(mask))) {
135133
cpu = cpumask_first(mask);
136134
sink = coresight_get_sink(etm_event_cpu_path(event_data, cpu));
137135
if (sink_ops(sink)->free_buffer)
@@ -166,7 +164,7 @@ static void *alloc_event_data(int cpu)
166164
if (cpu != -1)
167165
cpumask_set_cpu(cpu, mask);
168166
else
169-
cpumask_copy(mask, cpu_online_mask);
167+
cpumask_copy(mask, cpu_present_mask);
170168

171169
/*
172170
* Each CPU has a single path between source and destination. As such
@@ -218,37 +216,53 @@ static void *etm_setup_aux(int event_cpu, void **pages,
218216
* on the cmd line. As such the "enable_sink" flag in sysFS is reset.
219217
*/
220218
sink = coresight_get_enabled_sink(true);
221-
if (!sink)
219+
if (!sink || !sink_ops(sink)->alloc_buffer)
222220
goto err;
223221

224222
mask = &event_data->mask;
225223

226-
/* Setup the path for each CPU in a trace session */
224+
/*
225+
* Setup the path for each CPU in a trace session. We try to build
226+
* trace path for each CPU in the mask. If we don't find an ETM
227+
* for the CPU or fail to build a path, we clear the CPU from the
228+
* mask and continue with the rest. If ever we try to trace on those
229+
* CPUs, we can handle it and fail the session.
230+
*/
227231
for_each_cpu(cpu, mask) {
228232
struct list_head *path;
229233
struct coresight_device *csdev;
230234

231235
csdev = per_cpu(csdev_src, cpu);
232-
if (!csdev)
233-
goto err;
236+
/*
237+
* If there is no ETM associated with this CPU clear it from
238+
* the mask and continue with the rest. If ever we try to trace
239+
* on this CPU, we handle it accordingly.
240+
*/
241+
if (!csdev) {
242+
cpumask_clear_cpu(cpu, mask);
243+
continue;
244+
}
234245

235246
/*
236247
* Building a path doesn't enable it, it simply builds a
237248
* list of devices from source to sink that can be
238249
* referenced later when the path is actually needed.
239250
*/
240251
path = coresight_build_path(csdev, sink);
241-
if (IS_ERR(path))
242-
goto err;
252+
if (IS_ERR(path)) {
253+
cpumask_clear_cpu(cpu, mask);
254+
continue;
255+
}
243256

244257
*etm_event_cpu_path_ptr(event_data, cpu) = path;
245258
}
246259

247-
if (!sink_ops(sink)->alloc_buffer)
260+
/* If we don't have any CPUs ready for tracing, abort */
261+
cpu = cpumask_first(mask);
262+
if (cpu >= nr_cpu_ids)
248263
goto err;
249264

250-
cpu = cpumask_first(mask);
251-
/* Get the AUX specific data from the sink buffer */
265+
/* Allocate the sink buffer for this session */
252266
event_data->snk_config =
253267
sink_ops(sink)->alloc_buffer(sink, cpu, pages,
254268
nr_pages, overwrite);

0 commit comments

Comments
 (0)