/* * rpmemd_fip_init_gpspm -- initialize GPSPM resources */ static int rpmemd_fip_init_gpspm(struct rpmemd_fip *fip) { int ret; /* allocate persist message buffer */ size_t msg_size = fip->nlanes * sizeof(struct rpmem_msg_persist); fip->pmsg = malloc(msg_size); if (!fip->pmsg) { RPMEMD_LOG(ERR, "!allocating GPSPM messages buffer"); goto err_msg_malloc; } /* register persist message buffer */ ret = fi_mr_reg(fip->domain, fip->pmsg, msg_size, FI_RECV, 0, 0, 0, &fip->pmsg_mr, NULL); if (ret) { RPMEMD_FI_ERR(ret, "registering GPSPM messages buffer"); goto err_mr_reg_msg; } /* get persist message buffer's local descriptor */ fip->pmsg_mr_desc = fi_mr_desc(fip->pmsg_mr); /* allocate persist response message buffer */ size_t msg_resp_size = fip->nlanes * sizeof(struct rpmem_msg_persist_resp); fip->pres = malloc(msg_resp_size); if (!fip->pres) { RPMEMD_FI_ERR(ret, "allocating GPSPM messages response buffer"); goto err_msg_resp_malloc; } /* register persist response message buffer */ ret = fi_mr_reg(fip->domain, fip->pres, msg_resp_size, FI_SEND, 0, 0, 0, &fip->pres_mr, NULL); if (ret) { RPMEMD_FI_ERR(ret, "registering GPSPM messages " "response buffer"); goto err_mr_reg_msg_resp; } /* get persist message buffer's local descriptor */ fip->pres_mr_desc = fi_mr_desc(fip->pres_mr); /* allocate lanes structures */ fip->lanes = malloc(fip->nlanes * sizeof(*fip->lanes)); if (!fip->lanes) { RPMEMD_LOG(ERR, "!allocating lanes"); goto err_alloc_lanes; } /* initialize lanes */ unsigned i; for (i = 0; i < fip->nlanes; i++) { struct rpmemd_fip_lane *lanep = &fip->lanes[i]; /* initialize basic lane structure */ ret = rpmem_fip_lane_init(&lanep->lane); if (ret) { RPMEMD_LOG(ERR, "!initializing lane"); goto err_lane_init; } /* initialize RECV message */ rpmem_fip_msg_init(&lanep->recv, fip->pmsg_mr_desc, 0, lanep, &fip->pmsg[i], sizeof(fip->pmsg[i]), FI_COMPLETION); /* initialize SEND message */ rpmem_fip_msg_init(&lanep->send, fip->pres_mr_desc, 0, lanep, &fip->pres[i], sizeof(fip->pres[i]), FI_COMPLETION); } return 0; err_lane_init: for (unsigned j = 0; j < i; j++) rpmem_fip_lane_fini(&fip->lanes[i].lane); err_alloc_lanes: RPMEMD_FI_CLOSE(fip->pres_mr, "unregistering GPSPM messages response buffer"); err_mr_reg_msg_resp: free(fip->pres); err_msg_resp_malloc: RPMEMD_FI_CLOSE(fip->pmsg_mr, "unregistering GPSPM messages buffer"); err_mr_reg_msg: free(fip->pmsg); err_msg_malloc: return -1; }
/* * rpmem_fip_init_lanes_gpspm -- (internal) initialize lanes for GPSPM */ static int rpmem_fip_init_lanes_gpspm(struct rpmem_fip *fip) { int ret = 0; /* allocate GPSPM lanes */ fip->lanes.gpspm = calloc(1, fip->nlanes * sizeof(*fip->lanes.gpspm)); if (!fip->lanes.gpspm) { RPMEM_LOG(ERR, "allocating GPSPM lanes"); goto err_malloc_lanes; } /* allocate persist messages buffer */ size_t msg_size = fip->nlanes * sizeof(struct rpmem_msg_persist); fip->pmsg = malloc(msg_size); if (!fip->pmsg) { RPMEM_LOG(ERR, "!allocating messages buffer"); ret = -1; goto err_malloc_pmsg; } /* * Register persist messages buffer. The persist messages * are sent to daemon thus the FI_SEND access flag. */ ret = fi_mr_reg(fip->domain, fip->pmsg, msg_size, FI_SEND, 0, 0, 0, &fip->pmsg_mr, NULL); if (ret) { RPMEM_FI_ERR(ret, "registering messages buffer"); goto err_fi_mr_reg_pmsg; } /* get persist messages buffer local descriptor */ fip->pmsg_mr_desc = fi_mr_desc(fip->pmsg_mr); /* allocate persist response messages buffer */ size_t msg_resp_size = fip->nlanes * sizeof(struct rpmem_msg_persist_resp); fip->pres = malloc(msg_resp_size); if (!fip->pres) { RPMEM_LOG(ERR, "!allocating messages response buffer"); ret = -1; goto err_malloc_pres; } /* * Register persist messages response buffer. The persist response * messages are received from daemon thus the FI_RECV access flag. */ ret = fi_mr_reg(fip->domain, fip->pres, msg_resp_size, FI_RECV, 0, 0, 0, &fip->pres_mr, NULL); if (ret) { RPMEM_FI_ERR(ret, "registering messages response buffer"); goto err_fi_mr_reg_pres; } /* get persist response messages buffer local descriptor */ fip->pres_mr_desc = fi_mr_desc(fip->pres_mr); /* allocate RECV structures for fi_recvmsg(3) */ fip->recv = malloc(fip->nlanes * sizeof(*fip->recv)); if (!fip->recv) { RPMEM_LOG(ERR, "!allocating response message iov buffer"); goto err_malloc_recv; } /* * Initialize all required structures for: * WRITE, SEND and RECV operations. * * If the completion is required the FI_COMPLETION flag and * appropriate context should be used. * * In GPSPM only the RECV and SEND completions are required. * * For RECV the context is RECV operation structure used for * fi_recvmsg(3) function call. * * For SEND the context is lane structure. * * The received buffer contains a lane id which is used * to obtain a lane which must be signaled that operation * has been completed. */ unsigned i; for (i = 0; i < fip->nlanes; i++) { ret = rpmem_fip_lane_init(&fip->lanes.gpspm[i].lane); if (ret) goto err_lane_init; /* WRITE */ rpmem_fip_rma_init(&fip->lanes.gpspm[i].write, fip->mr_desc, 0, fip->rkey, &fip->lanes.gpspm[i], 0); /* SEND */ rpmem_fip_msg_init(&fip->lanes.gpspm[i].send, fip->pmsg_mr_desc, 0, &fip->lanes.gpspm[i], &fip->pmsg[i], sizeof(fip->pmsg[i]), FI_COMPLETION); /* RECV */ rpmem_fip_msg_init(&fip->recv[i], fip->pres_mr_desc, 0, &fip->recv[i], &fip->pres[i], sizeof(fip->pres[i]), FI_COMPLETION); } return 0; err_lane_init: for (unsigned j = 0; j < i; j++) rpmem_fip_lane_fini(&fip->lanes.gpspm[i].lane); err_malloc_recv: RPMEM_FI_CLOSE(fip->pres_mr, "unregistering messages " "response buffer"); err_fi_mr_reg_pres: free(fip->pres); err_malloc_pres: RPMEM_FI_CLOSE(fip->pmsg_mr, "unregistering messages buffer"); err_fi_mr_reg_pmsg: free(fip->pmsg); err_malloc_pmsg: free(fip->lanes.gpspm); err_malloc_lanes: return ret; }