1.__switch_to
File:entry_v7m.S
TI_CPU_SAVE 即上下文环境,在thread_info中cpu_context的偏移量
/*
* Register switch for ARMv7-M processors.
* r0 = previous task_struct, r1 = previous thread_info, r2 = next thread_info
* previous and next are guaranteed not to be the same.
*/
ENTRY(__switch_to)
.fnstart
.cantunwind
/* save field */
add ip, r1, #TI_CPU_SAVE
stmia ip!, {r4 - r11} @ Store most regs on stack
str sp, [ip], #4
str lr, [ip], #4
mov r5, r0
add r4, r2, #TI_CPU_SAVE
/* notifier to switch process */
ldr r0, =thread_notify_head
mov r1, #THREAD_NOTIFY_SWITCH
bl atomic_notifier_call_chain
mov ip, r4
mov r0, r5
/* restore the new process field */
ldmia ip!, {r4 - r11} @ Load all regs saved previously
ldr sp, [ip]
ldr pc, [ip, #4]!
.fnend
ENDPROC(__switch_to)
2.thread_notify_head
File:process.c
ATOMIC_NOTIFIER_HEAD(thread_notify_head);
EXPORT_SYMBOL_GPL(thread_notify_head);
2.1 什么是notifier
* 摘抄源码中的注释*
/*
* Notifier chains are of four types:
*
* Atomic notifier chains: Chain callbacks run in interrupt/atomic
* context. Callouts are not allowed to block.
* 原子通知链:应用在中断或原子上下文
* Blocking notifier chains: Chain callbacks run in process context.
* Callouts are allowed to block.
* 阻塞通知链:应用在进程上下文
* Raw notifier chains: There are no restrictions on callbacks,
* registration, or unregistration. All locking and protection
* must be provided by the caller.
* 原始通知链:应用在不是很严格的条件下,比如回调,注册,注销的环境中。其中的锁保护需要由调用者提供。
* SRCU notifier chains: A variant of blocking notifier chains, with
* the same restrictions.
* SRCU 通知链:是阻塞通知链的变体,一样的应用限制。
* atomic_notifier_chain_register() may be called from an atomic context,
* but blocking_notifier_chain_register() and srcu_notifier_chain_register()
* must be called from a process context. Ditto for the corresponding
* _unregister() routines.
*
* atomic_notifier_chain_unregister(), blocking_notifier_chain_unregister(),
* and srcu_notifier_chain_unregister() _must not_ be called from within
* the call chain.
*
* SRCU notifier chains are an alternative form of blocking notifier chains.
* They use SRCU (Sleepable Read-Copy Update) instead of rw-semaphores for
* protection of the chain links. This means there is _very_ low overhead
* in srcu_notifier_call_chain(): no cache bounces and no memory barriers.
* As compensation, srcu_notifier_chain_unregister() is rather expensive.
* SRCU notifier chains should be used when the chain will be called very
* often but notifier_blocks will seldom be removed. Also, SRCU notifier
* chains are slightly more difficult to use because they require special
* runtime initialization.
* 补充一点,srcu通知链的花销是巨大的。当调用非常频繁,但是通知链的阻塞情况,很少被移除时,最好使用SRCU通知链。不过,用的时候会稍微麻烦一点,因为需要特殊的实时初始化。
*/
2.2 notifier
File: thread_notify.h
/*
* These are the reason codes for the thread notifier.
*/
#define THREAD_NOTIFY_FLUSH 0
#define THREAD_NOTIFY_EXIT 1
#define THREAD_NOTIFY_SWITCH 2
#define THREAD_NOTIFY_COPY 3