Linux 内核开发,如何获取物理核心id?

Linux kernel development, how to get physical core id?

我完全是 Linux 内核开发的新手。我正在尝试学习流程和调度(我知道我想做的不是 "useful" 它只是学习)。

我写了一个系统调用,其中 returns 我的 thread/logical 核心的 ID,我的进程 运行.

但是现在,我想做的是:编写一个系统调用,其中 returns 我的进程所在的物理核心的 ID 运行。

我试图阅读 task_struct,但我没有找到任何线索。

我迷失了所有这些代码。我不知道从哪里开始我的研究等等。

我对您的方法很感兴趣。我在 x86_64 上并且正在使用 Linux 5.6.2.

你想做的基本上和/proc/cpuinfo已经做的一样:

$ cat /proc/cpuinfo
processor   : 0  <== you have this
...
core id     : 0  <== you want to obtain this
...

因此,我们可以看看 /proc/cpuinfo 如何做到这一点,在 arch/x86/kernel/cpu/proc.c. By analyzing the code a little bit, we see that the CPU information is obtained calling cpu_data():

static void *c_start(struct seq_file *m, loff_t *pos)
{
    *pos = cpumask_next(*pos - 1, cpu_online_mask);
    if ((*pos) < nr_cpu_ids)
        return &cpu_data(*pos); // <=== HERE
    return NULL;
}

cpu_data()宏returns一个struct cpuinfo_x86, which contains all the relevant information, and is then used here打印核心ID:

seq_printf(m, "core id\t\t: %d\n", c->cpu_core_id);

因此,在内核模块中,您可以执行以下操作:

#include <linux/smp.h>     // get_cpu(), put_cpu()
#include <asm/processor.h> // cpu_data(), struct cpuinfo_x86

// ...

static int __init modinit(void)
{
    unsigned cpu;
    struct cpuinfo_x86 *info;

    cpu = get_cpu();
    info = &cpu_data(cpu);
    pr_info("CPU: %u, core: %d\n", cpu, info->cpu_core_id);
    put_cpu(); // Don't forget this!

    return 0;
}

inserting/removing模块三次后我机器上的dmesg输出:

[14038.937774] cpuinfo: CPU: 1, core: 1
[14041.084951] cpuinfo: CPU: 5, core: 1
[14087.329053] cpuinfo: CPU: 6, core: 2

和我/proc/cpuinfo的内容一致:

$ cat /proc/cpuinfo | grep -e 'processor' -e 'core id'
processor   : 0
core id     : 0
processor   : 1
core id     : 1
processor   : 2
core id     : 2
processor   : 3
core id     : 3
processor   : 4
core id     : 0
processor   : 5
core id     : 1
processor   : 6
core id     : 2
processor   : 7
core id     : 3

请注意, 作为 Martin James rightfully pointed out, this information is not very useful since your process could be preempted and moved to a different core by the time your syscall finishes execution. If you want to avoid this you can use the sched_setaffinity() 系统调用在您的用户空间程序中将关联设置为单个 CPU。