Test(dg_allocation, dgram_pack_unpack) { int ret = 0; ssize_t len; struct gnix_cm_nic *cm_nic; struct gnix_datagram *dgram_ptr; char in_buf[] = "0xdeadbeef"; char out_buf[GNI_DATAGRAM_MAXSIZE]; ep_priv = container_of(ep, struct gnix_fid_ep, ep_fid); cm_nic = ep_priv->cm_nic; cr_assert((cm_nic != NULL), "cm_nic NULL"); cr_assert((cm_nic->dgram_hndl != NULL), "cm_nic dgram_hndl NULL"); ret = _gnix_dgram_alloc(cm_nic->dgram_hndl, GNIX_DGRAM_BND, &dgram_ptr); cr_assert(!ret, "_gnix_dgram_alloc bnd"); /* * check pack/unpack for GNIX_DGRAM_IN_BUF */ len = _gnix_dgram_pack_buf(dgram_ptr, GNIX_DGRAM_IN_BUF, in_buf, sizeof(in_buf)); cr_assert(len > 0); cr_assert_eq(len, (ssize_t)sizeof(in_buf)); len = _gnix_dgram_unpack_buf(dgram_ptr, GNIX_DGRAM_IN_BUF, out_buf, sizeof(in_buf)); cr_assert(len > 0); cr_assert_eq(len, (ssize_t)sizeof(in_buf)); cr_assert_eq(0, strcmp(in_buf, out_buf)); /* * check pack/unpack for GNIX_DGRAM_OUT_BUF */ len = _gnix_dgram_pack_buf(dgram_ptr, GNIX_DGRAM_OUT_BUF, in_buf, sizeof(in_buf)); cr_assert(len > 0); cr_assert_eq(len, (ssize_t)sizeof(in_buf)); memset(out_buf, 0, sizeof(out_buf)); len = _gnix_dgram_unpack_buf(dgram_ptr, GNIX_DGRAM_OUT_BUF, out_buf, sizeof(in_buf)); cr_assert(len > 0); cr_assert_eq(len, (ssize_t)sizeof(in_buf)); cr_assert_eq(0, strcmp(in_buf, out_buf)); ret = _gnix_dgram_free(dgram_ptr); cr_assert(!ret, "_gnix_dgram_free bnd"); }
static void __dgram_set_tag(struct gnix_datagram *d, uint8_t tag) { _gnix_dgram_pack_buf(d, GNIX_DGRAM_IN_BUF, &tag, sizeof(uint8_t)); }
int _gnix_cm_nic_send(struct gnix_cm_nic *cm_nic, char *sbuf, size_t len, struct gnix_address target_addr) { int ret = FI_SUCCESS; struct gnix_datagram *dgram = NULL; ssize_t __attribute__((unused)) plen; uint8_t tag; struct gnix_work_req *work_req; GNIX_TRACE(FI_LOG_EP_CTRL, "\n"); if ((cm_nic == NULL) || (sbuf == NULL)) return -FI_EINVAL; if (len > GNI_DATAGRAM_MAXSIZE) return -FI_ENOSPC; ret = _gnix_dgram_alloc(cm_nic->dgram_hndl, GNIX_DGRAM_BND, &dgram); if (ret != FI_SUCCESS) { GNIX_WARN(FI_LOG_EP_CTRL, "_gnix_dgram_alloc returned %s\n", fi_strerror(-ret)); goto exit; } dgram->target_addr = target_addr; dgram->callback_fn = __process_datagram; dgram->cache = cm_nic; tag = GNIX_CM_NIC_BND_TAG; __dgram_set_tag(dgram, tag); plen = _gnix_dgram_pack_buf(dgram, GNIX_DGRAM_IN_BUF, sbuf, len); assert (plen == len); /* If connecting with the same CM NIC, skip datagram exchange. The * caller could be holding an endpoint lock, so schedule connection * completion for later. */ if (GNIX_ADDR_EQUAL(target_addr, cm_nic->my_name.gnix_addr)) { char tmp_buf[GNIX_CM_NIC_MAX_MSG_SIZE]; /* Pack output buffer with input data. */ _gnix_dgram_unpack_buf(dgram, GNIX_DGRAM_IN_BUF, tmp_buf, GNIX_CM_NIC_MAX_MSG_SIZE); _gnix_dgram_pack_buf(dgram, GNIX_DGRAM_OUT_BUF, tmp_buf, GNIX_CM_NIC_MAX_MSG_SIZE); work_req = calloc(1, sizeof(*work_req)); if (work_req == NULL) { _gnix_dgram_free(dgram); return -FI_ENOMEM; } work_req->progress_fn = __gnix_cm_nic_intra_progress_fn; work_req->data = dgram; work_req->completer_fn = NULL; fastlock_acquire(&cm_nic->wq_lock); dlist_insert_before(&work_req->list, &cm_nic->cm_nic_wq); fastlock_release(&cm_nic->wq_lock); GNIX_INFO(FI_LOG_EP_CTRL, "Initiated intra-CM NIC connect\n"); } else { ret = _gnix_dgram_bnd_post(dgram); if (ret == -FI_EBUSY) { ret = -FI_EAGAIN; _gnix_dgram_free(dgram); } } exit: return ret; }