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

相关文章

SysMain服务可以关吗? 解决SysMain服务导致的高CPU使用率问题

《SysMain服务可以关吗?解决SysMain服务导致的高CPU使用率问题》SysMain服务是超级预读取,该服务会记录您打开应用程序的模式,并预先将它们加载到内存中以节省时间,但它可能占用大量... 在使用电脑的过程中,CPU使用率居高不下是许多用户都遇到过的问题,其中名为SysMain的服务往往是罪魁

MySQL中优化CPU使用的详细指南

《MySQL中优化CPU使用的详细指南》优化MySQL的CPU使用可以显著提高数据库的性能和响应时间,本文为大家整理了一些优化CPU使用的方法,大家可以根据需要进行选择... 目录一、优化查询和索引1.1 优化查询语句1.2 创建和优化索引1.3 避免全表扫描二、调整mysql配置参数2.1 调整线程数2.

C++11范围for初始化列表auto decltype详解

《C++11范围for初始化列表autodecltype详解》C++11引入auto类型推导、decltype类型推断、统一列表初始化、范围for循环及智能指针,提升代码简洁性、类型安全与资源管理效... 目录C++11新特性1. 自动类型推导auto1.1 基本语法2. decltype3. 列表初始化3

Spring Bean初始化及@PostConstruc执行顺序示例详解

《SpringBean初始化及@PostConstruc执行顺序示例详解》本文给大家介绍SpringBean初始化及@PostConstruc执行顺序,本文通过实例代码给大家介绍的非常详细,对大家的... 目录1. Bean初始化执行顺序2. 成员变量初始化顺序2.1 普通Java类(非Spring环境)(

Olingo分析和实践之OData框架核心组件初始化(关键步骤)

《Olingo分析和实践之OData框架核心组件初始化(关键步骤)》ODataSpringBootService通过初始化OData实例和服务元数据,构建框架核心能力与数据模型结构,实现序列化、URI... 目录概述第一步:OData实例创建1.1 OData.newInstance() 详细分析1.1.1

Linux进程CPU绑定优化与实践过程

《Linux进程CPU绑定优化与实践过程》Linux支持进程绑定至特定CPU核心,通过sched_setaffinity系统调用和taskset工具实现,优化缓存效率与上下文切换,提升多核计算性能,适... 目录1. 多核处理器及并行计算概念1.1 多核处理器架构概述1.2 并行计算的含义及重要性1.3 并

Linux下进程的CPU配置与线程绑定过程

《Linux下进程的CPU配置与线程绑定过程》本文介绍Linux系统中基于进程和线程的CPU配置方法,通过taskset命令和pthread库调整亲和力,将进程/线程绑定到特定CPU核心以优化资源分配... 目录1 基于进程的CPU配置1.1 对CPU亲和力的配置1.2 绑定进程到指定CPU核上运行2 基于

C++中RAII资源获取即初始化

《C++中RAII资源获取即初始化》RAII通过构造/析构自动管理资源生命周期,确保安全释放,本文就来介绍一下C++中的RAII技术及其应用,具有一定的参考价值,感兴趣的可以了解一下... 目录一、核心原理与机制二、标准库中的RAII实现三、自定义RAII类设计原则四、常见应用场景1. 内存管理2. 文件操

Java进程CPU使用率过高排查步骤详细讲解

《Java进程CPU使用率过高排查步骤详细讲解》:本文主要介绍Java进程CPU使用率过高排查的相关资料,针对Java进程CPU使用率高的问题,我们可以遵循以下步骤进行排查和优化,文中通过代码介绍... 目录前言一、初步定位问题1.1 确认进程状态1.2 确定Java进程ID1.3 快速生成线程堆栈二、分析

conda安装GPU版pytorch默认却是cpu版本

《conda安装GPU版pytorch默认却是cpu版本》本文主要介绍了遇到Conda安装PyTorchGPU版本却默认安装CPU的问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的... 目录一、问题描述二、网上解决方案罗列【此节为反面方案罗列!!!】三、发现的根本原因[独家]3.1 p