+1 投票
分类:经验之谈 | 用户: (2.2k 分)
修改于 用户:

先介绍下背景:

我需要将kni移植到l2fwd上,所以将kni里面能用得到的函数都写到一个文件里面,l2fwd在另外一个文件中。共用的东西放到其他文件中。

出现的问题。kni_port_params_array这个在kni里面的全局变量,当我在l2fwd文件中引用的时候,结构体里面的数据总是nil。(kni_port_params_array[p]->kni[i])=nil

解决思路:打开gdb调试,发现内存的内容没有问题

395            nb_kni = kni_port_params_array[p]->nb_kni;
(gdb) x /32ga kni_port_params_array
0x8033a0 <kni_port_params_array>:    0x2aab1e4ee100    0x2aab1e4edf00
0x8033b0 <kni_port_params_array+16>:    0x0    0x0
0x8033c0 <kni_port_params_array+32>:    0x0    0x0
0x8033d0 <kni_port_params_array+48>:    0x0    0x0
0x8033e0 <kni_port_params_array+64>:    0x0    0x0
0x8033f0 <kni_port_params_array+80>:    0x0    0x0
0x803400 <kni_port_params_array+96>:    0x0    0x0
0x803410 <kni_port_params_array+112>:    0x0    0x0
0x803420 <kni_port_params_array+128>:    0x0    0x0
0x803430 <kni_port_params_array+144>:    0x0    0x0
0x803440 <kni_port_params_array+160>:    0x0    0x0
0x803450 <kni_port_params_array+176>:    0x0    0x0
0x803460 <kni_port_params_array+192>:    0x0    0x0
0x803470 <kni_port_params_array+208>:    0x0    0x0
0x803480 <kni_port_params_array+224>:    0x0    0x0
0x803490 <kni_port_params_array+240>:    0x0    0x0
(gdb) x /32ga 0x2aab1e4ee100  这个是kni_port_params_array[p]的地址
0x2aab1e4ee100:    0x100000000    0x2
0x2aab1e4ee110:    0x1    0x0
0x2aab1e4ee120:    0x0    0x0
0x2aab1e4ee130:    0x0    0x0
0x2aab1e4ee140:    0x0    0x0
0x2aab1e4ee150:    0x0    0x0
0x2aab1e4ee160:    0x0    0x0
0x2aab1e4ee170:    0x0    0x0
0x2aab1e4ee180:    0x0    0x0
0x2aab1e4ee190:    0x0    0x2aaab15eb700  这个是kni_port_params_array[p]->kni[i]的地址
0x2aab1e4ee1a0:    0x0    0x0
0x2aab1e4ee1b0:    0x0    0x0
0x2aab1e4ee1c0:    0x0    0x0
0x2aab1e4ee1d0:    0x0    0x0
0x2aab1e4ee1e0:    0x0    0x0
0x2aab1e4ee1f0:    0x0    0x0

没有别的办法,开始一步一步反汇编:

rt = kni_port_params_array[p]->kni[i];

1: x/10i $pc
=> 0x42e11a <lcore_main+795>:    mov    0x8043e0(,%rax,8),%rax               
   0x42e122 <lcore_main+803>:    mov    -0x278(%rbp),%edx
   0x42e128 <lcore_main+809>:    add    $0x10,%rdx
   0x42e12c <lcore_main+813>:    mov    0x20(%rax,%rdx,8),%rax
   0x42e131 <lcore_main+818>:    mov    %rax,-0x228(%rbp)
   0x42e138 <lcore_main+825>:    mov    -0x278(%rbp),%esi
   0x42e13e <lcore_main+831>:    mov    -0x27c(%rbp),%ecx
   0x42e144 <lcore_main+837>:    mov    -0x228(%rbp),%rdx
   0x42e14b <lcore_main+844>:    mov    -0x230(%rbp),%rax
   0x42e152 <lcore_main+851>:    mov    %esi,%r8d
   
   上面的0x8043e0这个地址就是 kni_port_params_array在程序中的全局地址,表达式

  kni_port_params_array[p]->kni[i];参照上面的汇编发现没有问题,继续。
   
   0x000000000042e12c    400                    rt = kni_port_params_array[p]->kni[i];
1: x/10i $pc
=> 0x42e12c <lcore_main+813>:    mov    0x20(%rax,%rdx,8),%rax    ---> 这一句对应结构体发现问题
struct kni_port_params {
    uint8_t port_id;/* Port ID */
    unsigned lcore_rx; /* lcore ID for RX */
    unsigned lcore_tx; /* lcore ID for TX */
    uint32_t nb_lcore_k; /* Number of lcores for KNI multi kernel threads */
    uint32_t nb_kni; /* Number of KNI devices to be created */
    unsigned lcore_k[KNI_MAX_KTHREAD]; /* lcore ID list for kthreads */
    struct rte_kni *kni[KNI_MAX_KTHREAD]; /* KNI context pointers */
} __rte_cache_aligned;  

 

0x42e131 <lcore_main+818>:    mov    %rax,-0x228(%rbp)
   0x42e138 <lcore_main+825>:    mov    -0x278(%rbp),%esi
   0x42e13e <lcore_main+831>:    mov    -0x27c(%rbp),%ecx
   0x42e144 <lcore_main+837>:    mov    -0x228(%rbp),%rdx
   0x42e14b <lcore_main+844>:    mov    -0x230(%rbp),%rax
   0x42e152 <lcore_main+851>:    mov    %esi,%r8d
   0x42e155 <lcore_main+854>:    mov    %rax,%rsi
   0x42e158 <lcore_main+857>:    mov    $0x55930a,%edi
   0x42e15d <lcore_main+862>:    mov    $0x0,%eax
(gdb) p $rdx
$20 = 16
(gdb) x $rax
0x2aab1e4ee100:    0x0000000100000000
(gdb) x /32g $rax

根据上面的汇编发现kni_port_params_array[p]->kni[i];对应的0x20(%rax,%rdx,8),%rax是取结构体偏移为0x20处的内容,但是结构体为64字节对齐,找到问题。然后对应代码发现头文件中在声明全局变量的时候把变量声明到了结构体的上面,把位置改变一下就可以了。

错误方法:

extern struct kni_port_params *kni_port_params_array[RTE_MAX_ETHPORTS];

struct kni_port_params {
    uint8_t port_id;/* Port ID */
    unsigned lcore_rx; /* lcore ID for RX */
    unsigned lcore_tx; /* lcore ID for TX */
    uint32_t nb_lcore_k; /* Number of lcores for KNI multi kernel threads */
    uint32_t nb_kni; /* Number of KNI devices to be created */
    unsigned lcore_k[KNI_MAX_KTHREAD]; /* lcore ID list for kthreads */
    struct rte_kni *kni[KNI_MAX_KTHREAD]; /* KNI context pointers */
} __rte_cache_aligned;  

 

正确方法:

struct kni_port_params {
    uint8_t port_id;/* Port ID */
    unsigned lcore_rx; /* lcore ID for RX */
    unsigned lcore_tx; /* lcore ID for TX */
    uint32_t nb_lcore_k; /* Number of lcores for KNI multi kernel threads */
    uint32_t nb_kni; /* Number of KNI devices to be created */
    unsigned lcore_k[KNI_MAX_KTHREAD]; /* lcore ID list for kthreads */
    struct rte_kni *kni[KNI_MAX_KTHREAD]; /* KNI context pointers */
} __rte_cache_aligned;  

extern struct kni_port_params *kni_port_params_array[RTE_MAX_ETHPORTS];

 

 

0x2aab1e4ee100:    0x0000000100000000    0x0000000000000002
0x2aab1e4ee110:    0x0000000000000001    0x0000000000000000
0x2aab1e4ee120:    0x0000000000000000    0x0000000000000000
0x2aab1e4ee130:    0x0000000000000000    0x0000000000000000
0x2aab1e4ee140:    0x0000000000000000    0x0000000000000000
0x2aab1e4ee150:    0x0000000000000000    0x0000000000000000
0x2aab1e4ee160:    0x0000000000000000    0x0000000000000000
0x2aab1e4ee170:    0x0000000000000000    0x0000000000000000
0x2aab1e4ee180:    0x0000000000000000    0x0000000000000000
0x2aab1e4ee190:    0x0000000000000000    0x00002aaab15eb700
0x2aab1e4ee1a0:    0x0000000000000000    0x0000000000000000
0x2aab1e4ee1b0:    0x0000000000000000    0x0000000000000000
0x2aab1e4ee1c0:    0x0000000000000000    0x0000000000000000
0x2aab1e4ee1d0:    0x0000000000000000    0x0000000000000000
0x2aab1e4ee1e0:    0x0000000000000000    0x0000000000000000
0x2aab1e4ee1f0:    0x0000000000000000    0x0000000000000000
(gdb) si
0x000000000042e131    400                    rt = kni_port_params_array[p]->kni[i];
1: x/10i $pc
=> 0x42e131 <lcore_main+818>:    mov    %rax,-0x228(%rbp)
   0x42e138 <lcore_main+825>:    mov    -0x278(%rbp),%esi
   0x42e13e <lcore_main+831>:    mov    -0x27c(%rbp),%ecx
   0x42e144 <lcore_main+837>:    mov    -0x228(%rbp),%rdx
   0x42e14b <lcore_main+844>:    mov    -0x230(%rbp),%rax
   0x42e152 <lcore_main+851>:    mov    %esi,%r8d
   0x42e155 <lcore_main+854>:    mov    %rax,%rsi
   0x42e158 <lcore_main+857>:    mov    $0x55930a,%edi
   0x42e15d <lcore_main+862>:    mov    $0x0,%eax
   0x42e162 <lcore_main+867>:    callq  0x41df90 <[email protected]>
(gdb) p $rax
$22 = 0
(gdb) x $rax
0x0:    Cannot access memory at address 0x0
(gdb) 

 

 

1个回答

0 投票
用户: (210 分)
kni移植到l2fwd中,启动l2fwd后就能直接创建vEth0那个虚拟网口吗?

欢迎来到 DPDK交流社区 ,有什么问题可以尽管在这里提问,您将会收到社区其他成员的回答;也可以将您的总结写在这里,为社区其他成员提供帮助。

QQ交流2群:635461501 (入群请注明来源)

冀ICP备15005332号-2
...