@@ -420,13 +420,23 @@ static enum resp_states rxe_resp_check_length(struct rxe_qp *qp,
420
420
return RESPST_CHK_RKEY ;
421
421
}
422
422
423
+ /* if the reth length field is zero we can assume nothing
424
+ * about the rkey value and should not validate or use it.
425
+ * Instead set qp->resp.rkey to 0 which is an invalid rkey
426
+ * value since the minimum index part is 1.
427
+ */
423
428
static void qp_resp_from_reth (struct rxe_qp * qp , struct rxe_pkt_info * pkt )
424
429
{
430
+ unsigned int length = reth_len (pkt );
431
+
425
432
qp -> resp .va = reth_va (pkt );
426
433
qp -> resp .offset = 0 ;
427
- qp -> resp .rkey = reth_rkey (pkt );
428
- qp -> resp .resid = reth_len (pkt );
429
- qp -> resp .length = reth_len (pkt );
434
+ qp -> resp .resid = length ;
435
+ qp -> resp .length = length ;
436
+ if (pkt -> mask & RXE_READ_OR_WRITE_MASK && length == 0 )
437
+ qp -> resp .rkey = 0 ;
438
+ else
439
+ qp -> resp .rkey = reth_rkey (pkt );
430
440
}
431
441
432
442
static void qp_resp_from_atmeth (struct rxe_qp * qp , struct rxe_pkt_info * pkt )
@@ -437,6 +447,10 @@ static void qp_resp_from_atmeth(struct rxe_qp *qp, struct rxe_pkt_info *pkt)
437
447
qp -> resp .resid = sizeof (u64 );
438
448
}
439
449
450
+ /* resolve the packet rkey to qp->resp.mr or set qp->resp.mr to NULL
451
+ * if an invalid rkey is received or the rdma length is zero. For middle
452
+ * or last packets use the stored value of mr.
453
+ */
440
454
static enum resp_states check_rkey (struct rxe_qp * qp ,
441
455
struct rxe_pkt_info * pkt )
442
456
{
@@ -473,10 +487,12 @@ static enum resp_states check_rkey(struct rxe_qp *qp,
473
487
return RESPST_EXECUTE ;
474
488
}
475
489
476
- /* A zero-byte op is not required to set an addr or rkey. See C9-88 */
490
+ /* A zero-byte read or write op is not required to
491
+ * set an addr or rkey. See C9-88
492
+ */
477
493
if ((pkt -> mask & RXE_READ_OR_WRITE_MASK ) &&
478
- (pkt -> mask & RXE_RETH_MASK ) &&
479
- reth_len ( pkt ) == 0 ) {
494
+ (pkt -> mask & RXE_RETH_MASK ) && reth_len ( pkt ) == 0 ) {
495
+ qp -> resp . mr = NULL ;
480
496
return RESPST_EXECUTE ;
481
497
}
482
498
@@ -555,6 +571,7 @@ static enum resp_states check_rkey(struct rxe_qp *qp,
555
571
return RESPST_EXECUTE ;
556
572
557
573
err :
574
+ qp -> resp .mr = NULL ;
558
575
if (mr )
559
576
rxe_put (mr );
560
577
if (mw )
@@ -885,7 +902,11 @@ static enum resp_states read_reply(struct rxe_qp *qp,
885
902
}
886
903
887
904
if (res -> state == rdatm_res_state_new ) {
888
- if (!res -> replay ) {
905
+ if (!res -> replay || qp -> resp .length == 0 ) {
906
+ /* if length == 0 mr will be NULL (is ok)
907
+ * otherwise qp->resp.mr holds a ref on mr
908
+ * which we transfer to mr and drop below.
909
+ */
889
910
mr = qp -> resp .mr ;
890
911
qp -> resp .mr = NULL ;
891
912
} else {
@@ -899,6 +920,10 @@ static enum resp_states read_reply(struct rxe_qp *qp,
899
920
else
900
921
opcode = IB_OPCODE_RC_RDMA_READ_RESPONSE_FIRST ;
901
922
} else {
923
+ /* re-lookup mr from rkey on all later packets.
924
+ * length will be non-zero. This can fail if someone
925
+ * modifies or destroys the mr since the first packet.
926
+ */
902
927
mr = rxe_recheck_mr (qp , res -> read .rkey );
903
928
if (!mr )
904
929
return RESPST_ERR_RKEY_VIOLATION ;
@@ -916,18 +941,16 @@ static enum resp_states read_reply(struct rxe_qp *qp,
916
941
skb = prepare_ack_packet (qp , & ack_pkt , opcode , payload ,
917
942
res -> cur_psn , AETH_ACK_UNLIMITED );
918
943
if (!skb ) {
919
- if (mr )
920
- rxe_put (mr );
921
- return RESPST_ERR_RNR ;
944
+ state = RESPST_ERR_RNR ;
945
+ goto err_out ;
922
946
}
923
947
924
948
err = rxe_mr_copy (mr , res -> read .va , payload_addr (& ack_pkt ),
925
949
payload , RXE_FROM_MR_OBJ );
926
- if (mr )
927
- rxe_put (mr );
928
950
if (err ) {
929
951
kfree_skb (skb );
930
- return RESPST_ERR_RKEY_VIOLATION ;
952
+ state = RESPST_ERR_RKEY_VIOLATION ;
953
+ goto err_out ;
931
954
}
932
955
933
956
if (bth_pad (& ack_pkt )) {
@@ -936,9 +959,12 @@ static enum resp_states read_reply(struct rxe_qp *qp,
936
959
memset (pad , 0 , bth_pad (& ack_pkt ));
937
960
}
938
961
962
+ /* rxe_xmit_packet always consumes the skb */
939
963
err = rxe_xmit_packet (qp , & ack_pkt , skb );
940
- if (err )
941
- return RESPST_ERR_RNR ;
964
+ if (err ) {
965
+ state = RESPST_ERR_RNR ;
966
+ goto err_out ;
967
+ }
942
968
943
969
res -> read .va += payload ;
944
970
res -> read .resid -= payload ;
@@ -955,6 +981,9 @@ static enum resp_states read_reply(struct rxe_qp *qp,
955
981
state = RESPST_CLEANUP ;
956
982
}
957
983
984
+ err_out :
985
+ if (mr )
986
+ rxe_put (mr );
958
987
return state ;
959
988
}
960
989
0 commit comments