免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1897 | 回复: 1
打印 上一主题 下一主题

请教MD驱动问题:raid1里的freeze_array [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-04-30 09:22 |只看该作者 |倒序浏览
我在MD驱动,raid1.c里,把发生错误的I/O请求挂起来,等待15-20秒的时间,然后再结束该I/O。但处理总停在freeze_array()->wait_event_lock_irq()->schedule(),也就是说他自己睡眠等待以后,交出CPU就再也回不来了。
从现象看,就是我用iozone对MD进行写测试,8个写线程全部挂住,过一段时间,打出120秒I/O超时错误,并且内核爆出很多函数调用栈,比如pdflush失败。
跟踪代码,发现过程中穿插了read失败,产生了retryI/O,这样就进入了daemon(即raid1d)的读请求修复功能(fix_read_error)。在fix_read_error之前,为了保持数据一致性,系统会先冷冻阵列(freeze_array)。结果进去了就再也没有出来。
请教:bug原因有怎样的可能。是否因为哪种资源竞争或者死锁,可以产生这样的现象?

附个人对freeze_array的理解:
在修复该readI/O的时候,由于需要使用其他镜像盘,所以用freeze_array冰冻MD设备。
freeze_array具体实现:
conf->barrier++; //通过barrier计数挡住所有新的I/O
conf->nr_waiting++; //把触发freeze_array的I/O(即失败的readI/O)加到wait计数
/* 等待所有已经进入raid1层的I/O完成 */
wait_event_lock_irq(conf->wait_barrier,
   conf->nr_pending == conf->nr_queued+1,
   conf->resync_lock,
   ({ flush_pending_writes(conf);
      raid1_unplug(conf->mddev->queue); }));
这里等待的事件是“所有已进入raid1的readI/O挂入retry表,所有已进入raid1的writeI/O完成写动作。”

在冰冻设备完成后,设备上只剩未决的readI/O。这时,内核可以开始他的fix_read_error了


[ 本帖最后由 jjjjffff 于 2009-4-30 11:44 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2009-04-30 11:35 |只看该作者
问题有点眉目,我感觉是这样的,
1.raid1层里的writeI/O都被我挂起来了
2.这时发生读错误,进入冷冻设备的处理。
3.所有readI/O都在retrylist里
4.所有冷冻设备后产生的I/O被放入等待队列。

这时实际已没有活动的I/O了,也不会有新的I/O进来了,实际是一种逻辑竞争造成 冷冻处理中的schedule放弃了CPU以后就再也调度不到raid1的处理了。这就产生了我的bug现象,raid1d再也活不过来了。

以上是我对代码的分析,结果还没有最后确认出来。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP