什么是safe printk,就是 Use extra buffer to prevent a recursion deadlock in safe mode
的流程如下:
入口在printk中
asmlinkage __visible int printk(const char *fmt, ...)
{va_list args;int r;va_start(args, fmt);
#这里核心是调用vprintk_funcr = vprintk_func(fmt, args);va_end(args);return r;
}
vprintk_func的实现如下:
可以看到在vprintk_func中分了四种print_context,一般情况下我们走的是default
__printf(1, 0) int vprintk_func(const char *fmt, va_list args)
{/** Try to use the main logbuf even in NMI. But avoid calling console* drivers that might have their own locks.*/if ((this_cpu_read(printk_context) & PRINTK_NMI_DIRECT_CONTEXT_MASK) &&raw_spin_trylock(&logbuf_lock)) {int len;len = vprintk_store(0, LOGLEVEL_DEFAULT, NULL, 0, fmt, args);raw_spin_unlock(&logbuf_lock);defer_console_output();return len;}/* Use extra buffer in NMI when logbuf_lock is taken or in safe mode. */if (this_cpu_read(printk_context) & PRINTK_NMI_CONTEXT_MASK)return vprintk_nmi(fmt, args);
#根据printk_context的不同的值,走不同的分支,我们这里分析safe print/* Use extra buffer to prevent a recursion deadlock in safe mode. */if (this_cpu_read(printk_context) & PRINTK_SAFE_CONTEXT_MASK)return vprintk_safe(fmt, args);
#默认情况下走的这个flow,各个cpu 对printk中的锁竞争严重/* No obstacles. */return vprintk_default(fmt, args);
}
这里vprintk_safe->printk_safe_log_store
static __printf(2, 0) int printk_safe_log_store(struct printk_safe_seq_buf *s,const char *fmt, va_list args)
{int add;size_t len;va_list ap;again:len = atomic_read(&s->len);/* The trailing '\0' is not counted into len. */
#如果要打印的log的长度大于额外buffer的size,则调用queue_flush_work来flush logif (len >= sizeof(s->buffer) - 1) {atomic_inc(&s->message_lost);queue_flush_work(s);return 0;}/** Make sure that all old data have been read before the buffer* was reset. This is not needed when we just append data.*/if (!len)smp_rmb();
#否则直接打印log,这里也就是说要打印的log size 小于s->bufferva_copy(ap, args);add = vscnprintf(s->buffer + len, sizeof(s->buffer) - len, fmt, ap);va_end(ap);if (!add)return 0;/** Do it once again if the buffer has been flushed in the meantime.* Note that atomic_cmpxchg() is an implicit memory barrier that* makes sure that the data were written before updating s->len.*/
#如果在打印的同时又有log进来,则返回到前面继续打印if (atomic_cmpxchg(&s->len, len, len + add) != len)goto again;
#log打印完成后,还是调用queue_flush_work 包flush logqueue_flush_work(s);return add;
}
这里要说明的是每个cpu 都有一个queue来flush log,具体在下面这个函数中为每个cpu
来建立queue 用来flush log
void __init printk_safe_init(void)
{int cpu;for_each_possible_cpu(cpu) {struct printk_safe_seq_buf *s;
#为每个cpu 初始化queue来flush logs = &per_cpu(safe_print_seq, cpu);init_irq_work(&s->work, __printk_safe_flush);#ifdef CONFIG_PRINTK_NMIs = &per_cpu(nmi_print_seq, cpu);init_irq_work(&s->work, __printk_safe_flush);
#endif}/** In the highly unlikely event that a NMI were to trigger at* this moment. Make sure IRQ work is set up before this* variable is set.*/barrier();
#下面这个变量设置为1,表示可以在irq中安全打印logprintk_safe_irq_ready = 1;/* Flush pending messages that did not have scheduled IRQ works. */
#flush在queue 建立之前已经存在的logprintk_safe_flush();
}

safe printk相关推荐

  1. linux之printk

    今天和同事在遇到一个在内核中用printk打印log发现在一个printk里面,最后的log无法输出,如果去掉前面的一些log之后则可以显示后面的一些log信息,最后跟代码发现是由于在vprintk_ ...

  2. linux printk 时间戳,linux – kern.log中“00:00:00”时间戳的含义是什么?

    我正在寻找kern.log中特定问题的原因.有许多条目的00:00:00时间戳: Jun 11 00:00:00 mymachine kernel: [ 0.000000] Initializing ...

  3. scrum回顾_Scrum和SAFe之间有什么不同

    原文地址:https://www.knowledgehut.com/blog/agile/scrum-vs-safe Scrum是基于敏捷的价值观和原则的框架,而SAFe是在企业级别实施Scrum的框 ...

  4. It is not safe to rely on the system's timezone settings

    在写php程序中有时会出现这样的警告: PHP Warning: date(): It is not safe to rely on the system's timezone settings. Y ...

  5. mysql thread safe_Windows环境下完全手工配置Apache、MySQL和PHP(Thread Safe)

    happydagui:现在LAMP(Linux.Apache.MySQL.PHP/Perl/Python的简称)已经很流行了.在Windows下也有类似的,比如 WAMP(Apache, MySQL, ...

  6. xx.xib: error: Illegal Configuration: Safe Area Layout Guide before iOS 9.0报错问题解决

    之前是用xcode8.3.3创建的工程最近升级到Xcode9.0 遇见了这个问题 在Xcode 9.0以上 新建xib文件会报错 xx.xib: error: Illegal Configuratio ...

  7. China SAFe DAY 2020中国规模化敏捷大会圆满落幕

    11月15日,2020 China SAFe DAY暨中国首届规模化敏捷峰会在上海圆满落幕.本届大会由Scrum中文网和SAI联合主办,主题为"业务敏捷--数字化时代的核心竞争力" ...

  8. 2021China SAFe Day中国规模化敏捷会

    敏捷企业能够基于数字化业务解决方案快速响应市场变化,具备更快的创新速度,在数字时代具有更强的适应性和赢得竞争的能力. 敏捷企业要求参与提供解决方案的每个人--业务和技术领导者.开发.IT运营.法律.营 ...

  9. Linux查看dmesg日志,Linux中的Printk与dmesg功能

    要将linux内核的带级别控制的printk内容打印出来,在命令行输入 dmesg -n 8 就将所有级别的信息都打印出来. Linux命令:dmesg 功能说明:显示开机信息. 语 法:dmesg ...

最新文章

  1. win10鼠标灵敏度怎么调_和平精英最稳压枪灵敏度怎么调教程,适合所有段位以及适合国际版PUBG手游压枪...
  2. 技术图文:如何在leetcode上进行算法刻意练习?
  3. Mac-远程连接Mac
  4. python中with的用法,上下文管理器
  5. linux常用命令:wget 命令
  6. C++ CGI Helloword
  7. 手把手教你写DI_0_DI是什么?
  8. java学习(113):Calendar类
  9. linux下设置opencv环境变量
  10. Git和Github介绍,294页『Git与Github学习使用指南』分享
  11. linux socket编程:简易客户端与服务端
  12. java安全管理器视频_安全管理器 (Security Manager)
  13. paip.erlang环境搭建和脚本式escript运行halo world 在windows下attilax总结
  14. bp神经网络预测模型流程图,bp神经网络实例分析
  15. Android 项目之电话拨号器
  16. w ndows读音,汉字读音及音标 - 51windows.Net
  17. 计算机超链接文档顶端,电脑在Word文档里插入目录超链接的方法
  18. 机器学习实战(Machine Learning in Action)学习笔记————05.Logistic回归
  19. 一朵花的组成结构图_花是由哪几个部分组成的?
  20. QT图表chart-饼状图

热门文章

  1. 气候统计实习——EMD与ESMD方法介绍与应用(附matlab代码)
  2. 【华为OD机试真题】AI处理器组合(java)100%通过率 超详细代码注释 代码深度解读
  3. 模糊关系合成运算的Matlab实现
  4. 家庭中成药使用方法一览表
  5. 【构建PB级准实时分析引擎】 -- azkaban、airflow、dolphinscheduler、quartz、xxl-job 、oozie调度方案评测
  6. Java 输出星期几
  7. 并查集(树与环小希的迷宫)
  8. windows 备份树莓派 闪存卡(小镜像压缩备份 不需要等容量备份)
  9. 2021全网最全最详细的Spring面试题精选合集
  10. 最长回文串 马拉车算法 C++