Exemple #1
0
ssize_t	rxd_ep_readmsg(struct fid_ep *ep, const struct fi_msg_rma *msg,
		       uint64_t flags)
{
	struct rxd_ep *rxd_ep;
	struct rxd_peer *peer;
	struct rxd_tx_entry *tx_entry;
	uint64_t peer_addr;
	ssize_t ret;

	rxd_ep = container_of(ep, struct rxd_ep, util_ep.ep_fid);

	peer_addr = rxd_av_dg_addr(rxd_ep_av(rxd_ep), msg->addr);
	peer = rxd_ep_getpeer_info(rxd_ep, peer_addr);

	fastlock_acquire(&rxd_ep->lock);
	if (peer->state != CMAP_CONNECTED) {
		ret = rxd_ep_connect(rxd_ep, peer, peer_addr);
		fastlock_release(&rxd_ep->lock);
		if (ret == -FI_EALREADY) {
			rxd_ep->util_ep.progress(&rxd_ep->util_ep);
			ret = -FI_EAGAIN;
		}
		return ret ? ret : -FI_EAGAIN;
	}

	tx_entry = rxd_tx_entry_alloc(rxd_ep, peer, peer_addr, flags,
				      RXD_TX_READ_REQ);
	if (!tx_entry) {
		ret = -FI_EAGAIN;
		goto out;
	}

	tx_entry->read_req.msg = *msg;
	memcpy(&tx_entry->read_req.dst_iov[0], msg->msg_iov,
	       sizeof(*msg->msg_iov)* msg->iov_count);
	memcpy(&tx_entry->read_req.src_iov[0], msg->rma_iov,
	       sizeof(*msg->rma_iov) * msg->rma_iov_count);
	ret = rxd_ep_start_xfer(rxd_ep, peer, ofi_op_read_req, tx_entry);
	if (ret)
		rxd_tx_entry_free(rxd_ep, tx_entry);

out:
	fastlock_release(&rxd_ep->lock);
	return ret;
}
Exemple #2
0
static ssize_t rxd_generic_write_inject(struct rxd_ep *rxd_ep,
		const struct iovec *iov, size_t iov_count,
		const struct fi_rma_iov *rma_iov, size_t rma_count,
		fi_addr_t addr, void *context, uint32_t op, uint64_t data,
		uint32_t rxd_flags)
{
	struct rxd_x_entry *tx_entry;
	fi_addr_t rxd_addr;
	ssize_t ret = -FI_EAGAIN;

	assert(iov_count <= RXD_IOV_LIMIT && rma_count <= RXD_IOV_LIMIT);
	assert(ofi_total_iov_len(iov, iov_count) <= rxd_ep_domain(rxd_ep)->max_inline_rma);

	fastlock_acquire(&rxd_ep->util_ep.lock);
	fastlock_acquire(&rxd_ep->util_ep.tx_cq->cq_lock);

	if (ofi_cirque_isfull(rxd_ep->util_ep.tx_cq->cirq))
		goto out;

	rxd_addr = rxd_ep_av(rxd_ep)->fi_addr_table[addr];
	ret = rxd_send_rts_if_needed(rxd_ep, rxd_addr);
	if (ret)
		goto out;

	tx_entry = rxd_tx_entry_init(rxd_ep, iov, iov_count, NULL, 0, rma_count, data,
				     0, context, rxd_addr, op, rxd_flags);
	if (!tx_entry)
		goto out;

	ret = rxd_ep_send_op(rxd_ep, tx_entry, rma_iov, rma_count, NULL, 0, 0, 0);
	if (ret) {
		rxd_tx_entry_free(rxd_ep, tx_entry);
		goto out;
	}

	if (tx_entry->op == RXD_READ_REQ)
		goto out;

	ret = 0;

out:
	fastlock_release(&rxd_ep->util_ep.tx_cq->cq_lock);
	fastlock_release(&rxd_ep->util_ep.lock);
	return ret;
}
Exemple #3
0
ssize_t rxd_generic_rma(struct rxd_ep *rxd_ep, const struct iovec *iov,
	size_t iov_count, const struct fi_rma_iov *rma_iov, size_t rma_count,
	void **desc, fi_addr_t addr, void *context, uint32_t op, uint64_t data,
	uint32_t rxd_flags)
{
	struct rxd_x_entry *tx_entry;
	fi_addr_t rxd_addr;
	ssize_t ret = -FI_EAGAIN;

	if (rxd_flags & RXD_INJECT)
		return rxd_generic_write_inject(rxd_ep, iov, iov_count, rma_iov,
						rma_count, addr, context, op,
						data, rxd_flags);

	assert(iov_count <= RXD_IOV_LIMIT && rma_count <= RXD_IOV_LIMIT);

	fastlock_acquire(&rxd_ep->util_ep.lock);
	fastlock_acquire(&rxd_ep->util_ep.tx_cq->cq_lock);

	if (ofi_cirque_isfull(rxd_ep->util_ep.tx_cq->cirq))
		goto out;

	rxd_addr = rxd_ep_av(rxd_ep)->fi_addr_table[addr];
	ret = rxd_send_rts_if_needed(rxd_ep, rxd_addr);
	if (ret)
		goto out;

	tx_entry = rxd_tx_entry_init(rxd_ep, iov, iov_count, NULL, 0, rma_count,
				     data, 0, context, rxd_addr, op, rxd_flags);
	if (!tx_entry)
		goto out;

	ret = rxd_ep_send_op(rxd_ep, tx_entry, rma_iov, rma_count, NULL, 0, 0, 0);
	if (ret)
		rxd_tx_entry_free(rxd_ep, tx_entry);

out:
	fastlock_release(&rxd_ep->util_ep.tx_cq->cq_lock);
	fastlock_release(&rxd_ep->util_ep.lock);
	return ret;
}
Exemple #4
0
static void rxd_handle_conn_req(struct rxd_ep *ep, struct ofi_ctrl_hdr *ctrl,
				struct fi_cq_msg_entry *comp,
				struct rxd_rx_buf *rx_buf)
{
	struct rxd_pkt_data *pkt_data;
	struct rxd_peer *peer_info;
	fi_addr_t dg_fiaddr;
	void *addr;
	int ret;

	FI_INFO(&rxd_prov, FI_LOG_EP_DATA,
	       "conn req - rx_key: %" PRIu64 "\n", ctrl->rx_key);

	pkt_data = (struct rxd_pkt_data *) ctrl;
	addr = pkt_data->data;
	if (ctrl->seg_size > RXD_MAX_DGRAM_ADDR) {
		FI_WARN(&rxd_prov, FI_LOG_EP_DATA, "addr too large\n");
		goto repost;
	}

	ret = rxd_av_insert_dg_addr(rxd_ep_av(ep), ctrl->rx_key, addr, &dg_fiaddr);
	if (ret) {
		FI_WARN(&rxd_prov, FI_LOG_EP_DATA, "failed to insert peer address\n");
		goto repost;
	}

	peer_info = rxd_ep_getpeer_info(ep, dg_fiaddr);
	if (peer_info->state != CMAP_CONNECTED) {
		peer_info->state = CMAP_CONNECTED;
		peer_info->conn_data = ctrl->conn_id;
		peer_info->exp_msg_id++;
	}

	rxd_ep_reply_ack(ep, ctrl, ofi_ctrl_connresp, 0, ctrl->conn_id,
			 dg_fiaddr, dg_fiaddr);
repost:
	rxd_ep_repost_buff(rx_buf);
}
Exemple #5
0
int rxd_ep_send_pkt(struct rxd_ep *ep, struct rxd_pkt_entry *pkt_entry)
{
	int ret;

	if (ep->pending_cnt >= ep->tx_size)
		return 1;

	pkt_entry->timestamp = fi_gettime_ms();

	ret = fi_send(ep->dg_ep, (const void *) rxd_pkt_start(pkt_entry),
		      pkt_entry->pkt_size, rxd_mr_desc(pkt_entry->mr, ep),
		      rxd_ep_av(ep)->rxd_addr_table[pkt_entry->peer].dg_addr,
		      &pkt_entry->context);
	if (ret) {
		FI_WARN(&rxd_prov, FI_LOG_EP_CTRL, "error sending packet: %d (%s)\n",
			ret, fi_strerror(-ret));
	} else {
		pkt_entry->flags |= RXD_PKT_IN_USE;
		ep->pending_cnt++;
	}

	return ret;
}
Exemple #6
0
static void rxd_handle_start_data(struct rxd_ep *ep, struct rxd_peer *peer,
				  struct ofi_ctrl_hdr *ctrl,
				  struct fi_cq_msg_entry *comp,
				  struct rxd_rx_buf *rx_buf)
{
	struct rxd_rx_entry *rx_entry;
	struct rxd_pkt_data_start *pkt_start;
	int ret;

	FI_DBG(&rxd_prov, FI_LOG_EP_CTRL,
	       "start data- msg_id: %" PRIu64 ", segno: %d, buf: %p\n",
	       ctrl->msg_id, ctrl->seg_no, rx_buf);

	pkt_start = (struct rxd_pkt_data_start *) ctrl;
	if (pkt_start->op.version != OFI_OP_VERSION) {
		FI_WARN(&rxd_prov, FI_LOG_EP_CTRL, "op version mismatch\n");
		goto repost;
	}

	ret = rxd_check_start_pkt_order(ep, peer, ctrl, comp);
	if (ret) {
		if (ret == -FI_EALREADY) {
			FI_DBG(&rxd_prov, FI_LOG_EP_CTRL, "duplicate pkt: %d\n",
				ctrl->seg_no);
			rxd_handle_dup_datastart(ep, ctrl, rx_buf);
			goto repost;
		} else {
			FI_DBG(&rxd_prov, FI_LOG_EP_CTRL, "unexpected pkt: %d\n",
				ctrl->seg_no);
			goto repost;
		}
	}

	rx_entry = rxd_rx_entry_alloc(ep);
	if (!rx_entry)
		goto repost;

	rx_entry->peer_info = peer;
	rx_entry->op_hdr = pkt_start->op;
	rx_entry->exp_seg_no = 0;
	rx_entry->msg_id = ctrl->msg_id;
	rx_entry->done = 0;
	rx_entry->peer = ctrl->conn_id;
	rx_entry->source = (ep->util_ep.caps & FI_DIRECTED_RECV) ?
		rxd_av_fi_addr(rxd_ep_av(ep), ctrl->conn_id) : FI_ADDR_UNSPEC;
	rx_entry->credits = 1;
	rx_entry->last_win_seg = 1;

	FI_DBG(&rxd_prov, FI_LOG_EP_CTRL, "Assign rx_entry :%d for  %p\n",
	       rx_entry->key, rx_entry->msg_id);

	ep->credits--;
	ret = rxd_process_start_data(ep, rx_entry, peer, ctrl, comp, rx_buf);
	if (ret == -FI_ENOMEM)
		rxd_rx_entry_free(ep, rx_entry);
	else if (ret == -FI_ENOENT) {
		peer->exp_msg_id++;

		/* reply ack, with no window = 0 */
		FI_DBG(&rxd_prov, FI_LOG_EP_CTRL, "Sending wait-ACK [%p] - %d\n",
			ctrl->msg_id, ctrl->seg_no);
		goto out;
	} else {
		peer->exp_msg_id++;
	}

repost:
	rxd_ep_repost_buff(rx_buf);
out:
	assert(rxd_reposted_bufs);
	return;
}