¿Cómo interactúa la afinidad de CPU con cgroups en Linux?

10

Estoy tratando de ejecutar puntos de referencia de subprocesos múltiples en un conjunto de CPU aisladas. Para abreviar una larga historia, inicialmente intenté con isolcpusy taskset, pero tuve problemas . Ahora estoy jugando con cgroups / csets.

Creo que el cset shieldcaso de uso "simple" debería funcionar bien. Tengo 4 núcleos, por lo que me gustaría usar los núcleos 1-3 para la evaluación comparativa (también configuré estos núcleos para que estén en modo de ticks adaptativos), luego el núcleo 0 se puede usar para todo lo demás.

Siguiendo el tutorial aquí , debería ser tan simple como:

$ sudo cset shield -c 1-3
cset: --> shielding modified with:
cset: "system" cpuset of CPUSPEC(0) with 105 tasks running
cset: "user" cpuset of CPUSPEC(1-3) with 0 tasks running

Así que ahora tenemos un "escudo" que está aislado (el cset de usuario) y el núcleo 0 es para todo lo demás (el cset del sistema).

Muy bien, se ve bien hasta ahora. Ahora echemos un vistazo htop. Todos los procesos deberían haberse migrado a la CPU 0:

csets

¿Eh? Algunos de los procesos se muestran como ejecutados en los núcleos blindados. Para descartar el caso de que htop tiene un error, también intenté usar tasksetpara inspeccionar la máscara de afinidad de un proceso que se muestra como en el escudo.

¿Quizás esas tareas eran inamovibles? Arranquemos un proceso arbitrario que se muestra como ejecutándose en la CPU3 (que debería estar en el escudo) htopy veamos si aparece en el cgroup del sistema de acuerdo con cset:

$ cset shield -u -v | grep 864
   root       864     1 Soth [gmain]
   vext01    2412  2274 Soth grep 864 

Sí, eso se está ejecutando en el cgroup del sistema de acuerdo con cset. Entonces htopy csetno estoy de acuerdo.

Entonces, ¿qué está pasando aquí? ¿En quién confío: afinidades de la CPU ( htop/ taskset) o cset?

Sospecho que se supone que no debes usar csety afinidades juntos. Quizás el escudo esté funcionando bien, y debería ignorar las máscaras de afinidad y la htopsalida. De cualquier manera, esto me parece confuso. ¿Alguien puede arrojar algo de luz?

Edd Barrett
fuente
¿Qué distribución estás usando? Pregunto porque las herramientas y los flujos de trabajo son diferentes, dependiendo del sistema operativo y la versión.
ewwhite
Es un sistema debian 8.
Edd Barrett
Ah, vale. En el mundo Redhat, tenemos numactly la cgconfige cgrules/ cgreda racionalizar lo que está haciendo. Estos pueden estar disponibles para Debian con algo de trabajo.
ewwhite

Respuestas:

5

De la documentación de cpusets :

Las llamadas a sched_setaffinity se filtran solo a las CPU permitidas en el cpuset de esa tarea.

Esto implica que las máscaras de afinidad de CPU se cruzan con el cpus en el cgroup del que es miembro el proceso.

Por ejemplo, si la máscara de afinidad de un proceso incluye núcleos {0, 1, 3} y el proceso se ejecuta en el cgroup del sistema, que está restringido a núcleos {1, 2}, entonces el proceso se vería obligado a ejecutarse en el núcleo 1.

Estoy 99% seguro de que el htopresultado es "incorrecto" al hecho de que los procesos no se han despertado desde que se crearon los cgroups, y la pantalla muestra el último núcleo en el que se ejecutó el proceso.

Si inicio vim antes de hacer mi escudo, vim se bifurca dos veces (por alguna razón), y el niño más profundo se está ejecutando en el núcleo 2. Si luego hago el escudo, entonces duermo vim (ctrl + z) y lo despierto, ambos procesos tienen movido al núcleo 0. Creo que esto confirma la hipótesis que htopmuestra información obsoleta.

También puede inspeccionar /proc/<pid>/statusy mirar los cpus_allowed_*campos.

Por ejemplo, tengo un console-kit-daemonproceso (pid 857) aquí que se muestra en htop como ejecutándose en el núcleo 3, pero en /proc/857/status:

Cpus_allowed:   1
Cpus_allowed_list:      0

Creo que esto está diciendo que la máscara de afinidad es 0x1, lo que permite ejecutar solo en el núcleo 1 debido a los grupos c: es decir, intersectar ({0,1,2,3}, {0}) = {0}.

Si puedo, dejaré la pregunta abierta un momento para ver si surge alguna respuesta mejor.

Gracias a @davmac por ayudar con esto (en irc).

Edd Barrett
fuente
1
Tiene razón, la información que se muestra en HTOP no es en qué núcleo se encuentra actualmente el proceso, sino en el último núcleo en el que se programó (lo mismo ocurre con cualquier cosa que use la misma interfaz para recopilar información).
Austin Hemmelgarn