OVS-DPDK 82599 VF初始化失败诊断方法一例

问题

在82599上创建了两个VF之后,各自绑定到vfio,启动DPDK时出现错误:

1
2
3
PMD: eth_ixgbevf_dev_init(): VF Initialization Failure: -15
EAL: Error - exiting with code: 1
Cause: Requested device 0000:01:10.0 cannot be used

诊断

其实第一眼也看不出个什么来,但报错信息提供了两个线索:

  • 错误是eth_ixgbevf_dev_init报的
  • 错误代码是-15

剩下后面的看起来也直接提供了error code和错误的root cause,其实什么也没说。

所以从eth_ixgbevf_dev_init入手吧。

先找到这个方法在哪:

grep -r “eth_ixgbevf_dev_init” ./

1
2
3
4
5
6
./ixgbe_ethdev.c:static int eth_ixgbevf_dev_init(struct rte_eth_dev *eth_dev);
./ixgbe_ethdev.c:eth_ixgbevf_dev_init(struct rte_eth_dev *eth_dev)
./ixgbe_ethdev.c: sizeof(struct ixgbe_adapter), eth_ixgbevf_dev_init);
./ixgbe_ethdev.c: * is mapped to VFIO vector 0 in eth_ixgbevf_dev_init( ).
./ixgbe_ethdev.c: * If previous VFIO interrupt mapping setting in eth_ixgbevf_dev_init( )
./ixgbe_ethdev.c: ret = eth_ixgbevf_dev_init(dev);

是在ixgbe_ethdev.c这个文件里没跑了。

打开看一下,是在:

1
2
3
4
5
6
7
8
9
if ((diag != IXGBE_SUCCESS) && (diag != IXGBE_ERR_INVALID_MAC_ADDR)) {
PMD_INIT_LOG(ERR, "VF Initialization Failure: %d", diag);
/*
* This error code will be propagated to the app by
* rte_eth_dev_reset, so use a public error code rather than
* the internal-only IXGBE_ERR_RESET_FAILED
*/
return -EAGAIN;
}

这个位置,但实际上打印的是一个变量diag的值。在上面diag的赋值方法是:

diag = hw->mac.ops.reset_hw(hw)

这个看起来就是个抽象层封装了一堆ops函数指针的形式。要马上找到具体调用的是哪个实现还不是太容易的事情。但看到上面定义的IXGBE_ERR_INVALID_MAC_ADDR的宏就应该能猜到相关的error信息应该都在一起。

通过Ctags转跳IXGBE_ERR_INVALID_MAC_ADDR的定义,果然找到了我们要找的-15是什么错误:

#define IXGBE_ERR_RESET_FAILED -15

OK,下面只要看一下这个错误在什么地方返回:

1
2
3
4
5
6
7
8
9
10
[root@Server-N3 ixgbe]# grep -r "IXGBE_ERR_RESET_FAILED" ./
./base/ixgbe_82598.c: status = IXGBE_ERR_RESET_FAILED;
./base/ixgbe_vf.c: return IXGBE_ERR_RESET_FAILED;
./base/ixgbe_x540.c: status = IXGBE_ERR_RESET_FAILED;
./base/ixgbe_82599.c: status = IXGBE_ERR_RESET_FAILED;
./base/ixgbe_82599.c: ret_val = IXGBE_ERR_RESET_FAILED;
./base/ixgbe_phy.c: status = IXGBE_ERR_RESET_FAILED;
./base/ixgbe_type.h:#define IXGBE_ERR_RESET_FAILED -15
./base/ixgbe_x550.c: status = IXGBE_ERR_RESET_FAILED;
./ixgbe_ethdev.c: * the internal-only IXGBE_ERR_RESET_FAILED

对我们的VF初始化场景来说,肯定就是在./base/ixgbe_vf.c这个文件里返回的前述的错误。打开看一下返回这个错误的逻辑是什么:

1
2
3
4
5
6
7
8
/* we cannot reset while the RSTI / RSTD bits are asserted */
while (!mbx->ops.check_for_rst(hw, 0) && timeout) {
timeout--;
usec_delay(5);
}

if (!timeout)
return IXGBE_ERR_RESET_FAILED;

基本就是在一定时间段内检测一个寄存器有没有被设置正确,如果没有就返回这个错误。

好在代码注释中提到了检测的是RSTI/RSTD这两个标志位。

那就查查这两个标志位是什么意思呗,打开82599祖传的datasheet:

在PDF里搜索一下就能看到,这个标志位其实就是表示PF的reset过程有没有完成。

那么reset如果完成了..应该PF至少会UP起来吧…检查了一下果然PF没有UP,UP之后问题解决。

主要是

主要并不是想说这个具体的问题应该怎么解决,而是如何在不死扣细节的情况下快速找到线索,快速解决问题。从最直接的表象入手,熟稔一套猜测的直觉,保持对复杂问题的简单看法。

© 2020 DecodeZ All Rights Reserved. 本站访客数人次 本站总访问量
Theme by hiero