示例#1
0
/* -----------------------------------------------------------
 * Post a recv buffer
 */
DAT_BOOLEAN
DT_post_recv_buffer(DT_Tdep_Print_Head * phead,
		    DAT_EP_HANDLE ep_handle, Bpool * bp, int index, int size)
{
	unsigned char *buff = DT_Bpool_GetBuffer(bp, index);
	DAT_LMR_TRIPLET *iov = DT_Bpool_GetIOV(bp, index);
	DAT_LMR_CONTEXT lmr_c = DT_Bpool_GetLMR(bp, index);
	DAT_DTO_COOKIE cookie;
	DAT_RETURN ret;

	/*
	 * Prep the inputs
	 */
	iov->virtual_address = (DAT_VADDR) (uintptr_t) buff;
	iov->segment_length = size;
	iov->lmr_context = lmr_c;
	cookie.as_64 = (DAT_UINT64) 0UL;
	cookie.as_ptr = (DAT_PVOID) buff;

	DT_Tdep_PT_Debug(3,
			 (phead, "Post-Recv #%d [%p, %x]\n", index, buff,
			  size));

	/* Post the recv buffer */
	ret = dat_ep_post_recv(ep_handle,
			       1, iov, cookie, DAT_COMPLETION_DEFAULT_FLAG);
	if (ret != DAT_SUCCESS) {
		DT_Tdep_PT_Printf(phead,
				  "Test Error: dat_ep_post_recv failed: %s\n",
				  DT_RetToString(ret));
		DT_Test_Error();
		return false;
	}
	return true;
}
示例#2
0
/* -----------------------------------------------------------
 * Post a recv buffer on each of this thread's EPs.
 */
bool
DT_handle_post_recv_buf(DT_Tdep_Print_Head * phead,
			Ep_Context_t * ep_context,
			unsigned int num_eps, int op_indx)
{
	unsigned int i, j;

	for (i = 0; i < num_eps; i++) {
		Transaction_Test_Op_t *op = &ep_context[i].op[op_indx];
		DAT_LMR_TRIPLET *iov = DT_Bpool_GetIOV(op->bp, 0);
		DAT_DTO_COOKIE cookie;
		DAT_RETURN ret;

		/* Prep the inputs */
		for (j = 0; j < op->num_segs; j++) {
			iov[j].virtual_address = (DAT_VADDR) (uintptr_t)
			    DT_Bpool_GetBuffer(op->bp, j);
			iov[j].segment_length = op->seg_size;
			iov[j].lmr_context = DT_Bpool_GetLMR(op->bp, j);
		}
		cookie.as_64 = ((((DAT_UINT64) i) << 32)
				| (((uintptr_t) DT_Bpool_GetBuffer(op->bp, 0)) &
				   0xffffffffUL));

		/* Post the recv */
		ret = dat_ep_post_recv(ep_context[i].ep_handle,
				       op->num_segs,
				       iov,
				       cookie, DAT_COMPLETION_DEFAULT_FLAG);

		if (ret != DAT_SUCCESS) {
			DT_Tdep_PT_Printf(phead,
					  "Test Error: dat_ep_post_recv failed: %s\n",
					  DT_RetToString(ret));
			DT_Test_Error();
			return false;
		}
	}

	return true;
}
示例#3
0
文件: dtestx.c 项目: Cai900205/test
int connect_ep(char *hostname)
{
	DAT_IA_ADDRESS_PTR remote_addr = (DAT_IA_ADDRESS_PTR)&remote;
	DAT_EP_ATTR ep_attr;
	DAT_IA_ATTR ia_attr;
	DAT_RETURN status;
	DAT_REGION_DESCRIPTION region;
	DAT_EVENT event;
	DAT_COUNT nmore;
	DAT_LMR_TRIPLET iov;
	DAT_RMR_TRIPLET *r_iov;
	DAT_DTO_COOKIE cookie;
	DAT_CONN_QUAL conn_qual;
	DAT_BOOLEAN in, out;
	int i, ii, pdata, ctx;
	DAT_PROVIDER_ATTR prov_attrs;
	DAT_DTO_COMPLETION_EVENT_DATA *dto_event =
	    &event.event_data.dto_completion_event_data;

	status = dat_ia_open(provider, 8, &async_evd, &ia);
	_OK(status, "dat_ia_open");

	memset(&prov_attrs, 0, sizeof(prov_attrs));
	status = dat_ia_query(ia, NULL, 
			      DAT_IA_FIELD_ALL, &ia_attr,
			      DAT_PROVIDER_FIELD_ALL, &prov_attrs);
	_OK(status, "dat_ia_query");

	print_ia_address(ia_attr.ia_address_ptr);

	if (ucm && ud_test) {
		printf("%d UD test over UCM provider not supported\n",
			getpid());
		exit(1);
	}

	/* Print provider specific attributes */
	for (i = 0; i < prov_attrs.num_provider_specific_attr; i++) {
		LOGPRINTF(" Provider Specific Attribute[%d] %s=%s\n",
			  i, prov_attrs.provider_specific_attr[i].name,
			  prov_attrs.provider_specific_attr[i].value);

		/* check for counter support */
		status = strcmp(prov_attrs.provider_specific_attr[i].name,
				"DAT_COUNTERS");
		if (!status)
			counters_ok = 1;
	}

	/* make sure provider supports counters */
	if ((counters) && (!counters_ok)) {
		printf("Disable dat_query_counters:"
		       " Provider not built with counters\n");
		counters = 0;
	}

	status = dat_pz_create(ia, &pz);
	_OK(status, "dat_pz_create");

	status = dat_evd_create(ia, eps * 2, DAT_HANDLE_NULL, DAT_EVD_CR_FLAG,
				&cr_evd);
	_OK(status, "dat_evd_create CR");
	status = dat_evd_create(ia, eps * 2, DAT_HANDLE_NULL,
				DAT_EVD_CONNECTION_FLAG, &con_evd);
	_OK(status, "dat_evd_create CR");
	status = dat_evd_create(ia, eps * 10, DAT_HANDLE_NULL, DAT_EVD_DTO_FLAG,
				&dto_evd);
	_OK(status, "dat_evd_create DTO");

	memset(&ep_attr, 0, sizeof(ep_attr));
	if (ud_test) {
		msg_size += 40;
		ep_attr.service_type = DAT_IB_SERVICE_TYPE_UD;
		ep_attr.max_message_size = buf_size;
		ep_attr.max_rdma_read_in = 0;
		ep_attr.max_rdma_read_out = 0;
	} else {
		ep_attr.service_type = DAT_SERVICE_TYPE_RC;
		ep_attr.max_rdma_size = 0x10000;
		ep_attr.max_rdma_read_in = 4;
		ep_attr.max_rdma_read_out = 4;
	}
	ep_attr.qos = 0;
	ep_attr.recv_completion_flags = 0;
	ep_attr.max_recv_dtos = eps * 10;
	ep_attr.max_request_dtos = eps * 10;
	ep_attr.max_recv_iov = 1;
	ep_attr.max_request_iov = 1;
	ep_attr.request_completion_flags = DAT_COMPLETION_DEFAULT_FLAG;
	ep_attr.ep_transport_specific_count = 0;
	ep_attr.ep_transport_specific = NULL;
	ep_attr.ep_provider_specific_count = 0;
	ep_attr.ep_provider_specific = NULL;

	for (i = 0; i < eps; i++) {
		status = dat_ep_create(ia, pz, dto_evd, dto_evd,
				       con_evd, &ep_attr, &ep[i]);
		_OK(status, "dat_ep_create");
		LOGPRINTF(" create_ep[%d]=%p\n", i, ep[i]);
	}

	for (i = 0; i < REG_MEM_COUNT * eps; i++) {
		buf[i] = (DAT_RMR_TRIPLET *) malloc(buf_size);
		region.for_va = buf[i];
		status = dat_lmr_create(ia,
					DAT_MEM_TYPE_VIRTUAL,
					region,
					buf_size,
					pz,
					DAT_MEM_PRIV_ALL_FLAG |
					DAT_IB_MEM_PRIV_REMOTE_ATOMIC,
					DAT_VA_TYPE_VA,
					&lmr[i],
					&lmr_context[i],
					&rmr_context[i],
					&reg_size[i], &reg_addr[i]);
		_OK(status, "dat_lmr_create");
	}

	/* register atomic return buffer for original data */
	atomic_buf = (DAT_UINT64 *) malloc(BUF_SIZE_ATOMIC);
	region.for_va = atomic_buf;
	status = dat_lmr_create(ia,
				DAT_MEM_TYPE_VIRTUAL,
				region,
				BUF_SIZE_ATOMIC,
				pz,
				DAT_MEM_PRIV_ALL_FLAG |
				DAT_IB_MEM_PRIV_REMOTE_ATOMIC,
				DAT_VA_TYPE_VA,
				&lmr_atomic,
				&lmr_atomic_context,
				&rmr_atomic_context,
				&reg_atomic_size, &reg_atomic_addr);
	_OK(status, "dat_lmr_create atomic");

	for (ii = 0; ii < eps; ii++) {
		for (i = RECV_BUF_INDEX; i < REG_MEM_COUNT; i++) {
			int ep_idx = 0;
			cookie.as_64 = (ii * REG_MEM_COUNT) + i;
			iov.lmr_context = lmr_context[(ii * REG_MEM_COUNT) + i];
			iov.virtual_address =
			    (DAT_VADDR) (uintptr_t) buf[(ii * REG_MEM_COUNT) +
							i];
			iov.segment_length = buf_size;
			LOGPRINTF(" post_recv (%p) on ep[%d]=%p\n",
				  buf[(ii * REG_MEM_COUNT) + i], ii, ep[ii]);
			/* ep[0], unless testing Server and multi EP's */
			if (server && multi_eps) {
				ep_idx = ii;
				cookie.as_64 = i;
			}
			status = dat_ep_post_recv(ep[ep_idx],
						  1,
						  &iov,
						  cookie,
						  DAT_COMPLETION_DEFAULT_FLAG);
			_OK(status, "dat_ep_post_recv");
		}
	}
	/* setup receive buffer to initial string to be overwritten */
	strcpy((char *)buf[RCV_RDMA_BUF_INDEX], "blah, blah, blah\n");

	/* ud can resolve_ah and connect both ways, same EP */
	if (server || (!server && ud_test)) {
		if (server) {
			conn_qual = SERVER_ID;
			strcpy((char *)buf[SND_RDMA_BUF_INDEX], "Server data");
		} else {
			conn_qual = CLIENT_ID;
			strcpy((char *)buf[SND_RDMA_BUF_INDEX], "Client data");
		}
		status = dat_psp_create(ia,
					conn_qual,
					cr_evd, DAT_PSP_CONSUMER_FLAG, &psp);
		_OK(status, "dat_psp_create");

		/* Server always waits for first CR from Client */
		if (server)
			process_cr(0);

	}

	/* ud can resolve_ah and connect both ways */
	if (!server || (server && ud_test)) {
		struct addrinfo *target;

		if (ucm)
			goto no_resolution;

		if (getaddrinfo(hostname, NULL, NULL, &target) != 0) {
			printf("Error getting remote address.\n");
			exit(1);
		}

		printf("Remote %s Name: %s \n",
		       server ? "Client" : "Server", hostname);
		printf("Remote %s Net Address: %s\n",
		       server ? "Client" : "Server",
		       inet_ntoa(((struct sockaddr_in *)
				  target->ai_addr)->sin_addr));

		strcpy((char *)buf[SND_RDMA_BUF_INDEX], "Client written data");
		
		remote_addr = (DAT_IA_ADDRESS_PTR)target->ai_addr; /* IP */
no_resolution:
		
		/* one Client EP, multiple Server EPs, same conn_qual 
		 * use private data to select EP on Server 
		 */
		for (i = 0; i < eps; i++) {
			/* pdata selects Server EP, 
			 * support both muliple Server and single EP's 
			 */
			if (multi_eps)
				pdata = hton32(i);
			else
				pdata = 0;	/* just use first EP */

			status = dat_ep_connect(ep[0],
						remote_addr,
						(server ? CLIENT_ID :
						 SERVER_ID), CONN_TIMEOUT, 4,
						(DAT_PVOID) & pdata, 0,
						DAT_CONNECT_DEFAULT_FLAG);
			_OK(status, "dat_ep_connect");
		}

		if (!ucm)
			freeaddrinfo(target);
	}

	/* UD: process CR's starting with 2nd on server, 1st for client */
	if (ud_test) {
		for (i = (server ? 1 : 0); i < eps; i++)
			process_cr(i);
	}

	/* RC and UD: process CONN EST events */
	for (i = 0; i < eps; i++)
		process_conn(i);

	/* UD: CONN EST events for CONN's and CR's */
	if (ud_test) {
		for (i = 0; i < eps; i++)
			process_conn(i);
	}

	printf("Connected! %d endpoints\n", eps);

	/*
	 *  Setup our remote memory and tell the other side about it
	 *  Swap to network order.
	 */
	r_iov = (DAT_RMR_TRIPLET *) buf[SEND_BUF_INDEX];
	r_iov->rmr_context = hton32(rmr_context[RCV_RDMA_BUF_INDEX]);
	r_iov->virtual_address =
	    hton64((DAT_VADDR) (uintptr_t) buf[RCV_RDMA_BUF_INDEX]);
	r_iov->segment_length = hton32(buf_size);

	printf("Send RMR message: r_key_ctx=0x%x,va=" F64x ",len=0x%x\n",
	       hton32(r_iov->rmr_context),
	       hton64(r_iov->virtual_address), hton32(r_iov->segment_length));

	send_msg(buf[SEND_BUF_INDEX],
		 sizeof(DAT_RMR_TRIPLET),
		 lmr_context[SEND_BUF_INDEX],
		 cookie, DAT_COMPLETION_SUPPRESS_FLAG);

	dat_ep_get_status(ep[0], NULL, &in, &out);
	printf("EP[0] status: posted buffers: Req=%d, Rcv=%d\n", in, out);

	/*
	 *  Wait for their RMR
	 */
	for (i = 0, ctx = 0; i < eps; i++, ctx++) {
		/* expected cookie, recv buf idx in every mem pool */
		ctx = (ctx % REG_MEM_COUNT) ? ctx : ctx + RECV_BUF_INDEX;
		LOGPRINTF("Waiting for remote to send RMR data\n");

		status = dat_evd_wait(dto_evd, DTO_TIMEOUT, 1, &event, &nmore);
		_OK(status, "dat_evd_wait after dat_ep_post_send");

		if ((event.event_number != DAT_DTO_COMPLETION_EVENT) &&
		    (ud_test && event.event_number != DAT_IB_DTO_EVENT)) {
			printf("unexpected event waiting for RMR context "
			       "- 0x%x\n", event.event_number);
			exit(1);
		}
		_OK(dto_event->status, "event status for post_recv");

		/* careful when checking cookies:
		 * Client - receiving multi messages on a single EP 
		 * Server - not receiving on multiple EP's
		 */
		if (!server || (server && !multi_eps)) {
			if (dto_event->transfered_length != msg_size ||
			    dto_event->user_cookie.as_64 != ctx) {
				printf("unexpected event data on recv: len=%d"
				       " cookie=" F64x " expected %d/%d\n",
				       (int)dto_event->transfered_length,
				       dto_event->user_cookie.as_64,
				       msg_size, ctx);
				exit(1);
			}
			/* Server - receiving one message each across many EP's */
		} else {
			if (dto_event->transfered_length != msg_size ||
			    dto_event->user_cookie.as_64 != RECV_BUF_INDEX) {
				printf("unexpected event data on recv: len=%d"
				       "cookie=" F64x " expected %d/%d\n",
				       (int)dto_event->transfered_length,
				       dto_event->user_cookie.as_64,
				       msg_size, RECV_BUF_INDEX);
				exit(1);
			}
		}

		/* swap RMR,address info to host order */
		if (!server || (server && !multi_eps))
			r_iov = (DAT_RMR_TRIPLET *) buf[ctx];
		else
			r_iov =
			    (DAT_RMR_TRIPLET *) buf[(i * REG_MEM_COUNT) +
						    RECV_BUF_INDEX];

		if (ud_test)
			r_iov = (DAT_RMR_TRIPLET *) ((char *)r_iov + 40);

		r_iov->rmr_context = ntoh32(r_iov->rmr_context);
		r_iov->virtual_address = ntoh64(r_iov->virtual_address);
		r_iov->segment_length = ntoh32(r_iov->segment_length);

		printf("Recv RMR message: r_iov(%p):"
		       " r_key_ctx=%x,va=" F64x ",len=0x%x on EP=%p\n",
		       r_iov, r_iov->rmr_context,
		       r_iov->virtual_address,
		       r_iov->segment_length, dto_event->ep_handle);
	}
	return (0);
}
int mca_btl_udapl_component_progress()
{
    mca_btl_udapl_module_t* btl;
    static int32_t inprogress = 0;
    DAT_EVENT event;
    size_t i;
    int32_t j, rdma_ep_count;
    int count = 0, btl_ownership;
    mca_btl_udapl_frag_t* frag;
    mca_btl_base_endpoint_t* endpoint;

    /* prevent deadlock - only one thread should be 'progressing' at a time */
    if(OPAL_THREAD_ADD32(&inprogress, 1) > 1) {
        OPAL_THREAD_ADD32(&inprogress, -1);
        return OMPI_SUCCESS;
    }

    /* check for work to do on each uDAPL btl */
    OPAL_THREAD_LOCK(&mca_btl_udapl_component.udapl_lock);
    for(i = 0; i < mca_btl_udapl_component.udapl_num_btls; i++) {
        btl = mca_btl_udapl_component.udapl_btls[i];

        /* Check DTO EVD */
        while(DAT_SUCCESS ==
                dat_evd_dequeue(btl->udapl_evd_dto, &event)) {
            DAT_DTO_COMPLETION_EVENT_DATA* dto;

            switch(event.event_number) {
            case DAT_DTO_COMPLETION_EVENT:
                dto = &event.event_data.dto_completion_event_data;

                frag = dto->user_cookie.as_ptr;

                /* Was the DTO successful? */
                if(DAT_DTO_SUCCESS != dto->status) {

                    if (DAT_DTO_ERR_FLUSHED == dto->status) {

                        BTL_UDAPL_VERBOSE_OUTPUT(VERBOSE_INFORM,
                            ("DAT_DTO_ERR_FLUSHED: probably OK if occurs during MPI_Finalize().\n"));
                    } else {

                        BTL_UDAPL_VERBOSE_OUTPUT(VERBOSE_CRITICAL,
                            ("ERROR: DAT_DTO_COMPLETION_EVENT: %d %d %lu %p.\n",
                                dto->status, frag->type,
                                (unsigned long)frag->size, dto->ep_handle));
                    }
                    return OMPI_ERROR;		    
                }
                endpoint = frag->endpoint;
                btl_ownership = (frag->base.des_flags & MCA_BTL_DES_FLAGS_BTL_OWNERSHIP);

                switch(frag->type) {
                case MCA_BTL_UDAPL_RDMA_WRITE:
                {
                    assert(frag->base.des_src == &frag->segment);
                    assert(frag->base.des_src_cnt == 1);
                    assert(frag->base.des_dst == NULL);
                    assert(frag->base.des_dst_cnt == 0);
                    assert(frag->type == MCA_BTL_UDAPL_RDMA_WRITE);
    
                    frag->base.des_cbfunc(&btl->super, endpoint,
                        &frag->base, OMPI_SUCCESS);
                    if( btl_ownership ) {
                        mca_btl_udapl_free(&btl->super,
                            &frag->base);
                    }

                    OPAL_THREAD_ADD32(&(endpoint->endpoint_lwqe_tokens[BTL_UDAPL_EAGER_CONNECTION]), 1);

		    mca_btl_udapl_frag_progress_pending(btl,
                        endpoint, BTL_UDAPL_EAGER_CONNECTION);

                    break;
                }
                case MCA_BTL_UDAPL_SEND:
                {
                    int connection = BTL_UDAPL_EAGER_CONNECTION;

                    assert(frag->base.des_src == &frag->segment);
                    assert(frag->base.des_src_cnt == 1);
                    assert(frag->base.des_dst == NULL);
                    assert(frag->base.des_dst_cnt == 0);
                    assert(frag->type == MCA_BTL_UDAPL_SEND);

                    if(frag->size !=
                            mca_btl_udapl_component.udapl_eager_frag_size) {
                        assert(frag->size ==
                            mca_btl_udapl_component.udapl_max_frag_size);

                        connection = BTL_UDAPL_MAX_CONNECTION;
                    }
                    frag->base.des_cbfunc(&btl->super, endpoint,
                            &frag->base, OMPI_SUCCESS);
                    if( btl_ownership ) {
                        mca_btl_udapl_free(&btl->super,
                            &frag->base);
                    }

                    OPAL_THREAD_ADD32(&(endpoint->endpoint_lwqe_tokens[connection]), 1);

                    mca_btl_udapl_frag_progress_pending(btl,
                        endpoint, connection);
                    break;
                }
                case MCA_BTL_UDAPL_RECV:
                {
                    mca_btl_active_message_callback_t* reg;
                    int cntrl_msg = -1;

                    assert(frag->base.des_dst == &frag->segment);
                    assert(frag->base.des_dst_cnt == 1);
                    assert(frag->base.des_src == NULL);
                    assert(frag->base.des_src_cnt == 0);
                    assert(frag->type == MCA_BTL_UDAPL_RECV);
                    assert(frag->triplet.virtual_address ==
                            (DAT_VADDR)(uintptr_t)frag->segment.seg_addr.pval);
                    assert(frag->triplet.segment_length == frag->size);
                    assert(frag->btl == btl);

                    /* setup frag ftr location and do callback */
                    frag->segment.seg_len = dto->transfered_length -
                        sizeof(mca_btl_udapl_footer_t);
                    frag->ftr = (mca_btl_udapl_footer_t *)
                        ((char *)frag->segment.seg_addr.pval + 
                        frag->segment.seg_len);

                    cntrl_msg = frag->ftr->tag;

                    reg = mca_btl_base_active_message_trigger + frag->ftr->tag;
                    OPAL_THREAD_UNLOCK(&mca_btl_udapl_component.udapl_lock);

                    reg->cbfunc(&btl->super,
                            frag->ftr->tag, &frag->base, reg->cbdata);
                    OPAL_THREAD_LOCK(&mca_btl_udapl_component.udapl_lock);

                    /* Repost the frag */
                    frag->ftr = frag->segment.seg_addr.pval;
                    frag->segment.seg_len =
                        (frag->size - sizeof(mca_btl_udapl_footer_t) -
                            sizeof(mca_btl_udapl_rdma_footer_t)); 
                    frag->base.des_flags = 0;

                    if(frag->size ==
                              mca_btl_udapl_component.udapl_eager_frag_size) {

                        OPAL_THREAD_ADD32(&(frag->endpoint->endpoint_sr_credits[BTL_UDAPL_EAGER_CONNECTION]), 1);

                        dat_ep_post_recv(frag->endpoint->endpoint_eager,
                            1, &frag->triplet, dto->user_cookie,
                            DAT_COMPLETION_DEFAULT_FLAG);

                        if (frag->endpoint->endpoint_sr_credits[BTL_UDAPL_EAGER_CONNECTION] >=
                            mca_btl_udapl_component.udapl_sr_win) {
                            mca_btl_udapl_endpoint_send_sr_credits(frag->endpoint,
                                BTL_UDAPL_EAGER_CONNECTION);
                        }

                        if (MCA_BTL_TAG_UDAPL == cntrl_msg) {
                            mca_btl_udapl_frag_progress_pending(btl,
                                frag->endpoint,
                                BTL_UDAPL_EAGER_CONNECTION);
                        }

                    } else {
                        assert(frag->size ==
                            mca_btl_udapl_component.udapl_max_frag_size);

                        OPAL_THREAD_ADD32(&(frag->endpoint->endpoint_sr_credits[BTL_UDAPL_MAX_CONNECTION]), 1);

                        dat_ep_post_recv(frag->endpoint->endpoint_max,
                            1, &frag->triplet, dto->user_cookie,
                            DAT_COMPLETION_DEFAULT_FLAG);

                        if (frag->endpoint->endpoint_sr_credits[BTL_UDAPL_MAX_CONNECTION] >=
                            mca_btl_udapl_component.udapl_sr_win) {
                            mca_btl_udapl_endpoint_send_sr_credits(frag->endpoint,
                                BTL_UDAPL_MAX_CONNECTION);
                        }

                        if (MCA_BTL_TAG_UDAPL == cntrl_msg) {
                            mca_btl_udapl_frag_progress_pending(btl,
                                frag->endpoint,
                                BTL_UDAPL_MAX_CONNECTION);
                        }
                    }

                    break;
                }
                case MCA_BTL_UDAPL_PUT:
                {
                    assert(frag->base.des_src == &frag->segment);
                    assert(frag->base.des_src_cnt == 1);
                    assert(frag->base.des_dst_cnt == 1);
                    assert(frag->type == MCA_BTL_UDAPL_PUT);
                    
                    frag->base.des_cbfunc(&btl->super, endpoint,
                        &frag->base, OMPI_SUCCESS);
                    if( btl_ownership ) {
                        mca_btl_udapl_free(&btl->super,
                            &frag->base);
                    }

                    OPAL_THREAD_ADD32(&(endpoint->endpoint_lwqe_tokens[BTL_UDAPL_MAX_CONNECTION]), 1);
                    OPAL_THREAD_ADD32(&(endpoint->endpoint_sr_tokens[BTL_UDAPL_MAX_CONNECTION]), 1);

                    mca_btl_udapl_frag_progress_pending(btl,
                        endpoint, BTL_UDAPL_MAX_CONNECTION);
         
                    break;
                }                    
                case MCA_BTL_UDAPL_CONN_RECV:
                    mca_btl_udapl_endpoint_finish_connect(btl,
                            frag->segment.seg_addr.pval,
                            (int32_t *)((char *)frag->segment.seg_addr.pval  +
                                sizeof(mca_btl_udapl_addr_t)),
                            event.event_data.connect_event_data.ep_handle);
                    /* No break - fall through to free */
                case MCA_BTL_UDAPL_CONN_SEND:
                    frag->segment.seg_len =
                            mca_btl_udapl_module.super.btl_eager_limit;
                    mca_btl_udapl_free(&btl->super, &frag->base);
                    break;
                default:
                    BTL_UDAPL_VERBOSE_OUTPUT(VERBOSE_DIAGNOSE,
                        ("WARNING: unknown frag type: %d\n",
                        frag->type));
                }
                count++;
                break;
            default:
                BTL_UDAPL_VERBOSE_OUTPUT(VERBOSE_DIAGNOSE,
                    ("WARNING: DTO event: %s (%d)\n",
                    mca_btl_udapl_dat_event_to_string(event.event_number),
                    event.event_number));
            }
        }

        /* Check connection EVD */
        while((btl->udapl_connect_inprogress > 0) && (DAT_SUCCESS ==
            dat_evd_dequeue(btl->udapl_evd_conn, &event))) {

            switch(event.event_number) {
                case DAT_CONNECTION_REQUEST_EVENT:
                    /* Accept a new connection */
                    mca_btl_udapl_accept_connect(btl,
                            event.event_data.cr_arrival_event_data.cr_handle);
                    count++;
                    break;
                case DAT_CONNECTION_EVENT_ESTABLISHED:
                    /* Both the client and server side of a connection generate
                       this event */
                    if (mca_btl_udapl_component.udapl_conn_priv_data) {
                        /* private data is only valid at this point if this 
                         * event is from a dat_ep_connect call, not an accept
                         */
                        mca_btl_udapl_endpoint_pd_established_conn(btl,
                            event.event_data.connect_event_data.ep_handle);
                    } else {
                        /* explicitly exchange process data */
                        mca_btl_udapl_sendrecv(btl,
                            event.event_data.connect_event_data.ep_handle);
                    }
                    count++;
                    break;
                case DAT_CONNECTION_EVENT_PEER_REJECTED:
                case DAT_CONNECTION_EVENT_NON_PEER_REJECTED:
                case DAT_CONNECTION_EVENT_ACCEPT_COMPLETION_ERROR:
                case DAT_CONNECTION_EVENT_DISCONNECTED:
                case DAT_CONNECTION_EVENT_BROKEN:
                case DAT_CONNECTION_EVENT_TIMED_OUT:
                    /* handle this case specially? if we have finite timeout,
                       we might want to try connecting again here. */
                case DAT_CONNECTION_EVENT_UNREACHABLE:
                    /* Need to set the BTL endpoint to MCA_BTL_UDAPL_FAILED
                       See dat_ep_connect documentation pdf pg 198 */
                    BTL_UDAPL_VERBOSE_OUTPUT(VERBOSE_CRITICAL,
                        ("WARNING: connection event not handled : %s (%d)\n",
                        mca_btl_udapl_dat_event_to_string(event.event_number),
                        event.event_number));
                    break;
                default:
                    BTL_ERROR(("ERROR: connection event : %s (%d)",
                        mca_btl_udapl_dat_event_to_string(event.event_number),
                        event.event_number));
            }
        }

        /* Check async EVD */
        if (btl->udapl_async_events == mca_btl_udapl_component.udapl_async_events) {
            btl->udapl_async_events = 0;

            while(DAT_SUCCESS ==
                dat_evd_dequeue(btl->udapl_evd_async, &event)) {

                switch(event.event_number) {
                case DAT_ASYNC_ERROR_EVD_OVERFLOW:
                case DAT_ASYNC_ERROR_IA_CATASTROPHIC:
                case DAT_ASYNC_ERROR_EP_BROKEN:
                case DAT_ASYNC_ERROR_TIMED_OUT:
                case DAT_ASYNC_ERROR_PROVIDER_INTERNAL_ERROR:
                    BTL_UDAPL_VERBOSE_OUTPUT(VERBOSE_CRITICAL,
                        ("WARNING: async event ignored : %s (%d)",
                        mca_btl_udapl_dat_event_to_string(event.event_number),
                        event.event_number));
                    break;
                default:
                    BTL_UDAPL_VERBOSE_OUTPUT(VERBOSE_CRITICAL,
                        ("WARNING: %s (%d)\n",
                        mca_btl_udapl_dat_event_to_string(event.event_number),
                        event.event_number));
                }
            }
        } else {
            btl->udapl_async_events++;
        }

        /*
         * Check eager rdma segments
         */
        
        /* find the number of endpoints with rdma buffers */
        rdma_ep_count = btl->udapl_eager_rdma_endpoint_count;
        
        for (j = 0; j < rdma_ep_count; j++) {
            mca_btl_udapl_endpoint_t* endpoint;
            mca_btl_udapl_frag_t *local_rdma_frag;

            endpoint =
                opal_pointer_array_get_item(btl->udapl_eager_rdma_endpoints, j);

            OPAL_THREAD_LOCK(&endpoint->endpoint_eager_rdma_local.lock);

            local_rdma_frag =             
                MCA_BTL_UDAPL_GET_LOCAL_RDMA_FRAG(endpoint,
                    endpoint->endpoint_eager_rdma_local.head);

            if (local_rdma_frag->rdma_ftr->active == 1) {
                int pad = 0;
                mca_btl_active_message_callback_t* reg;

                MCA_BTL_UDAPL_RDMA_NEXT_INDEX(endpoint->endpoint_eager_rdma_local.head);
                OPAL_THREAD_UNLOCK(&endpoint->endpoint_eager_rdma_local.lock);

                /* compute pad as needed */
                MCA_BTL_UDAPL_FRAG_CALC_ALIGNMENT_PAD(pad,
                    (local_rdma_frag->rdma_ftr->size +
                        sizeof(mca_btl_udapl_footer_t)));
                
                /* set fragment information */
                local_rdma_frag->ftr = (mca_btl_udapl_footer_t *)
                    ((char *)local_rdma_frag->rdma_ftr -
                        pad -
                        sizeof(mca_btl_udapl_footer_t));
                local_rdma_frag->segment.seg_len =
                    local_rdma_frag->rdma_ftr->size;
                local_rdma_frag->segment.seg_addr.pval = (unsigned char *)
                    ((char *)local_rdma_frag->ftr -
                        local_rdma_frag->segment.seg_len);

                /* trigger callback */
                reg = mca_btl_base_active_message_trigger + local_rdma_frag->ftr->tag;
                reg->cbfunc(&btl->super,
                    local_rdma_frag->ftr->tag, &local_rdma_frag->base, reg->cbdata);

                /* repost */
                local_rdma_frag->rdma_ftr->active = 0; 
                local_rdma_frag->segment.seg_len =
                    mca_btl_udapl_module.super.btl_eager_limit;
                local_rdma_frag->base.des_flags = 0;

                /* increment local rdma credits */
                OPAL_THREAD_ADD32(&(endpoint->endpoint_eager_rdma_local.credits),
                    1);

                if (endpoint->endpoint_eager_rdma_local.credits >=
                    mca_btl_udapl_component.udapl_eager_rdma_win) {
                    mca_btl_udapl_endpoint_send_eager_rdma_credits(endpoint);
                }

                count++;

            } else {
                OPAL_THREAD_UNLOCK(&endpoint->endpoint_eager_rdma_local.lock);
            }
        } /* end of rdma_count loop */
    }

    /* unlock and return */
    OPAL_THREAD_UNLOCK(&mca_btl_udapl_component.udapl_lock);
    OPAL_THREAD_ADD32(&inprogress, -1);
    return count;
}
static inline int mca_btl_udapl_sendrecv(mca_btl_udapl_module_t* btl,
        DAT_EP_HANDLE* endpoint)
{
    int rc;
    mca_btl_udapl_frag_t* frag;
    DAT_DTO_COOKIE cookie;
    static int32_t connection_seq = 1;
    uint32_t flags = 0;
    mca_btl_base_endpoint_t* btl_endpoint = NULL; /* endpoint required by
                                                   * mca_btl_udapl_alloc has not
                                                   * been created at this point
                                                   */
    
    /* Post a receive to get the peer's address data */
    frag = (mca_btl_udapl_frag_t*)
        mca_btl_udapl_alloc(
                            &btl->super,
                            btl_endpoint, 
                            MCA_BTL_NO_ORDER,
                            sizeof(mca_btl_udapl_addr_t) +
                            sizeof(int32_t),
                            flags);
    cookie.as_ptr = frag;

    frag->type = MCA_BTL_UDAPL_CONN_RECV;

    rc = dat_ep_post_recv(endpoint, 1,
            &frag->triplet, cookie, DAT_COMPLETION_DEFAULT_FLAG);
    if(DAT_SUCCESS != rc) {
        char* major;
        char* minor;

        dat_strerror(rc, (const char**)&major,
            (const char**)&minor);
        BTL_ERROR(("ERROR: %s %s %s\n", "dat_ep_post_recv",
            major, minor));
        return OMPI_ERROR;
    }


    /* Send our local address data over this EP */
    frag = (mca_btl_udapl_frag_t*)
        mca_btl_udapl_alloc(
                            &btl->super, 
                            btl_endpoint, 
                            MCA_BTL_NO_ORDER,
                            sizeof(mca_btl_udapl_addr_t) +
                            sizeof(int32_t),
                            flags);
    cookie.as_ptr = frag;

    memcpy(frag->segment.seg_addr.pval,
            &btl->udapl_addr, sizeof(mca_btl_udapl_addr_t));
    memcpy((char *)frag->segment.seg_addr.pval + sizeof(mca_btl_udapl_addr_t),
            &connection_seq, sizeof(int32_t));
    connection_seq++;

    frag->type = MCA_BTL_UDAPL_CONN_SEND;

    rc = dat_ep_post_send(endpoint, 1,
            &frag->triplet, cookie, DAT_COMPLETION_DEFAULT_FLAG);
    if(DAT_SUCCESS != rc) {
        char* major;
        char* minor;

        dat_strerror(rc, (const char**)&major,
            (const char**)&minor);
        BTL_ERROR(("ERROR: %s %s %s\n", "dat_ep_post_send",
            major, minor));
        return OMPI_ERROR;
    }

    return OMPI_SUCCESS;
}