​Linux kernel 驱动中,有不少驱动会引用到 EPROBE_DEFER 这个错误号。比如下面这个例子,对 devm_gpiod_get 的返回值进行判断,如果有错误且错误号不是 -EPRBOE_DEFER,才输出error log。

Linux驱动中的EPROBE_DEFER是个啥-LMLPHP

那么 EPRBOE_DEFER 有什么特别之处吗,需要驱动程序这样特意处理?这个与 kernel 设计的 driver-deferred-probe 机制有关。

kernel 下有多个独立的驱动,每个驱动或多或少地会引用到其他驱动提供的资源,比如某个外设驱动需要使用 gpio 资源,就会通过 gpio 驱动提供的函数接口去申请 gpio;但是当A驱动引用B驱动提供的资源时,B驱动可能还没有工作起来,为了解决驱动之间的这种依赖关系,kernel 设计了 driver-deferred-probe 机制:某个驱动在 probe 过程中,如果遇到依赖的资源还没有准备好,那么就返回 -EPRBOE_DEFER,kernel 检测到该驱动返回的是  -EPRBOE_DEFER,就会在过一段时间后让该驱动再次 probe。

driver-deferred-probe 流程如下图所示,有三条可能的路径

  • 生成新的 device 时

  • 注册新的 driver 时

  • later_initcall 主动再次触发

Linux驱动中的EPROBE_DEFER是个啥-LMLPHP

driver-deferred-probe 机制的核心数据结构与函数是:

  • deferred_probe_pending_list,用来记录哪些驱动被 deferred probe,并提供函数接口 driver_deferred_probe_add。

Linux驱动中的EPROBE_DEFER是个啥-LMLPHP

  • deferred_probe_work,用来调度相应的 work func 来执行 deferred probe 动作,并提供函数接口 driver_deferred_probe_trigger。

Linux驱动中的EPROBE_DEFER是个啥-LMLPHP

Linux驱动中的EPROBE_DEFER是个啥-LMLPHP

有了 driver-deferred-probe 机制后,编写驱动程序时,除了某些驱动有严格的执行次序,需要特意去定义 initcall 等级之外,一般的驱动则无需太过关心驱动间的依赖,从而在一定程度上简化了驱动开发。

以上就是对 EPRBOE_DEFER 的简要介绍。


作者:bigfish99

博客:https://www.cnblogs.com/bigfish0506/

公众号:大鱼嵌入式

Linux驱动中的EPROBE_DEFER是个啥-LMLPHP

06-26 12:25