Il framework di pianificazione della qualità del servizio (QoS) di SDV fornisce un'allocazione deterministica delle risorse CPU per i bundle di servizi gestiti da Lifecycle Manager (LM). Astrattendo gli attributi di pianificazione Linux di basso livello (Policy, Priority, Nice) in preset logici, la piattaforma consente una netta separazione tra lo sviluppo dei servizi e l'ottimizzazione del sistema a livello di veicolo. Ciò contribuisce a fornire la larghezza di banda di calcolo necessaria per i carichi di lavoro mission critical e sensibili al tempo, mentre il sistema limita le attività in background per evitare l'instabilità.
Ruoli e responsabilità
Il modello di pianificazione SDV segue un pattern di responsabilità delegata per garantire che i servizi rimangano portatili, consentendo al contempo all'OEM di ottimizzare il sistema.
| Ruolo | Responsabilità | Prodotto principale |
|---|---|---|
| Piattaforma SDV (Google) | Definisce lo schema sdv_service_bundles_scheduling.proto, implementa la logica di applicazione LM e fornisce la libreria client sdv_service_bundles_scheduling. |
Definizioni Protobuf e librerie della piattaforma |
| OEM (integratore di sistemi) | Definisce i valori concreti per ogni preset, ad esempio cosa significa ELEVATED su hardware specifico, e controlla la configurazione a livello di sistema. |
/product/etc/lifecycle_config.textproto |
| Sviluppatore di servizi | Seleziona il nome del preset logico appropriato e registra il percorso scheduling_config.textproto nel manifest del bundle di servizi. |
scheduling_config.textproto e sdv_service_bundles_manifest.textproto |
Flusso di lavoro tecnico
- Integrazione della piattaforma: l'OEM definisce
lifecycle_config.textprotospecifico per il veicolo. Questo file stabilisce i profili di pianificazione a livello di sistema (preset) e li mappa agli attributi di pianificazione Linux concreti in base all'hardware di destinazione. - Sviluppo del bundle di servizi: lo sviluppatore raggruppa un
scheduling_config.textprotoall'interno del pacchetto APEX, consigliando un preset logico (ad esempioELEVATED) e definendo eventuali nomi di thread interni. - Integrazione del bundle di servizi: durante la fase di integrazione del veicolo, l'OEM esamina il preset consigliato dallo sviluppatore. L'OEM può mantenere il profilo consigliato o sostituirlo, ad esempio eseguire il downgrade di un servizio
ELEVATEDaNORMAL, per migliorare la stabilità complessiva del sistema prima di firmare l'APEX. - Risoluzione degli attributi di runtime: quando viene avviato un servizio, LM identifica il preset autorizzato dal manifest del servizio e recupera gli attributi Linux corrispondenti dalla configurazione di sistema dell'OEM.
- Sincronizzazione e applicazione all'avvio: LM applica gli attributi risolti al processo del servizio prima di segnalare di continuare l'esecuzione utilizzando il protocollo signal-and-continue.
Concetti principali
I seguenti concetti sono fondamentali per il framework di pianificazione SDV.
Preset di pianificazione
I preset di pianificazione sono il meccanismo principale per la gestione della QoS in SDV. Anziché definire i parametri di pianificazione Linux non elaborati, gli sviluppatori fanno riferimento ai preset predefiniti per nome. In fase di runtime, LM mappa questi nomi logici agli attributi di pianificazione Linux concreti.
I seguenti preset sono configurati come esempio in lifecycle_config.textproto:
| Nome preset | Policy di pianificazione | Valore nice tipico | Caso d'uso tipico |
|---|---|---|---|
NORMAL |
SCHED_OTHER |
0 |
Servizi standard (HVAC, media, impostazioni) |
ELEVATED |
SCHED_OTHER |
-10 |
Componenti e infrastruttura di sistema principali |
IDLE |
SCHED_IDLE |
19 |
Analisi in background e logging non critico |
CUSTOM |
Definito dall'utente | -20 (iniziale) |
Servizi che richiedono policy o affinità in tempo reale |
Quando applica un preset, LM utilizza la chiamata di sistema setpriority per impostare il valore nice a livello di processo. Ciò influisce sulla quota di CPU relativa che il processo riceve durante la contesa con lo scheduler CFS (Completely Fair Scheduler) predefinito di Linux.
Privilegi e sicurezza
Per impedire l'escalation non autorizzata della priorità, la piattaforma SDV utilizza un modello di sicurezza a livelli basato su domini SELinux e funzionalità Linux.
Domini di sicurezza
untrusted_service_bundle: il dominio predefinito per i preset standard (NORMAL,ELEVATED,IDLE). Il kernel limita i processi in questo dominio, impedendo loro di modificare i propri parametri di pianificazione.priority_service_bundle: concesso a qualsiasi bundle di servizi che utilizza un preset in cuiis_privileged: trueè impostato inlifecycle_config.textprotoa livello di sistema. La transizione a questo dominio concede al processo la funzionalitàCAP_SYS_NICE, consentendogli di gestire la propria allocazione delle risorse.
Funzionalità CAP_SYS_NICE
La piattaforma concede la funzionalità CAP_SYS_NICE ai processi nel dominio priority_service_bundle. Questa autorizzazione consente a un processo di eseguire le seguenti operazioni:
- Aumentare il proprio valore
niceoltre l'assegnazione iniziale. - Modificare la policy di pianificazione in classi in tempo reale come
SCHED_FIFOoSCHED_RR. - Impostare l'affinità della CPU utilizzando
sched_setaffinity. - Configurare i parametri di scadenza specializzati per
SCHED_DEADLINE.
La limitazione di questa funzionalità a un dominio dedicato protegge l'equilibrio della pianificazione a livello di sistema limitando le interruzioni ai servizi autorizzati in modo esplicito.
Guida alla configurazione
Questa sezione fornisce indicazioni sulla configurazione sia per gli OEM sia per gli sviluppatori di servizi.
Guida per gli OEM: preset a livello di sistema
L'OEM definisce i profili di pianificazione in /product/etc/lifecycle_config.textproto. La piattaforma fornisce un esempio in lifecycle_management/config/lifecycle_config.textproto che gli OEM devono modificare in base all'hardware del veicolo.
Esempio: definire un preset in tempo reale
Un OEM potrebbe definire un preset CRITICAL per i servizi correlati alla sicurezza che non devono mai essere preempted dalle applicazioni standard:
# lifecycle_config.textproto
scheduling_presets {
name: "CRITICAL"
is_privileged: true
thread_scheduling_configuration {
policy: 1 # SCHED_FIFO
priority: 80 # High real-time priority
}
}
Guida per gli sviluppatori: configurazione del bundle di servizi
Gli sviluppatori di servizi consigliano un preset e, facoltativamente, definiscono i nomi dei thread logici in un file scheduling_config.textproto. Per essere rilevato dalla piattaforma, il percorso di questo file deve essere registrato in sdv_service_bundles_manifest.textproto.
Esempio: registrazione del manifest
# sdv_service_bundles_manifest.textproto
service_bundle_entries {
name: "SensorService"
scheduling_config_path: "configs/scheduling_config.textproto"
}
Esempio: utilizzare un preset standard
Per la maggior parte dei servizi, è sufficiente fare riferimento a un nome di preset in scheduling_config.textproto:
# configs/scheduling_config.textproto
scheduling_preset_name: "ELEVATED"
Esempio: pianificazione per i thread worker generati dal servizio
Uno sviluppatore di servizi potrebbe creare thread worker aggiuntivi nel codice per gestire attività specializzate, ad esempio un loop di dati dei sensori a bassa latenza. Lo sviluppatore può definire gli attributi di pianificazione denominati per questi thread interni nel file di configurazione.
Utilizza l'applicazione manuale solo nei servizi con privilegi che utilizzano questi metadati per impostare le proprietà dei thread worker interni:
# configs/scheduling_config.textproto
scheduling_preset_name: "CUSTOM"
# Map of logical thread names to their attributes (propagated as metadata)
thread_scheduling_configuration {
key: "sensor-processing-thread"
value {
policy: 1 # SCHED_FIFO
priority: 50
cpu_affinity_ids: [2, 3] # Pin to specific cores
}
}
Comportamento e applicazione del sistema
La piattaforma SDV utilizza un modello di applicazione rigoroso per attivare le configurazioni di pianificazione prima di eseguire qualsiasi codice specifico del servizio.
Sincronizzazione all'avvio
Per impedire l'esecuzione di un servizio con una priorità errata (anche durante la fase di inizializzazione), LM e Service Bundle Runner (SBR) utilizzano un protocollo di sincronizzazione signal-and-continue:
- Creazione del processo: LM esegue il fork del processo SBR. A questo punto, il processo figlio SBR è in esecuzione, ma entra immediatamente in uno stato bloccato, in attesa di un segnale sul relativo
stdin. - Applicazione degli attributi: mentre il figlio è bloccato, LM utilizza la chiamata di sistema
setpriorityper applicare il valorenicerichiesto e configura la policy di pianificazione (ad esempioSCHED_IDLE). - Transizione di sicurezza: LM esegue la transizione del dominio SELinux, spostando il figlio nel dominio
untrusted_service_bundleopriority_service_bundle. - Segnale: solo dopo che tutti i parametri sono stati applicati correttamente, LM invia un segnale di un byte a
stdindel figlio. - Esecuzione: SBR riceve il segnale e inizia a caricare le librerie di servizi e a chiamare i metodi del ciclo di vita.
Impatto sul thread principale e sul ciclo di vita
Sincronizzando prima di caricare le librerie di servizi, la piattaforma mantiene la priorità richiesta per il thread di esecuzione principale in tutti i callback del ciclo di vita:
onCreate: tutta l'iniezione delle dipendenze e l'allocazione iniziale delle risorse avvengono con la priorità corretta.onStart: il preset regola la transizione allo stato attivo e tutti i loop di lavoro iniziali.onStopeonDestroy: la piattaforma esegue le operazioni di pulizia con la stessa priorità per evitare di bloccare le attività di sistema critiche durante l'arresto.
Pool di thread Binder ed ereditarietà della priorità
I thread nel pool di thread Binder gestito dalla piattaforma non eseguono il lavoro con la priorità del thread che ha creato il pool. Al contrario, per le transazioni sincrone, il thread del server eredita la priorità del chiamante. Il driver del kernel Binder controlla questo meccanismo di ereditarietà della priorità.
Ottimizzazione a livello di thread
I bundle di servizi che richiedono un controllo granulare (ad esempio, i loop di elaborazione in tempo reale) devono applicare manualmente le configurazioni ai thread worker. Per applicare le configurazioni a livello di thread:
- Richiedi un preset con privilegi (in cui
is_privileged: trueè impostato). - Utilizza la funzione
get_scheduling_configurationdella libreriasdv_service_bundles_schedulingper leggerethread_scheduling_configuration. - Applica gli attributi ai thread worker utilizzando
sched_setattr.
Applicazione di SELinux e delle funzionalità
La piattaforma utilizza SELinux e la funzionalità Linux CAP_SYS_NICE per applicare i preset di pianificazione:
- Per i servizi che utilizzano preset come
NORMALoIDLE, la pianificazione viene configurata da LM durante l'avvio. Questi servizi non hanno la funzionalitàCAP_SYS_NICEe non possono modificare la priorità o la policy. - Ai servizi che utilizzano un preset con privilegi (
is_privileged: true) viene concessa la funzionalitàCAP_SYS_NICE. Ciò consente loro di controllare manualmente la pianificazione dei thread interni, come richiesto per le attività in tempo reale.
Verifica ed esempi
La verifica del comportamento di pianificazione richiede una combinazione di analisi dei log e misurazione del rendimento a livello di sistema. La piattaforma SDV fornisce un esempio dedicato per illustrare queste tecniche.
L'esempio di pianificazione QoS
Questo esempio, che si trova in samples/qos_scheduling, include diversi servizi di test del rendimento progettati per essere eseguiti in parallelo e segnalare i loro progressi.
PerformanceTesterNormal: viene eseguito con il presetNORMAL.PerformanceTesterElevated: viene eseguito con il presetELEVATED.PerformanceTesterRealtime: utilizza il presetCUSTOMper applicareSCHED_FIFOai thread worker interni.PolicyOffender: un servizio di diagnostica che tenta di impostare una priorità in tempo reale utilizzando un presetNORMAL. Viene utilizzato per verificare che la piattaforma blocchi correttamente l'escalation non autorizzata.
Esegui la suite di verifica
Attiva la configurazione di orchestrazione specifica per QoS:
adb shell setprop persist.sdv.orchestrator_config_path /etc/orch/vm_qos_scheduling_orch_config.textprotoRiavvia il dispositivo per avviare i servizi nei rispettivi domini di pianificazione:
adb rebootFiltra i log per visualizzare i risultati comparativi del rendimento:
adb logcat | grep sdv_sample_qos_commonIl servizio
PerformanceTesterElevatedsegnala un numero di unità di lavoro completate significativamente più elevato rispetto aPerformanceTesterNormal. I log del servizioPolicyOffenderincludono gli errori di negazioneEPERMo SELinux.
Compatibilità con le versioni precedenti
- Per la compatibilità con le versioni precedenti, qualsiasi bundle di servizi legacy che specifica un
scheduling_config_pathnel manifest, ma non specifica unscheduling_preset_namenel file di configurazione, viene trattato automaticamente come un servizio con privilegi. In questo modo vengono mantenute le funzionalità necessarie (ad esempioCAP_SYS_NICE) per i servizi precedenti che si basano sull'ottimizzazione manuale dei thread. - Il messaggio di configurazione principale
DeadlineSchedulingConfigurationverrà rinominato in una release futura. Il nome attuale è storico e non riflette più con precisione il fatto che il messaggio gestisce tutti i tipi di pianificazione, non solo la pianificazione delle scadenze.