参考rxe驱动代码,
在rxe_req.c文件里,取wqe时,会调用req_next_wqe函数,
在函数的最后有个判断,
qp->req.wait_fence设置为1,然后返回NULL,所以rxe_requester函数直接退出了,不会进行这个wqe的处理,那么什么时候可以处理呢?只有等到这个设置了IBV_SEND_FENCE标记位的上一个wqe收到了最后一个ack以后,才会对当前设置了IBV_SEND_FENCE标记位的wqe进行处理。
if (unlikely((wqe->wr.send_flags & IB_SEND_FENCE) &&
(index != cons))) {
qp->req.wait_fence = 1;
return NULL;
}
在rxe_comp.c里do_complete函数的最后有相应的设置,并且在设置之前,已经产生了cqe,即ack已经得到了相应的处理。
if (qp->req.wait_fence) {
qp->req.wait_fence = 0;
rxe_run_task(&qp->req.task, 0);
}
不过在:https://www.rdmamojo.com/2013/01/26/ibv_post_send/
说,这个标记位只有对read和atomic起作用,从rxe驱动代码来看貌似不是这回事。
为了说的明白一点,这里举一个例子。
这里注意发数据包的时候,取wqe的index,它是取的req.wqe_index的
值,假设当前,pi指向7,而ci指向2,wqe5携带了FENCE标记,
发包函数处理到wqe5的时候看到带有fence标记,流程就会结束,
并设置wait_fence为1,当收ack的调度收到了wqe的最后一个ack时,这个时候会设置
wait_fence为0,然后ci变为3,但是,发包函数是根据req_index取到的wqe,
由于req.wqe_index没有更新,所以此时再次进入发包函数时,取出的
wqe是wqe5,所以再次返回NULL,当处理到wqe5时,ci是5,req.wqe_index也是5
所以,这个时候wait_fence不会设置为1,从而不会返回NULL。这个时候流程进行往下走