忘记密码   免费注册 查看新帖 |

ChinaUnix.net

  平台 论坛 博客 认证专区 大话IT 徽章 文库 自测 下载 频道自动化运维 虚拟化 储存备份 C/C++ PHP MySQL 嵌入式 Linux系统
最近访问板块 发新帖
查看: 3807 | 回复: 4

如何理解blk_plug_device(),blk_remove_plug() [复制链接]

论坛徽章:
0
发表于 2011-01-06 09:10 |显示全部楼层
各位大虾好:

         小弟在看文件系统相关代码时,对Block层的blk_plug_device(),blk_remove_plug()这个两个函数不大理解,ULK上说“blk_plug_device()是指的是插入到某个块设备驱动程序处理的请求队列中,blk_remove_plug()是拔去一个请求队列q”。但在2.6.24的__make_request()函数中:
         1   当通过elv_queue_empty()判断请求队列为空时调用了blk_plug_device(),这是什么原因?
         2   而当该bio操作有sync标志时会调用__generic_unplug_device(),这个我能想明白,要立刻处理此bio,但为什么在里面又调用了blk_remove_plug()?
         怎么感觉上述的调用和ULK上对这两个函数功能描述不大对应啊,我是新手,还请大家多多指教,谢谢了

论坛徽章:
0
发表于 2011-01-10 12:34 |显示全部楼层
哎,还是没人回啊,只好自己顶了,各位大侠别嫌太简单啊,小弟真心求教啊

论坛徽章:
0
发表于 2011-01-10 19:31 |显示全部楼层
我的理解是:plug相当于暂停IO调度,而unplug恢复IO调度。
为什么要有这两个动作呢?IO调度的原理类似于电梯算法,对于一组IO请求来说,这样的算法可以减少磁头移动的距离。而如果待处理的IO请求永远只有一个呢?电梯算法也就退化成先进先出算法。
plug+unplug的意图就是让待处理的IO请求积攒一些时间,只有当IO请求有一定数目的时候,电梯算法才会发挥它的优势。当然,也不能等待得太久。

论坛徽章:
0
发表于 2011-01-12 08:41 |显示全部楼层
谢谢kouu了,向你说的从调度的角度来说我想我明白点了,继续看代码咯

论坛徽章:
0
发表于 2018-01-29 17:20 |显示全部楼层
如果queue为空,则blk_run_queue,中会设置queue为UNPLUG,这样就没有3ms后的数据写入设备的timer了。
所以在如果想往queue中添加request需要先打开timer,这样3ms过后数据才会被timer调用的__generic_unplug_device内核线程写入设备。


NOTE:如果不开启设备queue的plug(即不调用blk_plug_device),直接调用add_request,那么requset,将永远保留在queue中不会刷新到设备中。

  1. //从队列中移除被插入的请求,表示要队列中的请求都写入设备                                                                 
  2. //Return Value:0表示前一个状态是未插入,1表示前一个状态是插入                                                                                                                                 
  3. /*                                                                 
  4. * remove the queue from the plugged list, if present. called with                                                                 
  5. * queue lock held and interrupts disabled.                                                                 
  6. */                                                                 
  7. int blk_remove_plug(request_queue_t *q)                                                                 
  8. {                                                                 
  9.     WARN_ON(!irqs_disabled());                                                            
  10.                                                                  
  11.     if (!test_and_clear_bit(QUEUE_FLAG_PLUGGED, &q->queue_flags))                        //清楚队列plug状态,如果之前是unplug状态直接返回0,因为此时至准没有unplug的timer被设置                              
  12.         return 0;                                                         
  13.     del_timer(&q->unplug_timer);                //如果前一个状态是插入状态,那么一定为设置在3ms后unplug队列的计时器,所以这里删除定时器,防止队列unplug(防止队列把数据写入磁盘)                                             
  14.     return 1;                                                            
  15. }      
复制代码

                                                         
一般blk_remove_plug会和__generic_unplug_device一起只用,用来往设备上刷新request。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号 北京市公安局海淀分局网监中心备案编号:11010802020122
广播电视节目制作经营许可证(京) 字第1234号 中国互联网协会会员  联系我们:
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP