Linux 内核中关于 CPU 编号和拓扑管理

ops/2025/2/24 11:07:15/

CPU 拓扑结构定义

// topology.h
struct cpu_topology {int thread_id;    // SMT IDint core_id;      // 核心 IDint package_id;   // 物理 CPU IDint die_id;       // Die IDcpumask_t thread_sibling; // SMT 线程掩码cpumask_t core_sibling;   // 核心掩码
};

CPU 在线/离线管理

//cpu.c
/* CPU 热插拔核心函数 */
int cpu_up(unsigned int cpu)
{int err = 0;struct device *dev;struct device *parent;if (!cpu_possible(cpu)) {pr_err("can't online cpu %d because it is not configured as may-hotadd at boot time\n",cpu);return -EINVAL;}dev = get_cpu_device(cpu);if (!dev) {pr_err("can't online cpu %d as device does not exist\n", cpu);return -ENODEV;}/* 确保 CPU 已经完全离线 */cpu_maps_update_begin();if (cpu_online(cpu)) {err = -EEXIST;goto out;}/* 执行架构相关的 CPU 上线操作 */err = _cpu_up(cpu, 0, CPUHP_ONLINE);out:cpu_maps_update_done();return err;
}
EXPORT_SYMBOL_GPL(cpu_up);

CPU 设备注册

// cpu.c
static struct bus_type cpu_subsys = {.name = "cpu",.dev_name = "cpu",
};static int __init cpu_dev_init(void)
{int err;err = subsys_system_register(&cpu_subsys, cpu_root_attr_groups);if (err)return err;/* 创建 /sys/devices/system/cpu 目录 */cpu_dev_root = kzalloc(sizeof(*cpu_dev_root), GFP_KERNEL);if (!cpu_dev_root)return -ENOMEM;/* 注册每个 CPU 的 sysfs 接口 */for_each_possible_cpu(cpu) {struct device *dev;dev = get_cpu_device(cpu);if (dev) {err = device_register(dev);if (err)return err;}}return 0;
}

CPU 掩码管理

//cpumask.c
/* CPU 掩码操作函数 */
void cpumask_set_cpu(unsigned int cpu, struct cpumask *dstp)
{set_bit(cpu, cpumask_bits(dstp));
}void cpumask_clear_cpu(unsigned int cpu, struct cpumask *dstp)
{clear_bit(cpu, cpumask_bits(dstp));
}int cpumask_test_cpu(int cpu, const struct cpumask *cpumask)
{return test_bit(cpu, cpumask_bits((struct cpumask *)cpumask));
}

CPU 拓扑信息初始化

//tepology.c
/* 初始化 CPU 拓扑信息 */
void detect_extended_topology(struct cpuinfo_x86 *c)
{unsigned int eax, ebx, ecx, edx;if (c->extended_cpuid_level < 0xb)return;cpuid_count(0xb, 0, &eax, &ebx, &ecx, &edx);/* 如果 CPUID.0BH 不支持,返回 */if (ebx == 0 || (ecx & 0xff00) == 0)return;/* 解析 SMT 级别 */c->x86_max_cores = (ecx & 0xff00) >> 8;c->cpu_core_id = edx;/* 解析 Core 级别 */cpuid_count(0xb, 1, &eax, &ebx, &ecx, &edx);if ((ecx & 0xff00) != 0) {c->x86_max_cores = c->x86_max_cores / ((ecx & 0xff00) >> 8);c->phys_proc_id = edx;}
}

sysfs CPU 接口

//cpu.c
/* CPU 设备属性 */
static DEVICE_ATTR(online, 0644, show_online, store_online);
static DEVICE_ATTR(offline, 0444, show_offline, NULL);
static DEVICE_ATTR(possible, 0444, show_possible, NULL);
static DEVICE_ATTR(present, 0444, show_present, NULL);/* CPU 在线状态控制 */
static ssize_t store_online(struct device *dev,struct device_attribute *attr,const char *buf, size_t count)
{struct cpu *cpu = container_of(dev, struct cpu, dev);int ret;switch (buf[0]) {case '0':ret = cpu_down(cpu->dev.id);break;case '1':ret = cpu_up(cpu->dev.id);break;default:ret = -EINVAL;}return ret ? ret : count;
}

CPU 热插拔状态机

//cpu.c
/* CPU 热插拔状态定义 */
enum cpuhp_state {CPUHP_OFFLINE = 0,CPUHP_CREATE_THREADS,CPUHP_PERF_PREPARE,CPUHP_WORKQUEUE_PREP,/* ... 更多状态 ... */CPUHP_ONLINE,
};/* CPU 热插拔回调注册 */
int __cpuhp_setup_state(enum cpuhp_state state,const char *name,bool invoke,int (*startup)(unsigned int cpu),int (*teardown)(unsigned int cpu),bool multi_instance)
{int ret = 0;/* ... 实现代码 ... */return ret;
}';

这些源码展示了 Linux 内核如何管理 CPU 编号和拓扑结构。主要涉及:
CPU 拓扑管理
CPU 热插拔
sysfs 接口
CPU 状态控制
设备注册


http://www.ppmy.cn/ops/160955.html

相关文章

ArcGIS Pro中等高线的生成与应用详解

在地理信息科学与空间数据分析领域&#xff0c;等高线作为一种重要的地形表达方式&#xff0c;扮演着至关重要的角色。 无论是在地图制图、城市规划&#xff0c;还是在自然资源管理等诸多方面&#xff0c;等高线都为我们提供了丰富的地形信息。 而ArcGIS Pro作为一款功能强大…

【Java项目】基于SpringBoot的【高校校园点餐系统】

【Java项目】基于SpringBoot的【高校校园点餐系统】 技术简介&#xff1a;采用Java技术、MySQL数据库、B/S结构实现。 系统简介&#xff1a;高校校园点餐系统是一个面向高校师生的在线点餐平台&#xff0c;主要分为前台和后台两大模块。前台功能模块包括&#xff08;1&#xff…

MySQL日志undo log、redo log和binlog详解

MySQL 日志&#xff1a;undo log、redo log、binlog 有什么用&#xff1f; 一、前言 在MySQL数据库中&#xff0c;undo log、redo log和binlog这三种日志扮演着至关重要的角色&#xff0c;它们各自承担着不同的功能&#xff0c;共同保障了数据库的正常运行和数据的完整性。了解…

使用Socket编写超牛的http服务器和客户端(二)

客户端 动态扩展连接池、线程池优雅关闭、超时机制、健康检查等功能,并将代码模块化: 文件结构 HTTPClientProject/ ├── ConnectionPool.h ├── ConnectionPool.cpp ├── TaskQueue.h ├── ThreadPool.h ├── main.cpp 工程代码主要分为以下几个模块: Connectio…

vector结构刨析与模拟实现

目录 1.引言 2.C模拟实现 2.1模拟实现构造函数 1&#xff09;直接构造 2&#xff09;拷贝构造 3&#xff09;单一赋值构造 4&#xff09;迭代器构造 2.2模拟实现析构函数 2.3模拟实现其他常规函数 1&#xff09;capacity函数 2&#xff09;size函数 3&#xff09;b…

10.Docker 仓库管理

Docker 仓库管理 Docker 仓库管理 Docker 仓库管理 Docker 仓库&#xff0c;类似于 yum 仓库&#xff0c;是用来保存镜像的仓库。为了方便的管理和使用 docker 镜像,可以将镜像集中保存至 Docker 仓库中&#xff0c;将制作好的镜像 push 到仓库集中保存&#xff0c;在需要镜像…

Python+Selenium+Pytest+POM自动化测试框架封装

&#x1f345; 点击文末小卡片 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 1、测试框架简介 1&#xff09;测试框架的优点 代码复用率高&#xff0c;如果不使用框架的话&#xff0c;代码会显得很冗余。可以组装日志、报告、邮件等一些高…

手动搭建Redis1主2从+ 3 Sentinel 高可用集群

环境准备 一台机器部署&#xff1a; Redis 主节点: 127.0.0.1:6379Redis 从节点: 127.0.0.1:6380, 127.0.0.1:6381Sentinel 节点: 127.0.0.1:26379, 127.0.0.1:26380, 127.0.0.1:26381 步骤 1&#xff1a;安装 Redis 6.2.17 # 下载并编译 Redis wget https://download.redis.…