Linux – How does the kernel assign cpu ids to physical cores

cpulinuxlinux-kernel

One may find a lot of info about how to inspect physical cores layout in a running linux system, but I'm wondering how the physical cores are assigned a cpu id in the first place.

After experiencing on a couple of machines, it appears to me that the assignment is deterministic (i.e. booting from the same hardware will result in the same cpu ids assignment to physical processing core).
Also, it seems to me that the assignment works somehow "round-robin", such that two cores with nearby numbers are physically far away from each other. For example, in one server I'm working on (2 sockets x 8 cpus x 2 hyperthreading, x86_64): cpu0 is on socket 0, cpu1 is on socket 1, then cpu2 is again on socket 0 but it's on a different physical core from cpu0; … goes on like this until cpu15, then cpu16 is hyperthreaded on the same physical core as cpu0.

cpus layout on a 2-sockets x86_64

If this is deliberate as it seems, do you know of anywhere I can find this behaviour documented? What's the rationale behind it?

I'd expecially appreciate any reference to documentation or lkml post, but even a pointer to the right place in the sources could be helpful.

Best Answer

Is is hardly documented and largely depends on a platform. For x86, next available id is assigned to CPU in the function generic_processor_info()

So, for x86, cpu ids are depending on order in which we would call that function. It is called when APIC (interrupt controller) is initialized, while APIC settings are taken from ACPI MADT table and the ACPI tables are provided by BIOS.

You may try to decode them yourself using ACPI tools (acpica-tools package in CentOS):

# acpidump > acpi.dat
# acpixtract -a acpi.dat
# iasl -d apic.dat
...
# cat apic.dsl | awk -F: '/Subtable Type/ { st = $2 }
                          /Processor ID/ { id = $2 }
                          /Processor Enabled/ { print id, $2, st } '
Related Question