Skip to content

Commit 28fd85a

Browse files
ubizjakPeter Zijlstra
authored andcommitted
perf/core: Use local64_try_cmpxchg in perf_swevent_set_period
Use local64_try_cmpxchg instead of local64_cmpxchg (*ptr, old, new) == old in perf_swevent_set_period. x86 CMPXCHG instruction returns success in ZF flag, so this change saves a compare after cmpxchg (and related move instruction in front of cmpxchg). Also, try_cmpxchg implicitly assigns old *ptr value to "old" when cmpxchg fails. There is no need to re-read the value in the loop. No functional change intended. Signed-off-by: Uros Bizjak <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Link: https://lkml.kernel.org/r/[email protected]
1 parent 4c1c9de commit 28fd85a

File tree

1 file changed

+9
-9
lines changed

1 file changed

+9
-9
lines changed

kernel/events/core.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9595,16 +9595,16 @@ u64 perf_swevent_set_period(struct perf_event *event)
95959595

95969596
hwc->last_period = hwc->sample_period;
95979597

9598-
again:
9599-
old = val = local64_read(&hwc->period_left);
9600-
if (val < 0)
9601-
return 0;
9598+
old = local64_read(&hwc->period_left);
9599+
do {
9600+
val = old;
9601+
if (val < 0)
9602+
return 0;
96029603

9603-
nr = div64_u64(period + val, period);
9604-
offset = nr * period;
9605-
val -= offset;
9606-
if (local64_cmpxchg(&hwc->period_left, old, val) != old)
9607-
goto again;
9604+
nr = div64_u64(period + val, period);
9605+
offset = nr * period;
9606+
val -= offset;
9607+
} while (!local64_try_cmpxchg(&hwc->period_left, &old, val));
96089608

96099609
return nr;
96109610
}

0 commit comments

Comments
 (0)