printk内核实现原理

基于linux 6.1.12

  1. files

  • /kernel/printk/printk.c

  • /include/linux/printk.h

  • /kernel/printk/printk_ringbuffer.c

  • /kernel/printk/printk_ringbuffer.h

  1. data structure

3. overall call flow

3.1 write flow

(1)desc_reserve:从prb_desc数组中获取一个空闲的entry,若没有空闲的entry,则覆盖最老的entry。分配完成后将该描述符状态设置为desc_reserved

(2)设置该条log的seq序号

(3)data_alloc:从ring buffer中分配一段用于保存新log的空间,若空闲空间不足,则覆盖掉最老的数据,直到空间足够为止

(4)log data copy:将需要写入的数据拷贝到从log buffer中分配的空间中

(5)_prb_commit:将prb_desc的状态更新为desc_committed

(6)desc_make_final:将prb_desc的状态更新为desc_finalized,该操作后log写入完成且可被读取。

3.2 read flow

读取log时以seq序号为参数,并调用prb_read读取该seq对应的log,若读取失败则调用prb_first_seq获取该seq之后第一条可读的log,并重新读取。

(1)desc_read_finalized_seq:读取该条log对应的状态,若状态合法,则执行下面的log数据和信息读取操作,否则表明该条log已被覆盖、正在被修改或其描述符是空闲的。数据读取完成后,再次执行本函数重新读取其状态和seq号,若状态合法且seq号未变,表明在读的过程中,数据未被写操作修改。否则,表明在读的过程中,该条log的信息或数据已被log写接口覆盖修改了。若整个读流程成功,则数据读取完成,否则调用prb_first_seq获取下一条可读的log

(2)prb_first_seq:由于buffer中尾节点是最老的log数据,因此若待读取数据比尾结点数据还老,则表明该数据已被覆盖,将尾结点作为first seq读取即可。若该节点合法,但数据读取失败,则将下一个节点作为first seq读取。若缓冲区中无有效数据,则返回错误

4. 设计思想

  1. 如何通过细化数据,分而治之,通过添加 prb_desc_ring,以及采用 atomic_t 变量等方法来去除锁的消耗。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值