/* * rpmemd_fip_worker -- worker callback which processes persist * operation in GPSPM */ static int rpmemd_fip_worker(void *arg, void *data) { struct rpmemd_fip *fip = arg; struct rpmemd_fip_lane *lanep = data; int ret = 0; /* wait until last SEND message has been processed */ rpmem_fip_lane_wait(&lanep->lane, FI_SEND); /* * Get persist message and persist message response from appropriate * buffers. The persist message is in lane's RECV buffer and the * persist response message in lane's SEND buffer. */ struct rpmem_msg_persist *pmsg = rpmem_fip_msg_get_pmsg(&lanep->recv); struct rpmem_msg_persist_resp *pres = rpmem_fip_msg_get_pres(&lanep->send); /* verify persist message */ ret = rpmemd_fip_check_pmsg(fip, pmsg); if (unlikely(ret)) goto err; /* return back the lane id */ pres->lane = pmsg->lane; /* * Perform the persist operation. * * XXX * * Maybe the persist could be divided into flush + drain. * We could issue flush operation, do some other work like * posting RECV buffer and then call drain. Need to consider this. */ fip->persist((void *)pmsg->addr, pmsg->size); /* post lane's RECV buffer */ ret = rpmemd_fip_gpspm_post_msg(fip, &lanep->recv); if (unlikely(ret)) goto err; /* initialize lane for waiting for SEND completion */ rpmem_fip_lane_begin(&lanep->lane, FI_SEND); /* post lane's SEND buffer */ ret = rpmemd_fip_gpspm_post_resp(fip, &lanep->send); if (unlikely(ret)) goto err; err: return ret; }
/* * rpmem_fip_process_gpspm -- (internal) process completion queue entry for * GPSPM */ static int rpmem_fip_process_gpspm(struct rpmem_fip *fip, void *context, uint64_t flags) { if (flags & FI_RECV) { /* RECV completion */ struct rpmem_fip_msg *resp = context; struct rpmem_msg_persist_resp *msg_resp = rpmem_fip_msg_get_pres(resp); VALGRIND_DO_MAKE_MEM_DEFINED(msg_resp, sizeof(*msg_resp)); if (unlikely(msg_resp->lane >= fip->nlanes)) { RPMEM_LOG(ERR, "lane number received (%lu) is greater " "than maximum lane number (%u)", msg_resp->lane, fip->nlanes - 1); return -1; } struct rpmem_fip_lane *lanep = &fip->lanes.gpspm[msg_resp->lane].lane; /* post RECV buffer immediately */ int ret = rpmem_fip_gpspm_post_resp(fip, resp); if (unlikely(ret)) RPMEM_FI_ERR((int)ret, "MSG send"); rpmem_fip_lane_sigret(lanep, flags, ret); return ret; } struct rpmem_fip_lane *lanep = context; /* SEND completion */ rpmem_fip_lane_signal(lanep, flags); return 0; }