Linux разработка ядра, как получить физический идентификатор ядра? - PullRequest
0 голосов
/ 21 апреля 2020

Я полностью начинаю разработку ядра Linux. Я пытаюсь узнать о процессах и планировании (я знаю, что я хочу сделать, это не «полезно», это просто учиться).

Я написал системный вызов, который возвращает мне идентификатор потока / логического ядра на котором запущен мой процесс.

Но теперь я хотел бы сделать следующее: написать системный вызов, который возвращает мне идентификатор физического ядра, на котором работает мой процесс.

I попытался прочитать task_struct, но я не нашел никакой подсказки.

Я потерян со всем этим кодом. Я понятия не имею, где я могу начать свои исследования и т. Д.

Меня интересует ваша методология. Я на x86_64 и использую Linux 5.6.2.

1 Ответ

0 голосов
/ 22 апреля 2020

То, что вы хотите сделать, это то же самое, что /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() в вашей пользовательской программе, чтобы установить привязку к одному ЦП.

...