CPU 拓扑结构定义
// topology.h
struct cpu_topology {
int thread_id; // SMT ID
int core_id; // 核心 ID
int package_id; // 物理 CPU ID
int die_id; // Die ID
cpumask_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 状态控制
设备注册