将偏移量添加到dma_buf_addr的地址有什么用?

时间:2017-07-14 21:03:45

标签: c openonload

#define MEMBER_OFFSET(c_type, mbr_name) ((uint32_t) (uintptr_t)(&((c_type*)0)->mbr_name))
#define CACHE_ALIGN __attribute__((aligned(EF_VI_DMA_ALIGN)))

struct pkt_buf {
    struct pkt_buf* next;
    ef_addr dma_buf_addr;
    int id;
    uint8_t dma_buf[1] CACHE_ALIGN;
};


struct pkt_buf* pkt_bufs [N_BUFS];

for( i = 0; i < N_BUFS; ++i ) {
    struct pkt_buf* pb = (struct pkt_buf*) ((char*) p + i * 2048);
    pb->id = i;
    pb->dma_buf_addr = ef_memreg_dma_addr(&memreg, i * 2048);
    pb->dma_buf_addr += MEMBER_OFFSET(struct pkt_buf, dma_buf); // why do this?
    pkt_bufs[i] = pb;
}

问题&GT;我理解MEMBER_OFFSET的含义。但是,我没有得到以下行的含义:

pb->dma_buf_addr += MEMBER_OFFSET(struct pkt_buf, dma_buf)

基本上,MEMBER_OFFSET(struct pkt_buf, dma_buf)的值是dma_buf中成员变量struct pkt_buf的字节偏移值。

1 个答案:

答案 0 :(得分:0)

此代码使用的是&#39; struct hack&#39;的变体,后来被&#39;灵活的数组成员取代。在显示的代码中既未定义memreg也未定义p,函数(宏?)ef_memreg_dma_addr()也未定义,因此此处有推测元素。

然而,它正在进行计算,以便 if

pb->dma_buf_addr = ef_memreg_dma_addr(&memreg, i * 2048);

pb->dma_buf_addr指向struct pkt_buf的开头,然后指定作业:

pb->dma_buf_addr += MEMBER_OFFSET(struct pkt_buf, dma_buf);

pb->dma_buf_addr指向数据包中dma_buf数组的地址。使用的i * 2048表明p是一个连续的内存块,分为2个KiB页面,DMA缓冲区紧跟在ID字段之后。