-
【时间子系统】五、高精度定时器
通过对低精度定时器的分析,我们知道这类定时器的精度是毫秒级的,也就是说存在毫秒级的误差范围。对于像IO超时错误处理这类定时任务,毫秒级的误差完全不算什么问题。然而,对于工业上的许多实时任务,毫秒级的误差是完全不可接受的。因此,基于更高精度的时间硬件(例如TSC和LAPIC Timer),内核工程师们开发了一套全新的高精度定时器功能(传统基于时间轮的低精度定时器已经很稳定了,与其对它修修补补,还不如新建一套全新的机制)。1. 高精度定时器的初始化 高精度定时器的初始化和低精度定时器的初...…
-
【时间子系统】四、低精度定时器
通过定时器,我们可以控制计算机在将来指定的某个时刻执行特定的动作。传统的定时器,以时钟滴答(jiffy)作为计时单位,因此它的精度较低(例如HZ=1000时,精度为1毫秒),我们也称之为低精度定时器。1. 初始化定时器 我们在概述中介绍过,内核中通过init_timer对定时器进行初始化,定时器中最关键的三个信息是:到期时间、到期处理函数、到期处理函数的参数。init_timer宏及定时器结构struct timer_list(取名struct timer可能更合适)的定义如下:li...…
-
【时间子系统】三、时钟中断-定时基础
时钟中断是各种定时器(timer)能够正常工作的前提,同时它和进程调度(tick事件)也密不可分,因此在分析定时器原理前,我们先来深入了解一下时钟中断的原理。1. 中断初始化 时钟中断涉及时钟事件设备(Clock Event Device)等多个概念,我们先通过分析初始化流程来理解这些概念。1.1. BSP初始化阶段 时钟中断的初始化发生在启动CPU(BSP)上,由start_kernel函数作为总体入口。在完成IO-APIC中断控制器的相关初始化动作后,由late_time_in...…
-
【时间子系统】二、计时原理-timekeeper与clocksource
本篇博文我们将深入分析一下内核是如何使用计时硬件对应用提供服务的。1. 内核表示时间数据结构 内核中对时间的表示有多种形式,可以使用在不同的应用场景。我们在时间概述中看到的gettimeofday的示例中,采用的数据结构是struct timeval,它的定义如下:linux/include/uapi/linux/time.h:struct timeval { __kernel_time_t tv_sec; /* seconds */ __kern...…
-
【时间子系统】一、概述
除了计算、存储、网络等核心子系统外,计算机内部还包含时间子系统,它对系统的运行起着重要作用。什么是计算机的时间子系统? 计算机内的时间子系统包含多种时间设备,我们可以把这些设备分为两大类:计时设备和定时通知设备。 我们可以将计时设备理解为生活中所见的”墙上挂钟”或者”手表”,它们为系统提供了时间(时刻)。常见的计时设备有TSC(Time Stamp Counter)、RTC(Real Time Clock)、ACPI_PM: TSC是每个CPU内部的一个计数器,它按CPU...…
-
【计算子系统】进程管理之二:进程替换
本篇讨论进程替换(exec),计算子系统相关内容目录点此进入。什么是进程替换?为什么需要它? 进程替换是用新的代码和数据替换当前进程已有代码和数据,从而开始执行新的业务逻辑。 通过fork创建出来的进程是继承父进程的代码和数据,如果想要进程执行一些新的任务,那就得从磁盘程序中加载新的代码和数据并替换当前进程已有的代码和数据。如何实现进程替换?1. exec用户态示例代码 我们先来看看在用户态程序中是如何实现替换的:exec_test.c:#include <stdio.h&...…
-
【Rados Block Device】五、Client内核RBD驱动分析-网络信使messenger
4. libceph.ko中messenger模块分析 messenger模块(信使)是libceph中相对比较独立的部分,旨在为上层各种网络客户端(如mon_client、osd_client)提供稳定可靠、有序的网络服务。messenger构建在网络TCP协议之上,虽然TCP协议本身是面向连接且可靠的网络协议,但是TCP连接有可能断开(broken,非长连接情况下会发生;长连接存在底层网络故障排除后上层应用感知不及时的问题)。为解决TCP短连接不可靠的问题,messenger通过间隔...…
-
【Rados Block Device】四、Client内核RBD驱动分析-设备IO流程
内核RBD驱动整体软件栈如下: 3. RBD块设备IO流程分析 上节我们在分析映射流程时,已经涉及和OSD的交互,但并未深入讨论,因此这里我们将通过IO的处理流程来深入分析其内部原理。 IO流程可分为请求下发和响应返回两个阶段,整体过程如下图所示: 应用程序下发的IO请求在rbd层被表达为一个rbd_img_request;每个rbd_img_request会被划分成一个个以4M为粒度的rbd_obj_request(其实我们在上一节分析时已经涉及rbd_obj_req...…
-
【Rados Block Device】三、Client内核RBD驱动分析-设备映射流程
内核RBD驱动整体软件栈如下: rbd工具通过map子命令映射产生一个可使用的内核块设备,其本质原理是由rbd工具往sysfs(“/sys/bus/rbd/add”)内核文件接口中写入待创建块设备的信息(例如前文实例写入的内容为”9.22.115.154:6789 name=amdin,key=client, wbpool wb -“,其中9.22.115.154为主monitor的IP),内核在处理这个写入请求时会调用由RBD驱动事先注册好的处理函数来生成一个内核块设备对象。2...…
-
【Rados Block Device】二、Client内核RBD驱动分析-设备创建流程
1. RBD块设备创建 回顾开篇介绍RBD块设备的使用方法,分为创建、映射和使用三步。创建过程主要是用户态rbd工具与rados集群通信完成的,不涉及内核RBD驱动;但问题是rados集群中的OSD提供的是对象服务(我们可以把对象简单理解成key/value对),如何来表达一个RBD块设备? 我们通过rados ls命令来查看一下wbpool中创建了一个名为wb的RBD设备后都生成了哪些对象: [root@ceph-client]# rados ls --pool wbpoolrbd...…
-
【Rados Block Device】一、概述
ceph作为流行的SDS(Software Define Storage)开源实现备受业界关注,从本篇博文开始我们将从它提供的块服务(Rados Block Device)角度对ceph进行深入分析。什么是Rados Block Device?什么是ceph? 看一下官方的解释:”Ceph is a unified, distributed storage system designed for excellent performance, reliability and scala...…
-
【计算子系统】进程管理之一:进程创建
进程管理也是计算子系统(CPU&Memory)的核心功能,从本篇博文起,我们开始讨论进程管理。计算子系统相关内容目录点此进入。什么是进程?什么是进程管理?为什么需要进程管理? 从物理视角说上,进程是CPU上的一段逻辑过程,它的控制(代码段)和数据(数据段)存放于内存。回顾一下计算子系统开篇中描绘的系统结构图(如下图),进程的执行要素包括CPU中的寄存器和内存段两个部分(虚拟内存段最终会映射到物理内存段):寄存器代表进程的瞬时运行状态;代码段存储指令,控制进程执行逻辑;数据段存...…
-
【计算子系统】内存管理之六:初始化
初始化过程往往是比较冗长且乏味的,如果一接触就开始学习这块内容会让人烦闷。在了解内存管理几个核心功能模块后,我们再回头看看内存管理的初始化过程,相信大家会有新的收获。计算子系统相关内容目录点此进入。低级阶段-汇编实现 我们可以把整个内存初始化过程大体分成低级阶段和高级阶段两个过程。低级阶段主要是用低级汇编语言实现的,又可细分成三步: 首先是BIOS,它在计算机启动的最初阶段检测了物理内存的分布情况,并在x86实模式的高端地址处(1M内存以下)记录了这些内存分布信息(称为e820表)...…
-
【计算子系统】内存管理之五:内存压缩
本节将讨论内存压缩,计算子系统相关内容目录点此进入。什么是内存压缩?为什么需要它? 内存压缩(memory compaction)是指把应用程序正在使用的物理页内容迁移(migrate)到其它物理页中,以释放原有物理页,从而方便空闲页的合并以形成大段连续空闲内存,有效避免内存碎片的产生。 前文介绍优化型伙伴算法时,我们已经看到空闲内存被分成不可移动、可回收、可移动几个类别,应用程序从可移动类别中获取内存页。连续的内存分配和释放如果产生碎片无法满足当前内存分配请求时,内核进入慢速分配...…
-
【计算子系统】内存管理之四:内存交换
本节将讨论内存交换,计算子系统相关内容目录点此进入。什么是内存交换?为什么需要它? 当系统内存使用压力较大时,内核会将访问率不好的匿名页暂时写到磁盘(换出)以释放这部分匿名页供系统使用;当换出的页再次被访问时,内核重新将其读入(换入)。 内存交换是回收匿名页的唯一手段。我们知道,应用程序使用的内存页分为文件映射页和匿名页两种。对于文件映射页,回收时可以将它的内容回刷到映射文件中。而对于匿名页(也包括私有的文件映射页),默认情况下没有持久化文件和它对应。如果要回收这部分内存,必然要寻...…
-
【计算子系统】内存管理之三:内存回收
本节将讨论内存回收,计算子系统相关内容目录点此进入。什么是内存回收?为什么需要它? 内存分配过程中如果发现剩余内存量低于预定的水位线(代表内存使用紧张),就会强制回收一部分使用频度不高的已分配内存,供后续分配使用。如此一来,好的方面是可最大限度满足系统内应用程序的内存分配请求,提升系统可用性。坏的方面是被回收页所属的应用可能再次访问该页,需要通过缺页处理再次分配映射页,从而带来应用性能的下降。一个优秀的内存回收算法需要在系统整体可用性和应用性能之间寻找合适的平衡点。如何实现?1. 四...…
-
【计算子系统】内存管理之二:内存分配
本节将讨论内存分配,计算子系统相关内容目录点此进入。什么是内存分配?为什么需要它?有何技术难点? 前文分析页异常处理时,我们看到内核会为应用程序分配内存页,而应用程序本身不直接申请内存页(只会通过malloc在堆中动态申请内存)。此外,内核在处理系统调用或中断时,也有可能需要动态申请页。Linux内核实现内存页申请的接口是alloc_pages(gfp_mask, order):其中,gfp_mask代表申请内存的方式(隐含内存用途),控制内存分配的行为;order代表需要的连续内存...…
-
【计算子系统】内存管理之一:地址映射
地址映射是CPU核心和MMU共同完成的内存管理功能之一,本节将对此展开深入讨论。计算子系统相关内容目录点此进入。什么是地址映射?为什么需要它? 正如在计算机系统整体介绍中所说明的一样,MMU在CPU的配合下(通过页异常触发),实现了线性地址到物理地址的动态映射,为正在CPU上运行的应用程序(进程)提供了一个独立的连续内存空间(线性地址空间,或称虚拟内存空间,其中放置了代码段、数据段和堆栈段),屏蔽了地址分配、内存分配和内存回收等一系列复杂的系统行为,不仅提升了内存资源的利用效率,而且...…
-
【计算子系统】CPU中断处理
从计算机系统内部看,中断无时无刻不在,这篇博文就和大家一起探讨中断的原理,并以x86_64平台上的linux 3.10内核为例来分析底层实现细节。什么是中断? 中断是一个系统过程,是计算系统中外部设备向CPU(或CPU之间)通知事件发生的一种机制。这种说法也许有些偏底层,可以从上层更直观的角度来理解:想象你正面对你的个人电脑,当你按下一个键盘按键时,你就触发了一个中断,随后屏幕上会出现你期望的字母;或者当你移动鼠标时,你也会触会一个中断,随后光标会随鼠标的移动而移动。严格意义上说,中...…
-
【计算子系统】系统调用
计算子系统的诸多功能大多是通过系统调用来实现的,而且对于应用程序员来说,函数调用可能再熟悉不过了,但是对于系统调用这类特殊的函数调用,可能就局限在使用层面,而不会过多地去做深入研究。因此,这篇博文就从系统调用的角度来深入理解计算子系统。什么是系统调用? 在计算子系统中,当CPU执行进程时,系统调用是经常发生的一个过程。它是操作系统内核为应用程序提供的一组功能接口(API),通过这组接口应用程序可以实现一系列全局性的系统功能,如创建新的进程(进程是系统全局性的资源,受内核统一调度和管理...…