分析:

/*
* blk_plug permits building a queue of related requests by holding the I/O
* fragments for a short period. This allows merging of sequential requests
* into single larger request. As the requests are moved from a per-task list to
* the device's request_queue in a batch, this results in improved scalability
* as the lock contention for request_queue lock is reduced.
*
* It is ok not to disable preemption when adding the request to the plug list
* or when attempting a merge, because blk_schedule_flush_list() will only flush
* the plug list when the task sleeps by itself. For details, please see
* schedule() where blk_schedule_flush_plug() is called.
*/
struct blk_plug {
unsigned long magic; /* detect uninitialized use-cases */
struct list_head list; /* requests */
struct list_head cb_list; /* md requires an unplug callback */
unsigned int should_sort; /* list to be sorted before flushing? */
};
#define BLK_MAX_REQUEST_COUNT 16 struct blk_plug_cb;
typedef void (*blk_plug_cb_fn)(struct blk_plug_cb *, bool);
struct blk_plug_cb {
struct list_head list;
blk_plug_cb_fn callback;
void *data;
};

blk_plug构建了一个缓存碎片IO的请求队列。用于将顺序请求合并成一个大的请求。

合并后请求批量从per-task链表移动到设备请求队列,减少了设备请求队列锁竞争,
从而提高了效率。
blk_plug的使用很简单:
1、设置该线程开启请求合并模式  blk_start_plug
2、关闭线程请求合并  blk_finish_plug
至于如何合并、如何下发请求,这些工作都是由内核来完成的。

那么blk_plug适用于什么情况呢?由于是专门优化请求合并的,所以适合于连续的小块请求。
下面是一个测试的结果:
测试环境:
SATA控制器:intel 82801JI
OS: linux3.6, redhat 
raid5: 4个ST31000524NS盘
没有blk_plug:
Total (8,16):
Reads Queued: 309811, 1239MiB Writes Queued: 0, 0KiB
Read Dispatches: 283583, 1189MiB Write Dispatches: 0, 0KiB
Reads Requeued: 0 Writes Requeued: 0
Reads Completed: 273351, 1149MiB Writes Completed: 0, 0KiB
Read Merges: 23533, 94132KiB Write Merges: 0, 0KiB
IO unplugs: 0 Timer unplugs: 0 添加了 blk_plug:
Total (8,16):
Reads Queued: 428697, 1714MiB Writes Queued: 0, 0KiB
Read Dispatches: 3954, 1714MiB Write Dispatches: 0, 0KiB
Reads Requeued: 0 Writes Requeued: 0
Reads Completed: 3956, 1715MiB Writes Completed: 0, 0KiB
Read Merges: 424743, 1698MiB Write Merges: 0, 0KiB
IO unplugs: 0 Timer unplugs: 3384

可以看出,读请求大量被合并下发了。
blk_plug其他域说明:
magic:用于判断blk_plug是否有效
list:用于缓存请求的队列
cb_list:回调函数的链表,下发请求时会调用到
should_sort:下发之前是否对请求进行排序
 

linux内核函数之 blk_plug的更多相关文章

  1. linux内核函数库文件的寻找

    linux内核函数的so库文件怎么找呢? 首先还是要产生一个进程的coredump文件的 linux有一个lib-gdb.so库,这个进程的coredump文件中所有load段的最后一个load段中, ...

  2. linux内核追踪——find_next_bit函数详详详解

    写在前面 宗旨:把话说清楚,把道理讲透彻. 约定:所有代码均来自Linux内核2.6.24版. 建议:本文介绍得十分详细,但也略显繁琐,读者可以先看“Ⅴ.总结”部分带注释的源码,如果哪里不清楚,再回头 ...

  3. linux 内核(驱动)常用函数

    2.4.1 内存申请和释放 include/linux/kernel.h里声明了kmalloc()和kfree().用于在内核模式下申请和释放内存.    void *kmalloc(unsigned ...

  4. 关于Linux系统调用,内核函数【转】

    转自:http://blog.csdn.net/ubuntulover/article/details/5988220 早上听人说到某个程序的一部分是内核态,另一部分是用户态,需要怎么怎么.当时突然想 ...

  5. linux内核申请内存函数

    kmap函数:    把某块高端内存映射到页表,然后返回给用户一个填好vitual字段的page结构    建立永久地址映射,不是简单的返回virtual字段的pageioremap:    驱动程序 ...

  6. Linux内核中常见内存分配函数(二)

    常用内存分配函数 __get_free_pages unsigned long __get_free_pages(gfp_t gfp_mask, unsigned int order) __get_f ...

  7. Linux内核中常见内存分配函数(三)

    ioremap void * ioremap (unsigned long offset, unsigned long size) ioremap是一种更直接的内存“分配”方式,使用时直接指定物理起始 ...

  8. linux内核中的排序接口--sort函数

    linux内核中的sort函数,其实跟我们所说的qsort函数很像,我们来看看qsort: qsort 的函数原型是 void qsort(void*base,size_t num,size_t wi ...

  9. 对于Linux内核执行过程的理解(基于fork、execve、schedule等函数)

    382 + 原创作品转载请注明出处 + https://github.com/mengning/linuxkernel/ 一.实验环境 win10 -> VMware -> Ubuntu1 ...

随机推荐

  1. hdu 2896 病毒侵袭 AC自动机 基础题

    病毒侵袭 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submi ...

  2. Oracle成长点点滴滴(3)— 权限管理

    上篇我们解说了创建用户以及主要的授权问题.以下我们来解说权限包含对象权限和系统权限. 事实上上节课我们解说就是系统的权限.系统权限就是一些创建表了,表空间等等的系统的权限. 1.      系统权限 ...

  3. jquery $.post

    jQuery.post() jQuery.post( url [, data ] [, success ] [, dataType ] )Returns:jqXHR Description: Load ...

  4. WCF技术剖析之十八:消息契约(Message Contract)和基于消息契约的序列化

    原文:WCF技术剖析之十八:消息契约(Message Contract)和基于消息契约的序列化 [爱心链接:拯救一个25岁身患急性白血病的女孩[内有苏州电视台经济频道<天天山海经>为此录制 ...

  5. 基于visual Studio2013解决面试题之1105字符串压缩

     题目

  6. Andorid时间控件和日期控件

      

  7. 解决java mail发送TXT附件被直接显示在正文中的问题

    这两天遇到一个问题,关于使用java mail发送邮件的问题. 详细是这样子的:我使用java mail发送异常报告邮件,邮件中有一个包含异常日志的附件,和关于设备信息的邮件正文.假设日志为log后缀 ...

  8. 中转server

    中转传输概要设计 中转传输的消息架构为模拟MFC的消息架构,请參考我的上一篇文章. 1. 概述 中转server採用事件驱动的方式,与socket结合.其层次例如以下: 在事件驱动层中,将相关消息发送 ...

  9. ZYNQ-7000 Unable to connect to ps7_cortexa9 解决方案

    图1 开发工具:Xilinx SDk 14.4(基于Eclipse,ISE suite 14.4组件之一) 开发板:Xilinx ZYNQ-7000 zc702 rev 1.0(注意:这个板子的版本说 ...

  10. (WinForm)文件夹状态监控,最小化到托盘,开机自启动

    原文 (WinForm)文件夹状态监控,最小化到托盘,开机自启动 . 文件夾監控(監測文件夾中的文件動態): //MSDN上的例子 public class Watcher { public stat ...