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

相关文章

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

定位cpu占用过高的线程和对应的方法

如何定位cpu占用过高的线程和对应的方法? 主要是通过线程id找到对应的方法。 1 查询某个用户cpu占用最高的进程号 top -u 用户名 2 查询这个进程中占用cpu最高的线程号 top –p 进程号-H    3 查询到进程id后把进程相关的代码打印到jstack文件 jstack -l pid > jstack.txt 4 在jstack文件中通过16进制的线程id搜索到

@postconstruct初始化的操作

从Java EE 5规范开始,Servlet中增加了两个影响Servlet生命周期的注解(Annotion);@PostConstruct和@PreDestroy。这两个注解被用来修饰一个非静态的void()方法 。写法有如下两种方式: @PostConstruct Public void someMethod() {}

spring和tomcat初始化的类和注解

1.InitializingBean接口为bean提供了初始化方法的方式,它只包括afterPropertiesSet方法,凡是继承该接口的类,在初始化bean的时候会执行该方法。 spring为bean提供了两种初始化bean的方式,实现InitializingBean接口,实现afterPropertiesSet方法,或者在配置文件中同过init-method指定,两种方式可以同时使用 实

CPU亲和性设置 代码示例 sched_setaffinity sched_getaffinity

视频教程在这: cpu亲和性设置,NCCL,sched_setaffinity sched_getaffinity,CPU_ZERO、SET、ISSET、linux_哔哩哔哩_bilibili 一、CPU亲和性简介 CPU亲和性(CPU Affinity)设置是操作系统中一个重要的性能优化手段,它允许程序或进程被绑定到特定的CPU核心上运行。这样做的好处包括减少缓存未命中、降低线程迁移(co

ubuntu16.04 caffe(github源码cpu)+python3.5+opencv3.4.5安装编译

https://www.cnblogs.com/hanjianjian90/p/10604926.html

LabVIEW环境中等待FPGA模块初始化完成

这个程序使用的是LabVIEW环境中的FPGA模块和I/O模块初始化功能,主要实现等待FAM(Field-Programmable Gate Array Module,FPGA模块)的初始化完成,并处理初始化过程中的错误。让我们逐步分析各部分的功能: 1. Wait for FAM Initialization框架 此程序框架用于等待I/O模块成功初始化。如果在5秒钟内模块没有完成配