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。
我完全是 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。