Skip to content

Commit 67e1b00

Browse files
d-tatianinpmladek
authored andcommitted
printk_ringbuffer: don't needlessly wrap data blocks around
Previously, data blocks that perfectly fit the data ring buffer would get wrapped around to the beginning for no reason since the calculated offset of the next data block would belong to the next wrap. Since this offset is not actually part of the data block, but rather the offset of where the next data block is going to start, there is no reason to include it when deciding whether the current block fits the buffer. Signed-off-by: Daniil Tatianin <d-tatianin@yandex-team.ru> Reviewed-by: Petr Mladek <pmladek@suse.com> Tested-by: Petr Mladek <pmladek@suse.com> Reviewed-by: John Ogness <john.ogness@linutronix.de> Tested-by: John Ogness <john.ogness@linutronix.de> Link: https://patch.msgid.link/20250905144152.9137-2-d-tatianin@yandex-team.ru [pmladek@suse.com: Updated indentation.] Signed-off-by: Petr Mladek <pmladek@suse.com>
1 parent 48e3694 commit 67e1b00

1 file changed

Lines changed: 20 additions & 8 deletions

File tree

kernel/printk/printk_ringbuffer.c

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -999,6 +999,17 @@ static bool desc_reserve(struct printk_ringbuffer *rb, unsigned long *id_out)
999999
return true;
10001000
}
10011001

1002+
static bool is_blk_wrapped(struct prb_data_ring *data_ring,
1003+
unsigned long begin_lpos, unsigned long next_lpos)
1004+
{
1005+
/*
1006+
* Subtract one from next_lpos since it's not actually part of this data
1007+
* block. This allows perfectly fitting records to not wrap.
1008+
*/
1009+
return DATA_WRAPS(data_ring, begin_lpos) !=
1010+
DATA_WRAPS(data_ring, next_lpos - 1);
1011+
}
1012+
10021013
/* Determine the end of a data block. */
10031014
static unsigned long get_next_lpos(struct prb_data_ring *data_ring,
10041015
unsigned long lpos, unsigned int size)
@@ -1010,7 +1021,7 @@ static unsigned long get_next_lpos(struct prb_data_ring *data_ring,
10101021
next_lpos = lpos + size;
10111022

10121023
/* First check if the data block does not wrap. */
1013-
if (DATA_WRAPS(data_ring, begin_lpos) == DATA_WRAPS(data_ring, next_lpos))
1024+
if (!is_blk_wrapped(data_ring, begin_lpos, next_lpos))
10141025
return next_lpos;
10151026

10161027
/* Wrapping data blocks store their data at the beginning. */
@@ -1087,7 +1098,7 @@ static char *data_alloc(struct printk_ringbuffer *rb, unsigned int size,
10871098
blk = to_block(data_ring, begin_lpos);
10881099
blk->id = id; /* LMM(data_alloc:B) */
10891100

1090-
if (DATA_WRAPS(data_ring, begin_lpos) != DATA_WRAPS(data_ring, next_lpos)) {
1101+
if (is_blk_wrapped(data_ring, begin_lpos, next_lpos)) {
10911102
/* Wrapping data blocks store their data at the beginning. */
10921103
blk = to_block(data_ring, 0);
10931104

@@ -1131,7 +1142,7 @@ static char *data_realloc(struct printk_ringbuffer *rb, unsigned int size,
11311142
return NULL;
11321143

11331144
/* Keep track if @blk_lpos was a wrapping data block. */
1134-
wrapped = (DATA_WRAPS(data_ring, blk_lpos->begin) != DATA_WRAPS(data_ring, blk_lpos->next));
1145+
wrapped = is_blk_wrapped(data_ring, blk_lpos->begin, blk_lpos->next);
11351146

11361147
size = to_blk_size(size);
11371148

@@ -1167,7 +1178,7 @@ static char *data_realloc(struct printk_ringbuffer *rb, unsigned int size,
11671178

11681179
blk = to_block(data_ring, blk_lpos->begin);
11691180

1170-
if (DATA_WRAPS(data_ring, blk_lpos->begin) != DATA_WRAPS(data_ring, next_lpos)) {
1181+
if (is_blk_wrapped(data_ring, blk_lpos->begin, next_lpos)) {
11711182
struct prb_data_block *old_blk = blk;
11721183

11731184
/* Wrapping data blocks store their data at the beginning. */
@@ -1203,7 +1214,7 @@ static unsigned int space_used(struct prb_data_ring *data_ring,
12031214
if (BLK_DATALESS(blk_lpos))
12041215
return 0;
12051216

1206-
if (DATA_WRAPS(data_ring, blk_lpos->begin) == DATA_WRAPS(data_ring, blk_lpos->next)) {
1217+
if (!is_blk_wrapped(data_ring, blk_lpos->begin, blk_lpos->next)) {
12071218
/* Data block does not wrap. */
12081219
return (DATA_INDEX(data_ring, blk_lpos->next) -
12091220
DATA_INDEX(data_ring, blk_lpos->begin));
@@ -1250,14 +1261,15 @@ static const char *get_data(struct prb_data_ring *data_ring,
12501261
}
12511262

12521263
/* Regular data block: @begin less than @next and in same wrap. */
1253-
if (DATA_WRAPS(data_ring, blk_lpos->begin) == DATA_WRAPS(data_ring, blk_lpos->next) &&
1264+
if (!is_blk_wrapped(data_ring, blk_lpos->begin, blk_lpos->next) &&
12541265
blk_lpos->begin < blk_lpos->next) {
12551266
db = to_block(data_ring, blk_lpos->begin);
12561267
*data_size = blk_lpos->next - blk_lpos->begin;
12571268

12581269
/* Wrapping data block: @begin is one wrap behind @next. */
1259-
} else if (DATA_WRAPS(data_ring, blk_lpos->begin + DATA_SIZE(data_ring)) ==
1260-
DATA_WRAPS(data_ring, blk_lpos->next)) {
1270+
} else if (!is_blk_wrapped(data_ring,
1271+
blk_lpos->begin + DATA_SIZE(data_ring),
1272+
blk_lpos->next)) {
12611273
db = to_block(data_ring, 0);
12621274
*data_size = DATA_INDEX(data_ring, blk_lpos->next);
12631275

0 commit comments

Comments
 (0)