Skip to content

Commit 4c1daba

Browse files
rmurphy-armwilldeacon
authored andcommitted
perf/smmuv3: Don't trample existing events with global filter
With global filtering, we only allow an event to be scheduled if its filter settings exactly match those of any existing events, therefore it is pointless to reapply the filter in that case. Much worse, though, is that in doing that we trample the event type of counter 0 if it's already active, and never touch the appropriate PMEVTYPERn so the new event is likely not counting the right thing either. Don't do that. CC: stable@vger.kernel.org Signed-off-by: Robin Murphy <robin.murphy@arm.com> Link: https://lore.kernel.org/r/32c80c0e46237f49ad8da0c9f8864e13c4a803aa.1623153312.git.robin.murphy@arm.com Signed-off-by: Will Deacon <will@kernel.org>
1 parent 59d697a commit 4c1daba

1 file changed

Lines changed: 10 additions & 8 deletions

File tree

drivers/perf/arm_smmuv3_pmu.c

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -277,25 +277,27 @@ static int smmu_pmu_apply_event_filter(struct smmu_pmu *smmu_pmu,
277277
struct perf_event *event, int idx)
278278
{
279279
u32 span, sid;
280-
unsigned int num_ctrs = smmu_pmu->num_counters;
280+
unsigned int cur_idx, num_ctrs = smmu_pmu->num_counters;
281281
bool filter_en = !!get_filter_enable(event);
282282

283283
span = filter_en ? get_filter_span(event) :
284284
SMMU_PMCG_DEFAULT_FILTER_SPAN;
285285
sid = filter_en ? get_filter_stream_id(event) :
286286
SMMU_PMCG_DEFAULT_FILTER_SID;
287287

288-
/* Support individual filter settings */
289-
if (!smmu_pmu->global_filter) {
288+
cur_idx = find_first_bit(smmu_pmu->used_counters, num_ctrs);
289+
/*
290+
* Per-counter filtering, or scheduling the first globally-filtered
291+
* event into an empty PMU so idx == 0 and it works out equivalent.
292+
*/
293+
if (!smmu_pmu->global_filter || cur_idx == num_ctrs) {
290294
smmu_pmu_set_event_filter(event, idx, span, sid);
291295
return 0;
292296
}
293297

294-
/* Requested settings same as current global settings*/
295-
idx = find_first_bit(smmu_pmu->used_counters, num_ctrs);
296-
if (idx == num_ctrs ||
297-
smmu_pmu_check_global_filter(smmu_pmu->events[idx], event)) {
298-
smmu_pmu_set_event_filter(event, 0, span, sid);
298+
/* Otherwise, must match whatever's currently scheduled */
299+
if (smmu_pmu_check_global_filter(smmu_pmu->events[cur_idx], event)) {
300+
smmu_pmu_set_evtyper(smmu_pmu, idx, get_event(event));
299301
return 0;
300302
}
301303

0 commit comments

Comments
 (0)