Bug #1540: Fix memory leaks in PAMI, Verbs, MPI RDMA implementations
[charm.git] / src / arch / verbs / machine-onesided.c
blobf422ee601b294e903a3170fd49e78f6b3697a19b
1 /*
2 * included in machine-ibverbs.c
3 * Jaemin Choi
4 */
6 void verbsOnesidedAllOpsDone(char *msg) {
7 int sndlen = ((CmiMsgHeaderBasic *) msg)->size;
9 handleOneRecvedMsg(sndlen, msg);
12 /* function called on completion of the rdma operation */
13 void verbsOnesidedOpDone(CmiVerbsRdmaRecvOp_t *recvOpInfo) {
14 CmiVerbsRdmaRecv_t *recvInfo = (CmiVerbsRdmaRecv_t *)(
15 ((char *)recvOpInfo) - recvOpInfo->opIndex * sizeof(CmiVerbsRdmaRecvOp_t)
16 - sizeof(CmiVerbsRdmaRecv_t));
18 if (ibv_dereg_mr(recvOpInfo->local_mr)) {
19 MACHSTATE(3, "ibv_dereg_mr() failed\n");
22 verbsOnesidedSendAck(recvInfo->peNum, recvOpInfo);
23 recvInfo->comOps++;
24 if (recvInfo->comOps == recvInfo->numOps) {
25 verbsOnesidedAllOpsDone(recvInfo->msg);
26 // free the receiver's machine specific information, CmiVerbsRdmaRecv_t allocated inside CkRdmaIssueRgets
27 free(recvInfo);
31 /* function to perform RDMA read operation */
32 void verbsOnesidedPostRdmaRead(int peNum, CmiVerbsRdmaRecvOp_t *recvOpInfo) {
33 struct infiRdmaPacket *rdmaPacket = malloc(sizeof(struct infiRdmaPacket));
34 rdmaPacket->type = INFI_ONESIDED;
35 rdmaPacket->localBuffer = recvOpInfo;
37 uint64_t local_addr = recvOpInfo->local_addr;
38 uint64_t remote_addr = recvOpInfo->remote_addr;
39 int size = recvOpInfo->size;
40 uint32_t rkey = recvOpInfo->key;
42 #if CMK_IBVERBS_TOKENS_FLOW
43 context->tokensLeft--;
44 #if CMK_IBVERBS_STATS
45 if(context->tokensLeft < minTokensLeft)
46 minTokensLeft = context->tokensLeft;
47 #endif
48 #endif
50 struct ibv_mr *mr;
51 mr = ibv_reg_mr(context->pd, (void *)local_addr, size, IBV_ACCESS_LOCAL_WRITE |
52 IBV_ACCESS_REMOTE_WRITE | IBV_ACCESS_REMOTE_READ);
53 if (!mr) {
54 MACHSTATE(3, "ibv_reg_mr() failed\n");
56 recvOpInfo->local_mr = mr;
58 struct ibv_sge list = {
59 .addr = (uintptr_t)local_addr,
60 .length = size,
61 .lkey = mr->lkey
64 struct ibv_send_wr *bad_wr;
65 struct ibv_send_wr wr = {
66 .wr_id = (uint64_t)rdmaPacket,
67 .sg_list = &list,
68 .num_sge = 1,
69 .opcode = IBV_WR_RDMA_READ,
70 .send_flags = IBV_SEND_SIGNALED,
71 .wr.rdma = {
72 .remote_addr = remote_addr,
73 .rkey = rkey
77 OtherNode node = nodes_by_pe[peNum];
78 #if CMK_IBVERBS_TOKENS_FLOW
79 if(context->tokensLeft<0){
80 char errMsg[200];
81 sprintf(errMsg, "No remaining tokens! Pass a larger value for maxTokens (%d) using argument +IBVMaxSendTokens\n", maxTokens);
82 CmiAbort(errMsg);
84 #endif
86 int retval;
87 if (retval = ibv_post_send(node->infiData->qp, &wr, &bad_wr)) {
88 char errMsg[200];
89 CmiPrintf(" Pe:%d, Node:%d, thread id:%d infidata nodeno:[%d] failed with return value %d\n", CmiMyPe(), CmiMyNode(), CmiMyRank(), node->infiData->nodeNo, retval);
90 sprintf(errMsg,"ibv_post_send failed in verbsOnesidedPostRdmaRead!! Try passing a larger value for maxTokens (%d) using argument +IBVMaxSendTokens\n",maxTokens);
91 CmiAbort(errMsg);
95 void LrtsIssueRgets(void *recv, int pe) {
96 CmiVerbsRdmaRecv_t* recvInfo = (CmiVerbsRdmaRecv_t*)recv;
97 int peNum = recvInfo->peNum;
98 int i;
100 for (i = 0; i < recvInfo->numOps; i++)
101 verbsOnesidedPostRdmaRead(peNum, &recvInfo->rdmaOp[i]);
104 /* function to send the acknowledgement to the sender */
105 void verbsOnesidedSendAck(int peNum, CmiVerbsRdmaRecvOp_t *recvOpInfo) {
106 struct infiRdmaPacket *rdmaPacket = (struct infiRdmaPacket *)CmiAlloc(sizeof(struct infiRdmaPacket));
107 rdmaPacket->fromNodeNo = CmiNodeOf(peNum);
108 rdmaPacket->type = INFI_ONESIDED;
109 rdmaPacket->keyPtr = recvOpInfo->remote_mr;
110 rdmaPacket->localBuffer = recvOpInfo->src_info;
112 EnqueueRdmaAck(rdmaPacket);
113 CmiFree(rdmaPacket);
116 /* function called on the sender on receiving acknowledgement
117 * from the receiver to signal the completion of the rdma operation */
118 void verbsOnesidedReceivedAck(struct infiRdmaPacket *rdmaPacket) {
119 struct ibv_mr *mr = rdmaPacket->keyPtr;
120 if (ibv_dereg_mr(mr)) {
121 MACHSTATE(3, "ibv_dereg_mr() failed\n");
124 CmiRdmaAck *ack = rdmaPacket->localBuffer;
125 ack->fnPtr(ack->token);
127 //free callback structure, CmiRdmaAck allocated in CmiSetRdmaAck
128 free(ack);