spsc_pbuf: fix cache invalidation in spsc_pbuf_free

In case the read index points to the end of the packet buffer and thus
wraps around, we must not invalidate the cache, otherwise we draw
outside of the lines and purge data outside of our responsibility.

Signed-off-by: Patrick Wildt <pwildt@google.com>
This commit is contained in:
Patrick Wildt 2023-10-03 11:43:10 +00:00 committed by David Leach
parent 02baa658d2
commit f61bbad625

View file

@ -327,21 +327,21 @@ void spsc_pbuf_free(struct spsc_pbuf *pb, uint16_t len)
uint8_t *data_loc = get_data_loc(pb, flags);
rd_idx = ROUND_UP(rd_idx, sizeof(uint32_t));
cache_inv(&data_loc[rd_idx], sizeof(uint8_t), flags);
/* Handle wrapping or the fact that next packet is a padding. */
if (rd_idx == pblen) {
rd_idx = 0;
} else if (data_loc[rd_idx] == PADDING_MARK) {
cache_inv(wr_idx_loc, sizeof(*wr_idx_loc), flags);
/* We may hit the case when producer is in the middle of adding
* a padding (which happens in 2 steps: writing padding, resetting
* write index) and in that case we cannot consume this padding.
*/
if (rd_idx != *wr_idx_loc) {
rd_idx = 0;
if (rd_idx != pblen) {
cache_inv(&data_loc[rd_idx], sizeof(uint8_t), flags);
if (data_loc[rd_idx] == PADDING_MARK) {
cache_inv(wr_idx_loc, sizeof(*wr_idx_loc), flags);
/* We may hit the case when producer is in the middle of adding
* a padding (which happens in 2 steps: writing padding, resetting
* write index) and in that case we cannot consume this padding.
*/
if (rd_idx != *wr_idx_loc) {
rd_idx = 0;
}
}
} else {
/* empty */
rd_idx = 0;
}
*rd_idx_loc = rd_idx;