SDV 服务质量 (QoS) 调度框架为生命周期管理器 (LM) 管理的服务软件包提供确定性的 CPU 资源分配。通过将低级别 Linux 调度属性(政策、优先级、Nice)抽象为逻辑预设,该平台实现了服务开发与车辆级系统调优之间的清晰分离。这有助于为安全关键型和时间敏感型工作负载提供必要的计算带宽,同时系统会限制后台任务以防止不稳定。
角色和职责
SDV 调度模型遵循委托责任模式,有助于确保服务保持可移植性,同时允许 OEM 调优系统。
| 角色 | 职责 | 主要交付成果 |
|---|---|---|
| SDV 平台 (Google) | 定义 sdv_service_bundles_scheduling.proto 架构,实现 LM 执行逻辑,并提供 sdv_service_bundles_scheduling 客户端库。 |
Protobuf 定义和平台库 |
| OEM(系统集成商) | 为每个预设定义具体值,例如 ELEVATED 在特定硬件上的含义,并控制系统级配置。 |
/product/etc/lifecycle_config.textproto |
| 服务开发者 | 选择适当的逻辑预设名称,并在服务软件包清单中注册 scheduling_config.textproto 路径。 |
scheduling_config.textproto 和 sdv_service_bundles_manifest.textproto |
技术工作流
- 平台集成: OEM 定义车辆专用的
lifecycle_config.textproto。此文件建立系统级调度配置文件(预设),并根据目标硬件将其映射到具体的 Linux 调度属性。 - 服务软件包开发: 开发者在其 APEX 软件包中捆绑
scheduling_config.textproto,推荐逻辑预设(例如ELEVATED),并定义任何内部线程名称。 - 服务软件包集成: 在车辆集成阶段,OEM 会审核开发者推荐的预设。OEM 可以保留推荐的配置文件,也可以替换它,例如将
ELEVATED服务降级为NORMAL,以在签署 APEX 之前提高整体系统稳定性。 - 运行时属性解析: 启动服务后,LM 会从服务的清单中识别授权的预设,并从 OEM 的系统配置中检索相应的 Linux 属性。
- 启动同步和执行: LM 会将解析的属性应用于服务进程,然后使用信号和继续协议向其发送信号以继续执行。
核心概念
以下概念是 SDV 调度框架的核心。
调度预设
调度预设是管理 SDV 中 QoS 的主要机制。开发者无需定义原始 Linux 调度参数,而是按名称引用预定义的预设。在运行时,LM 会将这些逻辑名称映射到具体的 Linux 调度属性。
以下预设在 lifecycle_config.textproto 中配置为示例:
| 预设名称 | 调度政策 | 典型 Nice 值 | 典型应用场景 |
|---|---|---|---|
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:标准预设(NORMAL、ELEVATED、IDLE)的默认网域。内核会限制此网域中的进程,阻止它们更改自己的调度参数。priority_service_bundle:授予在系统级lifecycle_config.textproto中设置了is_privileged: true的任何使用预设的服务软件包。转换到此网域会授予进程CAP_SYS_NICE功能,使其能够管理自己的资源分配。
CAP_SYS_NICE 功能
该平台会向 priority_service_bundle 网域中的进程授予 CAP_SYS_NICE 功能。此权限允许进程执行以下操作:
- 将其自己的
nice值提升到初始分配值以上。 - 将其调度政策更改为实时类,例如
SCHED_FIFO或SCHED_RR。 - 使用
sched_setaffinity设置 CPU 亲和性。 - 为
SCHED_DEADLINE配置专用截止时间参数。
将此功能限制为专用网域,可通过限制对明确授权服务的干扰来保护系统级调度平衡。
配置指南
本部分为 OEM 和服务开发者提供配置指南。
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 和服务软件包运行程序 (SBR) 使用信号和继续同步协议:
- 进程创建: LM 会派生 SBR 进程。此时,SBR 子进程正在运行,但会立即进入阻塞状态,等待其
stdin上的信号。 - 属性应用: 在子进程被阻塞期间,LM 会使用
setpriority系统调用来应用请求的nice值,并配置调度政策(例如SCHED_IDLE)。 - 安全转换: LM 执行 SELinux 网域转换,将子进程移至
untrusted_service_bundle或priority_service_bundle网域。 - 信号: 只有在成功应用所有参数后,LM 才会向子进程的
stdin发送单字节信号。 - 执行: SBR 接收信号并开始加载服务库和调用生命周期方法。
对主线程和生命周期的影响
通过在加载服务库之前进行同步,该平台会在所有生命周期回调中为主执行线程保持请求的优先级:
onCreate:所有依赖项注入和初始资源分配都以正确的优先级进行。onStart:预设控制向活跃状态的转换和任何初始工作循环。onStop和onDestroy:该平台以相同的优先级执行清理操作,以防止在关机期间关键系统活动被饿死。
Binder 线程池和优先级继承
平台管理的 Binder 线程池中的线程不会以创建该池的线程的优先级执行工作。相反,对于同步事务,服务器线程会继承调用方的优先级。Binder 内核驱动程序控制着此优先级继承机制。
线程级微调
需要精细控制(例如实时处理循环)的服务软件包必须手动将其配置应用于其工作器线程。请按照以下步骤应用线程级配置:
- 请求特权预设(其中
is_privileged: true已设置)。 - 使用
sdv_service_bundles_scheduling库中的get_scheduling_configuration函数读取thread_scheduling_configuration。 - 使用
sched_setattr将属性应用于工作器线程。
SELinux 和功能执行
该平台使用 SELinux 和 CAP_SYS_NICE Linux 功能来执行调度预设:
- 对于使用
NORMAL或IDLE等预设的服务,调度由 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预设时设置实时优先级。这用于验证平台是否成功阻止未经授权的升级。
运行验证套件
启用特定于 QoS 的编排配置:
adb shell setprop persist.sdv.orchestrator_config_path /etc/orch/vm_qos_scheduling_orch_config.textproto重启设备以在其各自的调度网域中启动服务:
adb reboot过滤日志以查看比较性能结果:
adb logcat | grep sdv_sample_qos_common与
PerformanceTesterNormal相比,PerformanceTesterElevated服务报告的已完成工作单元明显更高。PolicyOffender服务的日志中包含EPERM或 SELinux 拒绝错误。
向后兼容性
- 为了实现向后兼容性,任何在其清单中指定了
scheduling_config_path但未 在配置文件中指定scheduling_preset_name的旧版服务软件包都会自动被视为特权服务。这保留了依赖手动线程调优的旧版服务所需的必要功能(例如CAP_SYS_NICE)。 - 根配置消息
DeadlineSchedulingConfiguration计划在未来的版本中重命名。当前名称是历史名称,不再准确反映该消息处理所有调度类型(而不仅仅是截止时间调度)。