IB/mthca: Fix posting lists of 256 receive requests to SRQ for Tavor
If we post a list of length exactly a multiple of 256, nreq in doorbell gets set to 256 which is wrong: it should be encoded by 0. This is because we only zero it out on the next WR, which may not be there. The solution is to ring the doorbell after posting a WQE, not before posting the next one. This is the same bug that we just fixed for QPs with non-shared RQ. Signed-off-by: Michael S. Tsirkin <mst@mellanox.co.il> Signed-off-by: Roland Dreier <rolandd@cisco.com>
This commit is contained in:
Родитель
da8bacf6d5
Коммит
ab28b171ea
|
@ -490,26 +490,7 @@ int mthca_tavor_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
|
|||
|
||||
first_ind = srq->first_free;
|
||||
|
||||
for (nreq = 0; wr; ++nreq, wr = wr->next) {
|
||||
if (unlikely(nreq == MTHCA_TAVOR_MAX_WQES_PER_RECV_DB)) {
|
||||
nreq = 0;
|
||||
|
||||
doorbell[0] = cpu_to_be32(first_ind << srq->wqe_shift);
|
||||
doorbell[1] = cpu_to_be32(srq->srqn << 8);
|
||||
|
||||
/*
|
||||
* Make sure that descriptors are written
|
||||
* before doorbell is rung.
|
||||
*/
|
||||
wmb();
|
||||
|
||||
mthca_write64(doorbell,
|
||||
dev->kar + MTHCA_RECEIVE_DOORBELL,
|
||||
MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
|
||||
|
||||
first_ind = srq->first_free;
|
||||
}
|
||||
|
||||
for (nreq = 0; wr; wr = wr->next) {
|
||||
ind = srq->first_free;
|
||||
|
||||
if (ind < 0) {
|
||||
|
@ -569,6 +550,26 @@ int mthca_tavor_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
|
|||
|
||||
srq->wrid[ind] = wr->wr_id;
|
||||
srq->first_free = next_ind;
|
||||
|
||||
++nreq;
|
||||
if (unlikely(nreq == MTHCA_TAVOR_MAX_WQES_PER_RECV_DB)) {
|
||||
nreq = 0;
|
||||
|
||||
doorbell[0] = cpu_to_be32(first_ind << srq->wqe_shift);
|
||||
doorbell[1] = cpu_to_be32(srq->srqn << 8);
|
||||
|
||||
/*
|
||||
* Make sure that descriptors are written
|
||||
* before doorbell is rung.
|
||||
*/
|
||||
wmb();
|
||||
|
||||
mthca_write64(doorbell,
|
||||
dev->kar + MTHCA_RECEIVE_DOORBELL,
|
||||
MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
|
||||
|
||||
first_ind = srq->first_free;
|
||||
}
|
||||
}
|
||||
|
||||
if (likely(nreq)) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче