コード例 #1
0
ファイル: ugni_smsg_iface.c プロジェクト: brminich/ucx
static void process_mbox(uct_ugni_smsg_iface_t *iface, uct_ugni_smsg_ep_t *ep){
    ucs_status_t status;
    uint8_t tag;
    void *data_ptr;
    gni_return_t ugni_rc;
    uct_ugni_smsg_header_t *header;
    void *user_data;

    pthread_mutex_lock(&uct_ugni_global_lock);

    while(1){
        tag = GNI_SMSG_ANY_TAG;
        ugni_rc = GNI_SmsgGetNextWTag(ep->super.ep, (void **)&data_ptr, &tag);

        /* Yes, GNI_RC_NOT_DONE means that you're done with the smsg mailbox */
        if(GNI_RC_NOT_DONE == ugni_rc){
            pthread_mutex_unlock(&uct_ugni_global_lock);
            return;
        }

        if(GNI_RC_SUCCESS != ugni_rc){
            ucs_error("Unhandled smsg error: %s %d", gni_err_str[ugni_rc], ugni_rc);
            pthread_mutex_unlock(&uct_ugni_global_lock);
            return;
        }

        if(NULL == data_ptr){
            ucs_error("Empty data pointer in smsg.");
            pthread_mutex_unlock(&uct_ugni_global_lock);
            return;
        }

        header = (uct_ugni_smsg_header_t *)data_ptr;
        user_data = (void *)(header + 1);
        void *user_desc = iface->user_desc+1;

        uct_iface_trace_am(&iface->super.super, UCT_AM_TRACE_TYPE_RECV,
                           tag, user_data, header->length, "RX: AM");

        pthread_mutex_unlock(&uct_ugni_global_lock);
        status = uct_iface_invoke_am(&iface->super.super, tag, user_data,
                                     header->length, user_desc);
        pthread_mutex_lock(&uct_ugni_global_lock);

        if(status != UCS_OK){
            uct_recv_desc_iface(user_desc) = &iface->super.super.super;
            UCT_TL_IFACE_GET_TX_DESC(&iface->super.super, &iface->free_desc,
                                     iface->user_desc, iface->user_desc = NULL);
        }

        ugni_rc = GNI_SmsgRelease(ep->super.ep);
        if(GNI_RC_SUCCESS != ugni_rc){
            ucs_error("Unhandled smsg error in GNI_SmsgRelease: %s %d", gni_err_str[ugni_rc], ugni_rc);
            pthread_mutex_unlock(&uct_ugni_global_lock);
            return;
        }
    }
}
コード例 #2
0
ファイル: gnix_vc.c プロジェクト: metalpine/libfabric
/* Process a VC's SMSG mailbox. */
int _gnix_vc_dequeue_smsg(struct gnix_vc *vc)
{
	int ret = FI_SUCCESS;
	struct gnix_nic *nic;
	gni_return_t status;
	void *msg_ptr;
	uint8_t tag;

	GNIX_TRACE(FI_LOG_EP_DATA, "\n");

	assert(vc->gni_ep != NULL);
	assert(vc->conn_state == GNIX_VC_CONNECTED);

	nic = vc->ep->nic;
	assert(nic != NULL);

	do {
		tag = GNI_SMSG_ANY_TAG;
		status = GNI_SmsgGetNextWTag(vc->gni_ep,
					     &msg_ptr,
					     &tag);

		if (status == GNI_RC_SUCCESS) {
			GNIX_INFO(FI_LOG_EP_DATA, "Found RX (%p)\n", vc);
			ret = nic->smsg_callbacks[tag](vc, msg_ptr);
			if (ret != FI_SUCCESS) {
				/* Stalled, reschedule */
				break;
			}
		} else if (status == GNI_RC_NOT_DONE) {
			/* No more work. */
			ret = FI_SUCCESS;
			break;
		} else {
			GNIX_WARN(FI_LOG_EP_DATA,
				"GNI_SmsgGetNextWTag returned %s\n",
				gni_err_str[status]);
			ret = gnixu_to_fi_errno(status);
			break;
		}
	} while (1);

	return ret;
}
コード例 #3
0
/* progress */
int mca_btl_ugni_smsg_process (mca_btl_base_endpoint_t *ep)
{
    mca_btl_active_message_callback_t *reg;
    mca_btl_ugni_base_frag_t frag;
    mca_btl_base_segment_t seg;
    bool disconnect = false;
    uintptr_t data_ptr;
    gni_return_t rc;
    uint32_t len;
    int count = 0;

    if (!opal_atomic_cmpset_32 (&ep->smsg_progressing, 0, 1)) {
        /* already progressing (we can't support reentry here) */
        return 0;
    }

    /* per uGNI documentation we loop until the mailbox is empty */
    do {
        uint8_t tag = GNI_SMSG_ANY_TAG;

        rc = GNI_SmsgGetNextWTag (ep->smsg_ep_handle, (void **) &data_ptr, &tag);
        if (GNI_RC_NOT_DONE == rc) {
            BTL_VERBOSE(("no smsg message waiting. rc = %d", rc));

            ep->smsg_progressing = 0;

            return count;
        }

        if (OPAL_UNLIKELY(GNI_RC_SUCCESS != rc)) {
            fprintf (stderr, "Unhandled Smsg error: %d\n", rc);
            assert (0);
            return OMPI_ERROR;
        }

        if (OPAL_UNLIKELY(0 == data_ptr)) {
            BTL_ERROR(("null data ptr!"));
            assert (0);
            return OMPI_ERROR;
        }

        count++;

        BTL_VERBOSE(("got smsg fragment. tag = %d\n", tag));

        switch (tag) {
        case MCA_BTL_UGNI_TAG_SEND:
            frag.hdr.send = ((mca_btl_ugni_send_frag_hdr_t *) data_ptr)[0];

            tag = frag.hdr.send.lag >> 24;
            len = frag.hdr.send.lag & 0x00ffffff;

            BTL_VERBOSE(("received smsg fragment. hdr = {len = %u, tag = %d}", len, tag));

            reg = mca_btl_base_active_message_trigger + tag;
            frag.base.des_dst     = &seg;
            frag.base.des_dst_cnt = 1;

            seg.seg_addr.pval = (void *)((uintptr_t)data_ptr + sizeof (mca_btl_ugni_send_frag_hdr_t));
            seg.seg_len       = len;

            assert (NULL != reg->cbfunc);

            reg->cbfunc(&ep->btl->super, tag, &(frag.base), reg->cbdata);

            break;
        case MCA_BTL_UGNI_TAG_GET_INIT:
            frag.hdr.eager_ex = ((mca_btl_ugni_eager_ex_frag_hdr_t *) data_ptr)[0];

            mca_btl_ugni_start_eager_get (ep, frag.hdr.eager_ex, NULL);
            break;
        case MCA_BTL_UGNI_TAG_RDMA_COMPLETE:
            frag.hdr.rdma = ((mca_btl_ugni_rdma_frag_hdr_t *) data_ptr)[0];

            mca_btl_ugni_frag_complete (frag.hdr.rdma.ctx, OMPI_SUCCESS);
            break;
        case MCA_BTL_UGNI_TAG_DISCONNECT:
            /* remote endpoint has disconnected */
            disconnect = true;
            break;
        default:
            BTL_ERROR(("unknown tag %d\n", tag));
            break;
        }

        rc = GNI_SmsgRelease (ep->smsg_ep_handle);
        if (OPAL_UNLIKELY(GNI_RC_SUCCESS != rc)) {
            BTL_ERROR(("Smsg release failed! rc = %d", rc));
            return OMPI_ERROR;
        }
    } while (!disconnect);

    ep->smsg_progressing = false;

    /* disconnect if we get here */
    mca_btl_ugni_ep_disconnect (ep, false);

    return count;
}