Test(dg_allocation, dgram_wc_post_exchg) { int ret = 0; struct gnix_cm_nic *cm_nic; struct gnix_datagram *dgram_wc, *dgram_bnd; 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_WC, &dgram_wc); cr_assert(!ret, "_gnix_dgram_alloc wc"); dgram_wc->callback_fn = dgram_callback_fn; ret = _gnix_dgram_wc_post(dgram_wc); cr_assert((ret == 0), "_gnix_dgram_alloc wc"); ret = _gnix_dgram_alloc(cm_nic->dgram_hndl, GNIX_DGRAM_BND, &dgram_bnd); cr_assert((ret == 0), "_gnix_dgram_alloc bnd"); dgram_bnd->target_addr = cm_nic->my_name.gnix_addr; local_address = cm_nic->my_name.gnix_addr; dgram_bnd->callback_fn = dgram_callback_fn; ret = _gnix_dgram_bnd_post(dgram_bnd); cr_assert(ret == 0); /* * progress auto, don't need to do anything */ while (dgram_match != 1) { ret = _gnix_cm_nic_progress(cm_nic); cr_assert(ret == 0); pthread_yield(); } ret = _gnix_dgram_free(dgram_bnd); cr_assert(!ret, "_gnix_dgram_free bnd"); ret = _gnix_dgram_free(dgram_wc); cr_assert(!ret, "_gnix_dgram_free wc"); }
static int __process_datagram(struct gnix_datagram *dgram, struct gnix_address peer_address, gni_post_state_t state) { int ret = FI_SUCCESS; struct gnix_cm_nic *cm_nic = NULL; uint8_t in_tag = 0, out_tag = 0; char rcv_buf[GNIX_CM_NIC_MAX_MSG_SIZE]; GNIX_TRACE(FI_LOG_EP_CTRL, "\n"); cm_nic = (struct gnix_cm_nic *)dgram->cache; if (cm_nic == NULL) { GNIX_WARN(FI_LOG_EP_CTRL, "process_datagram, null cache\n"); goto err; } if (state != GNI_POST_COMPLETED) { ret = __process_dgram_w_error(cm_nic, dgram, peer_address, state); GNIX_WARN(FI_LOG_EP_CTRL, "process_datagram bad post state %d\n", state); goto err; } __dgram_get_in_tag(dgram, &in_tag); if ((in_tag != GNIX_CM_NIC_BND_TAG) && (in_tag != GNIX_CM_NIC_WC_TAG)) { GNIX_WARN(FI_LOG_EP_CTRL, "datagram with unknown in tag %d\n", in_tag); goto err; } __dgram_unpack_out_tag(dgram, &out_tag); if ((out_tag != GNIX_CM_NIC_BND_TAG) && (out_tag != GNIX_CM_NIC_WC_TAG)) { GNIX_WARN(FI_LOG_EP_CTRL, "datagram with unknown out tag %d\n", out_tag); goto err; } /* * if out buf actually has data, call consumer's * receive callback */ if (out_tag == GNIX_CM_NIC_BND_TAG) { _gnix_dgram_unpack_buf(dgram, GNIX_DGRAM_OUT_BUF, rcv_buf, GNIX_CM_NIC_MAX_MSG_SIZE); ret = cm_nic->rcv_cb_fn(cm_nic, rcv_buf, peer_address); if (ret != FI_SUCCESS) { GNIX_WARN(FI_LOG_EP_CTRL, "cm_nic->rcv_cb_fn returned %s\n", fi_strerror(-ret)); goto err; } ret = _gnix_cm_nic_progress(cm_nic); if (ret != FI_SUCCESS) GNIX_WARN(FI_LOG_EP_CTRL, "_gnix_cm_nic_progress returned %s\n", fi_strerror(-ret)); } /* * if we are processing a WC datagram, repost, otherwise * just put back on the freelist. */ if (in_tag == GNIX_CM_NIC_WC_TAG) { dgram->callback_fn = __process_datagram; dgram->cache = cm_nic; __dgram_set_tag(dgram, in_tag); ret = _gnix_dgram_wc_post(dgram); if (ret != FI_SUCCESS) { GNIX_WARN(FI_LOG_EP_CTRL, "_gnix_dgram_wc_post returned %s\n", fi_strerror(-ret)); goto err; } } else { ret = _gnix_dgram_free(dgram); if (ret != FI_SUCCESS) GNIX_WARN(FI_LOG_EP_CTRL, "_gnix_dgram_free returned %s\n", fi_strerror(-ret)); } return ret; err: if (in_tag == GNIX_CM_NIC_BND_TAG) _gnix_dgram_free(dgram); return ret; }
int _gnix_cm_nic_enable(struct gnix_cm_nic *cm_nic) { int i, ret = FI_SUCCESS; struct gnix_fid_fabric *fabric; struct gnix_datagram *dg_ptr; uint8_t tag = GNIX_CM_NIC_WC_TAG; GNIX_TRACE(FI_LOG_EP_CTRL, "\n"); if (cm_nic == NULL) return -FI_EINVAL; if (cm_nic->domain == NULL) { GNIX_FATAL(FI_LOG_EP_CTRL, "domain is NULL\n"); } if (cm_nic->domain->fabric == NULL) { GNIX_FATAL(FI_LOG_EP_CTRL, "fabric is NULL\n"); } fabric = cm_nic->domain->fabric; assert(cm_nic->dgram_hndl != NULL); for (i = 0; i < fabric->n_wc_dgrams; i++) { ret = _gnix_dgram_alloc(cm_nic->dgram_hndl, GNIX_DGRAM_WC, &dg_ptr); /* * wildcards may already be posted to the cm_nic, * so just break if -FI_EAGAIN is returned by * _gnix_dgram_alloc */ if (ret == -FI_EAGAIN) { ret = FI_SUCCESS; break; } if (ret != FI_SUCCESS) { GNIX_WARN(FI_LOG_EP_CTRL, "_gnix_dgram_alloc call returned %d\n", ret); goto err; } dg_ptr->callback_fn = __process_datagram; dg_ptr->cache = cm_nic; __dgram_set_tag(dg_ptr, tag); ret = _gnix_dgram_wc_post(dg_ptr); if (ret != FI_SUCCESS) { GNIX_WARN(FI_LOG_EP_CTRL, "_gnix_dgram_wc_post returned %d\n", ret); _gnix_dgram_free(dg_ptr); goto err; } } /* * TODO: better cleanup in error case */ err: return ret; }
struct gnix_datagram *dgram_wc, *dgram_bnd; 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->ctrl_progress == FI_PROGRESS_MANUAL); cr_assert((cm_nic->dgram_hndl != NULL), "cm_nic dgram_hndl NULL"); ret = _gnix_dgram_alloc(cm_nic->dgram_hndl, GNIX_DGRAM_WC, &dgram_wc); cr_assert(!ret, "_gnix_dgram_alloc wc"); dgram_wc->callback_fn = dgram_callback_fn; ret = _gnix_dgram_wc_post(dgram_wc); cr_assert((ret == 0), "_gnix_dgram_alloc wc"); ret = _gnix_dgram_alloc(cm_nic->dgram_hndl, GNIX_DGRAM_BND, &dgram_bnd); cr_assert((ret == 0), "_gnix_dgram_alloc bnd"); dgram_bnd->target_addr = cm_nic->my_name.gnix_addr; local_address = cm_nic->my_name.gnix_addr; dgram_bnd->callback_fn = dgram_callback_fn; ret = _gnix_dgram_bnd_post(dgram_bnd); cr_assert(ret == 0); /*