2009-04-19 8 views
11

Estoy tratando de entender cómo funciona el syscall de linux sched_setaffinity(). Este es un seguimiento de mi pregunta here.¿Cómo funciona sched_setaffinity()?

Tengo this guide, que explica cómo usar el syscall y tiene un ejemplo bastante prolijo (¡trabajando!).

Así que descargué el Linux 2.6.27.19 kernel sources.

Hice un 'grep' para las líneas que contienen ese syscall, y obtuve 91 resultados. No es prometedor

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

estoy familiarizado con los programas de la forma de un solo núcleo de un solo hilos trabajo. Uno podría emitir una instrucción 'jmp foo', y esto básicamente establece la dirección IP a la dirección de memoria de la etiqueta 'foo'. Pero cuando uno tiene múltiples núcleos, uno tiene que decir "buscar la siguiente instrucción en la dirección de la memoria foo, y establecer el puntero de instrucción para número de núcleo 2 para comenzar la ejecución allí".

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

Volver 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", que es inconsistente con su manual page. Entonces, ¿qué es importante aquí? ¿Cuál de estos módulos muestra las instrucciones de montaje emitidas? ¿Qué módulo está leyendo la 'task_struct', mirando al miembro 'cpus_allowed' y luego convirtiéndolo en una instrucción? (También he hojeado la fuente glibc, pero creo que solo hace una llamada al código kernel para realizar esta tarea).

Respuesta

9

sched_setaffinity() simplemente le dice al programador qué CPU es ese proceso/subproceso permitido para ejecutarse, luego pide un reprogramación.

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

Si le interesa cómo puede llamar realmente algún código en otras CPU, le sugiero que eche un vistazo a smp_call_function_single(). En caso de que deseemos llamar a algo en otra CPU, esto llama al generic_exec_single(). Este último simplemente agrega la función a la cola de llamadas de la CPU de destino y fuerza una reprogramación a través de algunas cosas IPI (si la cola estaba vacía).

La línea inferior es: no existe una variante SMP real de la instrucción _jmp_. En cambio, el código que se ejecuta en otras CPU coopera para realizar la tarea.

1

Donde, en el código de ensamblaje, especificamos qué núcleo realiza esa operación?

No se requiere ensamblaje aquí. Cada tarea (hilo) se asigna a una sola CPU (o núcleo en sus términos) a la vez. Para detener la ejecución en una CPU determinada y reanudar en otra, la tarea tiene que "migrate" (también this). Cuando una tarea migra de una CPU a otra, el programador picks la CPU que está más inactiva entre las CPU permitidas por sched_setaffinity().

No hay instrucciones de montaje mágico emitidas.El kernel tiene una vista de bajo nivel del hardware, cada CPU es un objeto separado, muy diferente de cómo se ve para los procesos de espacio de usuario (en el espacio de usuario, las CPU son casi invisibles).

4

Creo que lo que no está entendiendo es que el núcleo se está ejecutando en todos los núcleos de la CPU. En cada interrupción del temporizador (~ 1000 por segundo), el planificador se ejecuta en cada CPU y elige un proceso para ejecutar. No hay una CPU que de alguna manera les indique a los demás que comiencen a ejecutar un proceso. sched_setaffinity() funciona simplemente configurando indicadores en el proceso. El planificador lee estos indicadores y no ejecutará ese proceso en su CPU si no está configurado.

+0

Ignorar este comentario – kumar

+0

<< En cada interrupción del reloj (~ 1000 por segundo), el planificador ejecuta en cada CPU y elige un proceso para funcionar. Tengo una pregunta aquí: Scheduler es una pieza de código que se ejecuta en el kernel. Un fragmento de código siempre se ejecuta en Single CPU en cualquier instante. ¿Correcto? Entonces, ¿ese programador malo (invocado por el controlador de interrupción del temporizador) cambia entre la CPU ... Entonces, eso significa que si tengo más CPUs es más programador de ejecución general en TODAS las CPU ... aquí se confunde un poco. – kumar

+0

Las diferentes CPU ejecutan diferentes copias del planificador. La interrupción del temporizador se genera en cada CPU individualmente. Entonces, si tiene 4 CPU, tiene 4 programadores. En realidad, el código del programador es el mismo, pero los datos son diferentes. – osgx