arm linux的switch_to 2017-01-11
文来自本人的旧博客: blog.163.com/awaken_ing/blog/static/12061319720158310574442/
<< Professional Linux Kernel Architecture >> page105标题为 Intricacies of switchto (intricacies:错综复杂的) , 絮絮叨叨着switchto.
下面看下arm linux的情况.
context_switch(struct rq *rq, struct task_struct *prev,
struct task_struct *next)
{
...
switch_to(prev, next, prev);
barrier();
/*
假定进程A被调出去, 进程B运行, 即switch_to(A, B, A)
那么, 这里是刚才被调度走的进程A 恢复运行后, 会执行这个地方,
要验证的话, 可以看看进程A让出CPU前, 最后一条修改lr的指令.
*/
finish_task_switch(this_rq(), prev);
}
调度器CFS的实现 2017-01-10
1. 概述
主要视角是, 考虑要多久才能轮到某个进程的运行, (称之为targeted preemption latency) 而不是每个进程分配多少份的时间片.
对单个进程 达到 时间段t1内被至少调度一次到, 对所有的进程都达到的话, 就是, 时间段t1内所有进程都跑一遍. the interval during which every runnable task should run at least once. 这个时间段t1我们成为 one latency period.
本文仅讨论SCHEDNORMAL. 且没有使能CONFIGFAIRGROUPSCHED. 内核版本3.10.
2. 时间的计算
等了多久, 具体如何量化?
每次计算时间, 若是逐个给每个TASK_RUNNING进程计算, 这样势必低效,
所以, 实现上, 不应该是逐个进程判断等待的时间.
当前的实现是, 记录各进程运行所占用的时间, 运行占用时间的另一面, 就是 没有运行. 一个进程运行时间久, 其他进程没有运行或者等待的时间就久. 故可以仅记录运行时间来反应等待时间, 这个运行的时间记为vruntime.
2.1 vruntime
virtual run time, 运行时间经加权后的数据, 加权方法为
deadline-iosched 2017-01-06
1. 背景
派发队列(q->queuehead)(the block device dispatch queue) 为空时,将request从 I/O调度队列(io scheduler queue) 转移到 派发队列,
具体是 通过 调用I/O调度算法的elevatordispatch_fn来完成的:
linux-3.10.86/block/blk.h
__elv_next_request
{
while (1) {
if (!list_empty(&q->queue_head)) {
rq = list_entry_rq(q->queue_head.next);
return rq;
}
...
if ( ... || !q->elevator->type->ops.elevator_dispatch_fn(q, 0))//比如deadline_dispatch_requests
return NULL;
}
}
具体调度策略有 cfq-iosched, deadline-iosched等.
do_generic_file_read中的readahead 2017-01-03
1. readahead
dogenericfile_read 中有两个ahead相关的函数:
do_generic_file_read -> page_cache_sync_readahead
generic_file_aio_read -> do_generic_file_read -> page_cache_async_readahead
问:pagecachesyncreadahead 和 pagecacheasyncreadahead 的差别在哪里? sync和async体现在哪?
答: 一个当前page cache中没有所需的数据, 发起的是对当下要用的数据的读取;
另一个是page cache中有所需的数据, 发起对后面可能要用的数据的读取.
linux-3.10.86/mm/filemap.c
do_generic_file_read
{
page = find_get_page(mapping, index);
if (!page){
page_cache_sync_readahead(...)
...
}
if (PageReadahead(page)) {
page_cache_async_readahead(...)
}
...
}