Skip to content

Commit 24198ad

Browse files
melverPeter Zijlstra
authored andcommitted
perf/hw_breakpoint: Remove useless code related to flexible breakpoints
Flexible breakpoints have never been implemented, with bp_cpuinfo::flexible always being 0. Unfortunately, they still occupy 4 bytes in each bp_cpuinfo and bp_busy_slots, as well as computing the max flexible count in fetch_bp_busy_slots(). This again causes suboptimal code generation, when we always know that `!!slots.flexible` will be 0. Just get rid of the flexible "placeholder" and remove all real code related to it. Make a note in the comment related to the constraints algorithm but don't remove them from the algorithm, so that if in future flexible breakpoints need supporting, it should be trivial to revive them (along with reverting this change). Signed-off-by: Marco Elver <elver@google.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Reviewed-by: Dmitry Vyukov <dvyukov@google.com> Acked-by: Ian Rogers <irogers@google.com> Link: https://lore.kernel.org/r/20220829124719.675715-9-elver@google.com
1 parent 9caf87b commit 24198ad

File tree

1 file changed

+17
-40
lines changed

1 file changed

+17
-40
lines changed

kernel/events/hw_breakpoint.c

Lines changed: 17 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,6 @@ struct bp_cpuinfo {
4545
#else
4646
unsigned int *tsk_pinned;
4747
#endif
48-
/* Number of non-pinned cpu/task breakpoints in a cpu */
49-
unsigned int flexible; /* XXX: placeholder, see fetch_this_slot() */
5048
};
5149

5250
static DEFINE_PER_CPU(struct bp_cpuinfo, bp_cpuinfo[TYPE_MAX]);
@@ -67,12 +65,6 @@ static const struct rhashtable_params task_bps_ht_params = {
6765

6866
static bool constraints_initialized __ro_after_init;
6967

70-
/* Gather the number of total pinned and un-pinned bp in a cpuset */
71-
struct bp_busy_slots {
72-
unsigned int pinned;
73-
unsigned int flexible;
74-
};
75-
7668
/* Serialize accesses to the above constraints */
7769
static DEFINE_MUTEX(nr_bp_mutex);
7870

@@ -190,14 +182,14 @@ static const struct cpumask *cpumask_of_bp(struct perf_event *bp)
190182
}
191183

192184
/*
193-
* Report the number of pinned/un-pinned breakpoints we have in
194-
* a given cpu (cpu > -1) or in all of them (cpu = -1).
185+
* Returns the max pinned breakpoint slots in a given
186+
* CPU (cpu > -1) or across all of them (cpu = -1).
195187
*/
196-
static void
197-
fetch_bp_busy_slots(struct bp_busy_slots *slots, struct perf_event *bp,
198-
enum bp_type_idx type)
188+
static int
189+
max_bp_pinned_slots(struct perf_event *bp, enum bp_type_idx type)
199190
{
200191
const struct cpumask *cpumask = cpumask_of_bp(bp);
192+
int pinned_slots = 0;
201193
int cpu;
202194

203195
for_each_cpu(cpu, cpumask) {
@@ -210,24 +202,10 @@ fetch_bp_busy_slots(struct bp_busy_slots *slots, struct perf_event *bp,
210202
else
211203
nr += task_bp_pinned(cpu, bp, type);
212204

213-
if (nr > slots->pinned)
214-
slots->pinned = nr;
215-
216-
nr = info->flexible;
217-
if (nr > slots->flexible)
218-
slots->flexible = nr;
205+
pinned_slots = max(nr, pinned_slots);
219206
}
220-
}
221207

222-
/*
223-
* For now, continue to consider flexible as pinned, until we can
224-
* ensure no flexible event can ever be scheduled before a pinned event
225-
* in a same cpu.
226-
*/
227-
static void
228-
fetch_this_slot(struct bp_busy_slots *slots, int weight)
229-
{
230-
slots->pinned += weight;
208+
return pinned_slots;
231209
}
232210

233211
/*
@@ -298,7 +276,12 @@ __weak void arch_unregister_hw_breakpoint(struct perf_event *bp)
298276
}
299277

300278
/*
301-
* Constraints to check before allowing this new breakpoint counter:
279+
* Constraints to check before allowing this new breakpoint counter.
280+
*
281+
* Note: Flexible breakpoints are currently unimplemented, but outlined in the
282+
* below algorithm for completeness. The implementation treats flexible as
283+
* pinned due to no guarantee that we currently always schedule flexible events
284+
* before a pinned event in a same CPU.
302285
*
303286
* == Non-pinned counter == (Considered as pinned for now)
304287
*
@@ -340,8 +323,8 @@ __weak void arch_unregister_hw_breakpoint(struct perf_event *bp)
340323
*/
341324
static int __reserve_bp_slot(struct perf_event *bp, u64 bp_type)
342325
{
343-
struct bp_busy_slots slots = {0};
344326
enum bp_type_idx type;
327+
int max_pinned_slots;
345328
int weight;
346329
int ret;
347330

@@ -357,15 +340,9 @@ static int __reserve_bp_slot(struct perf_event *bp, u64 bp_type)
357340
type = find_slot_idx(bp_type);
358341
weight = hw_breakpoint_weight(bp);
359342

360-
fetch_bp_busy_slots(&slots, bp, type);
361-
/*
362-
* Simulate the addition of this breakpoint to the constraints
363-
* and see the result.
364-
*/
365-
fetch_this_slot(&slots, weight);
366-
367-
/* Flexible counters need to keep at least one slot */
368-
if (slots.pinned + (!!slots.flexible) > hw_breakpoint_slots_cached(type))
343+
/* Check if this new breakpoint can be satisfied across all CPUs. */
344+
max_pinned_slots = max_bp_pinned_slots(bp, type) + weight;
345+
if (max_pinned_slots > hw_breakpoint_slots_cached(type))
369346
return -ENOSPC;
370347

371348
ret = arch_reserve_bp_slot(bp);

0 commit comments

Comments
 (0)