@@ -183,9 +183,11 @@ static enum ibv_wc_opcode dev_wc_opcode(enum ibv_wr_opcode opcode)
183183 return IBV_WC_SEND ;
184184 } else if (opcode == IBV_WR_RDMA_READ ) {
185185 return IBV_WC_RDMA_READ ;
186+ } else if (opcode == IBV_WR_RDMA_WRITE ) {
187+ return IBV_WC_RDMA_WRITE ;
186188 }
187189
188- return IBV_WC_RDMA_READ ;
190+ return -1 ;
189191}
190192
191193static int
@@ -253,9 +255,10 @@ rx_rdma(struct fake_qp *fqp, struct fake_hdr *hdr, struct iovec *iov, int count)
253255 struct {
254256 void * addr ;
255257 uint32_t len ;
256- } __attribute__((packed )) dest [hdr -> rdma .count ];
258+ } __attribute__((packed )) data [hdr -> rdma .count ];
257259 int i ;
258260 size_t src_off , dst_off , total , len ;
261+ void * dst , * src ;
259262
260263 array_foreach (mr , & fqp -> fpd -> mrs ) {
261264 if ((* mr )-> mr .lkey == hdr -> rdma .rkey ) {
@@ -273,7 +276,7 @@ rx_rdma(struct fake_qp *fqp, struct fake_hdr *hdr, struct iovec *iov, int count)
273276 i = 0 ;
274277 src_off = sizeof (* hdr );
275278 dst_off = 0 ;
276- for (dst_off = 0 ; dst_off < sizeof (dest );) {
279+ for (dst_off = 0 ; dst_off < sizeof (data );) {
277280 while (i < count && src_off >= iov [i ].iov_len ) {
278281 src_off = 0 ;
279282 i ++ ;
@@ -284,16 +287,25 @@ rx_rdma(struct fake_qp *fqp, struct fake_hdr *hdr, struct iovec *iov, int count)
284287 return 0 ;
285288 }
286289
287- len = min (sizeof (dest ) - dst_off , iov [i ].iov_len - src_off );
288- memcpy ((void * )dest + dst_off , iov [i ].iov_base + src_off , len );
290+ len = min (sizeof (data ) - dst_off , iov [i ].iov_len - src_off );
291+ memcpy ((void * )data + dst_off , iov [i ].iov_base + src_off , len );
289292 dst_off += len ;
290293 src_off += len ;
291294 }
292295
293296 total = 0 ;
294297 for (i = 0 ; i < hdr -> rdma .count ; i ++ ) {
295- memcpy (dest [i ].addr , (void * )hdr -> rdma .addr + total , dest [i ].len );
296- total += dest [i ].len ;
298+ if (hdr -> opcode == IBV_WR_RDMA_READ ) {
299+ dst = data [i ].addr ;
300+ src = (void * )hdr -> rdma .addr + total ;
301+ } else {
302+ assert (hdr -> opcode == IBV_WR_RDMA_WRITE );
303+ src = data [i ].addr ;
304+ dst = (void * )hdr -> rdma .addr + total ;
305+ }
306+
307+ memcpy (dst , src , data [i ].len );
308+ total += data [i ].len ;
297309 }
298310
299311 assert (total == hdr -> rdma .len );
@@ -326,8 +338,11 @@ static int dev_rx_cb(struct iovec *iov, int count)
326338
327339 if (hdr -> opcode == IBV_WR_SEND ) {
328340 ret = rx_send (fqp , hdr , iov , count );
329- } else if (hdr -> opcode == IBV_WR_RDMA_READ ) {
341+ } else if ((hdr -> opcode == IBV_WR_RDMA_READ ) ||
342+ (hdr -> opcode == IBV_WR_RDMA_WRITE )) {
330343 ret = rx_rdma (fqp , hdr , iov , count );
344+ } else {
345+ ret = 1 ;
331346 }
332347
333348 return ret ;
@@ -359,7 +374,9 @@ static int dev_wr_send_serialize(struct ibv_qp *qp, struct ibv_send_wr *wr,
359374 struct ibv_wc * wc ;
360375 int i , ret , count ;
361376
362- if ((wr -> opcode != IBV_WR_SEND ) && (wr -> opcode != IBV_WR_RDMA_READ )) {
377+ if ((wr -> opcode != IBV_WR_SEND ) &&
378+ (wr -> opcode != IBV_WR_RDMA_READ ) &&
379+ (wr -> opcode != IBV_WR_RDMA_WRITE )) {
363380 return -1 ;
364381 }
365382
@@ -383,7 +400,7 @@ static int dev_wr_send_serialize(struct ibv_qp *qp, struct ibv_send_wr *wr,
383400 iov [1 + i ].iov_len = wr -> sg_list [i ].length ;
384401
385402 total += iov [1 + i ].iov_len ;
386- } else if ( wr -> opcode == IBV_WR_RDMA_READ ) {
403+ } else {
387404 iov [1 + (2 * i )].iov_base = & wr -> sg_list [i ].addr ;
388405 iov [1 + (2 * i )].iov_len = sizeof (wr -> sg_list [i ].addr );
389406 iov [2 + (2 * i )].iov_base = & wr -> sg_list [i ].length ;
@@ -394,7 +411,7 @@ static int dev_wr_send_serialize(struct ibv_qp *qp, struct ibv_send_wr *wr,
394411 }
395412
396413 count = wr -> num_sge + 1 ;
397- if (wr -> opcode == IBV_WR_RDMA_READ ) {
414+ if (wr -> opcode != IBV_WR_SEND ) {
398415 hdr -> rdma .rkey = wr -> wr .rdma .rkey ;
399416 hdr -> rdma .addr = wr -> wr .rdma .remote_addr ;
400417 hdr -> rdma .len = total ;
@@ -892,16 +909,29 @@ void dev_qp_wr_start(struct ibv_qp_ex *qp_ex)
892909 memset (& fqp -> sr , 0 , sizeof (fqp -> sr ));
893910}
894911
895- void dev_qp_wr_rdma_read (struct ibv_qp_ex * qp_ex , uint32_t rkey ,
896- uint64_t remote_addr )
912+ void dev_qp_wr_rdma (struct ibv_qp_ex * qp_ex , int opcode ,
913+ uint32_t rkey ,
914+ uint64_t remote_addr )
897915{
898916 struct fake_qp * fqp = (struct fake_qp * )qp_ex ;
899917
900- fqp -> sr .opcode = IBV_WR_RDMA_READ ;
918+ fqp -> sr .opcode = opcode ;
901919 fqp -> sr .wr .rdma .rkey = rkey ;
902920 fqp -> sr .wr .rdma .remote_addr = remote_addr ;
903921}
904922
923+ void dev_qp_wr_rdma_read (struct ibv_qp_ex * qp_ex , uint32_t rkey ,
924+ uint64_t remote_addr )
925+ {
926+ dev_qp_wr_rdma (qp_ex , IBV_WR_RDMA_READ , rkey , remote_addr );
927+ }
928+
929+ void dev_qp_wr_rdma_write (struct ibv_qp_ex * qp_ex , uint32_t rkey ,
930+ uint64_t remote_addr )
931+ {
932+ dev_qp_wr_rdma (qp_ex , IBV_WR_RDMA_WRITE , rkey , remote_addr );
933+ }
934+
905935void dev_qp_wr_set_sge_list (struct ibv_qp_ex * qp_ex , size_t num_sge ,
906936 const struct ibv_sge * sg_list )
907937{
0 commit comments