学写块设备驱动(二)----更换IO调度器

来源:互联网 发布:java 熔断机制 编辑:程序博客网 时间:2024/06/07 02:07
上节我们的块设备驱动已经可以使用了,本节我们对其进行一点小的改动,修改其使用的IO调度器。我们知道,标准磁盘的寻道延时很高,故有了IO调度器存在的必要,它通过对IO请求进行合并或者排序来提高块设备的使用效率。但是因为我们目前的块设备在内存中,即没有通常的磁盘寻道延时,且读写迅速,所以我们不需要IO调度器为我们做多余的事情浪费资源。目前Linux有四种IO调度器,anticipatory、cfq、deadline和noop。例子这里最适合我们的是noop,它基本对IO请求什么都不做。



我们想要更换IO调度器,关键的函数是这么两个:

首先,为请求队列选择IO调度器

int elevator_init(struct request_queue *q, char *name)

其次,由于我们使用blk_init_queue(request_fn_proc *)初始化IO请求队列时,通用块层为我们初始化了默认的IO调度器,所以我们需要下面的函数来释放它:

void elevator_exit(struct elevator_queue *old_eq) 释放某个请求队列上的IO调度器



更改后的simp_blkdev_init 函数 如下:

[cpp]
view plaincopyprint?
static int simp_blkdev_init(void){
int ret;
struct elevator_queue *old_e;
//init the request queue by the handler function
simp_blkdev_queue = blk_init_queue(simp_blkdev_do_request,&rq_lock);
if(!simp_blkdev_queue){
ret = -ENOMEM;
goto error_init_queue;
}
//init a new io scheduler
old_e = simp_blkdev_queue->elevator;
if(IS_ERR_VALUE( elevator_init(simp_blkdev_queue,"noop") ) ){
printk(KERN_WARNING "Switch elevator failed,using default\n");
}else{
elevator_exit(old_e);
}

//alloc the resource of gendisk
simp_blkdev_disk = alloc_disk(1);
if(!simp_blkdev_disk){
ret = -ENOMEM;
goto error_alloc_disk;
}


//populate the gendisk structure
strcpy(simp_blkdev_disk->disk_name,SIMP_BLKDEV_DISKNAME);
simp_blkdev_disk->major = SIMP_BLKDEV_DEVICEMAJOR;
simp_blkdev_disk->first_minor = 0;
simp_blkdev_disk->fops = &simp_blkdev_fops;
simp_blkdev_disk->queue = simp_blkdev_queue;
set_capacity(simp_blkdev_disk,SIMP_BLKDEV_BYTES>>9);

add_disk(simp_blkdev_disk);
printk("module simp_blkdev added.\n");
return 0;

error_init_queue:
blk_cleanup_queue(simp_blkdev_queue);

error_alloc_disk:
return ret;

}


效果
没有更换IO调度器之前(cfq):




更换IO调度器(noop)