То, что вы хотите сделать, это то же самое, что /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
. Немного проанализировав код, мы увидим, что информация о процессоре получается, вызывая 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()
возвращает struct cpuinfo_x86
, который содержит всю соответствующую информацию, а затем используется здесь для печати идентификатора ядра:
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;
}
Вывод 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 , эта информация не очень полезна, поскольку ваш процесс может быть прерван и перенесен в другое ядро к моменту окончания системного вызова. выполнение. Если вы хотите избежать этого, вы можете использовать системный вызов sched_setaffinity()
в вашей пользовательской программе, чтобы установить привязку к одному ЦП.