Example #1
0
/* returnvalue like write(), except on error errno is negative return */
static
int _pselan_sendv(pselan_con_info_t *ci, struct iovec *iov, int size, unsigned int magic)
{
	int len;
	int pselanlen;
	pselan_msg_t *msg;

	if (ci->con_broken) goto err_broken;

	/* Its allowed to send, if
	   At least 2 tokens left or (1 token left AND n_tosend > 0)
	*/

	if ((ci->n_send_toks < 2) &&
	    ((ci->n_send_toks < 1) || (ci->n_tosend_toks == 0))) goto err_busy;

	len = (size <= (int)ELAN_BUFSIZE_PAYLOAD) ? size : (int)ELAN_BUFSIZE_PAYLOAD;
	pselanlen = PSELAN_LEN(len);

	msg = ci->send_bufs + ci->send_pos;

	msg->tail.token = ci->n_tosend_toks;
	msg->tail.payload = len;
	msg->tail.magic = magic;

	char *buf = msg->data - pselanlen;

	/* copy to registerd send buffer */
	pscom_memcpy_from_iov(buf, iov, len);

	pselan_flush_sendbuf(ci, buf,
			     ci->remote_r_buf[ci->send_pos].data - pselanlen,
			     pselanlen + sizeof(pselan_msgheader_t));

	pscom_forward_iov(iov, len);

	ci->n_tosend_toks = 0;
	ci->send_pos = (ci->send_pos + 1) % SIZE_SR_QUEUE;
	ci->n_send_toks--;

	pselan_flush_event(ci);

	return len;
err_busy:
	pselan_get_fresh_tokens(ci);
	pselan_flush_event(ci);

	return -EAGAIN;
err_broken:
	return -EPIPE;
}
Example #2
0
/* send iov.
   Call only if shm_cansend() == true (no check inside)!
   len must be smaller or equal SHM_BUFLEN!
*/
static
void shm_iovsend(shm_conn_t *shm, struct iovec *iov, int len)
{
	int cur = shm->send_cur;
	shm_buf_t *shmbuf = &shm->remote_com->buf[cur];

	/* copy to sharedmem */
	pscom_memcpy_from_iov(SHM_DATA(shmbuf, len), iov, len);
	shmbuf->header.len = len;

	shm_mb();

	/* Notification about the new message */
	shmbuf->header.msg_type = SHM_MSGTYPE_STD;
	shm->send_cur = (shm->send_cur + 1) % SHM_BUFS;
}
Example #3
0
/* sends an iov. FIXME: returns 0 if the send is complete, -EAGAIN if
   it created one or more requests for it, and -EPIPE in case of an
   error. */
static
int _pspsm_sendv(pspsm_con_info_t *con_info, uint64_t magic)
{
	uint64_t tag = con_info->send_id | magic;
	unsigned int i=0;
	psm_error_t ret;
	size_t len = con_info->iov[0].iov_len + con_info->iov[1].iov_len;

	if (len <= pscom.env.readahead){
		pscom_memcpy_from_iov(sendbuf, con_info->iov, len);
		/* we hope that doesn't block - it shouldn't, as the
		 * message is sufficiently small */
		ret = psm_mq_send(pspsm_mq, con_info->epaddr,
				  /* flags*/ 0, tag, sendbuf, len);
		if (ret != PSM_OK) goto err;
		return 0;
	}

	for (i=0; i<2; i++){
		if (con_info->iov[i].iov_len){
			/* pspsm_dprint(0, "Send part[%d], %p len %d to con %s\n", i,
			   con_info->iov[i].iov_base, (int)con_info->iov[i].iov_len,
			   con_info->con->pub.remote_con_info.name); */
			if (_pspsm_send_buf(con_info, con_info->iov[i].iov_base,
					    con_info->iov[i].iov_len,
					    tag, &con_info->sreqs[i], i)){
				return -EPIPE;
			}
			/* inc for each outstanding send request */
			poll_user_inc();
		}
	}
	return -EAGAIN;

 err:
	pspsm_err(psm_error_get_string(ret));
	pspsm_dprint(1, "_pspsm_send_buf: %s", pspsm_err_str);
	return -EPIPE;
}
Example #4
0
/* returnvalue like write(), except on error errno is negative return */
static
int _psex_sendv(psex_con_info_t *con_info, struct iovec *iov, int size, unsigned int magic)
{
	int len;
	int psex_len;
	psex_msg_t *_msg;
	int rc;
	psex_msgheader_t *tail;
	hca_info_t *hca_info = con_info->hca_info;

	if (con_info->con_broken) goto err_broken;

	/* Its allowed to send, if
	   At least 2 tokens left or (1 token left AND n_tosend > 0)
	*/

	if ((con_info->n_send_toks < 2) &&
	    ((con_info->n_send_toks < 1) || (con_info->n_tosend_toks == 0))) {
		psex_stat.busy_notokens++;
		goto err_busy;
	}

	if (psex_global_sendq && psex_pending_global_sends >= psex_sendq_size && psex_event_count) {
		// printf("Busy global\n"); usleep(10*1000);
		psex_stat.busy_global_cq++;
		goto err_busy;
	}

	len = (size <= (int)PSEX_RMA2_PAYLOAD) ? size : (int)PSEX_RMA2_PAYLOAD;
	psex_len = PSEX_LEN(len);

	ringbuf_t *send = (con_info->send.bufs.mr) ? &con_info->send : &hca_info->send;
	_msg = ((psex_msg_t *)send->bufs.ptr) + send->pos;

	tail = (psex_msgheader_t *)((char*)_msg + psex_len - sizeof(psex_msgheader_t));

	tail->token = con_info->n_tosend_toks;
	tail->payload = len;
	tail->magic = magic;

	/* copy to registerd send buffer */
	pscom_memcpy_from_iov((void *)_msg, iov, len);
	rc = rma2_post_put_bt(con_info->rma2_port, con_info->rma2_handle, send->bufs.mr,
			     ((char*)_msg - (char *)send->bufs.ptr), psex_len,
			     PSEX_DATA(con_info->remote_rbuf_nla +
				       con_info->remote_recv_pos * sizeof(psex_msg_t), psex_len),
			      0, 0);
	if (rc != 0) goto err_rma2_post_cl;

	psex_pending_global_sends++; // ToDo: Decrease the counter somewhere!

	pscom_forward_iov(iov, len);

	con_info->n_tosend_toks = 0;
	con_info->remote_recv_pos = (con_info->remote_recv_pos + 1) % psex_recvq_size;
	send->pos = (send->pos + 1) % psex_sendq_size;
	con_info->n_send_toks--;

	return len;
	/* --- */
err_busy:
	return -EAGAIN;
	/* --- */
err_rma2_post_cl:
    if (0 /*rc == ???EAGAIN  Too many posted work requests ? */) {
	psex_stat.post_send_eagain++;
	return -EAGAIN;
    } else {
	psex_stat.post_send_error++;
	psex_err_rma2_error("rma2_post_put_cl()", rc);
	con_info->con_broken = 1;
	return -EPIPE;
    }
    /* --- */
 err_broken:
    return -EPIPE;
}
Example #5
0
/* returnvalue like write(), except on error errno is negative return */
static
int _psdapl_sendv(psdapl_con_info_t *ci, struct iovec *iov, int size, unsigned int magic)
{
	int len;
	int psdapllen;
	psdapl_msg_t *msg;
	int rc;
	psdapl_msgheader_t *tail;

	if (ci->con_broken) goto err_broken;

	/* Its allowed to send, if
	   At least 2 tokens left or (1 token left AND n_tosend > 0)
	*/

	if ((ci->n_send_toks < 2) &&
	    ((ci->n_send_toks < 1) || (ci->n_tosend_toks == 0))) {
		psdapl_stat.busy_notokens++;
		goto err_busy;
	}

	if (ci->outstanding_cq_entries >= EVD_MIN_QLEN) {
		psdapl_stat.busy_local_cq++;
		goto err_busy;
	}
/*
	if (psdapl_outstanding_cq_entries >= ???) {
		psdapl_stat.busy_global_cq++;
		goto err_busy;
	}
*/
	len = (size <= (int)DAPL_BUFSIZE_PAYLOAD) ? size : (int)DAPL_BUFSIZE_PAYLOAD;
	psdapllen = PSDAPL_LEN(len);

	msg = ((psdapl_msg_t *)ci->send_bufs.lmr_mem) + ci->send_pos;

	tail = (psdapl_msgheader_t *)((char*)msg + psdapllen);

	tail->token = ci->n_tosend_toks;
	tail->payload = len;
	tail->magic = magic;

	/* copy to registerd send buffer */
	pscom_memcpy_from_iov((void *)msg, iov, len);

	rc = psdapl_flush_sendbuf(ci,
				  (char *)msg,
				  PSDAPL_DATA_OFFSET(ci->send_pos, psdapllen),
				  psdapllen + sizeof(psdapl_msgheader_t));

	if (rc != 0) goto err_send;

	ci->outstanding_cq_entries++;

	pscom_forward_iov(iov, len);

	ci->n_tosend_toks = 0;
	ci->send_pos = (ci->send_pos + 1) % SIZE_SR_QUEUE;
	ci->n_send_toks--;

	psdapl_flush_evd(ci);

	return len;
err_busy:
	psdapl_get_fresh_tokens(ci);
	psdapl_flush_evd(ci);

	return -EAGAIN;
err_send:
	psdapl_stat.post_send_error++;
	/* ToDo: Check for EAGAIN ? */
	ci->con_broken = 1;
	return -EPIPE;
err_broken:
	return -EPIPE;
}