ssize_t usdf_dgram_sendv(struct fid_ep *fep, const struct iovec *iov, void **desc, size_t count, fi_addr_t dest_addr, void *context) { struct usd_dest *dest; struct usdf_ep *ep; size_t len; ep = ep_ftou(fep); len = sizeof(struct usd_udp_hdr); dest = (struct usd_dest *)(uintptr_t) dest_addr; len += _usdf_iov_len(iov, count); if (len <= USD_SEND_MAX_COPY) { return _usdf_dgram_send_iov_copy(ep, dest, iov, count, context, ep->ep_tx_completion); } else if (ep->e.dg.tx_op_flags & FI_INJECT) { USDF_DBG_SYS(EP_DATA, "given inject length (%zu) exceeds max inject length (%d)\n", len, USD_SEND_MAX_COPY); return -FI_ENOSPC; } if (count > ep->e.dg.tx_iov_limit) { USDF_DBG_SYS(EP_DATA, "max iov count exceeded: %zu\n", count); return -FI_ENOSPC; } return _usdf_dgram_send_iov(ep, dest, iov, count, context, ep->ep_tx_completion); }
ssize_t usdf_dgram_prefix_sendv(struct fid_ep *fep, const struct iovec *iov, void **desc, size_t count, fi_addr_t dest_addr, void *context) { struct usdf_ep *ep; struct usd_dest *dest; struct usd_wq *wq; struct usd_qp_impl *qp; struct usd_udp_hdr *hdr; uint32_t last_post; struct usd_wq_post_info *info; struct iovec send_iov[USDF_DGRAM_MAX_SGE]; size_t len; unsigned i; size_t padding; ep = ep_ftou(fep); dest = (struct usd_dest *)(uintptr_t) dest_addr; padding = USDF_HDR_BUF_ENTRY - sizeof(struct usd_udp_hdr); len = 0; for (i = 0; i < count; i++) { len += iov[i].iov_len; } if (len + sizeof(struct usd_udp_hdr) > USD_SEND_MAX_COPY) { qp = to_qpi(ep->e.dg.ep_qp); wq = &qp->uq_wq; hdr = (struct usd_udp_hdr *) ((char *) iov[0].iov_base + padding); memcpy(hdr, &dest->ds_dest.ds_udp.u_hdr, sizeof(*hdr)); /* adjust lengths and insert source port */ hdr->uh_ip.tot_len = htons(len - padding - sizeof(struct ether_header)); hdr->uh_udp.len = htons(len - padding - sizeof(struct ether_header) - sizeof(struct iphdr)); hdr->uh_udp.source = qp->uq_attrs.uqa_local_addr.ul_addr.ul_udp.u_addr.sin_port; memcpy(send_iov, iov, sizeof(struct iovec) * count); send_iov[0].iov_base = hdr; send_iov[0].iov_len -= padding; last_post = _usd_post_send_iov(wq, send_iov, count, 1); info = &wq->uwq_post_info[last_post]; info->wp_context = context; info->wp_len = len; } else { _usdf_dgram_send_iov_copy(ep, dest, iov, count, context); } return 0; }
ssize_t usdf_dgram_prefix_sendmsg(struct fid_ep *fep, const struct fi_msg *msg, uint64_t flags) { struct iovec send_iov[USDF_DGRAM_MAX_SGE]; struct usd_dest *dest; struct usdf_ep *ep; uint8_t completion; size_t len; size_t padding; ep = ep_ftou(fep); dest = (struct usd_dest *)(uintptr_t) msg->addr; len = _usdf_iov_len(msg->msg_iov, msg->iov_count); completion = ep->ep_tx_dflt_signal_comp || (flags & FI_COMPLETION); padding = USDF_HDR_BUF_ENTRY - sizeof(struct usd_udp_hdr); if (msg->iov_count > ep->e.dg.tx_iov_limit) { USDF_DBG_SYS(EP_DATA, "max iov count exceeded: %zu\n", msg->iov_count); return -FI_ENOSPC; } if ((len - padding) <= USD_SEND_MAX_COPY) { /* _usdf_dgram_send_iov_copy isn't prefix aware and allocates * its own prefix. reorganize iov[0] base to point to data and * len to reflect data length. */ memcpy(send_iov, msg->msg_iov, sizeof(struct iovec) * msg->iov_count); send_iov[0].iov_base = ((char *) send_iov[0].iov_base + USDF_HDR_BUF_ENTRY); send_iov[0].iov_len -= USDF_HDR_BUF_ENTRY; return _usdf_dgram_send_iov_copy(ep, dest, send_iov, msg->iov_count, msg->context, completion); } else if (flags & FI_INJECT) { USDF_DBG_SYS(EP_DATA, "given inject length (%zu) exceeds max inject length (%d)\n", len, USD_SEND_MAX_COPY); return -FI_ENOSPC; } return _usdf_dgram_send_iov_prefix(ep, dest, msg->msg_iov, msg->iov_count, msg->context, completion); }
ssize_t usdf_dgram_prefix_sendv(struct fid_ep *fep, const struct iovec *iov, void **desc, size_t count, fi_addr_t dest_addr, void *context) { struct iovec send_iov[USDF_DGRAM_MAX_SGE]; struct usd_dest *dest; struct usdf_ep *ep; size_t len; size_t padding; ep = ep_ftou(fep); dest = (struct usd_dest *)(uintptr_t) dest_addr; len = _usdf_iov_len(iov, count); padding = USDF_HDR_BUF_ENTRY - sizeof(struct usd_udp_hdr); if (count > ep->e.dg.tx_iov_limit) { USDF_DBG_SYS(EP_DATA, "max iov count exceeded: %zu\n", count); return -FI_ENOSPC; } if ((len - padding) <= USD_SEND_MAX_COPY) { /* _usdf_dgram_send_iov_copy isn't prefix aware and allocates * its own prefix. reorganize iov[0] base to point to data and * len to reflect data length. */ memcpy(send_iov, iov, sizeof(struct iovec) * count); send_iov[0].iov_base = ((char *) send_iov[0].iov_base + USDF_HDR_BUF_ENTRY); send_iov[0].iov_len -= USDF_HDR_BUF_ENTRY; return _usdf_dgram_send_iov_copy(ep, dest, send_iov, count, context, ep->ep_tx_completion); } else if (ep->e.dg.tx_op_flags & FI_INJECT) { USDF_DBG_SYS(EP_DATA, "given inject length (%zu) exceeds max inject length (%d)\n", len, USD_SEND_MAX_COPY); return -FI_ENOSPC; } return _usdf_dgram_send_iov_prefix(ep, dest, iov, count, context, ep->ep_tx_completion); }
ssize_t usdf_dgram_sendmsg(struct fid_ep *fep, const struct fi_msg *msg, uint64_t flags) { struct usd_dest *dest; struct usdf_ep *ep; uint8_t completion; size_t len; ep = ep_ftou(fep); len = sizeof(struct usd_udp_hdr); dest = (struct usd_dest *)(uintptr_t) msg->addr; completion = ep->ep_tx_dflt_signal_comp || (flags & FI_COMPLETION); len += _usdf_iov_len(msg->msg_iov, msg->iov_count); if (len <= USD_SEND_MAX_COPY) { return _usdf_dgram_send_iov_copy(ep, dest, msg->msg_iov, msg->iov_count, msg->context, completion); } else if (flags & FI_INJECT) { USDF_DBG_SYS(EP_DATA, "given inject length (%zu) exceeds max inject length (%d)\n", len, USD_SEND_MAX_COPY); return -FI_ENOSPC; } if (msg->iov_count > ep->e.dg.tx_iov_limit) { USDF_DBG_SYS(EP_DATA, "max iov count exceeded: %zu\n", msg->iov_count); return -FI_ENOSPC; } return _usdf_dgram_send_iov(ep, dest, msg->msg_iov, msg->iov_count, msg->context, completion); }