嵌入式复位流程与优化(2)
2016-04-17 20:49
190 查看
背景
在前一篇《嵌入式复位流程研究与优化》中,主要针对之前复位流程中无脑关闭FD进行了优化。这几日,出现了一次复位流程未能走完的问题,一直阻塞在umount中不能出来。经过优化后,即使卡在umount中,也不会像以前那样控制台断开了(因为没有关闭控制台对应的套接字),保留了现场。经过对内核态堆栈的分析,我们认为应当是阻塞在了工作队列(work queue)上,在umount中,需要刷新cache到一个工作队列上,并等待该工作队列中的工作全部处理完,但是很遗憾,我们没有等到。板卡复位后,通过对日志的分析,发现有一个任务一直在占用CPU。目前,该问题我们可以在实验室稳定复现,可以证明时该问题导致了复位流程阻塞,未能执行完,导致复位不成功。由于umount阻塞的问题不止一次出现,且原因并不相同,考虑到该问题严重影响设备稳定性,我们不能仅解决引起umount阻塞的问题,我们必须寻求办法来进行规避,使阻塞在umount中的问题,在任何情况下都不能出现。
分析与解决
解决该问题最直接且暴力的方法,就是另起一个线程,等待一定时间后直接无脑复位。但我一直认为这种修改比较别扭,未采用。主要原因如下:(1) 需要pthread_create创建一个线程,还需要设置一大堆参数,优先级设置的不合适不定出现什么问题,麻烦;
(2) pthread_create需要指定一个入口函数,目前我们没有这样线程的入口函数。而且在新平台架构下,复位函数被绑定到了板卡配置的一个reset_func函数指针上。目前复位函数本身,包含了文件系统同步,而这个线程入口函数,则不能含有文件系统的同步。新写一个函数是肯定的了,而这个函数由需要直接操作寄存器,怎么写都觉得别扭。
直到今日翻《APUE》时,偶然看到了其中对于慢速I/O读超时的处理方法。书中的例子主要针对的是read函数,使用alarm函数来实现。alarm函数向系统注册一个alarm定时器,该定时器超时后,会向进程发送SIGALRM信号。在SIGALRM信号中,我们只需要使其跳出阻塞的系统调用即可。信号处理函数,会打断系统调用的执行,在处理完信号后,系统调用是否会重试,依赖于具体的操作系统。在我们的这种场景下,我们需要系统调用被打断后,不能重试,否则又会陷入到阻塞态。这里,我们就要使用setjmp以及longjmp,书中之前就多次提到这两个函数配合信号使用,达到打断系统调用的目的。先写了一个demo做试验,代码如下:
#include <stdio.h> #include <setjmp.h> #include <signal.h> #include <unistd.h> static jmp_buf env_alrm; void sig_alrm(int signo) { printf("receive sig alarm.\n"); longjmp(env_alrm, 1); } int main() { if(signal(SIGALRM, sig_alrm) == SIG_ERR) { printf("fail to regist sig_alrm.\n"); } if(setjmp(env_alrm) != 0) { printf("saved by alarm.\n"); return 0; } alarm(10); while(1) { sleep(1); } }
代码十分简单,在main函数中,通过setjmp设置jump点,在收到alarm信号后,即可还原到该点,然后从main函数中退出。代码在调用alarm注册后,直接陷入无限循环。我们期望,alarm信号可以把这段代码从无限循环中拯救出来。运行结果如下:
$ ./test4.o receive sig alarm. saved by alarm.
代码最终正常退出。这段代码对应到我们的项目中,main函数就可以理解成reboot_hook函数,在该函数内仅执行文件系统同步的功能,并不执行复位操作,我们可以通过alarm注册,保证该函数在一定时间内一定会返回,不会导致再次卡死在复位函数中。
相关文章推荐
- RabbitMQ消息队列应用
- linux apache 2.4.20版本安装
- unsigned关键字的学习
- 专题二1008
- Java中的接口
- 第七周进度报告
- openstack之nova启动实例过程
- ZOJ3861 手机锁
- 线程控制与分离
- 逆康拓展开展开
- 仿qq侧滑删除的一个自定义View,独立的,不需要依赖其他的view
- N皇后Java算法
- 逆康拓展开展开
- 关于javassist.NotFoundException
- DBScan聚类算法Java实现
- 这些年MAC下我常用的那些快捷键
- 20145211 《Java程序设计》第7周学习总结——沧海横流
- 20145235《Java程序设计》第7周学习总结
- 阿里巴巴笔试
- 指针与引用