linux块设备7

elevator.c:


elv_iosched_allow_merge: 调用具体电梯算法的elevator_allow_merge_fn函数检查是否允许merge
elv_rq_merge_ok:由具体电梯算法或者elevator的其他函数调用, 检查bio是否能merge到request。
1. 调用rq_mergeable检查request类型,判断是否可merge
2. 检查其他方面, 看bio是否和request匹配
3. 调用elv_iosched_allow_merge,检查是否可merge

elv_try_merge:得到merge类型
1. 调用elv_rq_merge_ok看是否可merge,
2.  如果request的当前位置加上request的sectors等于bio的起点, 返回back merge
3. 如果request的当前位置减去bio的sector size等于bio的起点, 返回front merge


elevator_find:根据名字在elv_list中查找elv


elevator_put:增加模块的递减计数

elevator_get:调用elevator_find查找, 没有的话调用request_module, 增加模块的递增计数, 返回elevator_type


elevator_init_queue: 调用elevator_queue的elevator_init_fn函数(实际应该就是elevator_type的init函数), 由elevator_init调用


elevator_attach: 设置request queue的elevetor queue和它的data


elevator_setup: 设置chosen elevator


elevator_alloc: 生成elevator_queue, 并用elevator_type初始化它


elevator_release: 释放elevator_queue




elevator_init:初始化elevtor

初始化request queue中几个跟eveltor相关的变量

调用elevator_get根据名字得到elevator_type, 如果没有给定名字, 用chosen_elevator指定的名字, 否则用CONFIG_DEFAULT_IOSCHED指定的缺省名字,如果还是没有得到elevatortype,用noop作为指定的名字。(花样多)

调用elevator_alloc得到elevator queue

调用elevator_init_queue

调用elevator_attach把elevator queue赋值给request queue



elevator_exit:

调用elevator_queue ops的elevator_exit_fn

较少elevator_queue的引用计数



__elv_rqhash_del/elv_rqhash_del:从hashlist删除request

elv_rqhash_add:增加request到elevator的hash list

elv_rqhash_reposition:重新增加request到hash list

elv_rqhash_find:查找hash key request 当前sector加上剩余sectors等于给定offset的request


elv_rb_add/elv_rb_del/elv_rb_find: request红黑树增加, 删除, 查找


elv_dispatch_sort:将request插入queue的合适位置(当request的位置>=查找的request的位置时, 尝试插入),

elv_dispatch_add_tail:将request加到queue的尾。


elv_merge: core的make request调用, merge给定的bio

根据bio, 从queue中得到可以用来merge的request,

先尝试cached last_merge, 再根据bio从elv_rqhash_find查找, 找到的话返回ELEVATOR_BACK_MERGE, 否则调用queue的elevator_queue的elevator_merge_fn函数。


elv_attempt_insert_merge: 尝试merge给定的request, 或者和last_merge合并, 或者根据request的sector查找kemerge的request并merge。这个主要是用于sorted 的request的merge,会调用blkmerge的blk_attempt_req_merge/attempt_merge。最终会通过elv_merge_requests调用elevator_merge_req_fn


elv_merged_request: 调用elevator_merged_fn进行电梯算法层的merge, 如果是ELEVATOR_BACK_MERGE, 还要elv_rqhash_reposition, 这里不会合并什么, 主要是对request进行一些处理, 包括设置last_merge等于request


elv_merge_requests:

如果next request是sorted, 调用elevator_merge_req_fn, 重插request, 调用elv_rqhash_del删除sorted next request,并设last_merge为request

back merge, front merge还有sort都是sorted merge, 都会调用这个。


elv_bio_merged: 调用elevator_bio_merged_fn, 被core的try fromt/back merge使用


elv_requeue_request:

如果request started, 调用elv_deactivate_rq,调用__elv_add_request重新增加request到queue


elv_drain_elevator:循环调用elevator_dispatch_fn, nr_sorted会被减少


elv_quiesce_start: 设置QUEUE_FLAG_ELVSWITCH标志,调用elv_drain_elevator

elv_quiesce_end: 清除QUEUE_FLAG_ELVSWITCH标志


__elv_add_request: 增加request到queue, insert sort指request会被增加到elv_rqhash_add, 并调用elevator_add_req_fn


elv_add_request: 调用__elv_add_request, 由driver调用


elv_latter_request/elv_former_request:由back/front merge调用, 查找prev/nextrequest, 会调用具体电梯算法的相关函数


elv_set_request/elv_put_request/elv_may_queue: 调用电梯算法的elevator_set_req_fn/elevator_put_req_fn/elevator_may_queue_fn



elv_abort_queue:

调用blk_abort_flushes去restore flush request

重新start queue中的request


elv_completed_request: 调用elevator_completed_req_fn



elv_attr_show/elv_attr_store: elv sysfs函数


elv_register_queue: 注册queue的elevator 到sysfs

__elv_unregister_queue/elv_unregister_queue:从sysfs去掉queue的elevator


elv_register/: 注册elevator_type到elv_list

elv_unregister:取消


elevator_switch:

调用elevator_alloc分配elevator queue

调用elevator_init_queue/elevator_init_fn: 初始化电梯算法的私有数据结构, 并把queue设给这个数据结构。

调用elv_quiesce_start设置queue flag as QUEUE_FLAG_ELVSWITCH, 并使queue不再flight状态

调用elevator_attach注册新电梯算法和其私有数据到request queue

调用__elv_unregister_queue 释放已经注册到kobj的old elevator,kobj del应该会调到release(sorry, 也可能在kobj put时?)

调用elv_register_queue注册新的elevator到sysfs

调用elevator_exit: 调用elevator_exit_fn在电梯算法层进行释放处理, 并调用kobject_put释放old elev

调用elv_quiesce_end清除QUEUE_FLAG_ELVSWITCH。


elevator_change:get指定name的电梯, 并调用elevator_switch切换算法


elv_iosched_store: 由blk sysfs调用设置指定名字的电梯

elv_iosched_show: 由blk sysfs调用显示电梯名


elv_rb_former_request: 返回指定request的红黑数的prev request

elv_rb_latter_request: 返回指定request的红黑数的next request

它们最终被elv_latter_request/elv_former_request(由merge调用)调用


cfq-iosched.c:

cfq算法Completely Fair Queueing IO scheduler: 根据进程, 生成多个请求队列, 每个新的进程的请求放在本进程队列的末尾, 调度时选择第一个非空的队列, 然后把该队列移到调度队列的末尾。

cfq_init:

调用cfq_slab_setup分配cfq_pool/cfq_ioc_pool

调用elv_register注册iosched_cfq elevator_type到elv_list,包含sysfs属性处理函数show/store等

调用blkio_policy_register注册blkio_policy_cfq blkio_policy_type(io policy)到blkio_list


cfq_exit:init的相反过程, 多了个等待所有ioc完成(待细化)。


elevator_type函数

cfq_init_queue:生成cfq_data并初始化

cfq_exit_queue:释放cfq_data


cfq_idle_slice_timer: timer到,调用cfq_schedule_dispatch引起unplug_work work调度。

cfq_kick_queue: unplug_work处理函数,调用 __blk_run_queue发起queue请求处理


cfq_set_request: 设置request的 cic, cfqq, cfqg(并增加引用计数), cfqq是保存在cic中的跟task相关的


cfq_insert_request(add): 把request插入cfqq的的fifo,sort_list,如有必要,插cfqq到sfqd的优先级树, 如有必要, 调用__blk_run_queue


cfq_dispatch_requests: 从cfqq取request, 并把request插入request queue


 

noop-iosched.c:没有特别的队列,新请求插入队尾或头,下一个请求就是第一个请求



deadline-iosched.c:增加防饿死处理



ioctl.c: 由driver/char/raw.c, fs/blk_dev, compat_ioctl.c调用, 对block device进行一些设置或者读取信息


compat_ioctl.c: fd, cdrom等用

arch_compat_alloc_user_space:指向栈顶减len的地方

get_user: copy user data

compat_ptr: 转换指针为用户空间指针

put_user: copy data to user

compat_blkdev_ioctl: 有些会调用ioctl.c的blkdev_ioctl, 其他则调用compat的ioctl


scsi_ioctl.c:由block/bsg, fd, cdrom, scsi driver等使用, 多是要执行request

blk_execute_rq: block方式执行request




你可能感兴趣的:(数据结构,linux,算法,IOC,insert,merge)