SDV 中的服務品質排程

SDV 服務品質 (QoS) 排程架構可為 Lifecycle Manager (LM) 管理的服務套件,提供確定性的 CPU 資源分配。平台會將低階 Linux 排程屬性 (政策、優先順序、Nice) 抽象化為邏輯預設值,讓服務開發與車輛系統調整作業清楚分離。這有助於為安全關鍵和時間敏感型工作負載提供必要的運算頻寬,同時系統會限制背景工作,避免不穩定。

角色與職責

SDV 排程模型採用委派責任模式,確保服務可攜性,同時讓原始設備製造商調整系統。

角色 責任 主要成果
SDV 平台 (Google) 定義 sdv_service_bundles_scheduling.proto 架構、實作 LM 強制執行邏輯,並提供 sdv_service_bundles_scheduling 用戶端程式庫。 Protobuf 定義和平台程式庫
原始設備製造商 (系統整合商) 定義每個預設值的具體值,例如特定硬體上的 ELEVATED 意義,並控制全系統設定。 /product/etc/lifecycle_config.textproto
服務開發人員 選取適當的邏輯預設名稱,並在服務套件資訊清單中註冊 scheduling_config.textproto 路徑。 scheduling_config.textprotosdv_service_bundles_manifest.textproto

技術工作流程

  1. 平台整合:OEM 會定義車輛專屬的 lifecycle_config.textproto。這個檔案會建立全系統的排程設定檔 (預設值),並根據目標硬體將這些設定檔對應至具體的 Linux 排程屬性。
  2. 服務套件開發:開發人員會在 APEX 套件中組合 scheduling_config.textproto,建議使用邏輯預設值 (例如 ELEVATED),並定義任何內部執行緒名稱。
  3. 服務套裝組合整合:在車輛整合階段,原始設備製造商會審查開發人員建議的預設設定。OEM 可以保留建議的設定檔或覆寫設定檔,例如將 ELEVATED 服務降級為 NORMAL,以在簽署 APEX 前提升整體系統穩定性。
  4. 執行階段屬性解析:服務啟動時,LM 會從服務的資訊清單中找出授權的預設值,並從 OEM 的系統設定中擷取對應的 Linux 屬性。
  5. 啟動同步和強制執行:LM 會先將已解析的屬性套用至服務程序,再使用信號和繼續通訊協定,發出信號讓服務程序繼續執行。

核心概念

下列概念是 SDV 排程架構的核心。

排程預設設定

排程預設集是管理 SDV 中 QoS 的主要機制。開發人員會依名稱參照預先定義的預設集,而非定義原始的 Linux 排程參數。在執行階段,LM 會將這些邏輯名稱對應至具體的 Linux 排程屬性。

以下是在 lifecycle_config.textproto 中設定的預設集範例:

預設名稱 排程政策 一般好值 常見用途
NORMAL SCHED_OTHER 0 標準服務 (空調、媒體、設定)
ELEVATED SCHED_OTHER -10 核心系統元件和基礎架構
IDLE SCHED_IDLE 19 背景分析和非重大記錄
CUSTOM 使用者定義 -20 (初始) 需要即時政策或親和性的服務

套用預設值時,LM 會使用 setpriority 系統呼叫設定程序範圍的 nice 值。這會影響程序在預設 Linux 完全公平排程器 (CFS) 下發生爭用時,所獲得的相對 CPU 分享量。

權限與安全性

為防止未經授權的優先權提升,SDV 平台採用分層安全模型,以 SELinux 網域和 Linux 功能為基礎。

安全領域

  • untrusted_service_bundle:標準預設集 (NORMALELEVATEDIDLE) 的預設網域。核心會限制這個網域中的程序,防止程序變更自身的排程參數。
  • priority_service_bundle:授予使用預設集的任何服務套裝組合,其中 is_privileged: true 會在全系統 lifecycle_config.textproto 中設定。轉換至這個網域後,程序就會獲得 CAP_SYS_NICE 功能,可自行管理資源分配。

CAP_SYS_NICE 功能

平台會將 CAP_SYS_NICE 功能授予 priority_service_bundle 網域中的程序。這項權限可讓程序執行下列操作:

  • 將自己的 nice 值提升至初始指派值以上。
  • 將排程政策變更為即時課程,例如 SCHED_FIFOSCHED_RR
  • 使用 sched_setaffinity 設定 CPU 親和性。
  • 設定 SCHED_DEADLINE 的專屬期限參數。

將這項功能限制在專屬網域,可限制明確授權的服務中斷,進而保護全系統的排程平衡。

設定指南

本節提供 OEM 和服務開發人員的設定指南。

原始設備製造商指南:系統通用的預設集

OEM 會在 /product/etc/lifecycle_config.textproto 中定義排程設定檔。平台會在 lifecycle_management/config/lifecycle_config.textproto 提供範例,OEM 應根據車輛硬體調整範例。

範例:定義即時預設值

OEM 可能會為安全相關服務定義 CRITICAL 預設值,確保標準應用程式絕不會搶占這些服務的資源:

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

開發人員指南:服務套裝組合設定

服務開發人員建議使用預設值,並視需要在 scheduling_config.textproto 檔案中定義邏輯執行緒名稱。如要讓平台探索到這個檔案,必須在 sdv_service_bundles_manifest.textproto 中註冊檔案路徑。

範例:註冊資訊清單

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

範例:使用標準預設設定

對於大多數服務,在 scheduling_config.textproto 中參照預設名稱就已足夠:

# configs/scheduling_config.textproto
scheduling_preset_name: "ELEVATED"

範例:為服務衍生的工作者執行緒排程

服務開發人員可能會在程式碼中建立額外的工作執行緒,處理特殊工作,例如低延遲感應器資料迴圈。開發人員可以在設定檔中,為這些內部執行緒定義具名的排程屬性。

只有在特權服務使用這項中繼資料為內部工作者執行緒設定屬性時,才應手動套用:

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

系統行為和強制執行

SDV 平台採用嚴格的強制執行模式,會在執行任何服務專屬程式碼前,先啟用排程設定。

啟動同步

為防止服務以錯誤的優先順序執行 (即使是在初始化階段),LM 和 Service Bundle Runner (SBR) 會使用訊號和繼續同步處理通訊協定:

  1. 程序建立:LM 會分支 SBR 程序。此時,SBR 子程序正在執行,但會立即進入封鎖狀態,等待 stdin 上的信號。
  2. 屬性應用程式:子項遭到封鎖時,LM 會使用 setpriority 系統呼叫套用要求的 nice 值,並設定排程政策 (例如 SCHED_IDLE)。
  3. 安全性轉換:LM 會執行 SELinux 網域轉換,將子項移至 untrusted_service_bundlepriority_service_bundle 網域。
  4. 信號:只有在所有參數都成功套用後,LM 才會將單一位元組信號傳送至子項的 stdin
  5. 執行:SBR 接收信號,開始載入服務程式庫並呼叫生命週期方法。

對主執行緒和生命週期的影響

在載入服務程式庫前進行同步處理,平台就能在所有生命週期回呼中,為主要執行緒維持要求的優先順序:

  • onCreate:所有依附元件注入和初始資源分配作業,都會以正確的優先順序執行。
  • onStart:預設集會控管轉換為有效狀態的過程,以及所有初始工作迴圈。
  • onStoponDestroy:平台會以相同優先順序執行清除作業,避免在關機期間中斷重要系統活動。

繫結器執行緒集區和優先順序繼承

平台管理的 Binder 執行緒集區中的執行緒,不會以建立集區的執行緒優先順序執行工作。相反地,如果是同步交易,伺服器執行緒會沿用呼叫端的優先順序。Binder 核心驅動程式會控管這項優先順序沿用機制。

討論串層級微調

需要細微控制的服務套件 (例如即時處理迴圈) 必須手動將設定套用至工作執行緒。請按照下列步驟套用執行緒層級的設定:

  1. 要求特殊權限預設設定 (其中 is_privileged: true 已設定)。
  2. 使用 sdv_service_bundles_scheduling 程式庫中的 get_scheduling_configuration 函式讀取 thread_scheduling_configuration
  3. 使用 sched_setattr 將屬性套用至工作執行緒。

SELinux 和功能強制執行

平台會使用 SELinux 和 CAP_SYS_NICE Linux 功能,強制執行排程預設值:

  • 對於使用 NORMALIDLE 等預設值的服務,排程是由 LM 在啟動期間設定。這些服務沒有 CAP_SYS_NICE 功能,無法變更優先順序或政策。
  • 使用具備特殊權限的預設值 (is_privileged: true) 的服務會獲得 CAP_SYS_NICE 功能。這類服務可視需要手動控管內部執行緒的排程,以執行即時工作。

驗證與範例

如要驗證排程行為,必須結合記錄分析和系統層級的效能評估。SDV 平台提供專屬範例,示範這些技巧。

QoS 排程範例

這個範例位於 samples/qos_scheduling,包含多項效能測試服務,可平行執行並回報進度。

  • PerformanceTesterNormal:使用 NORMAL 預設集執行。
  • PerformanceTesterElevated:使用 ELEVATED 預設集執行。
  • PerformanceTesterRealtime:使用 CUSTOM 預設值,將 SCHED_FIFO 套用至內部工作執行緒。
  • PolicyOffender:診斷服務,會嘗試在使用NORMAL預設設定時設定即時優先順序。這項測試用於驗證平台是否能成功封鎖未經授權的升級。

執行驗證套件

  1. 啟用 QoS 專屬的協調設定:

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

  2. 重新啟動裝置,在各自的排程網域中啟動服務:

    adb reboot

  3. 篩選記錄檔,查看比較效能結果:

    adb logcat | grep sdv_sample_qos_common

    PerformanceTesterElevated 服務回報的已完成工作單元數遠高於 PerformanceTesterNormalEPERM 或 SELinux 拒絕錯誤會記錄在 PolicyOffender 服務的記錄中。

回溯相容性

  • 為確保回溯相容性,如果舊版服務套件在資訊清單中指定 scheduling_config_path,但在設定檔中指定 scheduling_preset_name,系統會自動將其視為具備特殊權限的服務。這項做法可為依賴手動執行緒調整作業的舊版服務保留必要功能 (例如 CAP_SYS_NICE)。
  • 根設定訊息 DeadlineSchedulingConfiguration 預計在日後的版本中重新命名。目前的名稱是舊名,已無法準確反映訊息可處理所有排程類型,而不只是截止日期排程。