diff --git a/pyverbs/qp.pyx b/pyverbs/qp.pyx index b4f84033f..05ce47bb9 100644 --- a/pyverbs/qp.pyx +++ b/pyverbs/qp.pyx @@ -32,6 +32,19 @@ cdef extern from 'endian.h': unsigned long htobe32(unsigned long host_32bits) +cdef void update_mw_rkeys(v.ibv_send_wr *wr, v.ibv_send_wr *bad_wr): + """ + Update MW rkeys for successfully posted bind WRs. + + ibv_post_send() returns the first WR that was not posted in bad_wr, so + only the WRs preceding it were accepted when posting a list fails. + """ + while wr != bad_wr: + if wr.opcode == e.IBV_WR_BIND_MW: + wr.bind_mw.mw.rkey = wr.bind_mw.rkey + wr = wr.next + + cdef class QPCap(PyverbsObject): def __init__(self, max_send_wr=1, max_recv_wr=10, max_send_sge=1, max_recv_sge=1, max_inline_data=0): @@ -1262,8 +1275,9 @@ cdef class QP(PyverbsCM): """ # In order to provide a pointer to a pointer, use a temporary cdef'ed # variable. - cdef v.ibv_send_wr *my_bad_wr + cdef v.ibv_send_wr *my_bad_wr = NULL rc = v.ibv_post_send(self.qp, &wr.send_wr, &my_bad_wr) + update_mw_rkeys(&wr.send_wr, my_bad_wr) if rc != 0: if (bad_wr): memcpy(&bad_wr.send_wr, my_bad_wr, sizeof(bad_wr.send_wr)) diff --git a/tests/test_mr.py b/tests/test_mr.py index ef75f4b24..b7ef04e8c 100644 --- a/tests/test_mr.py +++ b/tests/test_mr.py @@ -317,9 +317,11 @@ def bind_mw_type_2(self): # Poll the bind MW WR. u.poll_cq(self.server.cq) u.poll_cq(self.client.cq) - self.server.rkey = client_send_wr.rkey + self.assertEqual(self.client.mw.rkey, client_send_wr.rkey) + self.assertEqual(self.server.mw.rkey, server_send_wr.rkey) + self.server.rkey = self.client.mw.rkey self.server.raddr = self.client.mr.buf - self.client.rkey = server_send_wr.rkey + self.client.rkey = self.server.mw.rkey self.client.raddr = self.server.mr.buf def invalidate_mw_type1(self):