Example #1
0
/*
 * 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;
}
Example #2
0
/*
 * 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;
}