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