¿Cómo detecta Linux la cantidad de CPU "posibles"?

Sep 16 2020

Tengo una CPU AMD con 8 núcleos y 2 hilos por núcleo. Linux (correctamente) muestra esto como 16 "cpus". Sin embargo, sysfs en realidad muestra 32 cpus "posibles", con 16 de ellos no presentes y fuera de línea:

$ cat /sys/devices/system/cpu/possible 0-31 $ cat /sys/devices/system/cpu/present
0-15

$ cat /sys/devices/system/cpu/online 0-15 $ cat /sys/devices/system/cpu/offline 
16-31

Para ser claros, no hay nada de malo aquí; De hecho, hay 16 CPU lógicas presentes y en línea. Lo que no tengo claro es por qué Linux detecta una adición de 16 CPU lógicas que no están presentes pero son posibles.

Creo que estos son los documentos relevantes del kernel: https://www.kernel.org/doc/html/latest/core-api/cpu_hotplug.html. Pero no veo ninguna indicación de cómo se elige la cantidad de CPU posibles. (Tenga en cuenta que es mucho menor que la kernel_maxcantidad de CPU, que es 8191 en mi sistema).

(Un poco de información adicional: tengo un código que necesita analizar estos valores. Hacer lo correcto parece sencillo, pero me gustaría tener una cadena de documentación clara que explique por qué la cantidad de CPU posibles puede exceder la cantidad de CPU actuales en un computadora de escritorio ordinaria.)

Respuestas

2 Gilles'SO-stopbeingevil' Sep 16 2020 at 02:40

Una CPU es "posible" si hay espacio para ella en la memoria del kernel. La cantidad de CPU posibles es la cantidad máxima de CPU que se pueden poner en línea, incluidas las que se conectan en caliente después del arranque.

La documentación de esta parte de sysfs se encuentra en Cómo se exporta la información de topología de la CPU a través de sysfs :

posible: CPU a las que se han asignado recursos y se pueden poner en línea si están presentes. [cpu_possible_mask]

Pero la documentación más detallada cpu_possible_maskestá en CPU hotplug en el Kernel :

Mapa de bits de posibles CPU que pueden estar disponibles en el sistema. Esto se utiliza para asignar algo de memoria de tiempo de arranque para las variables por_cpu que no están diseñadas para crecer / reducirse a medida que las CPU están disponibles o se eliminan. Una vez configurado durante la fase de detección de tiempo de arranque, el mapa es estático, es decir, no se agregan ni eliminan bits en ningún momento. Recortarlo con precisión para las necesidades de su sistema por adelantado puede ahorrar algo de memoria en el tiempo de arranque.

Este parámetro se puede configurar a través de las opciones de la línea de comandos . En el caso probable de que su hardware no admita enchufar otra CPU sin reiniciar y no tenga la intención de hibernar su sistema y hacer que se active con más CPU, puede ahorrar una pequeña cantidad de memoria del kernel pasando possible_cpus=16el kernel línea de comando. En una PC o servidor típico, la cantidad probablemente sea demasiado pequeña para que valga la pena el esfuerzo.

En ausencia de opciones de línea de comando, creo que debe leer la fuente para averiguar qué está pasando. Si el kernel se compila sin el soporte de CPU hotplug ( CONFIG_HOTPLUG_CPU), solo mira cuántas CPU están presentes en el momento del arranque. Si el kernel tiene soporte para CPU hotplug, de acuerdo con un comentario prefill_possible_mapen el código fuente:

  • Si el BIOS especificó CPU deshabilitadas en ACPI / mptables, utilícelo.
  • El usuario puede sobrescribirlo con possible_cpus = NUM
  • De lo contrario, no reserve CPU adicionales.

No he verificado que esto sea lo que hace el código.

Tenga en cuenta que el principio de lo que significa "posibles CPU" se aplica a todas las arquitecturas, pero las formas de determinar el número de CPU son específicas de la arquitectura. En mi respuesta, asumo x86.