@@ -256,9 +256,8 @@ amd_get_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *event)
256256{
257257 struct hw_perf_event * hwc = & event -> hw ;
258258 struct amd_nb * nb = cpuc -> amd_nb ;
259- struct perf_event * old = NULL ;
260- int max = x86_pmu .num_counters ;
261- int i , j , k = -1 ;
259+ struct perf_event * old ;
260+ int idx , new = -1 ;
262261
263262 /*
264263 * if not NB event or no NB, then no constraints
@@ -276,48 +275,33 @@ amd_get_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *event)
276275 * because of successive calls to x86_schedule_events() from
277276 * hw_perf_group_sched_in() without hw_perf_enable()
278277 */
279- for (i = 0 ; i < max ; i ++ ) {
280- /*
281- * keep track of first free slot
282- */
283- if (k == -1 && !nb -> owners [i ])
284- k = i ;
278+ for (idx = 0 ; idx < x86_pmu .num_counters ; idx ++ ) {
279+ if (new == -1 || hwc -> idx == idx )
280+ /* assign free slot, prefer hwc->idx */
281+ old = cmpxchg (nb -> owners + idx , NULL , event );
282+ else if (nb -> owners [idx ] == event )
283+ /* event already present */
284+ old = event ;
285+ else
286+ continue ;
287+
288+ if (old && old != event )
289+ continue ;
290+
291+ /* reassign to this slot */
292+ if (new != -1 )
293+ cmpxchg (nb -> owners + new , event , NULL );
294+ new = idx ;
285295
286296 /* already present, reuse */
287- if (nb -> owners [i ] == event )
288- goto done ;
289- }
290- /*
291- * not present, so grab a new slot
292- * starting either at:
293- */
294- if (hwc -> idx != -1 ) {
295- /* previous assignment */
296- i = hwc -> idx ;
297- } else if (k != -1 ) {
298- /* start from free slot found */
299- i = k ;
300- } else {
301- /*
302- * event not found, no slot found in
303- * first pass, try again from the
304- * beginning
305- */
306- i = 0 ;
307- }
308- j = i ;
309- do {
310- old = cmpxchg (nb -> owners + i , NULL , event );
311- if (!old )
297+ if (old == event )
312298 break ;
313- if (++ i == max )
314- i = 0 ;
315- } while (i != j );
316- done :
317- if (!old )
318- return & nb -> event_constraints [i ];
319-
320- return & emptyconstraint ;
299+ }
300+
301+ if (new == -1 )
302+ return & emptyconstraint ;
303+
304+ return & nb -> event_constraints [new ];
321305}
322306
323307static struct amd_nb * amd_alloc_nb (int cpu )
0 commit comments