Pregunta

Estoy tratando de entender cómo funciona la llamada al sistema de Linux sched_setaffinity().Esta es una continuación de mi pregunta. aquí.

Tengo esta guía, que explica cómo usar syscall y tiene un ejemplo bastante claro (¡funciona!).

Entonces descargué Linux 2.6.27.19. fuentes del núcleo.

Hice un 'grep' para las líneas que contenían esa llamada al sistema y obtuve 91 resultados.No es prometedor.

En última instancia, estoy tratando de entender cómo el kernel puede configurar el puntero de instrucción. para un núcleo específico (o procesador).

Estoy familiarizado con cómo funcionan los programas de un solo núcleo y un solo subproceso.Se podría emitir una instrucción 'jmp foo', y esto básicamente establece la IP en la dirección de memoria de la etiqueta 'foo'.Pero cuando uno tiene varios núcleos, tiene que decir "busque la siguiente instrucción en la dirección de memoria foo y configure el puntero de instrucción para núcleo número 2 para comenzar la ejecución allí."

¿Dónde, en el código ensamblador, especificamos qué núcleo realiza esa operación?

Volvamos al código del kernel:¿Qué es importante aquí?El archivo 'kernel/sched.c' tiene una función llamada sched_setaffinity(), pero devuelve el tipo "long", lo cual es inconsistente con su pagina del manual.Entonces, ¿qué es importante aquí?¿Cuál de estos módulos muestra las instrucciones de montaje emitidas?¿Qué módulo lee 'task_struct', mira el miembro 'cpus_allowed' y luego lo traduce en una instrucción?(También hojeé la fuente de glibc, pero creo que simplemente realiza una llamada al código del kernel para realizar esta tarea).

¿Fue útil?

Solución

sched_setaffinity() simplemente indica al programador las CPU que es ese proceso / hilo permitido para funcionar, entonces pide una re-programación.

El planificador ejecuta en realidad en cada una de las CPUs, por lo que tiene la oportunidad de decidir qué tarea a ejecutar a continuación en esa CPU en particular.

Si está interesado en la forma en que realmente puede llamar a un cierto código en otras CPU, le sugiero que tome un vistazo a smp_call_function_single(). En caso de que queramos llamar a algo en otra CPU, esto exige generic_exec_single(). Esta última simplemente añade la función de cola de llamadas de la CPU de destino y fuerza una reprogramación a través de algunos IPI cosas ( si la cola estaba vacía).

hay ninguna variante SMP real de la instrucción _jmp_:

El fondo es. En su lugar, el código que se ejecuta en otras CPU coopera con el fin de realizar la tarea.

Otros consejos

Creo que lo que no está entendiendo es que el núcleo se está ejecutando en todos los núcleos de CPU. En cada interrupción del reloj (~ 1000 por segundo), el planificador ejecuta en cada CPU y elige un proceso para funcionar. No hay una sola CPU que de alguna manera dice a los demás para empezar a ejecutar un proceso. sched_setaffinity() funciona con sólo el establecimiento de indicadores en el proceso. El planificador lee estas banderas y no se ejecutará el proceso en su CPU si está establecido para no hacerlo.

  

Cuando, en el código de montaje, estamos especificando qué núcleo realiza esa operación?

No es ningún montaje en juego aquí. Cada tarea (rosca) se asigna a una sola CPU (o núcleo en sus términos) a la vez. Para detener la ejecución en una CPU dada y reanudará el otro, la tarea tiene que " migrar "(también este ). Cuando una tarea migra de una CPU a otra, el planificador picks la CPU que es más inactivo entre las CPUs permitidos por sched_setaffinity().

No hay instrucciones de montaje de magia emitidos. El núcleo tiene una visión más bajo nivel del hardware, cada CPU es un objeto independiente, muy diferente a la forma en que se ve como para los procesos de espacio de usuario (en el espacio de usuario, las CPU son casi invisibles).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top