仅检查TIF_NEED_RESCHED,不检查preempt_count? 2017-01-11

1. 何时设置 TIFNEEDRESCHED

任务task01还没有完成, 但调度器认为 其运行的够久了, 就设置TIFNEEDRESCHED, 这样, 在合适的时机, task01就会被调度走, 由其他task使用cpu.

除了schedulertick会设置外, 当一个优先级高的进程进入可执行状态的时候, trytowakeup()也会设置这个标志。

2. 不检查preempt_count?

例 linux-3.10.86/arch/arm/kernel/entry-armv.S

__vector_irq()
|--__irq_usr()  @entry-armv.S
|   |--usr_entry()
|   |--irq_handler()
|   |--ret_to_user_from_irq() @entry-common.S
|   |   |--work_pending()   
|   |   |   |--do_work_pending @signal.c

do_work_pending
{
    do {
        if (likely(thread_flags & _TIF_NEED_RESCHED))
            schedule();
        else
           ...
    }
}

调度器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(...)
        }
        ...

}

tag TOWRITE to avoid livelocking? 2017-01-03

主要介绍writeback中的livelocking.