云服务器内容精选

  • warning Warning是操作系统在运行时,检测到需要立即注意的内核问题(issue),而采取的上报动作,打印发生时的调用栈信息。上报后,系统继续运行。 原理 Warning是通过调用WARN、WARN_ON、WARN_ON_ONCE等宏来触发的。 导致Warning的原因有多种,需要根据调用栈回溯,找到调用Warning宏的具体原因。Warning宏并不会导致系统运行状态发生改变,也不提供处理Warning的指导。 触发方法 根据系统调用构造Warning条件。
  • panic Kernel panic是指操作系统在监测到内部的致命错误,并无法安全处理此错误时采取的动作。内核触发到某种异常情况,运行kernel_panic函数,并尽可能把异常发生时获取的全部信息打印出来。 原理 导致异常的原因多种多样,通过异常打印的调用信息,找到调用kernel_panic的原因。常见的原因包括内核堆栈溢出、内核空间的除0异常、内存访问越界、内核陷入死锁等。 触发方法 内核态读0地址。
  • MCE (Machine Check Exception) Machine Check Exception (MCE) 是CPU发现硬件错误时触发的异常(exception),上报中断号是18,异常的类型是abort。 原理 导致MCE的原因主要有:总线故障、内存ECC校验错、cache错误、TLB错误、内部时钟错误等。不仅硬件故障会引起MCE,不恰当的BIOS配置、firmware bug、软件bug也有可能引起MCE。 MCE中断上报,操作系统检查一组寄存器称为Machine-Check MSR,根据寄存器的错误码执行对应的处理函数(函数实现依赖不同的芯片架构实现)。 触发方法 无人为触发方法,当总线故障、内存ECC校验错、cache错误、TLB错误、内部时钟错误等时会触发MCE。
  • I/O error Linux I/O error报错通常表示输入/输出操作失败,在网卡、磁盘等IO设备驱动异常,或文件系统异常都可能打印这个错误。 原理 错误原因取决于代码执行失败的条件。常见的触发异常的原因是硬件故障、磁盘损坏、文件系统错误、驱动程序问题、权限问题等。例如当系统尝试读取或写入磁盘上的数据时,如果发生错误,就会出现I/O错误。 触发方法 系统读写磁盘过程,拔出磁盘,导致磁盘数据损坏。
  • EXT4-fs error EXT4-fs error是由于ext4格式的文件系统中,文件节点的错误导致。 原理 文件储存的最小存储单位叫做“扇区”(sector),连续多个扇区组成“块”(block)。inode节点储存文件的元信息,包括文件的创建者、创建日期、大小、属性、实际存储的数据块(block number)。EXT4格式的inode信息校验失败会触发EXT4-fs error。 内核ext4校验使用checksum校验inode信息,当出现分区表错误、磁盘硬件损坏时,内核返回-EIO错误码,系统上报EXT4-fs error checksum invalid错误。 触发方法 使用磁盘过程中强行拔盘,重新接入读盘。
  • hung task 当内核检测到进程处于D状态超过设定的时间时,上报hung task异常。 原理 进程其中一个状态是TASK_UNINTERRUPTIBLE,也叫D状态,处于D状态的进程只能被wake_up唤醒。内核引入D状态时,是为了让进程等待IO完成。正常情况下,IO正常处理,进程不应该长期处于D状态。 hung task检测进程长期处于D状态的原理,内核会创建一个线程khungtaskd,用来定期遍历系统中的所有进程,检查是否存在处于D状态超过设置时长(默认120秒)的进程。如果存在这样的进程,则打印并上报相关警告和进程堆栈。如果配置了hung_task_panic(通过proc或内核启动参数配置),则直接发起panic。 触发方法 创建内核线程,设成D状态,scheduler释放时间片。
  • page allocation failure page allocation failure是申请空闲页失败时,系统上报的错误。当程序申请某个阶数(order)的内存,但系统内存中,没有比申请阶数高的空闲页,即触发内核报错。 原理 Linux使用伙伴系统(buddy system)内存分配算法。将所有的空闲页表(一个页表的大小为4K)分别链接到包含了11个元素的数组中,数组中的每个元素将大小相同的连续页表组成一个链表,页表的数量为1、2、4、8、16、32、64、128、256、512、1024,所以一次性可以分配的最大连续内存为1024个连续的4k页表,即4MB的内存。 假设申请一个包括256个页表的内存,指定阶数order为6,系统会依次查找数组中的第9、10、11个链表,上一个为空,表示没有此阶数的空闲内存,查找下一个,直到最后一个链表。 如果所有链表均为空,申请失败,则内核上报错误page allocation failure。输出报错信息,描述申请阶数为6的内存页失败: page allocation failure:order:6 触发方法 用alloc_pages连续申请高阶数内存页(例如order=10),不释放,直到申请失败。
  • Bad mm_struct Bad mm_struct错误通常是由于内核中的一个或多个mm_struct数据结构被破坏或损坏所导致。 原理 mm_struct是Linux内核中的一个重要数据结构,用于跟踪进程的虚拟内存区域。如果该数据结构被破坏,可能会导致进程崩溃或系统崩溃。这种错误通常内存异常导致,例如mm_struct区域的内存被踩踏、内存越界等。 触发方法 无人为触发方法,当硬件错误,或者Linux系统内核代码错误时会触发Bad mm_struct。
  • 背景说明 HCE运行时,不可避免的会出现一些内核事件,例如soft lockup、RCU(Read-Copy Update) stall、hung task、global OOM、cgroup OOM、page allocation failure、list corruption、Bad mm_struct、I/O error、EXT4-fs error、MCE (Machine Check Exception)、fatal signal、warning、panic。本节为您介绍这些内核事件的原理及触发方法。
  • soft lockup soft lockup是内核检测CPU在一定时间内(默认20秒)没有发生调度切换时,上报的异常。 原理 soft lockup利用Linux内核watchdog机制触发。内核会为每一个CPU启动一个优先级最高的FIFO实时内核线程watchdog,名称为watchdog/0、watchdog/1以此类推。这个线程会定期调用watchdog函数,默认每4秒执行一次。同时调用过后会重置一个hrtimer定时器在2倍的watchdog_thresh时间后到期。watchdog_thresh是内核参数,对应默认超时时间为20秒。 在超时时间内,如果内核线程watchdog没被调度,hrtimer定时器到期,即触发内核打印类似如下的soft lockup异常。 BUG: soft lockup - CPU#3 stuck for 23s! [kworker/3:0:32] 触发方法 关闭中断或关闭抢占,软件执行死循环。
  • RCU(Read-Copy Update) stall RCU stall是一种rcu宽限期内rcu相关内核线程没有得到调度的异常。 原理 在RCU机制中,reader不用等待,可以任意读取数据,RCU记录reader的信息;writer更新数据时,先复制一份副本,在副本上完成修改,等待所有reader退出后,再一次性地替换旧数据。 writer需要等所有reader都停止引用“旧数据”才能替换旧数据。这相当于给了这些reader一个优雅退出的宽限期,这个等待的时间被称为grace-period,简称GP。 当reader长时间没有退出,writer等待的时间超过宽限期时,即上报RCU Stall。 触发方法 内核在Documentation/RCU/stallwarn.txt文档列出了可能触发RCU stall的场景:cpu在rcu reader临界区一直循环,cpu在关闭中断或关闭抢占场景中一直循环等。
  • global OOM Linux的OOM killer特性是一种内存管理机制,在系统可用内存较少的情况下,内核为保证系统还能够继续运行下去,会选择结束一些进程释放掉一些内存。 原理 通常oom_killer的触发流程是:内核为某个进程分配内存,当发现当前物理内存不够时,触发OOM。OOM killer遍历当前所有进程,根据进程的内存使用情况进行打分,然后从中选择一个分数最高的进程,终止进程释放内存。 OOM killer的处理主要集中在mm/oom_kill.c,核心函数为out_of_memory,函数处理流程为: 通知系统中注册了oom_notify_list的模块释放一些内存,如果从这些模块中释放出了一些内存,直接结束oom killer流程;如果回收失败,进入下一步。 触发oom killer通常是由当前进程进行内存分配所引起。如果当前进程已经挂起了一个SIG_KILL信号或者正在退出,直接选中当前进程,终止进程释放内存;否则进入下一步。 检查panic_on_oom系统管理员的设置,决定OOM时是进行oom killer还是panic。如果选择panic,则系统崩溃并重启;如果选择oom killer,进入下一步。 进入oom killer,检查系统设置,系统管理员可设置终止当前尝试分配内存、引起OOM的进程或其它进程。如果选择终止当前进程,oom killer结束;否则进入下一步。 调用select_bad_process选中合适进程,然后调用oom_kill_process终止选中的进程。如果select_bad_process没有选出任何进程,内核进入panic。 触发方法 执行占用大内存的程序,直到内存不足。
  • list corruption list corruption是内核检查链表有效性失败的报错,报错类型分为list_add corruption和list_del corruption。 原理 内核提供list_add和list_del,对传入的链表先检查链表的有效性(valid),检查通过后,修改链表增加或删除节点。如果检查链表失败,则上报corruption错误。检查和报错代码在内核lib/list_debug.c。 这种错误通常为内存异常操作导致,例如内存踩踏、内存损坏等。 触发方法 用list.h的内核标准接口创建链表,非法修改链表节点的prev或next指针,再调用内核list_add/list_del接口。
  • 需求背景 在业务混部场景中,Linux内核调度器需要为高优先级任务赋予更多的调度机会,并需要把低优先级任务对内核调度带来的影响降到最低。原有的在线、离线两级混部调度无法满足业务需求。 为解决此问题,HCE 2.0内核cpu cgroup支持多级混部调度,提供cgroup接口/sys/fs/cgroup/cpu/cpu.qos_level将任务调度级别扩展到5个级别,支持用户对每个cgroup组单独设置优先级。