定义稳定的驱动程序运行时

  • 项目负责人:surajmalhotra@google.com
  • 状态:已批准
  • 领域:设备

问题陈述

Banjo 是一种接口定义语言 (IDL),用于表示驱动程序之间使用的接口。它是 FIDL 的衍生产品,采用 2018 年的分支语法。 虽然语法类似,但与 FIDL 不同的是,banjo 是专为同步进程内通信而设计的,生成的代码生成就是一个非常标准的函数指针结构,与上下文指针相关联。

班卓琴的问题列表(并非详尽无遗):

  • 为 Benjo 生成的代码缺少接口和类型演变策略。这是确保界面稳定性的关键要求。
  • 自 2019 年初以来,Benjo 一直处于维护模式,在人体工程学和功能方面,已落后于 FIDL。了解如何编写班卓琴的语法变得令人困惑,因为 Fuchsia 项目依靠 FIDL 文档解决了班卓琴的功能和工效学设计方面的当前问题。
  • Banjo 经过优化,开销低,这会给驱动程序编写者带来很大的负担,让他们必须弄清楚如何将状态移到堆上或异步处理操作。为此,需要有大量样板代码涉及手动序列化逻辑。
  • 对于驱动程序编写人员如何调用 banjo 协议方法,并没有严格的要求,也没有任何保证会在哪些上下文调用他们自己的协议方法,从而导致不必要的线程派生为实现安全性(避免死锁)。
  • Banjo 类型与 FIDL 类型不兼容,通常在转移到进程外通信时会导致产生大量样板代码。

解决方案声明

我们希望通过改进班卓琴来解决这些问题。新传输的三个主要特点将是:

  1. 在驱动程序之间强制使用一个间接层,使运行时能够协调同一进程内驱动程序之间的通信
  2. 从 C 结构体迁移到考虑进化构建的类型。
  3. 强制执行一个明确定义的线程模型

我们希望找到具有以下特征的解决方案:

  • 将驱动程序之间的所有通信都改为面向消息,通过驱动程序之间的 FIDL 有线格式。
  • 允许驱动程序对其他驱动程序进行同步调用。
    • 需要注意的是,它只能在驱动程序拥有的线程中使用。
  • 在驱动程序之间共享线程
    • 请注意,共享线程上的所有通信都必须是异步的。
  • 允许驱动程序在他们未选择启用时从不处理重新进入或同步(这让他们完全避免锁定)。
  • 允许在驱动程序之间执行零复制和零序列化 / 反序列化。

我们保留根据早期原型的基准结果改变主意的权利。如果我们无法超越内核提供的机制,则需要尝试替代设计。我们还需要证明我们的假设:内核提供的机制不足以满足我们的需求。

我们将尝试通过以下里程碑跟踪新班卓琴的进度:

  1. 更新 banjo 语法以匹配 fidl 语法,使用 fidlc 作为前端,并实现一个自定义后端,该后端生成与 banjoc 当前生成的输出等同的输出。
    1. 这样可以避免维护负担和将来的语法偏移。
  2. 为我们设计时所围绕的驱动程序构建线程模型。
  3. 确定指标/基准,以判断未来的设计。
  4. 运行实验,看看我们是否可以使用较新的传输方式满足所需的基准测试。
  5. 实现新的 fidl 后端和驱动程序运行时。
    1. 我们可能首先创建一个针对新传输的 LLCPP fidl 绑定的变体。
  6. 对循环中的每个驱动程序堆栈重复执行以下步骤:
    1. 利用现有的 Banjo 传输将共同驻留在同一驱动程序主机中的驱动程序迁移到新的线程模型。
    2. 将共同驻留在同一驱动程序主机中的驱动程序迁移到新的进程内 FIDL 传输。

依赖项

我们可能需要与 FIDL 团队合作,允许将 LLCPP 绑定从锆石通道和端口中提取出来,以便在新的传输中大多按原样重新利用这些绑定,从而最大限度地减少用户可见差异。我们预计不需要对前端 IDL 进行任何更改,但可能需要更改 FIDL IR。

此外,迁移 300 多个驱动程序将需要大量的工作和时间,并且需要整个组织的各个团队参与,以确保不会出现中断。

风险和缓解措施

这样的重大更改会产生额外的开销,因此会对我们系统的性能特征产生长期影响。幸运的是,我们直接在框架架构中内置了一些进化支持,如果我们构建的解决方案无法满足未来需求,让我们能够转向另一种技术。为此,我们可以实现新的组件运行程序,并让驱动程序以新的运行程序为目标,而新的运行程序可能具有不同的驱动程序运行时。但是,将每个驱动程序都切换到新的驱动程序运行程序可能不切实际,因此我们最终需要同时维护这两个驱动程序,这会产生成本。因此,我们非常希望大家能够 正确使用这一方法,这样就不必再学习本课程了

将驱动程序切换到新的线程模型也需要付出巨大的成本,并且可能会在此过程中引入新的 bug。许多驾驶员都没有测试。此外,对于具有测试的驱动程序,单元测试在切换后也可能会失去其有效性,并且可能需要在转换时重写。我们编写了大量的驱动程序测试作为集成测试,即使在迁移后没有进行任何更改,这些测试也应继续有效。在迁移之前,我们将继续尝试投资执行更多的集成测试和 e2e 测试,以防止引入新的 bug。

估算迁移的时间表是另一项重大风险。如果没有针对至少一个驱动程序构建替代并试用迁移,则很难准确估算费用。我们将在实现设计时持续了解费用,并尽可能自动执行迁移。