Skip to content

Commit 1af61ad

Browse files
ubizjakPeter Zijlstra
authored andcommitted
perf/ring_buffer: Use local_try_cmpxchg in __perf_output_begin
Use local_try_cmpxchg instead of local_cmpxchg (*ptr, old, new) == old in __perf_output_begin. 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 d6b4548 commit 1af61ad

File tree

1 file changed

+3
-2
lines changed

1 file changed

+3
-2
lines changed

kernel/events/ring_buffer.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,9 +191,10 @@ __perf_output_begin(struct perf_output_handle *handle,
191191

192192
perf_output_get_handle(handle);
193193

194+
offset = local_read(&rb->head);
194195
do {
196+
head = offset;
195197
tail = READ_ONCE(rb->user_page->data_tail);
196-
offset = head = local_read(&rb->head);
197198
if (!rb->overwrite) {
198199
if (unlikely(!ring_buffer_has_space(head, tail,
199200
perf_data_size(rb),
@@ -217,7 +218,7 @@ __perf_output_begin(struct perf_output_handle *handle,
217218
head += size;
218219
else
219220
head -= size;
220-
} while (local_cmpxchg(&rb->head, offset, head) != offset);
221+
} while (!local_try_cmpxchg(&rb->head, &offset, head));
221222

222223
if (backward) {
223224
offset = head;

0 commit comments

Comments
 (0)