2009-04-19 7 views
11

Sto cercando di capire come funziona linux syscall sched_setaffinity(). Questo è un seguito dalla mia domanda here.Come funziona sched_setaffinity()?

Ho this guide, che spiega come utilizzare il syscall e ha un esempio molto carino (funzionante!).

Così ho scaricato il Linux 2.6.27.19 kernel sources.

Ho fatto un 'grep' per le linee che contengono quel syscall, e ho ottenuto 91 risultati. Non promettente.

In definitiva, sto cercando di capire come il kernel è in grado di impostare il puntatore all'istruzione per il nucleo speciale (o il processore.)

ho familiarità con programmi come single-core-single-thread lavoro. Si potrebbe emettere un'istruzione 'jmp foo', e in pratica questo imposta l'IP sull'indirizzo di memoria dell'etichetta 'foo'. Ma quando si hanno più core, si deve dire "scaricare l'istruzione successiva all'indirizzo di memoria foo, e impostare il puntatore di istruzioni per il numero di core per iniziare l'esecuzione lì."

Dove, nel codice assembly, stiamo specificando quale core esegue quell'operazione?

Torna al codice del kernel: cosa è importante qui? Il file 'kernel/sched.c' ha una funzione chiamata sched_setaffinity(), ma restituisce il tipo "long" - che è incoerente con il suo manual page. Quindi cosa è importante qui? Quale di questi moduli mostra le istruzioni di montaggio emesse? Quale modulo sta leggendo il 'task_struct', guardando il membro 'cpus_allowed' e poi traducendolo in un'istruzione? (Ho anche sfogliato la sorgente di glibc - ma penso che faccia una chiamata al codice del kernel per portare a termine questa operazione.)

risposta

9

sched_setaffinity() dice semplicemente allo scheduler quali CPU è il processo/thread a cui è consentito l'esecuzione, quindi richiede una riprogrammazione.

Lo scheduler viene eseguito su ognuna delle CPU, quindi ha la possibilità di decidere quale task eseguire successivamente su quella particolare CPU.

Se sei interessato a come puoi effettivamente chiamare un codice su altre CPU, ti suggerisco di dare un'occhiata a smp_call_function_single(). Nel caso in cui vogliamo chiamare qualcosa su un'altra CPU, questo chiama generic_exec_single(). Quest'ultimo aggiunge semplicemente la funzione alla coda di chiamate della CPU di destinazione e impone una riprogrammazione tramite alcune cose di IPI (se la coda era vuota).

La riga inferiore è: non esiste una variante SMP effettiva dell'istruzione _jmp_. Invece, il codice in esecuzione su altre CPU collabora per svolgere il compito.

1

Dove, nel codice assembly, stiamo specificando quale core esegue quell'operazione?

Non c'è assemblaggio coinvolto qui. Ogni attività (thread) è assegnata a una singola CPU (o core nei tuoi termini) alla volta. Per interrompere l'esecuzione su una determinata CPU e riprendere da un'altra, l'attività deve "migrate" (anche this). Quando un'attività esegue la migrazione da una CPU a un'altra, lo scheduler picks la CPU che è più inattiva tra le CPU consentite da sched_setaffinity().

Non ci sono istruzioni di montaggio magico emesse.Il kernel ha una visione più bassa dell'hardware, ogni CPU è un oggetto separato, molto diverso da come appare per i processi dello spazio utente (nello spazio utente, le CPU sono quasi invisibili).

4

Penso che la cosa che non state capendo è che il kernel è in esecuzione su tutti i core della CPU. Ad ogni interruzione del timer (~ 1000 al secondo), lo scheduler viene eseguito su ciascuna CPU e sceglie un processo da eseguire. Non c'è una CPU che in qualche modo dice agli altri di iniziare a eseguire un processo. sched_setaffinity() funziona semplicemente impostando i flag sul processo. Lo scheduler legge questi flag e non eseguirà quel processo sulla sua CPU se non è impostato.

+0

Ignora questo commento – kumar

+0

<< Ad ogni interruzione del timer (~ 1000 al secondo), lo scheduler viene eseguito su ogni CPU e sceglie un processo per l'esecuzione. Ho una domanda qui: Scheduler è un pezzo di codice in esecuzione nel kernel, Un pezzo di codice viene sempre eseguito a CPU singola in qualsiasi istante. Corretto? Quindi è che lo scheduler medio (invocato dal gestore di interrupt del timer) commuta tra la CPU ... Quindi è che se avessi più CPU è più uno schedulatore in esecuzione su TUTTE le CPU .... un po 'confuso qui. – kumar

+0

Le diverse CPU eseguono copie diverse dello scheduler. L'interrupt del timer viene generato su ogni CPU individualmente. Quindi, se hai 4 CPU, hai 4 programmatori. In realtà il codice dello scheduler è lo stesso, ma i dati sono diversi. – osgx