Planowanie jakości usług w SDV

Ramy harmonogramowania jakości usług (QoS) SDV zapewniają deterministyczną alokację zasobów procesora dla pakietów usług zarządzanych przez Menedżera cyklu życia (LM). Dzięki wyodrębnieniu atrybutów planowania niskiego poziomu w systemie Linux (zasady, priorytet, nice) do logicznych ustawień wstępnych platforma umożliwia wyraźne oddzielenie rozwoju usług od dostrajania systemu w całym pojeździe. Pomaga to zapewnić niezbędną przepustowość obliczeniową dla zadań o krytycznym znaczeniu dla bezpieczeństwa i zadań wrażliwych na czas, a jednocześnie ogranicza zadania w tle, aby zapobiec niestabilności.

Role i obowiązki

Model planowania SDV opiera się na wzorcu delegowania odpowiedzialności, aby zapewnić przenośność usług, a jednocześnie umożliwić producentowi OEM dostosowanie systemu.

Rola Odpowiedzialność Kluczowy rezultat
Platforma SDV (Google) Definiuje schemat sdv_service_bundles_scheduling.proto, wdraża logikę egzekwowania LM i udostępnia bibliotekę klienta sdv_service_bundles_scheduling. Definicje Protobuf i biblioteki platformy
OEM (integrator systemów) Określa konkretne wartości każdego ustawienia wstępnego, np. co oznacza ELEVATED na konkretnym sprzęcie, i kontroluje konfigurację całego systemu. /product/etc/lifecycle_config.textproto
Deweloper usługi Wybiera odpowiednią logiczną nazwę gotowych ustawień i rejestruje ścieżkę scheduling_config.textproto w manifeście pakietu usług. scheduling_config.textproto i sdv_service_bundles_manifest.textproto

Przepływ pracy technicznej

  1. Integracja z platformą: producent OEM określa lifecycle_config.textproto dla konkretnego pojazdu. Ten plik określa profile planowania w całym systemie (ustawienia wstępne) i mapuje je na konkretne atrybuty planowania w systemie Linux na podstawie sprzętu docelowego.
  2. Tworzenie pakietu usług: deweloper umieszcza scheduling_config.textproto w pakiecie APEX, zalecając logiczne ustawienie wstępne (np. ELEVATED) i definiując wewnętrzne nazwy wątków.
  3. Integracja pakietu usług: podczas fazy integracji z pojazdem producent OEM sprawdza zalecane ustawienie wstępne dewelopera. Producent OEM może zachować zalecany profil lub go zastąpić, np. obniżyć wersję usługi ELEVATED do NORMAL, aby poprawić ogólną stabilność systemu przed podpisaniem pliku APEX.
  4. Rozpoznawanie atrybutów w czasie działania: gdy usługa jest uruchamiana, LM identyfikuje autoryzowane ustawienie wstępne z manifestu usługi i pobiera odpowiednie atrybuty systemu Linux z konfiguracji systemu OEM.
  5. Synchronizacja i egzekwowanie podczas uruchamiania: LM stosuje rozwiązane atrybuty do procesu usługi przed wysłaniem sygnału, aby kontynuować wykonywanie za pomocą protokołu sygnał-i-kontynuuj.

Podstawowe pojęcia

Poniższe koncepcje mają kluczowe znaczenie w ramach planowania SDV.

Gotowe ustawienia planowania

Wstępnie zdefiniowane harmonogramy to podstawowy mechanizm zarządzania jakością usług w SDV. Zamiast definiować surowe parametry planowania w systemie Linux, deweloperzy odwołują się do wstępnie zdefiniowanych ustawień wstępnych według nazwy. W czasie działania LM mapuje te nazwy logiczne na konkretne atrybuty planowania w systemie Linux.

Poniżej przedstawiono przykładowe gotowe ustawienia skonfigurowane w lifecycle_config.textproto:

Nazwa gotowego ustawienia Zasady planowania Typowa wartość nice Typowy przypadek użycia
NORMAL SCHED_OTHER 0 Usługi standardowe (HVAC, multimedia, ustawienia)
ELEVATED SCHED_OTHER -10 Podstawowe komponenty systemu i infrastruktura
IDLE SCHED_IDLE 19 Analityka w tle i logowanie niekrytyczne
CUSTOM Definiowany przez użytkownika -20 (początkowy) Usługi wymagające zasad w czasie rzeczywistym lub pokrewieństwa

Podczas stosowania ustawienia wstępnego menedżer pamięci używa wywołania systemowego setpriority, aby ustawić wartość nice dla całego procesu. Ma to wpływ na względny udział procesora, jaki proces otrzymuje w przypadku konfliktu w ramach domyślnego algorytmu szeregowania CFS w systemie Linux.

Uprawnienia i bezpieczeństwo

Aby zapobiec nieautoryzowanemu zwiększeniu priorytetu, platforma SDV wykorzystuje wielopoziomowy model zabezpieczeń oparty na domenach SELinux i funkcjach systemu Linux.

Domeny zabezpieczeń

  • untrusted_service_bundle: domena domyślna dla standardowych ustawień wstępnych (NORMAL, ELEVATED, IDLE). Jądro ogranicza procesy w tej domenie, uniemożliwiając im zmianę własnych parametrów planowania.
  • priority_service_bundle: przyznawane każdemu pakietowi usług korzystającemu z ustawienia wstępnego, w którym w systemowym lifecycle_config.textproto ustawiono wartość is_privileged: true. Przejście na tę domenę przyznaje procesowi uprawnienie CAP_SYS_NICE i umożliwia mu zarządzanie własną alokacją zasobów.

Uprawnienie CAP_SYS_NICE

Platforma przyznaje procesom w domenie priority_service_bundle uprawnienie CAP_SYS_NICE. To uprawnienie umożliwia procesowi:

  • zwiększyć własną wartość nice ponad początkową wartość przypisaną.
  • zmienić zasady planowania na zajęcia w czasie rzeczywistym, takie jak SCHED_FIFO lub SCHED_RR;
  • Ustaw powiązanie procesora za pomocą sched_setaffinity.
  • Skonfiguruj specjalistyczne parametry terminu dla SCHED_DEADLINE.

Ograniczenie tej funkcji do dedykowanej domeny chroni równowagę planowania w całym systemie, ponieważ ogranicza zakłócenia do usług, które mają wyraźne uprawnienia.

Przewodnik po konfiguracji

Ta sekcja zawiera wskazówki dotyczące konfiguracji zarówno dla producentów OEM, jak i deweloperów usług.

Przewodnik dla producentów OEM: ogólne ustawienia wstępne

Producent OEM definiuje profile harmonogramu w /product/etc/lifecycle_config.textproto. Na platformie znajduje się przykład w lifecycle_management/config/lifecycle_config.textproto, który producenci OEM powinni dostosować do sprzętu pojazdu.

Przykład: definiowanie gotowego ustawienia w czasie rzeczywistym

Producent OEM może zdefiniować CRITICAL dla usług związanych z bezpieczeństwem, które nigdy nie mogą być wyprzedzane przez standardowe aplikacje:

# lifecycle_config.textproto
scheduling_presets {
  name: "CRITICAL"
  is_privileged: true
  thread_scheduling_configuration {
    policy: 1      # SCHED_FIFO
    priority: 80   # High real-time priority
  }
}

Przewodnik dla deweloperów: konfiguracja pakietu usług

Deweloperzy usług zalecają gotowe ustawienia i opcjonalnie definiują nazwy wątków logicznych w pliku scheduling_config.textproto. Aby platforma mogła wykryć ten plik, ścieżka do niego musi być zarejestrowana w usłudze sdv_service_bundles_manifest.textproto.

Przykład: rejestracja pliku manifestu

# sdv_service_bundles_manifest.textproto
service_bundle_entries {
  name: "SensorService"
  scheduling_config_path: "configs/scheduling_config.textproto"
}

Przykład: używanie standardowego ustawienia wstępnego

W przypadku większości usług wystarczy odwołać się do nazwy gotowych ustawień w scheduling_config.textproto:

# configs/scheduling_config.textproto
scheduling_preset_name: "ELEVATED"

Przykład: planowanie wątków roboczych wygenerowanych przez usługę

Deweloper usługi może utworzyć w kodzie dodatkowe wątki robocze do obsługi specjalistycznych zadań, takich jak pętla danych z czujników o niskim poziomie opóźnień. Deweloper może zdefiniować nazwane atrybuty planowania dla tych wątków wewnętrznych w pliku konfiguracyjnym.

Ręczne stosowanie jest możliwe tylko w przypadku usług uprzywilejowanych, które używają tych metadanych do ustawiania właściwości wewnętrznych wątków roboczych:

# 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
  }
}

Działanie systemu i egzekwowanie zasad

Platforma SDV stosuje ścisły model egzekwowania, aby aktywować konfiguracje harmonogramu przed uruchomieniem kodu specyficznego dla usługi.

Synchronizacja przy uruchamianiu

Aby zapobiec uruchamianiu usługi z nieprawidłowym priorytetem (nawet w fazie inicjowania), menedżer LM i moduł Service Bundle Runner (SBR) używają protokołu synchronizacji typu „sygnalizuj i kontynuuj”:

  1. Tworzenie procesu: model językowy rozwidla proces SBR. W tym momencie proces podrzędny SBR jest uruchomiony, ale natychmiast przechodzi w stan zablokowany, oczekując na sygnał na swoim gnieździe stdin.
  2. Zastosowanie atrybutu: gdy dziecko jest zablokowane, LM używa wywołania systemowego setpriority, aby zastosować żądaną wartość nice i skonfigurować zasady planowania (np. SCHED_IDLE).
  3. Przejście związane z bezpieczeństwem: LM przeprowadza przejście domeny SELinux, przenosząc proces podrzędny do domeny untrusted_service_bundle lub priority_service_bundle.
  4. Sygnał: dopiero po zastosowaniu wszystkich parametrów LM wysyła do stdin dziecka 1-bajtowy sygnał.
  5. Wykonanie: SBR odbiera sygnał i rozpoczyna wczytywanie bibliotek usług oraz wywoływanie metod cyklu życia.

Wpływ na główny wątek i cykl życia

Synchronizacja przed wczytaniem bibliotek usług zapewnia platformie zachowanie żądanego priorytetu dla głównego wątku wykonawczego we wszystkich wywołaniach zwrotnych cyklu życia:

  • onCreate: wszystkie wstrzykiwanie zależności i początkowa alokacja zasobów odbywają się z odpowiednim priorytetem.
  • onStart: ustawienie wstępne określa przejście do stanu aktywnego i wszelkie początkowe pętle robocze.
  • onStoponDestroy: platforma wykonuje operacje czyszczenia z tym samym priorytetem, aby zapobiec blokowaniu krytycznych działań systemu podczas zamykania.

Pula wątków Binder i dziedziczenie priorytetu

Wątki w puli wątków Binder zarządzanej przez platformę nie wykonują pracy z priorytetem wątku, który utworzył pulę. W przypadku transakcji synchronicznych wątek serwera dziedziczy priorytet wywołującego. Ten mechanizm dziedziczenia priorytetów jest kontrolowany przez sterownik jądra Binder.

Dostrajanie na poziomie wątku

Pakiety usług wymagające precyzyjnej kontroli (np. pętle przetwarzania w czasie rzeczywistym) muszą ręcznie stosować konfiguracje do swoich wątków roboczych. Aby zastosować konfiguracje na poziomie wątku:

  1. Poproś o gotowe ustawienia z podwyższonymi uprawnieniami (gdzie is_privileged: true jest ustawione).
  2. Użyj funkcji get_scheduling_configuration z biblioteki sdv_service_bundles_scheduling, aby odczytać thread_scheduling_configuration.
  3. Stosuj atrybuty do wątków roboczych za pomocą sched_setattr.

Wymuszanie SELinux i możliwości

Platforma korzysta z SELinux i CAP_SYS_NICE możliwości systemu Linux, aby wymuszać ustawienia harmonogramu:

  • W przypadku usług korzystających z ustawień wstępnych, takich jak NORMAL lub IDLE, harmonogram jest konfigurowany przez LM podczas uruchamiania. Te usługi nie mają CAP_SYS_NICE i nie mogą zmieniać swojego priorytetu ani zasad.
  • Usługi korzystające z uprzywilejowanego ustawienia wstępnego (is_privileged: true) mają przyznaną CAP_SYS_NICE. Dzięki temu mogą ręcznie kontrolować harmonogram wątków wewnętrznych, co jest wymagane w przypadku zadań w czasie rzeczywistym.

Weryfikacja i przykłady

Weryfikacja zachowania harmonogramu wymaga połączenia analizy logów i pomiaru wydajności na poziomie systemu. Platforma SDV udostępnia specjalny przykład, który pokazuje te techniki.

Przykładowy harmonogram QoS

Ten przykład, który znajduje się w samples/qos_scheduling, zawiera kilka usług testowania wydajności zaprojektowanych do równoległego działania i raportowania postępów.

  • PerformanceTesterNormal: działa z gotowymi ustawieniami NORMAL.
  • PerformanceTesterElevated: działa z gotowymi ustawieniami ELEVATED.
  • PerformanceTesterRealtime: używa gotowego ustawienia CUSTOM, aby zastosować SCHED_FIFO do wewnętrznych wątków roboczych.
  • PolicyOffender: usługa diagnostyczna, która próbuje ustawić priorytet w czasie rzeczywistym przy użyciu NORMAL gotowych ustawień. Służy to do sprawdzenia, czy platforma skutecznie blokuje nieautoryzowane podwyższenie uprawnień.

Uruchom pakiet weryfikacyjny

  1. Włącz konfigurację orkiestracji związaną z jakością usług:

    adb shell setprop persist.sdv.orchestrator_config_path /etc/orch/vm_qos_scheduling_orch_config.textproto

  2. Uruchom ponownie urządzenie, aby uruchomić usługi w odpowiednich domenach harmonogramowania:

    adb reboot

  3. Filtruj dzienniki, aby wyświetlić wyniki porównawczej skuteczności:

    adb logcat | grep sdv_sample_qos_common

    Usługa PerformanceTesterElevated zgłasza znacznie więcej ukończonych jednostek pracy niż usługa PerformanceTesterNormal. W logach usługi PolicyOffender znajdują się błędy EPERM lub błędy odmowy SELinux.

Zgodność wsteczna

  • Ze względu na zgodność wsteczną każdy starszy pakiet usług, który w pliku manifestu określa wartość scheduling_config_path, ale w pliku konfiguracyjnym nie określa wartości scheduling_preset_name, jest automatycznie traktowany jako usługa uprzywilejowana. Zachowuje to niezbędne możliwości (np. CAP_SYS_NICE) w przypadku starszych usług, które opierają się na ręcznym dostrajaniu wątków.
  • W przyszłej wersji planujemy zmienić nazwę wiadomości konfiguracji głównej DeadlineSchedulingConfiguration. Obecna nazwa jest historyczna i nie odzwierciedla już faktu, że wiadomość obsługuje wszystkie typy planowania, a nie tylko planowanie terminów.