History

ring-buffer: Force absolute timestamp on discard of event

There's a race where if an event is discarded from the ring buffer and an interrupt were to happen at that time and insert an event, the time stamp is still used from the discarded event as an offset. This can screw up the timings. If the event is going to be discarded, set the "before_stamp" to zero. When a new event comes in, it compares the "before_stamp" with the "write_stamp" and if they are not equal, it will insert an absolute timestamp. This will prevent the timings from getting out of sync due to the discarded event. Link: https://lore.kernel.org/linux-trace-kernel/20231206100244.5130f9b3@gandalf.local.home

Steven Rostedt (Google) committed 2 years ago

Commit b2dd7971 parent c0591b11 file · +8 −11Browse files

Showing the changes to kernel/trace (1 of 1 file). Show all

Unified · Split

kernel/trace/ring_buffer.c+8−11
@@ -3030,22 +3030,19 @@ rb_try_to_discard(struct ring_buffer_per_cpu *cpu_buffer, · 3029 unmodified lines
3030 local_read(&bpage->write) & ~RB_WRITE_MASK;3030 local_read(&bpage->write) & ~RB_WRITE_MASK;
3031 unsigned long event_length = rb_event_length(event);3031 unsigned long event_length = rb_event_length(event);
3032 3032
3033 /*
3034 * For the before_stamp to be different than the write_stamp
3035 * to make sure that the next event adds an absolute
3036 * value and does not rely on the saved write stamp, which
3037 * is now going to be bogus.
3038 */
3039 rb_time_set(&cpu_buffer->before_stamp, 0);
3040
3033 /* Something came in, can't discard */3041 /* Something came in, can't discard */
3034 if (!rb_time_cmpxchg(&cpu_buffer->write_stamp,3042 if (!rb_time_cmpxchg(&cpu_buffer->write_stamp,
3035 write_stamp, write_stamp - delta))3043 write_stamp, write_stamp - delta))
3036 return false;3044 return false;
3037 3045
3038 /*
3039 * It's possible that the event time delta is zero
3040 * (has the same time stamp as the previous event)
3041 * in which case write_stamp and before_stamp could
3042 * be the same. In such a case, force before_stamp
3043 * to be different than write_stamp. It doesn't
3044 * matter what it is, as long as its different.
3045 */
3046 if (!delta)
3047 rb_time_set(&cpu_buffer->before_stamp, 0);
3048
3049 /*3046 /*
3050 * If an event were to come in now, it would see that the3047 * If an event were to come in now, it would see that the
3051 * write_stamp and the before_stamp are different, and assume3048 * write_stamp and the before_stamp are different, and assume

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t