cpu masks的初始化

2024-03-11 17:36
文章标签 cpu 初始化 masks

本文主要是介绍cpu masks的初始化,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在内核中,有几个位图变量是用作标识cpu数量和状态的,它们分别是:

变量名称用途循环所使用的宏
cpu_possible_mask系统中有多少个可以运行的cpu核for_each_possible_cpu
cpu_present_mask系统中有多少个可处于运行状态的cpu核for_each_present_cpu
cpu_online_mask系统中有多少个正在工作的cpu核for_each_online_cpu
cpu_active_mask系统中有多少个活跃的cpu核

本文主要介绍一下cpu_possible_mask和cpu_present_mask的初始化。

1, cpu_possible_mask的初始化过程:

start_kernel
  --> setup_arch
    --> smp_init_cpus
        --> acpi_parse_and_init_cpus
            smp_cpu_setup
               -->set_cpu_possible

从上述过程中,内核从acpi中获取了可以运行的cpu的数量。

2,cpu_present_mask

start_kernel

  -->reset_init
     --> kernel_thread(kernel_thread)
 
         kernel_init(thread)        
            -->kernel_init_freeable
                -->smp_prepare_cpus
                    -->cpu_prepare
                        -->cpu_psci_cpu_prepare
                    -->set_cpu_present
                -->smp_init
                    -->cpu_up
                        -->cpu_psci_cpu_boot

还是从start_kernel开始,这个时候cpu0已经启动完成,内核创建了一个线程kernel_init,其余的cpu和在这个函数里进行初始化工作。

内核首先根据cpu_possible_mask中的信息,为每一个possible cpu调用cpu_prepare,得到了固件的回复后,将该cpu设置到cpu_present_mask相对应的位置上,这样系统就获得了可以运行的cpu的位图。

然后内核调用smp_init-->cpu_up逐一初始化这些内核,关于这些内核的的启动流程,可以参考我的另一篇博客:

smp_init过程解析_slab_prepare_cpu-CSDN博客

为什么想到要看这两个变量的初始化呢,原因是最近正在处理的项目是一个双cpu的服务器,每个服务器有32个核,但我们无论是在GUI的系统信息里,还是在dmidecode中,得到的信息都是一个64核的cpu,其中dmidecode信息如下:

dmidecode -r processor# dmidecode 3.2
Getting SMBIOS data from sysfs.
SMBIOS 3.3.0 present.
# SMBIOS implementations newer than version 3.2.0 are not
# fully supported by this version of dmidecode.Handle 0x0008, DMI type 4, 48 bytes
Processor InformationSocket Designation: SOCKET 0Type: Central ProcessorFamily: ARMManufacturer: PHYTIUM LTDID: 10 08 00 00 00 00 00 00Signature: Implementor 0x00, Variant 0x0, Architecture 0, Part 0x081, Revision 0Version: Phytium S5000C 64 CoreVoltage: 0.9 VExternal Clock: UnknownMax Speed: 2300 MHzCurrent Speed: 2300 MHzStatus: Populated, EnabledUpgrade: NoneL1 Cache Handle: 0x0005L2 Cache Handle: 0x0006L3 Cache Handle: 0x0007Serial Number: KAP8160405050000Asset Tag: Not SetPart Number: Not SetCore Count: 64Core Enabled: 64Thread Count: 64Characteristics:64-bit capableMulti-CoreExecute ProtectionEnhanced Virtualization

一开始以为是cpu_possible_mask或者cpu_present_mask有误,但根据dmidecode的源码分析后,看到这些信息是从内核的文件/sys/firmware/dmi/tables/smbios_entry_point中获取,dmidecode的过程如下,见dmidecode.c

static void dmi_decode(const struct dmi_header *h, u16 ver)
{const u8 *data = h->data;/** Note: DMI types 37 and 42 are untested*/switch (h->type){case 0: /* 7.1 BIOS Information */......case 4: /* 7.5 Processor Information */printf("Processor Information\n");if (h->length < 0x1A) break;printf("\tSocket Designation: %s\n",dmi_string(h, data[0x04]));printf("\tType: %s\n",dmi_processor_type(data[0x05]));printf("\tFamily: %s\n",dmi_processor_family(h, ver));printf("\tManufacturer: %s\n",dmi_string(h, data[0x07]));dmi_processor_id(h, "\t");printf("\tVersion: %s\n",dmi_string(h, data[0x10]));printf("\tVoltage:");dmi_processor_voltage(data[0x11]);printf("\n");printf("\tExternal Clock: ");dmi_processor_frequency(data + 0x12);printf("\n");printf("\tMax Speed: ");dmi_processor_frequency(data + 0x14);printf("\n");printf("\tCurrent Speed: ");dmi_processor_frequency(data + 0x16);printf("\n");if (data[0x18] & (1 << 6))printf("\tStatus: Populated, %s\n",dmi_processor_status(data[0x18] & 0x07));elseprintf("\tStatus: Unpopulated\n");printf("\tUpgrade: %s\n",dmi_processor_upgrade(data[0x19]));if (h->length < 0x20) break;if (!(opt.flags & FLAG_QUIET)){printf("\tL1 Cache Handle:");dmi_processor_cache(WORD(data + 0x1A), "L1", ver);printf("\n");printf("\tL2 Cache Handle:");dmi_processor_cache(WORD(data + 0x1C), "L2", ver);printf("\n");printf("\tL3 Cache Handle:");dmi_processor_cache(WORD(data + 0x1E), "L3", ver);printf("\n");}if (h->length < 0x23) break;printf("\tSerial Number: %s\n",dmi_string(h, data[0x20]));printf("\tAsset Tag: %s\n",dmi_string(h, data[0x21]));printf("\tPart Number: %s\n",dmi_string(h, data[0x22]));if (h->length < 0x28) break;if (data[0x23] != 0)printf("\tCore Count: %u\n",h->length >= 0x2C && data[0x23] == 0xFF ?WORD(data + 0x2A) : data[0x23]);if (data[0x24] != 0)printf("\tCore Enabled: %u\n",h->length >= 0x2E && data[0x24] == 0xFF ?WORD(data + 0x2C) : data[0x24]);if (data[0x25] != 0)printf("\tThread Count: %u\n",h->length >= 0x30 && data[0x25] == 0xFF ?WORD(data + 0x2E) : data[0x25]);printf("\tCharacteristics:");dmi_processor_characteristics(WORD(data + 0x26), "\t\t");break;......。

cpu的信息包括socket都在dmicode信息中。

dmi信息在内核中的处理是在driver/firmware/dmi_scan.c中,代码如下:

void __init dmi_scan_machine(void)
{char __iomem *p, *q;char buf[32];if (efi_enabled(EFI_CONFIG_TABLES)) {if (efi.smbios3 != EFI_INVALID_TABLE_ADDR) {p = dmi_early_remap(efi.smbios3, 32);......

dmidecode这些信息是由efi写到内存的efi.smbios3地址中,内核使用iomap将该地址映射到内核的虚拟地址空间,并且读出来放到了/sys/firmware/dmi/tables/smbios_entry_point中,工具dmidecode对其进行读取和解析。

所以这个问题是smbios信息有误,更新后就可以显示正确的信息了。

dmidecode的源码在如下地址:

Index of /releases/dmidecode/

这篇关于cpu masks的初始化的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/798542

相关文章

判断PyTorch是GPU版还是CPU版的方法小结

《判断PyTorch是GPU版还是CPU版的方法小结》PyTorch作为当前最流行的深度学习框架之一,支持在CPU和GPU(NVIDIACUDA)上运行,所以对于深度学习开发者来说,正确识别PyTor... 目录前言为什么需要区分GPU和CPU版本?性能差异硬件要求如何检查PyTorch版本?方法1:使用命

Java数组初始化的五种方式

《Java数组初始化的五种方式》数组是Java中最基础且常用的数据结构之一,其初始化方式多样且各具特点,本文详细讲解Java数组初始化的五种方式,分析其适用场景、优劣势对比及注意事项,帮助避免常见陷阱... 目录1. 静态初始化:简洁但固定代码示例核心特点适用场景注意事项2. 动态初始化:灵活但需手动管理代

QT进行CSV文件初始化与读写操作

《QT进行CSV文件初始化与读写操作》这篇文章主要为大家详细介绍了在QT环境中如何进行CSV文件的初始化、写入和读取操作,本文为大家整理了相关的操作的多种方法,希望对大家有所帮助... 目录前言一、CSV文件初始化二、CSV写入三、CSV读取四、QT 逐行读取csv文件五、Qt如何将数据保存成CSV文件前言

C++中初始化二维数组的几种常见方法

《C++中初始化二维数组的几种常见方法》本文详细介绍了在C++中初始化二维数组的不同方式,包括静态初始化、循环、全部为零、部分初始化、std::array和std::vector,以及std::vec... 目录1. 静态初始化2. 使用循环初始化3. 全部初始化为零4. 部分初始化5. 使用 std::a

Spring组件初始化扩展点BeanPostProcessor的作用详解

《Spring组件初始化扩展点BeanPostProcessor的作用详解》本文通过实战案例和常见应用场景详细介绍了BeanPostProcessor的使用,并强调了其在Spring扩展中的重要性,感... 目录一、概述二、BeanPostProcessor的作用三、核心方法解析1、postProcessB

Android如何获取当前CPU频率和占用率

《Android如何获取当前CPU频率和占用率》最近在优化App的性能,需要获取当前CPU视频频率和占用率,所以本文小编就来和大家总结一下如何在Android中获取当前CPU频率和占用率吧... 最近在优化 App 的性能,需要获取当前 CPU视频频率和占用率,通过查询资料,大致思路如下:目前没有标准的

Go使用pprof进行CPU,内存和阻塞情况分析

《Go使用pprof进行CPU,内存和阻塞情况分析》Go语言提供了强大的pprof工具,用于分析CPU、内存、Goroutine阻塞等性能问题,帮助开发者优化程序,提高运行效率,下面我们就来深入了解下... 目录1. pprof 介绍2. 快速上手:启用 pprof3. CPU Profiling:分析 C

C++初始化数组的几种常见方法(简单易懂)

《C++初始化数组的几种常见方法(简单易懂)》本文介绍了C++中数组的初始化方法,包括一维数组和二维数组的初始化,以及用new动态初始化数组,在C++11及以上版本中,还提供了使用std::array... 目录1、初始化一维数组1.1、使用列表初始化(推荐方式)1.2、初始化部分列表1.3、使用std::

MySQL的cpu使用率100%的问题排查流程

《MySQL的cpu使用率100%的问题排查流程》线上mysql服务器经常性出现cpu使用率100%的告警,因此本文整理一下排查该问题的常规流程,文中通过代码示例讲解的非常详细,对大家的学习或工作有一... 目录1. 确认CPU占用来源2. 实时分析mysql活动3. 分析慢查询与执行计划4. 检查索引与表

使用Python检查CPU型号并弹出警告信息

《使用Python检查CPU型号并弹出警告信息》本教程将指导你如何编写一个Python程序,该程序能够在启动时检查计算机的CPU型号,如果检测到CPU型号包含“I3”,则会弹出一个警告窗口,感兴趣的小... 目录教程目标方法一所需库步骤一:安装所需库步骤二:编写python程序步骤三:运行程序注意事项方法二