static void uct_ud_dump_neth(uct_ud_iface_t *iface, uct_am_trace_type_t type, char *p, int max, uct_ud_neth_t *neth, int pkt_len) { int n, ret = 0; uint32_t dest_id; uint32_t am_id; uint32_t is_am; uint32_t ack_req; uint32_t is_ctl; uint32_t is_put; dest_id = uct_ud_neth_get_dest_id(neth); am_id = uct_ud_neth_get_am_id(neth); is_am = neth->packet_type & UCT_UD_PACKET_FLAG_AM; ack_req = neth->packet_type & UCT_UD_PACKET_FLAG_ACK_REQ; is_ctl = neth->packet_type & UCT_UD_PACKET_FLAG_CTL; is_put = neth->packet_type & UCT_UD_PACKET_FLAG_PUT; n = snprintf(p, max, "PKT: dst=0x%x psn=%u ack=%u dlen=%u ", (unsigned)dest_id, (unsigned)neth->psn, (unsigned)neth->ack_psn, (unsigned)(pkt_len - sizeof(*neth)) ); p += n; max -= n; if (is_am) { n = snprintf(p, max, "AM: %d", am_id); p += n; max -= n; uct_iface_dump_am(&iface->super.super, type, am_id, neth + 1, pkt_len - sizeof(*neth), p, max); n = strlen(p); p += n; max -= n; } else if (is_put) { uct_ud_put_hdr_t *put_hdr; put_hdr = (uct_ud_put_hdr_t *)(neth+1); n = snprintf(p, max, "PUT: 0x%0lx", (unsigned long)put_hdr->rva); p += n; max -= n; ret += n; } else if (is_ctl) { uct_ud_ctl_hdr_t *ctl_hdr = (uct_ud_ctl_hdr_t *)(neth+1); ctl_hdr = (uct_ud_ctl_hdr_t *)(neth+1); switch(ctl_hdr->type) { case UCT_UD_PACKET_CREQ: n = snprintf(p, max, "CREQ: qp=%x lid=%d epid=%d cid=%d ", ctl_hdr->conn_req.ib_addr.qp_num, ctl_hdr->conn_req.ib_addr.lid, ctl_hdr->conn_req.ib_addr.id, ctl_hdr->conn_req.conn_id); p += n; max -= n; break; case UCT_UD_PACKET_CREP: n = snprintf(p, max, "CREP: src_ep_id=%d ", ctl_hdr->conn_rep.src_ep_id); p += n; max -= n; break; default: n = snprintf(p, max, "WTF_CTL"); p += n; max -= n; break; } } else if (pkt_len != sizeof(neth)) { n = snprintf(p, max, "WTF UKNOWN DATA"); p += n; max -= n; } if (ack_req) { n = snprintf(p, max, " ACK_REQ"); p += n; max -= n; } /* dump raw neth since it helps out to debug sniffer traces */ { int i; char *base = (char *)neth; n = snprintf(p, max, " NETH "); p += n; max -= n; for (i = 0; i < sizeof(*neth); i++) { n = snprintf(p, max, "%02X ", (unsigned)(char)base[i]); p += n; max -= n; } } }
void uct_ud_ep_process_rx(uct_ud_iface_t *iface, uct_ud_neth_t *neth, unsigned byte_len, uct_ud_recv_skb_t *skb) { uint32_t dest_id; uint32_t is_am, am_id; uct_ud_ep_t *ep = 0; /* todo: check why gcc complaints about uninitialized var */ ucs_frag_list_ooo_type_t ooo_type; dest_id = uct_ud_neth_get_dest_id(neth); am_id = uct_ud_neth_get_am_id(neth); is_am = neth->packet_type & UCT_UD_PACKET_FLAG_AM; if (ucs_unlikely(dest_id == UCT_UD_EP_NULL_ID)) { /* must be connection request packet */ uct_ud_iface_log_rx(iface, NULL, neth, byte_len); uct_ud_ep_rx_creq(iface, neth); goto out; } else if (ucs_unlikely(!ucs_ptr_array_lookup(&iface->eps, dest_id, ep) || ep->ep_id != dest_id)) { uct_ud_iface_log_rx(iface, ep, neth, byte_len); /* TODO: in the future just drop the packet */ ucs_fatal("Faied to find ep(%d)", dest_id); goto out; } uct_ud_iface_log_rx(iface, ep, neth, byte_len); ucs_assert(ep->ep_id != UCT_UD_EP_NULL_ID); UCT_UD_EP_HOOK_CALL_RX(ep, neth); uct_ud_ep_process_ack(iface, ep, neth->ack_psn); if (ucs_unlikely(neth->packet_type & UCT_UD_PACKET_FLAG_ACK_REQ)) { uct_ud_iface_queue_pending(iface, ep, UCT_UD_EP_OP_ACK); } if (ucs_unlikely(!is_am && (byte_len == sizeof(*neth)))) { goto out; } ooo_type = ucs_frag_list_insert(&ep->rx.ooo_pkts, &skb->ooo_elem, neth->psn); if (ucs_unlikely(ooo_type != UCS_FRAG_LIST_INSERT_FAST)) { ucs_fatal("Out of order is not implemented: got %d", ooo_type); goto out; } if (ucs_unlikely(!is_am && (neth->packet_type & UCT_UD_PACKET_FLAG_CTL))) { uct_ud_ep_rx_ctl(iface, ep, (uct_ud_ctl_hdr_t *)(neth + 1)); goto out; } if (ucs_unlikely(!is_am && (neth->packet_type & UCT_UD_PACKET_FLAG_PUT))) { uct_ud_ep_rx_put(neth, byte_len); goto out; } uct_ib_iface_invoke_am(&iface->super, am_id, neth + 1, byte_len - sizeof(*neth), &skb->super); return; out: ucs_mpool_put(skb); }