经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » 编程经验 » 查看文章
pcie reset系列之 内核框架
来源:cnblogs  作者:_备忘录  时间:2023/6/21 10:52:10  对本文有异议

FLR是pci reset的一种。

关于FLR的寄存器操作比较简单, 相关的寄存器有:
配置空间里device cap里的FLR capability bit, 这个表示设备是否支持FLR。
配置空间里device control里的BCR_FLR bit, 写这个bit可以触发FLR。

调用函数检测是否支持FLR:

  1. /* drivers/pci/pci.c */
  2. pcie_has_flr(struct pci_dev *dev)

Linux kernel里pcie_flr会被下面的函数调用到, 触发FLR

  1. /* drivers/pci/pci.c: below tree functions will call __pci_reset_function_locked */
  2. pci_reset_function(struct pci_dev *dev)
  3. pci_reset_function_locked(struct pci_dev *dev)
  4. pci_try_reset_function(struct pci_dev *dev)
  5. => __pci_reset_function_locked(struct pci_dev *dev)
  6. -> pcie_flr(struct pci_dev *dev)

执行 __pci_reset_function_locked 的时候,6.2内核提供的reset方法有:

  1. /* dev->reset_methods[] is a 0-terminated list of indices into this array */
  2. static const struct pci_reset_fn_method pci_reset_fn_methods[] = {
  3.     { },
  4.     { pci_dev_specific_reset, .name = "device_specific" },
  5.     { pci_dev_acpi_reset, .name = "acpi" },
  6.     { pcie_reset_flr, .name = "flr" },
  7.     { pci_af_flr, .name = "af_flr" },
  8.     { pci_pm_reset, .name = "pm" },
  9.     { pci_reset_bus_function, .name = "bus" },
  10. };

那么这些reset的优先级,是从数组下标小的,优先级就高。在4.19的内核中,并没有做成table,但顺序是一样的。
且前面reset只要返回不是 -ENOTTY,则不会执行后面的reset。

首先,暴露给用户态的接口,通过这个设备的sysfs接口可以触发FLR:

  1. /* drivers/pci/pci-sysfs.c */
  2. reset_store
  3. -> pci_reset_function(struct pci_dev *dev)

另外,vfio里也提供的接口,可以供给用户态触发FLR。这些接口包括,vfio设备的enable,
disable, 以及一个vfio设备相关的ioctl。

  1. /* drivers/vfio/pci/vfio_pci_config.c */
  2. vfio_exp_config_write
  3. -> pci_try_reset_function
  4. /* drivers/vfio/pci/vfio_pci.c */
  5. vfio_pci_enable
  6. vfio_pci_disable
  7. vfio_pci_ioctl (cmd == VFIO_DEVICE_RESET)
  8. => pci_try_reset_function(pdev);

单独的FLR操作需要配合整个reset流程工作, 在上面的调用pcie_flr的函数里,他们基本
的处理流程都是, 先做reset_prepare, 再触发FLR,最后做reset后的恢复:

  1. the logic of pci_reset_function and its brother functions are:
  2. - reset_prepare
  3. - flr operation if supporting flr
  4. - reset_done
  5. reset_prepare and reset_done callbacks are stored in pci_drivers pci_error_handlers,大多数驱动注册了pci_error_handler,但很多没有实现prepare
  6. these callbacks should be offered by your device driver:

驱动中的函数:

  1. struct pci_driver {
  2. ...
  3. const struct pci_error_handlers {
  4. ...
  5. void (*reset_prepare)(struct pci_dev *dev);
  6. void (*reset_done)(struct pci_dev *dev);
  7. ...
  8. }
  9. ...
  10. }

从上面的代码分析中可以看出,linux内核中的flr流程并不涉及到软件中设备结构的销毁.包括驱动资源的释放。
所以,只要在发生flr这段时间不去下发硬件请求,如果用lspci看,设备理论上会一直都在。对于使能了sriov的硬件,
在实现flr的时候,如果对pf执行flr,在硬件层面都有pf到vf的通知方式, 包括业务黑洞的设置,这样可以保证在pf flr时候通知到
flr做必要的处理,当pf flr完成后,可以通知vf驱动做必要的硬件配置上的恢复。
如果只是flr 某一个vf,不应该影响到其他vf的业务流。

注意,这个跟pcie g5 spec有一些相差。

原文链接:https://www.cnblogs.com/10087622blog/p/17495643.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号