linux kernel知识小记

linux kernel知识小记

  • 参考书籍:精通linux 设备驱动开发。

内核定时器

1、 HZ和jiffies

       HZ为每秒的定时器节拍数,HZ越大,定时器间隔时间越小,进程调度的准确性就会越高,但是,HZ越大会导致开销和电源消耗更多,所以HZ值需要权衡,linux中默认的HZ是100。
jiffies是记录系统启动以来定时器的节拍次数,每一秒中jiffies将增加1 HZ,对于HZ值为100的,1 jiffies即10ms。

长延时

       以jiffies为单位的延时通常被认为是长延时。实现长延时的方法是睡眠等待而不是忙等待。因为忙等待会占着茅坑不拉屎。但睡眠等待则无法精确延时,因为只有在时钟节拍中才会引发调度,所以延时的精度超过1 jiffies,而且还受优先级策略影响。

       长延时函数如:msleep。

短延时

       小于1 jiffies的延时被认为是短延时,实现短延时的唯一方法是忙等待。忙等待的实现方法是测量处理器执行一条指令的时间,为了延时,执行一定数量的指令。

       短延时函数如:mdelay,udelay,ndelay。

 

RTC实时时钟

       RTC在非易失性存储器上记录绝对时间或者墙上时间(wall time)。许多应用程序需要使用绝对时间,内核将墙上时间记录在xtirne变量中,在启动过程中,会根据从RTC读取到的目前的墙上时间初始化xtirne,在系统停机后,墙上时间会被写回RTC 。可以使用do_gettirneofday ()读取墙上时间。

       用户空间也包含一系列可以访问墙上时间的函数,包括:

  • (1) time (),该函数返回日历时间,或从新纪元( 1970年1 月1 日00 : 00:00 )以来经历的秒数:
  • (2) localtirne (),以分散的形式返回日历时间:
  • (3) mktirne ( ),进行localtime ( )函数的反向工作:
  • (4) gettirneofday(),如果你的平台支持,该函数将以微秒精度返回日历时间。

       用户空间使用RTC 的另一种途径是通过字符设备/dev/rtc来进行,同一时刻只有一个进程允许
返回该字符设备。

 

内核中的并发

      随着多核笔记本电脑时代的到来,对称多处理器(SMP)的使用不再被限于高科技用户。SMP和内核抢占是多线程执行的两种场景。多个线程能够同时操作共享的内核数据结构,因此,对这些数据结构的访问必须被串行化。

自旋锁和互斥体

      访问共享资源的代码区域称作临界区自旋锁(spinlocl)和互斥体( mutex, mutual exclusion的缩写)是保护内核临界区的两种基本机制。

      自旋锁可以确保在同时只有一个线程进入临界区。其他想进入临界区的线程必须不停地原地打转,直到第1个线程释放自旋锁。

      与自旋锁不同的是,互斥体在进入一个被占用的临界区之前不会原地打转,而是使当前线程
进入睡眠状态。如果要等待的时间较长,互斥体比自旋锁更合适,因为自旋锁会消耗CPU资源。

如何决定使用自旋锁还是互斥体?

(1)如果临界区需要睡眠,只能使用互斥体,因为在获得自旋锁后进行调度、抢占以及在等待队列上睡眠都是非法的;

(2)由于互斥体会在面临竞争的情况下将当前线程置于睡眠状态,因此,在中断处理函数中,只能使用自旋锁。

临界区的实现

临界区分为以下几种情况:

  • (1 )非抢占内核,单CPU情况下存在于进程上下文的临界区:
  • (2)非抢占内核,单CPU情况下存在于进程和中断上下文的临界区:
  • (3)可抢占内核,单CPU情况下存在于进程和中断上下文的临界区;
  • (4)可抢占内核, SMP情况下存在于进程和中断上下文的临界区。

案例1 :进程上下文,单CPU ,非抢占内核。

      这种情况最为简单,不需要加锁。

案例2 :进程和中断上下文,单CPU ,非抢占内核

      在这种情况下,为了保护临界区,仅仅需要禁止中断。

      假定进程上下文的执行单元A、B以及中断上下文的执行单元C都企图进入相同的临界区。
由于执行单元C总是在中断上下文执行,它会优先于执行单元A和B ,因此,它不用担心保护的问题。执行单元A和B也不必关心彼此会被互相打断,因为内核是非抢占的。因此,执行单元A和B仅仅需要担心C会在它们进入临界区的时候强行进入。为了实现此目的,它们会在进入临界区之前禁止中断。

案例3:进程和中断上下文,单CPU ,抢占内核

      如果内核便能了抢占,仅仅禁止中断将无法确保对临界区的保护,因为另一个处于进程上下文的执行单元可能会进入临界区。回到案例2中的例子,现在,除了C以外,执行单元A和B必须提防彼此。显而易见,解决该问题的方法是在进入临界区之前禁止内核抢占、中断,并在退出临界区的时候恢复内核抢占和中断。

案例4 :进程和中断上下文, SMP机器,抢占内核

      到目前为止讨论的场景中,自旋锁原语发挥的作用仅限于便能和禁止抢占和中断,时间的锁功能并未被完全编译进来。在SMP机器内,锁逻辑被编译进来,而且自旋锁原语确保了SMP安全性。在SMP系统上,获取自旋锁时,仅仅本CPU上的中断被禁止。

原子操作

      原子操作用于执行轻量级的、仅执行一次的操作,例如修改计数器、有条件的增加值、设置位等。原子操作可以确保操作的串行化,不再需要锁进行并发访问保护。原子操作的具体实现取决于体系架构。

proc文件系统

      proc文件系统(procfs)是一种虚拟的文件系统,它创建内核内部的视窗。浏览procfs时看到的数据是在内核运行过程中产生的。procfs中的文件可被用于配置内核参数、查看内核结构体、从设备驱动程序中收集统计信息或者获取通用的系统信息。

      procfs是一种虚拟的文件系统。procfs中的文件大
小都显示为0 。procfs通常在启动过程中挂载在/proc 目录,通过运行mount命令可以看出这一点。

 

 

僵尸进程

      如果某个父进程在没有等待其所有子进程都退出
的时候就死掉了,它的所有子进程都会成为僵尸进程( zombie process),仍然消耗资源。

 

内核线程的状态

一个内核线程(或一个常规的进程〉可以处于如下状态中的一种:

(1 )处于运行状态( TASK_RUNNING )的进程位于调度器的运行队列( run queue )中,等待调
度器将CPU时间分给它执行。

(2)处于可被打断的睡眠状态( TASK_INTERRUPTIBLE )的进程正在等待一个事件的发生,
不在调度器的运行队列之中。当它等待的事件发生后,或者如果它被信号打断,它将重新进入运
行队列。

(3)处于不可被打断的睡眼状态( TASK_INTERRU凹工BLE )的进程与处于可被打断的睡眼状
态的进程的行为相似,唯一的区别是信号的发生不会导致该进程被重新放入运行队列。

(4)处于停止状态( TASK_STOPPED )的进程由于收到了某些信号已经停止执行。

(5)如果l个应用程序如(strace)正在使用内核的ptrace支持以拦截一个进程,该进程将处于追踪状态( TASK_TRACED )。

(6)处于僵死状态(皿工T_ZOMBIE )的进程已经被终止,但是其父进程并未等待它完成。一
个退出后的进程要么处于EXIT_ZOMBIE状态,要么处于EXIT_DEAD状态。

中断上下文

      ISR(中断服务例程)是直接与硬件交互的非常重要的代码片段。它们拥有立即执行的特权,以提高系统的性能。为了对粗暴打断当前执行线程的行为进行补偿, ISR
不得不礼貌地执行于受限制的环境下,即所谓的中断上下文(或原子上下文)。

下面是中断上下文中的注意事项。

(1)中断上下文代码绝不可以停止运行。不能通过调用睡眠函数放弃处理器。在从中断处理函数中调用一个内核API之前,应该仔细分析它,以确保其内部不会触发阻塞等待。例如, input_register_device()表面上看起来没有问题,但是它
内部以GFP_KERNEL为参数调用了kmalloc (),用这种方式调用kmalloc()的话,
如果系统的空闲内存低于某警戒线,kmalloc()将睡眠,等待对换程序释放内存。

(2)为了在中断处理函数中保护临界区,不能使用互斥体,因为它们也许导致睡眠。应该使用自旋锁代替互斥体,但是一定要记住的是,只有不得不用的时候才采用。

(3)中断处理函数不能与用户空间直接交互数据,因为它们经由进程上下文与用户空间建立连接。这也是为什么中断处理函数不能睡眠的第2个理由:调度器工作于进程之间,如果中断处理函数睡眠井被调度出去,它们怎么返回到运行队列呢?

(4)中断处理函数一方面需要快速地为其他进程让位,另一方面又需要完成它的工作。为了规避这种冲突,中断处理函数通常将工作分成两个部分。顶半部设一个标志以宣称它已经服务了该中断,而重大的工作负载都被丢给了底半部。底半部的执行被延后,在其执行环境中,所有的中断都是便能的。

(5)中断处理函数不必是可重用的。当某中断函数运行的时候,在它返回之前,相应的IRQ都被禁止了。因此,与进程上下文代码不同,同一中断处理函数的不同实例不可能同时运行在多个处理器上。

(6)中断处理函数可以被更高优先级IRQ的中断处理函数打断。

.
.
.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值