Skip to content

Commit f6f3f53

Browse files
kwan-intcjgunthorpe
authored andcommitted
IB/hfi1: Delay the release of destination mr for TID RDMA WRITE DATA
The reference of destination memory region is first obtained when TID RDMA WRITE request is first received on the responder side. This reference is released once all TID RDMA WRITE RESP packets are sent to the requester side, even though not all TID RDMA WRITE DATA packets may have been received. This early release will especially be undesired if the software needs to access the destination memory before the last data packet is received. This patch delays the release of the MR until all TID RDMA DATA packets have been received. A helper function to release the reference is also created to simplify the code. Reviewed-by: Mike Marciniszyn <[email protected]> Reviewed-by: Dennis Dalessandro <[email protected]> Reviewed-by: Michael J. Ruhl <[email protected]> Signed-off-by: Kaike Wan <[email protected]> Signed-off-by: Dennis Dalessandro <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]>
1 parent 1abe186 commit f6f3f53

File tree

3 files changed

+18
-29
lines changed

3 files changed

+18
-29
lines changed

drivers/infiniband/hw/hfi1/rc.c

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -140,10 +140,7 @@ static int make_rc_ack(struct hfi1_ibdev *dev, struct rvt_qp *qp,
140140
case OP(RDMA_READ_RESPONSE_LAST):
141141
case OP(RDMA_READ_RESPONSE_ONLY):
142142
e = &qp->s_ack_queue[qp->s_tail_ack_queue];
143-
if (e->rdma_sge.mr) {
144-
rvt_put_mr(e->rdma_sge.mr);
145-
e->rdma_sge.mr = NULL;
146-
}
143+
release_rdma_sge_mr(e);
147144
/* FALLTHROUGH */
148145
case OP(ATOMIC_ACKNOWLEDGE):
149146
/*
@@ -343,7 +340,8 @@ static int make_rc_ack(struct hfi1_ibdev *dev, struct rvt_qp *qp,
343340
break;
344341

345342
e->sent = 1;
346-
qp->s_ack_state = OP(RDMA_READ_RESPONSE_LAST);
343+
/* Do not free e->rdma_sge until all data are received */
344+
qp->s_ack_state = OP(ATOMIC_ACKNOWLEDGE);
347345
break;
348346

349347
case TID_OP(READ_RESP):
@@ -2643,10 +2641,7 @@ static noinline int rc_rcv_error(struct ib_other_headers *ohdr, void *data,
26432641
len = be32_to_cpu(reth->length);
26442642
if (unlikely(offset + len != e->rdma_sge.sge_length))
26452643
goto unlock_done;
2646-
if (e->rdma_sge.mr) {
2647-
rvt_put_mr(e->rdma_sge.mr);
2648-
e->rdma_sge.mr = NULL;
2649-
}
2644+
release_rdma_sge_mr(e);
26502645
if (len != 0) {
26512646
u32 rkey = be32_to_cpu(reth->rkey);
26522647
u64 vaddr = get_ib_reth_vaddr(reth);
@@ -3088,10 +3083,7 @@ void hfi1_rc_rcv(struct hfi1_packet *packet)
30883083
update_ack_queue(qp, next);
30893084
}
30903085
e = &qp->s_ack_queue[qp->r_head_ack_queue];
3091-
if (e->rdma_sge.mr) {
3092-
rvt_put_mr(e->rdma_sge.mr);
3093-
e->rdma_sge.mr = NULL;
3094-
}
3086+
release_rdma_sge_mr(e);
30953087
reth = &ohdr->u.rc.reth;
30963088
len = be32_to_cpu(reth->length);
30973089
if (len) {
@@ -3166,10 +3158,7 @@ void hfi1_rc_rcv(struct hfi1_packet *packet)
31663158
update_ack_queue(qp, next);
31673159
}
31683160
e = &qp->s_ack_queue[qp->r_head_ack_queue];
3169-
if (e->rdma_sge.mr) {
3170-
rvt_put_mr(e->rdma_sge.mr);
3171-
e->rdma_sge.mr = NULL;
3172-
}
3161+
release_rdma_sge_mr(e);
31733162
/* Process OPFN special virtual address */
31743163
if (opfn) {
31753164
opfn_conn_response(qp, e, ateth);

drivers/infiniband/hw/hfi1/rc.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,14 @@ static inline u32 restart_sge(struct rvt_sge_state *ss, struct rvt_swqe *wqe,
4141
return rvt_restart_sge(ss, wqe, len);
4242
}
4343

44+
static inline void release_rdma_sge_mr(struct rvt_ack_entry *e)
45+
{
46+
if (e->rdma_sge.mr) {
47+
rvt_put_mr(e->rdma_sge.mr);
48+
e->rdma_sge.mr = NULL;
49+
}
50+
}
51+
4452
struct rvt_ack_entry *find_prev_entry(struct rvt_qp *qp, u32 psn, u8 *prev,
4553
u8 *prev_ack, bool *scheduled);
4654
int do_rc_ack(struct rvt_qp *qp, u32 aeth, u32 psn, int opcode, u64 val,

drivers/infiniband/hw/hfi1/tid_rdma.c

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2036,10 +2036,7 @@ static int tid_rdma_rcv_error(struct hfi1_packet *packet,
20362036
if (psn != e->psn || len != req->total_len)
20372037
goto unlock;
20382038

2039-
if (e->rdma_sge.mr) {
2040-
rvt_put_mr(e->rdma_sge.mr);
2041-
e->rdma_sge.mr = NULL;
2042-
}
2039+
release_rdma_sge_mr(e);
20432040

20442041
rkey = be32_to_cpu(reth->rkey);
20452042
vaddr = get_ib_reth_vaddr(reth);
@@ -2285,10 +2282,7 @@ void hfi1_rc_rcv_tid_rdma_read_req(struct hfi1_packet *packet)
22852282
update_ack_queue(qp, next);
22862283
}
22872284
e = &qp->s_ack_queue[qp->r_head_ack_queue];
2288-
if (e->rdma_sge.mr) {
2289-
rvt_put_mr(e->rdma_sge.mr);
2290-
e->rdma_sge.mr = NULL;
2291-
}
2285+
release_rdma_sge_mr(e);
22922286

22932287
rkey = be32_to_cpu(reth->rkey);
22942288
qp->r_len = len;
@@ -3751,10 +3745,7 @@ void hfi1_rc_rcv_tid_rdma_write_req(struct hfi1_packet *packet)
37513745
goto update_head;
37523746
}
37533747

3754-
if (e->rdma_sge.mr) {
3755-
rvt_put_mr(e->rdma_sge.mr);
3756-
e->rdma_sge.mr = NULL;
3757-
}
3748+
release_rdma_sge_mr(e);
37583749

37593750
/* The length needs to be in multiples of PAGE_SIZE */
37603751
if (!len || len & ~PAGE_MASK)
@@ -4347,6 +4338,7 @@ void hfi1_rc_rcv_tid_rdma_write_data(struct hfi1_packet *packet)
43474338
priv->r_tid_ack = priv->r_tid_tail;
43484339

43494340
if (opcode == TID_OP(WRITE_DATA_LAST)) {
4341+
release_rdma_sge_mr(e);
43504342
for (next = priv->r_tid_tail + 1; ; next++) {
43514343
if (next > rvt_size_atomic(&dev->rdi))
43524344
next = 0;

0 commit comments

Comments
 (0)