コード例 #1
0
ファイル: ps4_ib_pp.c プロジェクト: JonBau/pscom
static
VAPI_ret_t psib_check_cq(hca_info_t *hca_info)
{
    VAPI_wc_desc_t comp_desc;
    VAPI_ret_t rc;
    rc = VAPI_poll_cq(hca_info->hca_hndl, hca_info->cq_hndl, &comp_desc);
    if (rc == VAPI_OK) {
	if (comp_desc.opcode == VAPI_CQE_RQ_SEND_DATA) {
	    /* receive something */
	    con_info_t *con = (con_info_t *)(unsigned long)comp_desc.id;
//	    printf("Recv done... recv: %d tosend: %d send: %d\n",
//		   con->n_recv_toks, con->n_tosend_toks, con->n_send_toks);
	    if (comp_desc.status == VAPI_SUCCESS) {
		psib_msg_t *msg;
		msg = ((psib_msg_t *)con->recv_bufs.ptr) +
		    ((con->recv_pos + con->n_recv_toks) % SIZE_SR_QUEUE);

		/* Fresh tokens ? */
		con->n_send_toks += msg->header.token;
//		/* ToDo: Maybe disable the next 4 lines ? */
//		if ((con->n_recv_toks == 0) && (msg->header.payload == 0)) {
//		    /* no payload. skip packet. */
//		    psib_recvdone(con);
//		}
		con->n_recv_toks++;
	    } else {
		if (psib_debug > 0) {
		    printf("Failed receive request (status %d). Connection broken!\n",
			   comp_desc.status);
		}
		con->con_broken = 1;
	    }
	} else if (comp_desc.opcode == VAPI_CQE_SQ_SEND_DATA) {
	    /* Send done */
	    con_info_t *con = (con_info_t *)(unsigned long)comp_desc.id;
	    if (comp_desc.status == VAPI_SUCCESS) {
//		printf("Send done... recv: %d tosend: %d send: %d\n",
//		       con->n_recv_toks, con->n_tosend_toks, con->n_send_toks);
	    } else {
		if (psib_debug > 0) {
		    printf("Failed send request (status %d). Connection broken!\n",
			   comp_desc.status);
		}
		con->con_broken = 1;
	    }
	} else {
	    printf("Unknown Opcode: %d\n", comp_desc.opcode);
	}
    }
    return rc;
}
コード例 #2
0
VAPI_ret_t osmt_mtl_mad_poll4cqe(VAPI_hca_hndl_t hca, VAPI_cq_hndl_t cq,
				 VAPI_wc_desc_t * wc_desc_p,
				 u_int32_t max_poll, u_int32_t poll_sleep,
				 VAPI_ud_av_hndl_t * avh_p)
{
	VAPI_ret_t ret = VAPI_CQ_EMPTY;
	u_int32_t poll_cnt = 0;

	/* wait for something to arrive */
	while ((ret == VAPI_CQ_EMPTY) && (poll_cnt < max_poll)) {
		ret = VAPI_poll_cq(hca, cq, wc_desc_p);
		/* don't sleep if we already succeeded) */
		if (ret != VAPI_CQ_EMPTY) {
			break;
		}
		usleep(poll_sleep);
		poll_cnt++;
	}

	/* if passed an AVH to destory - do it */
	if (avh_p != NULL) {
		VAPI_destroy_addr_hndl(hca, *avh_p);
	}

	if ((poll_cnt == max_poll) && (ret == VAPI_CQ_EMPTY)) {
		MTL_DEBUG1(__FUNCTION__
			   ": Failed to get completion on wq after %d polls.\n",
			   max_poll);
		return VAPI_CQ_EMPTY;
	}

	if (ret != VAPI_OK) {
		MTL_DEBUG1(__FUNCTION__
			   ": VAPI_poll_cq failed with ret=%s on sq_cq\n",
			   mtl_strerror_sym(ret));
		return ret;
	}

	if (wc_desc_p->status != VAPI_SUCCESS) {
		MTL_DEBUG1(__FUNCTION__ ": completion error (%d) detected\n",
			   wc_desc_p->status);
	}

	return VAPI_OK;
}
コード例 #3
0
ファイル: ib.c プロジェクト: carriercomm/ix
void event_handler(VAPI_hca_hndl_t hca, VAPI_cq_hndl_t cq, void* data)
{
  VAPI_ret_t    ret;
 
  while(1) {
     
     ret = VAPI_poll_cq(hca, cq, &wc);

     if(ret == VAPI_CQ_EMPTY) {
        LOGPRINTF("Empty completion queue, requesting next notification\n");
        VAPI_req_comp_notif(hca_hndl, r_cq_hndl, VAPI_NEXT_COMP);
        return;
     } else if(ret != VAPI_OK) {
        fprintf(stderr, "Error in event_handler, polling cq: %s\n",
                VAPI_strerror(ret));
        exit(-1);
     } else if(wc.status != VAPI_SUCCESS) {
        fprintf(stderr, "Error in event_handler, on returned work completion "
                        "status: %s\n", VAPI_wc_status_sym(wc.status));
        exit(-1);
     }
     
     LOGPRINTF("Retrieved work completion\n");

     /* For ping-pong mode at least, this check shouldn't be needed for
      * normal operation, but it will help catch any bugs with multiple
      * sends coming through when we're only expecting one.
      */
     if(receive_complete == 1) {

        while(receive_complete != 0) sched_yield();

     }

     receive_complete = 1;

  }
  
}
コード例 #4
0
ファイル: ib.c プロジェクト: carriercomm/ix
/* Reset is used after a trial to empty the work request queues so we
   have enough room for the next trial to run */
void Reset(ArgStruct *p)
{

  VAPI_ret_t          ret;       /* Return code */
  VAPI_sr_desc_t      sr;        /* Send request */
  VAPI_rr_desc_t      rr;        /* Recv request */

  /* If comptype is event, then we'll use event handler to detect receive,
   * so initialize receive_complete flag
   */
  if(p->prot.comptype == NP_COMP_EVENT) receive_complete = 0;

  /* Prepost receive */
  rr.opcode = VAPI_RECEIVE;
  rr.comp_type = VAPI_SIGNALED;
  rr.sg_lst_len = 0;

  LOGPRINTF("Posting recv request in Reset\n");
  ret = VAPI_post_rr(hca_hndl, qp_hndl, &rr);
  if(ret != VAPI_OK) {
    fprintf(stderr, "  Error posting recv request: %s\n", VAPI_strerror(ret));
    CleanUp(p);
    exit(-1);
  }

  /* Make sure both nodes have preposted receives */
  Sync(p);

  /* Post Send */
  sr.opcode = VAPI_SEND;
  sr.comp_type = VAPI_SIGNALED;
  sr.set_se = FALSE; /* This needed due to a bug in Mellanox HW rel a-0 */
  sr.sg_lst_len = 0;

  LOGPRINTF("Posting send request \n");
  ret = VAPI_post_sr(hca_hndl, qp_hndl, &sr);
  if(ret != VAPI_OK) {
    fprintf(stderr, "  Error posting send request in Reset: %s\n", 
            VAPI_strerror(ret));
    exit(-1);
  }
  if(wc.status != VAPI_SUCCESS) {
     fprintf(stderr, "  Error in completion status: %s\n",
             VAPI_wc_status_sym(wc.status));
     exit(-1);
  }

  LOGPRINTF("Polling for completion of send request\n");
  ret = VAPI_CQ_EMPTY;
  while(ret == VAPI_CQ_EMPTY)
    ret = VAPI_poll_cq(hca_hndl, s_cq_hndl, &wc);

  if(ret != VAPI_OK) {
    fprintf(stderr, "Error polling CQ for send in Reset: %s\n", 
            VAPI_strerror(ret));
    exit(-1);
  }
  if(wc.status != VAPI_SUCCESS) {
     fprintf(stderr, "  Error in completion status: %s\n",
             VAPI_wc_status_sym(wc.status));
     exit(-1);
  }          
  
  LOGPRINTF("Status of send completion: %s\n", VAPI_wc_status_sym(wc.status));

  if(p->prot.comptype == NP_COMP_EVENT) { 
     /* If using event completion, the event handler will set receive_complete
      * when it gets the completion event.
      */
     LOGPRINTF("Waiting for receive_complete flag\n");
     while(receive_complete == 0) { /* BUSY WAIT */ }
  } else {
     LOGPRINTF("Polling for completion of recv request\n");
     ret = VAPI_CQ_EMPTY;
     while(ret == VAPI_CQ_EMPTY)
       ret = VAPI_poll_cq(hca_hndl, r_cq_hndl, &wc);
     
     if(ret != VAPI_OK) {
       fprintf(stderr, "Error polling CQ for recv in Reset: %s\n", 
               VAPI_strerror(ret));
       exit(-1);
     }
     if(wc.status != VAPI_SUCCESS) {
        fprintf(stderr, "  Error in completion status: %s\n",
                VAPI_wc_status_sym(wc.status));
        exit(-1);
     }

     LOGPRINTF("Status of recv completion: %s\n", VAPI_wc_status_sym(wc.status));
  }
  LOGPRINTF("Done with reset\n");
}
コード例 #5
0
ファイル: ib.c プロジェクト: carriercomm/ix
void RecvData(ArgStruct *p)
{
  VAPI_ret_t ret;

  /* Busy wait for incoming data */

  LOGPRINTF("Receiving at buffer address %p\n", p->r_ptr);

  if( p->prot.comptype == NP_COMP_LOCALPOLL ) {
       
    /* Poll for receive completion locally on the receive data */

    LOGPRINTF("Waiting for last byte of data to arrive\n");
     
    while(p->r_ptr[p->bufflen-1] != 'a' + (p->cache ? 1 - p->tr : 1) ) 
    {
       /* BUSY WAIT -- this should be fine since we 
        * declared r_ptr with volatile qualifier */ 
    }

    /* Reset last byte */
    p->r_ptr[p->bufflen-1] = 'a' + (p->cache ? p->tr : 0);

    LOGPRINTF("Received all of data\n");

  } else if( p->prot.comptype == NP_COMP_VAPIPOLL ) {
     
     /* Poll for receive completion using VAPI poll function */

     LOGPRINTF("Polling completion queue for VAPI work completion\n");
     
     ret = VAPI_CQ_EMPTY;
     while(ret == VAPI_CQ_EMPTY)
        ret = VAPI_poll_cq(hca_hndl, r_cq_hndl, &wc);

     if(ret != VAPI_OK) {
        fprintf(stderr, "Error in RecvData, polling for completion: %s\n",
                VAPI_strerror(ret));
        exit(-1);
     }

     if(wc.status != VAPI_SUCCESS) {
        fprintf(stderr, "Error in status of returned completion: %s\n",
              VAPI_wc_status_sym(wc.status));
        exit(-1);
     }

     LOGPRINTF("Retrieved successful completion\n");
     
  } else if( p->prot.comptype == NP_COMP_EVENT ) {

     /* Instead of polling directly on data or VAPI completion queue,
      * let the VAPI event completion handler set a flag when the receive
      * completes, and poll on that instead. Could try using semaphore here
      * as well to eliminate busy polling
      */

     LOGPRINTF("Polling receive flag\n");
     
     while( receive_complete == 0 )
     {
        /* BUSY WAIT */
     }

     /* If in prepost-burst mode, we won't be calling PrepareToReceive
      * between ping-pongs, so we need to reset the receive_complete
      * flag here.
      */
     if( p->preburst ) receive_complete = 0;

     LOGPRINTF("Receive completed\n");
  }
}