Re: [PATCH] ring-buffer: Fix slowpath of interrupted event

From: Steven Rostedt
Date: Tue Dec 19 2023 - 10:35:30 EST


On Tue, 19 Dec 2023 10:10:27 -0500
Steven Rostedt <rostedt@xxxxxxxxxxx> wrote:

> 1000 - interrupt event
> 2000 - normal context event
> 2100 - next normal context event
>
> Where we see the delta between the interrupt event and the normal context
> event was 1000. But if we just had it be delta = 0, it would be:
>
> 1000 - interrupt event
> 1000 - normal context event
> 2100 - next normal context event
>

Also, let me show the rare case of where we do have delta=0. That would be
an interrupt event coming in before *and* after the normal context event
was allocated. That is, we have:

|-- interrupt event --|-- normal context event --|-- interrupt event --|

And that could look like:

1000 - interrupt event
1000 - normal context event
2100 - next interrupt event

It may look like the normal context ran for 1000 before the next interrupt
event, but in reality it happened sometime between the two.

Hmm, in this case, what we could possibly do is to read the absolute
timestamp *after* the interrupted event!

That is, we detected we are here:

|-- interrupt event --|-- normal context event --|-- interrupt event --|

^
|
|


And we know that the write pointer is past this event. We can look at the
next event and see what its timestamp is. It is either a delta or a
absolute timestamp. It is a delta if the previous interrupt came in between
B and C, as that event would have made before_stamp == write_stamp. Or it
is an absolute delta if this event updated the before_stamp making it no
longer match the write_stamp of the previous event.

If it is an absolute timestamp, it means the interrupt came in before our
update of the before stamp, and we could make our delta:

absolute value of next timestamp - this event before_stamp

As we have:

|-- interrupt event --|-- normal context event --|-- interrupt event --|

^ ^ ^
| | |
ts is before before_stamp | |
our before_stamp |
absolute value

We just need to make our delta not go beyond the absolute value. So:

ts of first event + (absolute value - our before_stamp)

Should not be greater than the absolute value.

If the next event has a delta, we could make this event delta equal to it,
and then update the next event to have a delta of zero, which would give us:

1000 - interrupt event
2100 - normal context event
2100 - next interrupt event

Which is much more realistic to what happened.

But all this is for another time ;-)

-- Steve