PREEMPT_RT spiegato: funzionalità del kernel in tempo reale

PREEMPT_RT spiegato: funzionalità del kernel in tempo reale

PREEMPT_RT trasforma il kernel Linux in un sistema operativo real-time, garantendo tempi precisi per le attività critiche. Completamente integrato in Linux 6.12 (rilasciato il 20 settembre 2024), abilita funzionalità real-time per architetture come x86, ARM64 e RISC-V. Ecco cosa devi sapere:

  • Caratteristiche principali:
    • Sostituisce i tradizionali spinlock con blocchi di sospensione preemptibili.
    • Converte i gestori di interrupt in thread, rendendoli pianificabili e preemptibili.
    • Implementa l'ereditarietà delle priorità per risolvere i problemi di inversione delle priorità.
    • Rende le operazioni RCU (lettura-copia-aggiornamento) completamente preemptibili.
  • Applicazioni:
    • Utilizzato in settori come quello automobilistico, della robotica, delle telecomunicazioni e dei dispositivi medici, dove la tempistica precisa è fondamentale.
    • Alimenta sistemi come strumenti di automazione industriale, controlli di volo e ambienti di hosting che richiedono server privati virtuali a bassa latenza.
  • Impostare:
    • Abilitare CONFIG_PREEMPT_RT nella configurazione del kernel.
    • Regolare le impostazioni come CONFIG_NO_HZ_FULL e CONFIG_RCU_BOOST per prestazioni ottimali.
    • Utilizzare strumenti come test ciclico per misurare la latenza e convalidare le prestazioni.

PREEMPT_RT privilegia il timing rispetto al throughput, rendendo Linux adatto ad applicazioni in cui le scadenze non sono negoziabili. È una svolta per i settori che richiedono prestazioni deterministiche.

Caratteristiche principali di PREEMPT_RT: come Linux ottiene prestazioni in tempo reale

Caratteristiche principali di PREEMPT_RT: come Linux ottiene prestazioni in tempo reale

PREEMPT_RT spiegato: crea e ottimizza il kernel Linux per latenza ultra bassa e in tempo reale

Caratteristiche principali di PREEMPT_RT

PREEMPT_RT si concentra su quattro funzionalità principali progettate per ridurre il codice non preemptibile e migliorare il controllo sulla pianificazione delle attività. Ecco un'analisi più approfondita di ciascuna di esse.

Prelazione completa del kernel

Uno degli aggiornamenti più importanti è la trasformazione degli spinlock standard (spinlock_t) e blocchi di lettura-scrittura (rwlock_t) in spinlock dormienti basati su mutex. Gli spinlock tradizionali possono causare ritardi perché disabilitano la prelazione, costringendo le attività a restare in attesa. PREEMPT_RT cambia questa situazione introducendo blocchi che consentono alle attività di rimanere in modalità sleep e di essere prelazionate, anche quando contengono una risorsa.

Ciò significa che le attività ad alta priorità possono interrompere quelle a priorità inferiore, anche se queste ultime mantengono dei blocchi. Tuttavia, per alcune operazioni critiche, come lo scheduler o i punti di ingresso hardware, PREEMPT_RT mantiene raw_spinlock_t, che si comporta come i blocchi non preemptibili originali. Come afferma Paul McKenney, un ingegnere illustre:

""Il punto chiave della patch PREEMPT_RT è ridurre al minimo la quantità di codice kernel non preemptibile, riducendo al minimo anche la quantità di codice che deve essere modificato per fornire questa preemptibilità aggiuntiva.""

Vediamo ora in che modo la gestione degli interrupt trae vantaggio da questo approccio.

Interruzioni thread

PREEMPT_RT sposta la maggior parte dei gestori di interrupt hardware dal contesto "hard IRQ" a thread del kernel in esecuzione nel contesto del processo. Questa modifica consente di dare priorità, interrompere o addirittura bloccare i gestori degli interrupt.

In un kernel Linux standard, un gestore di interrupt di lunga durata può portare a una latenza illimitata perché interrompe tutte le altre esecuzioni. Gli interrupt threadizzati risolvono questo problema. Per impostazione predefinita, questi thread di interrupt vengono eseguiti con un SCHED_FIFO priorità di 50, ma gli amministratori possono modificare le loro priorità utilizzando strumenti come grafico. Ad esempio, è possibile dare priorità all'interrupt di una scheda di rete per il controllo industriale, riducendo al contempo la priorità per l'I/O del disco. Poiché questi thread utilizzano spinlock inattivi anziché spinlock grezzi, evitano la necessità di disabilitare gli interrupt hardware mentre mantengono un lock.

Ora esploriamo come PREEMPT_RT gestisce le sfide legate alle priorità.

Ereditarietà prioritaria e Rtmutex

Inversione di priorità è un problema importante quando un'attività ad alta priorità rimane bloccata in attesa di una risorsa detenuta da un'attività a bassa priorità, mentre un'attività a media priorità (che non ha bisogno della risorsa) prevale su quella a bassa priorità. PREEMPT_RT risolve questo problema con eredità prioritaria, aumentando temporaneamente la priorità dell'attività a bassa priorità per farla corrispondere all'attività con priorità più alta in attesa della risorsa.

IL rtmutex Primitive è lo strumento che rende possibile tutto questo. Garantisce che, in caso di conflitto, il task a bassa priorità riceva un aumento di priorità per completare la sua sezione critica senza interferenze da parte dei task a media priorità. Se il task con aumento di priorità viene bloccato su un altro blocco, l'aumento di priorità si propaga a cascata lungo la catena delle dipendenze. Come spiega la documentazione del kernel Linux:

""L'ereditarietà della priorità consente alle applicazioni ben progettate di utilizzare blocchi dello spazio utente in parti critiche di un thread ad alta priorità, senza perdere determinismo.""

Per raggiungere questo obiettivo, rtmutex utilizza un flag e un albero ordinato in base alla priorità per gestire le attività in attesa, mantenendo basso il sovraccarico sulle architetture supportate.

Infine, diamo un'occhiata a come PREEMPT_RT migliora le operazioni RCU.

RCU preemptibile (lettura-copia-aggiornamento)

RCU

Read-Copy-Update (RCU) è una tecnica di sincronizzazione ampiamente utilizzata nel kernel Linux. Nei kernel standard, le sezioni di lettura RCU non sono preemptibili, il che può portare a ritardi imprevedibili. PREEMPT_RT modifica questa situazione rendendo le sezioni di lettura RCU completamente preemptibile, garantendo che le scadenze delle attività in tempo reale non vengano compromesse. Questa regolazione è fondamentale per ottenere il comportamento prevedibile richiesto nei sistemi in tempo reale.

Come configurare e utilizzare PREEMPT_RT

PREEMPT_RT è completamente integrato nei kernel Linux principali, il che significa che non sono più necessarie patch esterne. Tuttavia, applicare la coda delle patch più recente è comunque una buona idea per un migliore supporto dell'architettura e una grafica migliorata. Una volta che il kernel è pronto, sarà necessario modificarne le impostazioni per sfruttarne appieno le capacità.

Impostazioni di configurazione del kernel

Per abilitare un kernel completamente preemptible, attivare CONFIG_PREEMPT_RT. Nei kernel più recenti, questa impostazione si trova in "Impostazioni generali", ma potrebbe essere necessario abilitarla CONFIG_EXPERT prima di renderlo visibile nel menu di configurazione.

Per la produzione server dedicati e altri ambienti ad alte prestazioni, opzioni aggiuntive possono ottimizzare ulteriormente le prestazioni:

  • CONFIG_NO_HZ_FULL: Riduce le interruzioni del clock di pianificazione sulle CPU occupate, contribuendo a ridurre al minimo il jitter.
  • CONFIG_RCU_BOOST: Impedisce ai lettori RCU interrotti di ritardare i periodi di grazia.
  • CONFIG_RCU_NOCB_CPU: Scarica la gestione delle callback RCU su CPU specifiche, riducendo l'interferenza con le attività in tempo reale.

È inoltre fondamentale disattivare le opzioni di debug che possono causare un'elevata latenza. Disattiva impostazioni come CONFIG_DEBUG_LOCKDEP, CONFIG_DEBUG_PREEMPT, CONFIG_DEBUG_OBJECTS, E CONFIG_SLUB_DEBUG. Sebbene questi strumenti siano utili per lo sviluppo, possono compromettere significativamente gli obiettivi di latenza. Come spiega kernelconfig.io:

""Questa opzione trasforma il kernel in un kernel in tempo reale sostituendo varie primitive di blocco (spinlock, rwlock, ecc.) con varianti preemptible che riconoscono l'ereditarietà della priorità.""

Una volta che il kernel è stato compilato e avviato, confermare che PREEMPT_RT è attivo eseguendo gatto /sys/kernel/tempo reale. Un valore di ritorno di 1 indica successo. È anche possibile verificare controllando "PREEMPT_RT" nell'output di uname -a.

Debug e ottimizzazione delle prestazioni

La messa a punto del kernel è essenziale per ottenere prestazioni ottimali con carichi di lavoro in tempo reale. Un'area chiave da affrontare è meccanismo di limitazione in tempo reale, che riserva 50 ms al secondo per le attività non in tempo reale per impostazione predefinita. Se il carico di lavoro è esclusivamente in tempo reale, è possibile disabilitare questo meccanismo scrivendo -1 per /proc/sys/kernel/sched_rt_runtime_us. Come sottolinea Jan Altenberg, Senior Open Source Consultant presso OSADL:

""Un'attività in tempo reale 'fuori controllo' può mettere a dura prova il sistema. Come meccanismo di protezione, il tempo di esecuzione delle attività in tempo reale può essere limitato impostando un valore in microsecondi in /proc/sys/kernel/sched_rt_runtime_us."‘

Per un determinismo migliorato, isolare specifici core della CPU utilizzando parametri come isolcpus=2,3, rcu_nocbs=2,3, nohz_full=2,3, e impostare irqaffinity=0. In questo modo, i core vengono riservati esclusivamente alle attività in tempo reale.

Per gestire i thread di interrupt, utilizzare grafico strumento. Questi thread in genere vengono eseguiti con un valore predefinito SCHED_FIFO La priorità è 50, ma è possibile modificarla per evitare conflitti con l'applicazione. Ad esempio, per impostare il thread IRQ di una scheda di rete alla priorità 98, utilizzare il comando: chrt -p -f 98.

Dopo aver completato la configurazione, è fondamentale testare e convalidare le prestazioni di latenza. Strumenti come test ciclico può misurare la latenza (ad esempio, testciclico -S -m -p98 -i250), Mentre rtla (Real-time Linux Analysis) aiuta a identificare e analizzare i picchi di latenza. Questi strumenti garantiscono che la configurazione soddisfi le esigenze delle applicazioni in tempo reale.

Applicazioni e vantaggi di PREEMPT_RT

Casi d'uso delle applicazioni in tempo reale

PREEMPT_RT brilla nei sistemi in cui la precisione temporale non è negoziabile. In aerospaziale, garantisce che i controlli di navigazione e di volo funzionino senza ritardi di microsecondi, che potrebbero altrimenti compromettere la sicurezza. Telecomunicazioni Le aziende contano su di esso per gestire l'instradamento dei dati in tempo reale, garantendo chiamate vocali e video fluide ed eliminando picchi di jitter e latenza.

Nel industria automobilistica, è una pietra angolare per i sistemi di controllo dei veicoli, con importanti attori come Continental Automotive che ne supportano l'adozione. In automazione industriale, PREEMPT_RT alimenta i controllori logici programmabili (PLC) e i sistemi SCADA, spesso lavorando insieme a protocolli come EtherCAT per mantenere la sicurezza e l'efficienza negli stabilimenti produttivi. Robotica si affida inoltre ampiamente a questa tecnologia per il controllo preciso degli attuatori e il feedback immediato dei sensori, consentendo ai robot di rispondere immediatamente ai cambiamenti ambientali.

Forse le applicazioni più critiche sono in dispositivi medici, dove la precisione è fondamentale. Dai monitor per pazienti ai robot chirurgici, PREEMPT_RT fornisce le prestazioni deterministiche necessarie per garantire il perfetto funzionamento dei sistemi critici per la vita.

Vantaggi per gli ambienti di hosting

I vantaggi di PREEMPT_RT si estendono agli ambienti di hosting, dove la reattività in tempo reale è altrettanto cruciale. Per VPS e server dedicati, riduce al minimo la latenza consentendo allo scheduler di dare priorità alle attività ad alta priorità rispetto a quelle meno critiche. Ciò garantisce tempi di risposta costanti, che incidono direttamente sull'esperienza utente e sull'affidabilità del servizio.

Il modello di interrupt threaded impedisce che le "tempeste di interrupt" sovraccarichino i sistemi durante le operazioni di I/O pesanti. Con rt_mutex, L'ereditarietà delle priorità garantisce che le attività in background a bassa priorità non blocchino i servizi di hosting critici. I timer ad alta risoluzione consentono una precisione di pianificazione nell'ordine dei microsecondi, riducendo il jitter nelle configurazioni virtualizzate. I provider di hosting, come Serverion, offrono build di kernel personalizzate con PREEMPT_RT, offrendo agli amministratori la flessibilità di ottimizzare le configurazioni per carichi di lavoro specifici. Utilizzando parametri come isolco e affinità, i provider possono dedicare i core della CPU ad attività critiche per le prestazioni, mantenendo isolate le operazioni di sistema di routine.

Conclusione

Questa guida ha approfondito come PREEMPT_RT Trasforma Linux in un sistema operativo in tempo reale, conferendo allo scheduler un controllo pressoché completo. Dalla sua inclusione nei kernel principali a partire da Linux 6.12 (settembre 2024), ha eliminato la necessità di patch esterne su architetture come x86, ARM64 e RISC-V.

Il concetto è semplice: ridurre il più possibile il codice non preemptibile. Convertendo gli spinlock in blocchi sospesi ed eseguendo i gestori di interrupt come thread, le attività ad alta priorità possono preemptire quasi tutte le attività del kernel. Funzionalità come l'ereditarietà della priorità impediscono alle attività a bassa priorità di ritardare le operazioni critiche, mentre l'RCU preemptibile garantisce che anche le sezioni critiche lato lettura non causino ritardi significativi. Sebastian Siewior, il responsabile della manutenzione di PREEMPT_RT, afferma giustamente:

""Tutto il controllo al pianificatore.""

Questo salto tecnico offre vantaggi pratici. Ad esempio, Serverion utilizza build del kernel PREEMPT_RT personalizzate per ottimizzare l'isolamento della CPU e i carichi di lavoro in tempo reale, garantendo tempi di risposta stabili anche in condizioni di intensa pressione I/O.

Ciò che distingue i sistemi in tempo reale non è solo la velocità, ma anche la prevedibilità. PREEMPT_RT riduce al minimo il jitter, garantendo che le attività vengano eseguite esattamente quando necessario. Questo è fondamentale per applicazioni come l'automazione industriale, le telecomunicazioni e i servizi di hosting critici per le prestazioni. Offre il tipo di comportamento deterministico che i kernel standard semplicemente non possono fornire.

Con la sua integrazione nel kernel principale e il supporto di distribuzioni aziendali come Ubuntu Pro (da febbraio 2023), PREEMPT_RT è diventato più accessibile per provider di hosting e amministratori di sistema. Offre le prestazioni affidabili e a bassa latenza richieste per gli ambienti odierni più esigenti e sensibili al fattore tempo.

Domande frequenti

Ho bisogno di PREEMPT_RT o è sufficiente il Linux standard?

Il kernel Linux standard, se combinato con Patch PREEMPT_RT, acquisisce capacità in tempo reale. Questo lo rende una scelta ideale per applicazioni in cui bassa latenza e tempi di risposta costanti sono essenziali. Da solo, tuttavia, il kernel Linux principale potrebbe non essere in grado di soddisfare le rigorose esigenze in tempo reale.

PREEMPT_RT ridurrà la produttività complessiva del mio sistema?

Per ottenere prestazioni in tempo reale, PREEMPT_RT si concentra sulla riduzione del codice kernel non preemptible, contribuendo a migliorare la reattività del sistema. Questo approccio può comportare una leggera riduzione della produttività complessiva, ma garantisce un comportamento coerente e prevedibile, fondamentale per le applicazioni sensibili al fattore tempo. Questo compromesso è intenzionale e fondamentale per soddisfare le esigenze dei sistemi in tempo reale.

Quale obiettivo di latenza è realistico con PREEMPT_RT?

Con PREEMPT_RT, raggiungere una latenza nell'ordine dei millisecondi è un obiettivo realistico sia per i sistemi desktop che per quelli embedded. Tuttavia, le prestazioni effettive dipendono fortemente da quanto bene il sistema è configurato e ottimizzato per soddisfare requisiti specifici. Una configurazione corretta è fondamentale per garantire il livello di reattività desiderato.

Post del blog correlati

it_IT