Le framework de planification de la qualité de service (QoS) SDV fournit une allocation déterministe des ressources de processeur pour les bundles de services gérés par le gestionnaire de cycle de vie (LM). En abstrayant les attributs de planification Linux de bas niveau (stratégie, priorité, nice) dans des préréglages logiques, la plate-forme permet une séparation claire entre le développement de services et le réglage du système à l'échelle du véhicule. Cela permet de fournir la bande passante de calcul nécessaire aux charges de travail critiques pour la sécurité et sensibles au temps, tandis que le système limite les tâches en arrière-plan pour éviter l'instabilité.
Rôles et responsabilités
Le modèle de planification SDV suit un modèle de responsabilité déléguée pour s'assurer que les services restent portables tout en permettant à l'OEM de régler le système.
| Rôle | Responsabilité | Livrable clé |
|---|---|---|
| Plate-forme SDV (Google) | Définit le schéma sdv_service_bundles_scheduling.proto, implémente la logique d'application LM et fournit la bibliothèque cliente sdv_service_bundles_scheduling. |
Définitions Protobuf et bibliothèques de plate-forme |
| OEM (intégrateur système) | Définit les valeurs concrètes pour chaque préréglage, par exemple ce que signifie ELEVATED sur un matériel spécifique, et contrôle la configuration à l'échelle du système. |
/product/etc/lifecycle_config.textproto |
| Développeur de services | Sélectionne le nom de préréglage logique approprié et enregistre le chemin d'accès scheduling_config.textproto dans le fichier manifeste du bundle de services. |
scheduling_config.textproto et sdv_service_bundles_manifest.textproto |
Workflow technique
- Intégration de la plate-forme : l'OEM définit le
lifecycle_config.textprotospécifique au véhicule. Ce fichier établit les profils de planification (préréglages) à l'échelle du système et les mappe à des attributs de planification Linux concrets en fonction du matériel cible. - Développement de bundles de services : le développeur regroupe un
scheduling_config.textprotodans son package APEX, en recommandant un préréglage logique (par exemple,ELEVATED) et en définissant les noms de threads internes. - Intégration du bundle de services : lors de la phase d'intégration du véhicule, l'OEM examine le préréglage recommandé par le développeur. L'OEM peut conserver le profil recommandé ou le remplacer, par exemple en rétrogradant un service
ELEVATEDenNORMAL, pour améliorer la stabilité globale du système avant de signer l'APEX. - Résolution des attributs d'exécution : lorsqu'un service est démarré, le LM identifie le préréglage autorisé à partir du fichier manifeste du service et récupère les attributs Linux correspondants à partir de la configuration système de l'OEM.
- Synchronisation et application au démarrage : le LM applique les attributs résolus au processus de service avant de lui signaler de poursuivre l'exécution à l'aide du protocole de signalisation et de poursuite.
Concepts fondamentaux
Les concepts suivants sont au cœur du framework de planification SDV.
Préréglages de programmation
Les préréglages de planification sont le principal mécanisme de gestion de la qualité de service dans SDV. Au lieu de définir des paramètres de planification Linux bruts, les développeurs font référence à des préréglages prédéfinis par leur nom. Lors de l'exécution, le LM mappe ces noms logiques à des attributs de planification Linux concrets.
Voici les préréglages configurés à titre d'exemple dans lifecycle_config.textproto :
| Nom du préréglage | Règle de planification | Valeur Nice typique | Cas d'utilisation typique |
|---|---|---|---|
NORMAL |
SCHED_OTHER |
0 |
Services standards (CVC, multimédia, paramètres) |
ELEVATED |
SCHED_OTHER |
-10 |
Composants et infrastructure du système principal |
IDLE |
SCHED_IDLE |
19 |
Analytics en arrière-plan et journalisation non critique |
CUSTOM |
Valeur personnalisée | -20 (initial) |
Services nécessitant des règles ou une affinité en temps réel |
Lors de l'application d'un préréglage, le LM utilise l'appel système setpriority pour définir la valeur nice à l'échelle du processus. Cela affecte la part relative de processeur que le processus reçoit en cas de conflit sous le planificateur CFS (Completely Fair Scheduler) Linux par défaut.
Privilèges et sécurité
Pour éviter toute escalade de priorité non autorisée, la plate-forme SDV utilise un modèle de sécurité à plusieurs niveaux basé sur les domaines SELinux et les capacités Linux.
Domaines de sécurité
untrusted_service_bundle: domaine par défaut pour les préréglages standards (NORMAL,ELEVATED,IDLE). Le noyau limite les processus de ce domaine, les empêchant de modifier leurs propres paramètres de planification.priority_service_bundle: accordé à tout bundle de services utilisant un préréglage oùis_privileged: trueest défini danslifecycle_config.textprotoà l'échelle du système. La transition vers ce domaine accorde au processus la capacitéCAP_SYS_NICEet lui permet de gérer sa propre allocation de ressources.
CAP_SYS_NICE
La plate-forme accorde la fonctionnalité CAP_SYS_NICE aux processus du domaine priority_service_bundle. Cette autorisation permet à un processus d'effectuer les opérations suivantes :
- Augmenter sa propre valeur
niceau-delà de son attribution initiale. - Modifiez sa règle de planification pour les cours en temps réel, comme
SCHED_FIFOouSCHED_RR. - Définissez l'affinité du processeur à l'aide de
sched_setaffinity. - Configurez des paramètres de délai spécialisés pour
SCHED_DEADLINE.
En limitant cette fonctionnalité à un domaine dédié, vous protégez l'équilibre de la planification à l'échelle du système en limitant les perturbations aux services explicitement autorisés.
Guide de configuration
Cette section fournit des conseils de configuration aux OEM et aux développeurs de services.
Guide de l'OEM : préréglages à l'échelle du système
L'OEM définit les profils de programmation dans /product/etc/lifecycle_config.textproto. La plate-forme fournit un exemple à l'adresse lifecycle_management/config/lifecycle_config.textproto que les OEM doivent ajuster en fonction du matériel du véhicule.
Exemple : Définir un préréglage en temps réel
Un OEM peut définir un préréglage CRITICAL pour les services liés à la sécurité qui ne doivent jamais être interrompus par des applications standards :
# lifecycle_config.textproto
scheduling_presets {
name: "CRITICAL"
is_privileged: true
thread_scheduling_configuration {
policy: 1 # SCHED_FIFO
priority: 80 # High real-time priority
}
}
Guide du développeur : configuration du bundle de services
Les développeurs de services recommandent un préréglage et définissent éventuellement des noms de threads logiques dans un fichier scheduling_config.textproto. Pour que la plate-forme puisse le trouver, le chemin d'accès à ce fichier doit être enregistré dans sdv_service_bundles_manifest.textproto.
Exemple : Enregistrement du fichier manifeste
# sdv_service_bundles_manifest.textproto
service_bundle_entries {
name: "SensorService"
scheduling_config_path: "configs/scheduling_config.textproto"
}
Exemple : Utiliser un préréglage standard
Pour la plupart des services, il suffit de référencer un nom prédéfini dans scheduling_config.textproto :
# configs/scheduling_config.textproto
scheduling_preset_name: "ELEVATED"
Exemple : Planification des threads de worker générés par le service
Un développeur de services peut créer des threads de nœud de calcul supplémentaires dans son code pour gérer des tâches spécialisées, comme une boucle de données de capteur à faible latence. Le développeur peut définir des attributs de planification nommés pour ces threads internes dans le fichier de configuration.
N'utilisez l'application manuelle que dans les services privilégiés qui utilisent ces métadonnées pour définir les propriétés de leurs threads de worker internes :
# 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
}
}
Comportement et application du système
La plate-forme SDV utilise un modèle d'application strict pour activer les configurations de planification avant d'exécuter tout code spécifique au service.
Synchronisation au démarrage
Pour empêcher un service de s'exécuter à une priorité incorrecte (même pendant sa phase d'initialisation), le LM et le Service Bundle Runner (SBR) utilisent un protocole de synchronisation signal-and-continue :
- Création du processus : le LM duplique le processus SBR. À ce stade, le processus enfant SBR est en cours d'exécution, mais passe immédiatement à l'état bloqué, en attente d'un signal sur son
stdin. - Application des attributs : lorsque l'enfant est bloqué, le LM utilise l'appel système
setprioritypour appliquer la valeurnicedemandée et configure la règle de planification (par exemple,SCHED_IDLE). - Transition de sécurité : le LM effectue la transition de domaine SELinux, en déplaçant l'enfant vers le domaine
untrusted_service_bundleoupriority_service_bundle. - Signal : Ce n'est qu'une fois que tous les paramètres ont été appliqués avec succès que le LM envoie un signal d'un octet au
stdinde l'enfant. - Exécution : le SBR reçoit le signal et commence à charger les bibliothèques de services et à appeler les méthodes de cycle de vie.
Impact sur le thread principal et le cycle de vie
En synchronisant avant de charger les bibliothèques de services, la plate-forme maintient la priorité demandée pour le thread d'exécution principal dans tous les rappels de cycle de vie :
onCreate: l'injection de dépendances et l'allocation initiale des ressources se produisent à la priorité appropriée.onStart: le préréglage régit la transition vers l'état actif et toutes les boucles de travail initiales.onStopetonDestroy: la plate-forme effectue des opérations de nettoyage à la même priorité pour éviter de priver les activités système critiques lors de l'arrêt.
Pool de threads Binder et héritage de priorité
Les threads du pool de threads Binder géré par la plate-forme n'exécutent pas le travail avec la priorité du thread qui a créé le pool. En revanche, pour les transactions synchrones, le thread du serveur hérite de la priorité de l'appelant. Le pilote de noyau Binder contrôle ce mécanisme d'héritage de priorité.
Affinage au niveau du thread
Les bundles de services nécessitant un contrôle précis (par exemple, les boucles de traitement en temps réel) doivent appliquer manuellement les configurations à leurs threads de nœud de calcul. Pour appliquer des configurations au niveau du thread, procédez comme suit :
- Demandez un préréglage privilégié (où
is_privileged: trueest défini). - Utilisez la fonction
get_scheduling_configurationde la bibliothèquesdv_service_bundles_schedulingpour lirethread_scheduling_configuration. - Appliquez des attributs aux threads de nœud de calcul à l'aide de
sched_setattr.
Application de SELinux et des fonctionnalités
La plate-forme utilise SELinux et la fonctionnalité Linux CAP_SYS_NICE pour appliquer les préréglages de planification :
- Pour les services utilisant des préréglages tels que
NORMALouIDLE, la planification est configurée par le LM au démarrage. Ces services ne disposent pas de la fonctionnalitéCAP_SYS_NICEet ne peuvent pas modifier leur priorité ni leur règle. - Les services utilisant un préréglage privilégié (
is_privileged: true) bénéficient de la fonctionnalitéCAP_SYS_NICE. Cela leur permet de contrôler manuellement la planification de leurs threads internes, comme l'exigent les tâches en temps réel.
Validation et exemples
Pour vérifier le comportement de planification, vous devez combiner l'analyse des journaux et la mesure des performances au niveau du système. La plate-forme SDV fournit un exemple dédié pour illustrer ces techniques.
Exemple de planification QoS
Situé dans samples/qos_scheduling, cet exemple inclut plusieurs services de test des performances conçus pour s'exécuter en parallèle et rendre compte de leur progression.
PerformanceTesterNormal: s'exécute avec le préréglageNORMAL.PerformanceTesterElevated: s'exécute avec le préréglageELEVATED.PerformanceTesterRealtime: utilise le préréglageCUSTOMpour appliquerSCHED_FIFOà ses threads de worker internes.PolicyOffender: service de diagnostic qui tente de définir une priorité en temps réel lors de l'utilisation d'un préréglageNORMAL. Cela permet de vérifier que la plate-forme bloque bien les escalades non autorisées.
Exécuter la suite de validation
Activez la configuration d'orchestration spécifique à la qualité de service :
adb shell setprop persist.sdv.orchestrator_config_path /etc/orch/vm_qos_scheduling_orch_config.textprotoRedémarrez l'appareil pour démarrer les services dans leurs domaines de planification respectifs :
adb rebootFiltrez les journaux pour afficher les résultats comparatifs des performances :
adb logcat | grep sdv_sample_qos_commonLe service
PerformanceTesterElevatedsignale un nombre d'unités de travail effectuées nettement plus élevé quePerformanceTesterNormal. Les erreursEPERMou de refus SELinux sont incluses dans les journaux du servicePolicyOffender.
Rétrocompatibilité.
- Pour assurer la rétrocompatibilité, tout ancien bundle de services qui spécifie un
scheduling_config_pathdans son fichier manifeste, mais ne spécifie pas descheduling_preset_namedans le fichier de configuration, est automatiquement traité comme un service privilégié. Cela préserve les capacités nécessaires (par exemple,CAP_SYS_NICE) pour les anciens services qui s'appuient sur le réglage manuel des threads. - Le message de configuration racine
DeadlineSchedulingConfigurationdoit être renommé dans une prochaine version. Le nom actuel est historique et ne reflète plus précisément le fait que le message gère tous les types de programmation, et pas seulement la programmation des échéances.