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) { int ret; struct rxd_rx_entry *rx_entry; struct rxd_pkt_data_start *pkt_start; pkt_start = (struct rxd_pkt_data_start *) ctrl; rxd_ep_lock_if_required(ep); 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 == RXD_PKT_ORDR_DUP) { 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 if (ret == RXD_PKT_ORDR_UNEXP) { FI_DBG(&rxd_prov, FI_LOG_EP_CTRL, "unexpected pkt: %d\n", ctrl->seg_no); rxd_ep_enqueue_pkt(ep, ctrl, comp); goto out; } rx_entry = rxd_get_rx_entry(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->caps & FI_DIRECTED_RECV) ? rxd_av_get_fi_addr(ep->av, ctrl->conn_id) : FI_ADDR_UNSPEC; rx_entry->window = 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_release(ep, rx_entry); else if (ret == -FI_ENOENT) { peer->exp_msg_id++; /* reply ack, with win_sz = 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: if (comp->flags & RXD_UNEXP_ENTRY) { rxd_release_unexp_entry(ep->rx_cq, comp); ep->num_unexp_pkt--; } rxd_ep_repost_buff(rx_buf); out: rxd_ep_unlock_if_required(ep); return; }
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; }