Documentation_scheduler_sched-arch.txt

来源:互联网 发布:c语言经典程序100例pdf 编辑:程序博客网 时间:2024/05/16 08:12
Chinese translated version of Documentation_scheduler_sched-arch.txt

If you have any comment or update to the content, please contact the
original document maintainer directly.  However, if you have a problem
communicating in English you can also ask the Chinese maintainer for
help.  Contact the Chinese maintainer if this translation is outdated
or if there is a problem with the translation.

Chinese maintainer: hai0704.hz <hai0704@sina.com>
---------------------------------------------------------------------
Documentation/00-INDEX 的中文翻译

如果想评论或更新本文的内容,请直接联系原文档的维护者。如果你使用英文
交流有困难的话,也可以向中文版维护者求助。如果本翻译更新不及时或者翻
译存在问题,请联系中文版维护者。

中文版维护者: 金振海  hai0704.hz <hai0704@sina.com>
中文版翻译者: 金振海  hai0704.hz <hai0704@sina.com>
中文版校译者: 金振海  hai0704.hz <hai0704@sina.com>



以下为正文
---------------------------------------------------------------------
    CPU Scheduler implementation hints for architecture specific code
    对特定代码架构实施CPU调度程序提示
    Nick Piggin, 2005

Context switch
上下文切换
==============
1. Runqueue locking

By default, the switch_to arch function is called with the runqueue
locked. This is usually not a problem unless switch_to may need to
take the runqueue lock. This is usually due to a wake up operation in
the context switch. See arch/ia64/include/asm/system.h for an example.

To request the scheduler call switch_to with the runqueue unlocked,
you must `#define __ARCH_WANT_UNLOCKED_CTXSW` in a header file
(typically the one where switch_to is defined).

Unlocked context switches introduce only a very minor performance
penalty to the core scheduler implementation in the CONFIG_SMP case.

上下文切换
==============
1.运行队列锁
默认情况下,切换到拱函数会引起运行队列锁。这通常不是一个问题除非切换
可能需要用到运行队列锁。这通常是因为在上下文切换中一个唤醒操作。比如
arch/ia64/include/asm/system.h 。
在运行队列不锁定的情况下进行调度程序切换,你必须在头文件中定义
`#define __ARCH_WANT_UNLOCKED_CTXSW`(通常是定义在与上下文切换相关的
头文件中)。

在CONFIG_SMP这个例子中对内核调度程序实现来说,解锁上下文切换介绍只有
很小的性能损失。

CPU idle
========
Your cpu_idle routines need to obey the following rules:

1. Preempt should now disabled over idle routines. Should only
   be enabled to call schedule() then disabled again.

2. need_resched/TIF_NEED_RESCHED is only ever set, and will never
   be cleared until the running task has called schedule(). Idle
   threads need only ever query need_resched, and may never set or
   clear it.

3. When cpu_idle finds (need_resched() == 'true'), it should call
   schedule(). It should not call schedule() otherwise.

4. The only time interrupts need to be disabled when checking
   need_resched is if we are about to sleep the processor until
   the next interrupt (this doesn't provide any protection of
   need_resched, it prevents losing an interrupt).

    4a. Common problem with this type of sleep appears to be:
            local_irq_disable();
            if (!need_resched()) {
                    local_irq_enable();
                    *** resched interrupt arrives here ***
                    __asm__("sleep until next interrupt");
            }

5. TIF_POLLING_NRFLAG can be set by idle routines that do not
   need an interrupt to wake them up when need_resched goes high.
   In other words, they must be periodically polling need_resched,
   although it may be reasonable to do some background work or enter
   a low CPU priority.

       5a. If TIF_POLLING_NRFLAG is set, and we do decide to enter
        an interrupt sleep, it needs to be cleared then a memory
        barrier issued (followed by a test of need_resched with
        interrupts disabled, as explained in 3).

arch/x86/kernel/process.c has examples of both polling and
sleeping idle functions.

CPU 空闲
========
你的CPU空闲例行程序必须准守以下原则:
1.CPU空闲例程应该禁用抢占。应该只在schedule()被调用时启用,
然后在禁用。
2.need_resched/TIF_NEED_RESCHED只是设置,并且永远不会被清除直到
运行任务调用schedule()。空闲线程只需要查询过need_resched,就可能永
远不会设置或清除它。
3.当cpu_idle发现(need_resched() == 'true')时,它才能调用schedule()
。否则它不能调用schedule()。
4.唯一一次中断需要被禁用的时候就是,当我们在检测need_resched是如果我
们在使处理器进入睡眠状态,直到下一个中断。(这对need_resched不提供任
何保护,它只是防止失去一个中断)。
    4a. Common problem with this type of sleep appears to be:
            local_irq_disable();
            if (!need_resched()) {
                    local_irq_enable();
                    *** resched interrupt arrives here ***
                    __asm__("sleep until next interrupt");
            }
5.当need_resched用量增加时,空闲例程可以通过不使用中断对
TIF_POLLING_NRFLAG进行设置。
    5a. If TIF_POLLING_NRFLAG is set, and we do decide to enter
        an interrupt sleep, it needs to be cleared then a memory
        barrier issued (followed by a test of need_resched with
        interrupts disabled, as explained in 3).
arch/x86/kernel/process.c都有轮询和使空闲例程睡眠的例子。

Possible arch/ problems
=======================

Possible arch problems I found (and either tried to fix or didn't):

h8300 - Is such sleeping racy vs interrupts? (See #4a).
        The H8/300 manual I found indicates yes, however disabling IRQs
        over the sleep mean only NMIs can wake it up, so can't fix easily
        without doing spin waiting.

ia64 - is safe_halt call racy vs interrupts? (does it sleep?) (See #4a)

sh64 - Is sleeping racy vs interrupts? (See #4a)

sparc - IRQs on at this point(?), change local_irq_save to _disable.
      - TODO: needs secondary CPUs to disable preempt (See #1)
可能产生的arch/问题
=======================
我发现的可能产生的arch问题(和一些试图去修改或者不修改的):
h8300 - Is such sleeping racy vs interrupts?(参见 4a)。
        我发现H8/300手册显示是“yes”,然而禁用终端请求的睡眠意味着只
        有NMIs可以唤醒它,所以如果不做旋转等待就不能轻易解决它。
ia64 - is safe_halt call racy vs interrupts? (它是否睡眠?)(参见 4a)
sh64 - Is sleeping racy vs interrupts? (参见 4a)
sparc - 终端请求在(?)这里,更改local_irq_save为local_irq_disable.
      - TODO:需要CPU二次禁用抢占