Kernel design
同大多数现代
内核一样,DragonFly的内核是混合型的,包含了
微内核与统一内核的特色,并试图集成两种技术的优势。例如
微内核的消息传递机制可以使OS能从被保护内存中节余更多空间;而统一内核在处理某些关键任务的速度方面更具优势。(DFBSD的)消息子系统看起来相似于某些
微内核系统,例如Mach,虽然Mach设计的更加简单。DFBSD的消息子系统可以工作在同步或异步模式,并试图在给定条件下达到系统的最佳性能。
为达到项目的剩余目标,同时提供设备I/O和VFS的消息机制。新架构将允许内核的许多部分可以被转移到
用户空间,其优点在于以更小的独立的程序取代了混杂在一起的大量代码,这使内核更小更容易调试;而那部分被允许在用户空间执行的内核代码带来的额外的好处是系统将更加稳定,即使用户空间的驱动崩溃了,内核也不会崩溃。
虽然同样被封装成消息,但实际上系统调用被分为
用户空间版本和
内核版本。把多种标准调用从内核转移到
用户空间的兼容层有助于降低内核的的大小和复杂度,这就有助于维护DFBSD版本前向后向的兼容性。Linux和其他类UNIX系统的兼容性代码被转移出来就与此类似。DFBSD可在jails中创建原生
用户空间兼容层的多个实例与UML(用户模式linux)就很相似。不同于UML(本质上宿主内核相当于一个不同的硬件平台,而UML是对其的一个linux移植)的是DFBSD的虚拟化对计算机的真实硬件不需要特殊驱动就可以直接通讯。
CPU localization
DFBSD中
线程被设计成被CPU锁定,并且每个处理器有着自己的LWKT调度器。线程只能通过在cpu之间传递一个IPI(Interprocessor Interrupt)消息来转移,而不能依据优先级从一个处理器切换到另一个处理器。进程间的
线程调度也是通过发送异步IPI消息来完成。(这样实现的)一个优点是通过
线程子系统的明确的隔离使得SMP系统的处理器的板载cache不会包含重复数据,并通过给予系统里的每个处理器使用自己的cache来缓存不同的事物以达到更高的性能。
在多个内核线程间分割工作给各个LWKT子系统(举个网络代码的例子;每个处理器每个协议一个线程),通过在移除在多个内核任务中共享某些资源的需求来减轻冲突。但是这个DFBSD设计的与众不同的关键特性“CPU局部化算法的线程分割实现”是有争议的。
Protecting shared resources
为了能在多处理器的机器上安全的运行,对共享资源(文件、数据结构等)必须
串行化,这样线程或者进程就不会在同一时刻修改同一资源。原子化操作、
自旋锁、关键
代码段(Critical sections 是一小块用来处理一份被共享资源的代码,该段代码必须独占的对某些共享资源的访问权。这可以让多行代码以原子方式执行。如果一个
线程进入了critical section,另外一个线程绝对不能进入该critical section)、互斥标记,串行令牌和
消息队列与所有可能的方式都可被用来防止访问冲突。linux和FreeBSD 5采用细化锁互斥模型来实现
多处理器系统的高性能,然而DFBSD却不是这样,为了防止多个
线程同时访问或者修改共享资源,DFBSD使用了关键
代码段和串行令牌技术。虽然直到最近,DFBSD仍在使用SPLs,但是将被关键
代码段取代。
很多系统核心包含LWKT子系统,其他事物中的IPI消息子系统和新的
核心内存分配器是没有加锁的,也就是说他们工作时没有使用互斥标记,并且在单CPU上运行。关键
代码段用于保护本地中断,也在单CPU上运行,保证了一个当前运行的线程不会被先占有。
串行令牌被用来阻止对其他CPU的同时访问并控制多个线程的同时并发,确保在一个给定时间只有一个线程运行。不同于互斥方式,处于阻塞或者
休眠状态的线程并不能防止别的线程对共享资源的访问。使用串行令牌可以阻止使用互斥方式时导致的很多死锁和优先级倒置的问题,这样极大的简化了一个需要在多个线程共享一个资源的多步程序的设计和实现。串行令牌的代码看起来于linux现在使用的”Read-copy-update”很相似,但不同于linux当前RCU的实现,DFBSD实现了竞争只影响到与同一个令牌相关的处理器,而不是计算机里所有的处理器。
Additional features
在开发初期,DFBSD就开发了一个slab分配器取代了FreeBSD 4的内核内存分配器。新的分配器不像它取代的那些代码,在
内存分配时既不需要互斥,也不需要时阻塞操作。而且它是mpsafe的。
DFBSD使用SFBUF(Super-Fast Buffers)和MSFUBF(Multi-SFBUFs)。SFBUF是用来管理快速单页内存映射并在适当的时候对页面缓存。它们被用来回收一个单VM页相对数据的引用。(这个设计)简单而又强大,在此之上可以发展很多功能,比如说在sendfile
系统调用里实现“zero-copy”。
内核里很多地方使用了SFBUF,比如在Vnode Object Pager和PIPE子系统(间接的如XIO)里用来支持高带宽传输。一个SFBUF只能对应一个单VM页;而MSFBUFs被用来管理多页的快速内存映射。
SFBUF这个概念最初是FreeBSD项目中的David Greenman在实现sendfile系统调用时设计的,后来的完善依赖于Dr. Alan L. Cox和Matthew Dillon。MSFBUFs则是由Hiten Pandya和Matthew Dillon设计的。