Kernel CPU 高的定位方法
2025/10/29大约 3 分钟
Kernel CPU 高的定位方法
在某些场景下,客户设备会遇到 CPU 持续高占用的情况,通过 FortiGate 自带的 CPU Profiling 程序,可以收集到 CPU 高时的代码级别的 Debug 信息。
通常来说,CPU 可以在 Kernel/System Space 和 User Space 内工作,Kernel Space 用于运行操作系统的可执行文件,以下方法仅适用于 Kernel Space 下 CPU 使用率高的情况,不适用于某个用户进程(如 IPS engine/WAD)CPU 占用高的情况。如下所示,获取的 CPU 状态信息中,System 或 softirg 占用较高,即为 Kernel Space CPU 使用率高(而不是使用 diagnose sys top 中看到的用户进程占用 CPU 高)。
FortiGate # get system performance status
CPU states: 0% user 99% system 0% nice 1% idle 0% iowait 0% irq 0% softirq
CPU0 states: 0% user 99% system 0% nice 1% idle 0% iowait 0% irq 0% softirq
CPU1 states: 0% user 98% system 0% nice 2% idle 0% iowait 0% irq 0% softirq
FortiGate # get system performance status
CPU36 states: 0% user 0% system 0% nice 0% idle 0% iowait 0% irq 100% softirq
CPU37 states: 0% user 0% system 0% nice 0% idle 0% iowait 0% irq 100% softirq
CPU38 states: 0% user 0% system 0% nice 0% idle 0% iowait 0% irq 100% softirq
CPU39 states: 0% user 0% system 0% nice 0% idle 0% iowait 0% irq 100% softirq定位方法
在 Kernel Space 下 CPU 使用率持续高的情况下,使用如下命令收集信息。
diag sys profile cpumask 15 //抓取特定的CPU核心,这里以15为例 diag sys profile start //开启profile程序,等待1分钟左右,再执行后续命令 diag sys profile stop diag sys profile show order diag sys profile show detail diag sys profile sysmap以上操作执行完成后,使用如下命令输出 CPU profile 的结果。
FortiGate # diag sys profile show order 0xffffffffa007990f: 2322 fqdn_ip_check+0x4f/0xa0 0xffffffffa0078537: 547 oal_ioctl+0xa57/0x1070 0xffffffff803ac8ec: 100 __write_lock_failed+0xc/0x20 0xffffffffa00323bb: 57 __iprope_check_one_policy+0x32b/0x21c0 0xffffffffa002bd4b: 38 timer_function+0xffb/0x2e70 0xffffffffa009c287: 37 __iprope_tree_check+0x1f7/0x3e0以上结果表明 CPU 在收集期间正在执行的函数,这些函数有两种类型,一种为标准的 Linux 函数,其意义何以在 Linux 标准中找到,另一种为 Fortinet 私有的函数。常见代表的意义如下:
| 函数名称 | 含义 | 排查方法 |
|---|---|---|
| poll_idle | CPU 没有在做任何操作 | 忽略 |
| inet_hash_connect inet_check_established | 用于打开 Socket 连接 | 通常在显式代理中出现,可能是 FortiGate 无法在出接口上打开更多的端口导致,解决方法是在显示代理的出接口上设置更多的端口或 IP(config web-proxy explicit) |
| inet_frag_find ip_defrag | 分片 | 执行分片相关的调试命令(如 sniffer、diagnose snmp ip frags),检查用户网络的 MTU 设置 |
| is_csf_valid | ISDB | 与 ISDB 进程或 SD-WAN 有关,检查调用大量 ISDB 条目的相关配置 |
| read_ses_rate | SNMP | 检查是否有大批量查询 FortiGate SNMP OID 的流量 |
| __local_bh_enable_ip | ||
| rb_next fqdn_check | FQDN | 检查是否存在大量引用 FQDN 的策略 |
| strncasecmp | FTP | 与 FTP Session Helper 会话有关 |
| queue_work_on process_one_work | Internal loop inside linux kernel | |
| __write_lock_failed | 通用 Linux 函数,表示进程正在等待进程锁释放 | |
| sal_no_sleep | FIB 转发表项变化 | 检查是否有大规模的路由变化(BGP/OSPF/IPsec tunnel up/down) |
| __posix_lock_file | 配置变更/更新特征库 | 本地配置变更,或 FortiGate 正在更新特征库 |
| fqdn_ip_check oal_ioctl __write_lock_failed | 被拒绝的流量 | DDoS 攻击、或大量数据包被 FortiGate 阻断 |
| ip_session_mark_one_dirty ip6_session_mark_one_dirty | 会话正在 dirty | 使用命令“diag sys cmdb info”检查配置变化情况,收集 fcnacd 进程的 Debug 信息,也可能有 FortiClient 终端注册情况导致的 Session Dirty |
| release_pages pagevec_lru_move_fn | 与 WAD 向 IPS 发送数据有关 | 与 UTM 深度包检测有关 |
| do_gettimeoffset_tsc | IPS 检测相关 | |
| unix_find_other.constprop | 配置变更 | 与移动安全策略顺序有关,使用“fnsysctl cat/proc/net/unix”收集信息 |
| add_ip_mcast_session | 与组播流量转发有关 | |
| STAT_IVS_COPY_CNT | 该计数器用于交换模块的 Flood 复制 | 与 NP 丢包无关 |