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

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 状态控制
设备注册

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值