diff options
author | Petr Mladek <pmladek@suse.com> | 2022-01-21 18:36:28 +0530 |
---|---|---|
committer | Petr Mladek <pmladek@suse.com> | 2022-01-26 16:00:32 +0100 |
commit | f244b4dc53e520d4570b2610436aba0593ce6f55 (patch) | |
tree | 4258a27d59e985d40193ade0de8418bdb8b7f415 /kernel/printk/printk_ringbuffer.h | |
parent | 11e4b63abbe23872b45f325a7c6c8b7f9ff42cad (diff) | |
download | linux-f244b4dc53e520d4570b2610436aba0593ce6f55.tar.gz linux-f244b4dc53e520d4570b2610436aba0593ce6f55.tar.bz2 linux-f244b4dc53e520d4570b2610436aba0593ce6f55.zip |
printk: ringbuffer: Improve prb_next_seq() performance
prb_next_seq() always iterates from the first known sequence number.
In the worst case, it might loop 8k times for 256kB buffer,
15k times for 512kB buffer, and 64k times for 2MB buffer.
It was reported that polling and reading using syslog interface
might occupy 50% of CPU.
Speedup the search by storing @id of the last finalized descriptor.
The loop is still needed because the @id is stored and read in the best
effort way. An atomic variable is used to keep the @id consistent.
But the stores and reads are not serialized against each other.
The descriptor could get reused in the meantime. The related sequence
number will be used only when it is still valid.
An invalid value should be read _only_ when there is a flood of messages
and the ringbuffer is rapidly reused. The performance is the least
problem in this case.
Reported-by: Chunlei Wang <chunlei.wang@mediatek.com>
Signed-off-by: Mukesh Ojha <quic_mojha@quicinc.com>
Reviewed-by: John Ogness <john.ogness@linutronix.de>
Signed-off-by: Petr Mladek <pmladek@suse.com>
Link: https://lore.kernel.org/r/1642770388-17327-1-git-send-email-quic_mojha@quicinc.com
Link: https://lore.kernel.org/lkml/YXlddJxLh77DKfIO@alley/T/#m43062e8b2a17f8dbc8c6ccdb8851fb0dbaabbb14
Diffstat (limited to 'kernel/printk/printk_ringbuffer.h')
-rw-r--r-- | kernel/printk/printk_ringbuffer.h | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/kernel/printk/printk_ringbuffer.h b/kernel/printk/printk_ringbuffer.h index 73cc80e01cef..18cd25e489b8 100644 --- a/kernel/printk/printk_ringbuffer.h +++ b/kernel/printk/printk_ringbuffer.h @@ -75,6 +75,7 @@ struct prb_desc_ring { struct printk_info *infos; atomic_long_t head_id; atomic_long_t tail_id; + atomic_long_t last_finalized_id; }; /* @@ -258,6 +259,7 @@ static struct printk_ringbuffer name = { \ .infos = &_##name##_infos[0], \ .head_id = ATOMIC_INIT(DESC0_ID(descbits)), \ .tail_id = ATOMIC_INIT(DESC0_ID(descbits)), \ + .last_finalized_id = ATOMIC_INIT(DESC0_ID(descbits)), \ }, \ .text_data_ring = { \ .size_bits = (avgtextbits) + (descbits), \ |