chapter 1:
处理器: 1.运行于内核空间,处于进程上下文
2.运行于内核空间,处于进中断上下文
3.运行于用户空间,执行用户进程
单内核
chapter 3:
1.内核调度的对象是线程,而不是进程。
2.两种虚拟机制:虚拟处理器和虚拟内存
3.进程描述符: task_struct 用slab分配器进行分配,达到对象复用和缓存着色
修改pid_t值: /proc/sys/kernel/pid_max
current宏返回当前进程描述符, 不同体系结构实现不一样,PPC有专门寄存器保存
进程5种状态
fork写时拷贝:fork的实际开销就是复制父进程的页表以及给子进程创建唯一的进程描述符
fork->clone->do_fork->copy_process
fork vfork区别:vfork不复制进程的页表
4.并发 并行
线程:linux把线程当作进程来实现,即拥有唯一task_struct,只不过和其他进程共享某些资源,当作进程共享资源的一种手段
内核线程:独立运行在内核空间的标准进程。没有独立的进程地址空间,mm被设置为null。可被调度和抢占
可用kernel_thread创建
5.进程退出: do_exit
TSK_ZOMBIE: 占有资源内核栈、thread_info、 task_struct
chapter 4:
1.多任务:非抢占式多任务和抢占式多任务
2.优先级高的进程使用的时间片较长
3.优先级: nice值(-20~+19),实时优先级(0~99)
4.时间片:表明进程在被抢占前能够持续运行的时间
5.O(1)核心:expired, active 不会循环遍历每个任务计算其时间片和优先级,直接交换两个指针,已经计算好了
6.schedule函数独立于每个CPU运行,每个CPU作出自己判断
7.计算优先级:初始优先级nice值,然后记录进程睡眠和执行的时间,存放于sleep_avg中,用于动态改变优先级,判断是I/O还是CPU型
计算时间片:依赖于静态优先级,fork时,父子均分剩下的时间片
对交互性很高的进程,时间片完后直接放回活动数组
8.用户抢占:1.从系统调用返回用户空间 2.从中断处理程序返回用户空间
会检查need_resched标志(每个进程都包含这个标志,而不是一个全局变量)
9.内核抢占:只要重新调度是安全的,内核就可以在任何时间抢占正在执行的任务
安全定义:内核没有持有锁 thread_info中增加了preempt_count统计锁
内核抢占发生时机:从中断处理程序返回内核之前
内核代码再一次具有可抢占的时候
内核中的任务显式调用shedule()
内核中的任务阻塞
10.实时进程: SCHELD_FIFO SCHELD_RR
chapter 5:
1. asmlinkage:通知编译器仅从栈中获取该函数的参数,所有系统调用都需要此限定符
2. 应用程序需要执行系统调用,通过软中断来通知内核: int $0x80 这条软中断指令会触发一个异常,导致系统切换到内核态并执行第128号异常处理程序,即系统调用处理程序(system_call())。
x86也支持sysenter指令快速进入系统调用。
3.系统调用时,内核处在进程上下文中,可以睡眠和被抢占。所以系统调用必须可重入
中断处理程序不能睡眠
chapter 6:中断和中断处理程序
1. 上半部:中断处理程序 立即执行,只做有严格时限的工作,如应答和复位硬件(禁止中断)
下半部: (开中断)
例如: 网卡
2.linux的中断处理程序无需重入,当中断在执行时,相应的中断线在所有处理器上都会被屏蔽掉,以防止同一个中断线上接收另一个中断
3.中断上下文没有进程的背静,不能睡眠,否则怎样调度?
4.中断处理程序打断了其他代码,甚至是另一条中断线上的另一种中断处理程序
5. 2.6内核以前,中断共享进程的内核栈(每个进程都有固定大小的内核栈),2.6以后,增加了中断单独的栈,进程的内核栈减小到1页
6. cat /proc/interrupts
chapter 7:
1.下半部: BH, 任务队列 已经被取消了
2.5内核: 软中断、tasklet、工作队列
2. softirq:编译期静态分配,共32个
一个软中断不可以抢占另一个软中断,只有中断处理程序可以
多个软中断可以在不同处理器上同时执行(即使是两个相同的软中断),可扩展性好,但需要加锁,tasklet只能在一个CPU上执行
软中断必须被标记后才会执行,中断处理程序会在返回前标记其相应的软中断
检查和执行时机:从硬件中断代码返回
从ksoftirqd内核线程中
显式检查和执行处理的软中断的代码中
3.只有对时间要求很严格的才使用软中断,如 网络和SCSI,内核定时器和tasklet建立在软中断之上
尽量使用tasklet
chapter 8:
1.临界区和竞争条件
为什么需要保护: 银行例子,单个变量。
2.锁: Linux实现了不同锁,每种锁的不同区别在于当锁被争用时的行为
实现依赖于体系结构,如test and set指令。
3.并发原因:用户进程会被调度程序抢占并重新调度。其次,信号处理是异步发生的
SMP, 中断,软中断和tasklet,内核抢占,睡眠及用户空间的同步
chapter 9:
对数据加锁,而不是代码。
1.原子性确保指令执行期间不会打断,要么执行,要么不执行
顺序性:确保即使两条或多条指令出现在独立的执行线程中,甚至独立的处理器上,他们本该的执行顺序依然要保持。
2.原子操作:整数,位
3.锁:
自旋锁:轮询,不睡眠。可以用在中断处理程序中,但使用前需要先禁止本地中断。
读写锁:照顾读者多一些
信号量:睡眠锁 信号量比自旋锁有更大的开销 适用于锁被长时间持有
chapter 11
1.内核分配内存比用户空间复杂
2.page结构与物理页相关,并非与虚拟页相关,内核用其描述相关的物理页中存放的东西,即描述物理内存本身,而不是数据,系统内存每一页必须有此结构
3.区:
ZONE_DMA
ZONE_NORMAL
ZONE_HIGHMEM
4.分配页: alloc_pages等函数 free_pages
kmalloc :分配字节大小的内存,分配的内存物理上连续(虚拟地址自然也连续)
kfree
vmalloc:分配的内存虚拟地址连续,物理地址无需连续(类似于用户空间函数malloc,保证页在进程的虚拟地址空间联系)。分配非连续的物理地址页,然后修改页表,将页映射到逻辑地址连续的区域中
5. 在栈上静态分配,尽量不要分配大数组,应采用动态分配,否则内核栈会溢出
6.在高端内存中的页不能永久地映射到内核地址空间上
一旦高端内存中的页被分配,就需要映射到内核逻辑地址空间上,x86下是映射到3G-4G之间
kmap:将给定的page建立永久映射 kunmap 只能呢个用在进程上下文中,可以睡眠
kmap_atomic:临时映射 不能睡眠
chapter 12:
1.文件相关信息(i节点)和文件本身
2.VFS 四个主要的对象:
超级块对象:代表一个已安装文件系统
索引节点对象:代表一个文件
目录项对象:代表一个目录项,是路径的组成部分
文件对象:代表由进程打开的文件
3.和文件系统相关的数据结构: file_system_type; vfsmount;
4.和进程相关的数据结构:
files_struct:打开的文件及文件描述符
fs_struct: 文件系统和进程相关的信息
namespace
chapter 14:
1. mm_struct: 多线程,共享地址空间,mm指向同一个内存描述符
2.内核线程,不使用用户空间数据,mm为null,但可以使用前一个进程的页表
阅读(955) | 评论(0) | 转发(0) |