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

相关文章

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程序步骤三:运行程序注意事项方法二

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

c++的初始化列表与const成员

初始化列表与const成员 const成员 使用const修饰的类、结构、联合的成员变量,在类对象创建完成前一定要初始化。 不能在构造函数中初始化const成员,因为执行构造函数时,类对象已经创建完成,只有类对象创建完成才能调用成员函数,构造函数虽然特殊但也是成员函数。 在定义const成员时进行初始化,该语法只有在C11语法标准下才支持。 初始化列表 在构造函数小括号后面,主要用于给

Java程序到CPU上执行 的步骤

相信很多的小伙伴在最初学习编程的时候会容易产生一个疑惑❓,那就是编写的Java代码究竟是怎么一步一步到CPU上去执行的呢?CPU又是如何执行的呢?今天跟随小编的脚步去化解开这个疑惑❓。 在学习这个过程之前,我们需要先讲解一些与本内容相关的知识点 指令 指令是指导CPU运行的命令,主要由操作码+被操作数组成。 其中操作码用来表示要做什么动作,被操作数是本条指令要操作的数据,可能是内存地址,也

win10不用anaconda安装tensorflow-cpu并导入pycharm

记录一下防止忘了 一、前提:已经安装了python3.6.4,想用tensorflow的包 二、在pycharm中File-Settings-Project Interpreter点“+”号导入很慢,所以直接在cmd中使用 pip install -i https://mirrors.aliyun.com/pypi/simple tensorflow-cpu下载好,默认下载的tensorflow