Beispiel #1
0
/* called with rxlock, process all RR's up to signal marker at wr_last */
static void m_pi_post_writeto(struct mcm_qp *m_qp, struct mcm_wr_rx *wr_sig, struct ibv_wc *wc)
{
	mcm_scif_dev_t *smd = m_qp->smd;
	struct mcm_wr_rx *wr_rx;
	struct mcm_sr *m_sr = NULL;
	off_t l_off, l_off_wr, r_off;
	int ret, i, l_start, l_end, l_len, sg_len, w_len, num_sge, wr_idx, wr_cnt = 0;
	int wt_flag;

	wr_idx = m_qp->wr_tl_r_wt; /* from WT tail, process RR's posted until reaching wr_last */

	while (m_qp->pi_rr_cnt) { /* RR's pending */
		wr_rx = (struct mcm_wr_rx *)(m_qp->wrc.wr_addr + (m_qp->wrc.wr_sz * wr_idx));

		if (!(wr_rx->flags & M_READ_POSTED)) {
			/* reached RR signaled marker, or head pointer */
			if (wr_idx == wr_sig->w_idx || wr_idx == m_qp->wr_hd_r)
				break;

			wr_idx = (wr_idx + 1) & m_qp->wrc.wr_end; /* next WR */
			continue;
		}
		wr_cnt++;
#if MCM_PROFILE
		if (wr_rx == wr_sig)
			mcm_qp_prof_ts(m_qp, MCM_QP_IB_RR, wr_rx->time, wr_rx->qcnt, wr_cnt);
#endif
		mlog(4, " WR_rx[%d-%d] %p m_qp %p wc %p wc->op %x wr_rx->wr.op %x\n",
			wr_rx->w_idx, wr_sig->w_idx, wr_rx, m_qp, wc,
			wc->opcode, wr_rx->wr.opcode);

		m_qp->pi_rr_cnt--; /* rdma read complete */
		MCNTR(smd->md, MCM_QP_READ_DONE);

		/* if SR or RW_imm, need a posted receive */
		if ((wr_rx->wr.opcode & IBV_WR_SEND) ||
		    (wr_rx->wr.opcode & IBV_WR_RDMA_WRITE_WITH_IMM)) {
			m_sr = m_pi_get_sr(m_qp, wr_rx->w_idx);
			if (!m_sr) {
				mlog(0, " WARNING: SR stalled, no RCV messages posted"
					" m_qp %p, sr_tl %d sr_hd %d\n",
					m_qp, m_qp->sr_tl, m_qp->sr_hd);
				wr_rx->flags |= M_RECV_PAUSED;
				return;
			}
			wr_rx->s_idx = m_sr->s_idx; /* link WR_RX and SR */
			m_sr->len = 0;
			num_sge = m_sr->num_sge;
			sg_len = m_sr->sg[0].length;
			r_off = m_sr->sg[0].addr; /* post recv buffer address */
			mlog(4, " WR SR or RW_IMM: m_sr[%d] %p -> scif r_off %Lx ln %d\n",
				m_sr->s_idx, m_sr, r_off, sg_len);
		}
		/* need to translate to rdma write dst */
		if (!(wr_rx->wr.opcode & IBV_WR_SEND)) {
			num_sge = 1;
			sg_len = wr_rx->sg[2].length;
			r_off = m_pi_mr_trans(smd, wr_rx->wr.wr.rdma.remote_addr,
					      wr_rx->wr.wr.rdma.rkey, sg_len);
			if (!r_off)
				goto bail;

			mlog(4, " RDMA_WRITE op: wr_rx[%d] %p -> scif r_off %Lx len %d\n",
				 wr_rx->w_idx, wr_rx, r_off, sg_len, 0);
		}

		/* sg[0] entry == proxy-out buffer, src for IB RR */
		/* sg[1] entry == proxy-in buffer, dst for IB RR */
		/* sg[2] entry == proxy-in buffer src for scif_sendto */
		/* wr.rdma.remote_addr, wr.rdma.rkey, dst for scif_sento - TPT to sci_off */
		wr_rx->wr.wr_id = 0;
		l_off_wr = (uint64_t) (m_qp->wr_off_r + (wr_rx->w_idx * m_qp->wrc.wr_sz));
		l_off = wr_rx->sg[2].addr;
		l_len = wr_rx->sg[2].length;
		l_start = l_off - (uint64_t)smd->m_offset_r;
		l_end = l_start + l_len;

		for (i=0; (i<num_sge && l_len); i++) {
			w_len = min(sg_len, l_len);
			wt_flag = 0;
			mlog(4, " WR_rx[%d] %p writeto l_off %Lx r_off %Lx rb_off 0x%x-0x%x ln %d org_id %Lx tl %d hd %d\n",
				wr_rx->w_idx, wr_rx, l_off, r_off, l_start, l_end, w_len, wr_rx->org_id,
				m_qp->wr_tl_r, m_qp->wr_hd_r);
#if MCM_PROFILE
			wr_rx->time = mcm_ts_us();
			wr_rx->qcnt = m_qp->post_cnt_wt;
#endif
			if (w_len < 256)
				wt_flag = SCIF_RMA_USECPU;

			ret = scif_writeto(smd->scif_tx_ep, l_off, w_len, r_off, wt_flag);

			if (ret) {
				mlog(0, " ERR: scif_sendto, ret %d err: %d %s\n",
					ret, errno, strerror(errno));
				goto bail;
			}
			MCNTR(smd->md, MCM_SCIF_WRITE_TO);

			/* adjust for multiple SG entries on post_recv */
			l_off += w_len;
			l_len = l_len - w_len;
			if (m_sr) {
				m_sr->len += w_len;
				r_off = m_sr->sg[i].addr; /* next SR segment */
				sg_len = m_sr->sg[i].length;
			}
		}
		if (l_len) {
			mlog(0, " ERR: RX overrun: written %d remaining %d sge's %d\n",
				wr_rx->sg[2].length, l_len, num_sge);
			goto bail;
		}

		/* signal last segment */
		mlog(4, " SCIF_fence_signal: l_off_wr %p, wr_rx %p wr_idx %d\n",
			l_off_wr, wr_rx, wr_rx->w_idx);

		ret = scif_fence_signal(smd->scif_tx_ep, l_off_wr, wr_rx->org_id, 0, 0,
					SCIF_FENCE_INIT_SELF | SCIF_SIGNAL_LOCAL);
		if (ret) {
			mlog(0," ERR: scif_fence_signal, ret %d %s\n", ret, strerror(errno));
			goto bail;
		}
		MCNTR(smd->md, MCM_SCIF_SIGNAL);
		wr_rx->flags &= ~M_READ_POSTED; /* reset READ_POSTED */
		wr_rx->flags |= M_READ_DONE;
		wr_rx->flags |= M_READ_WRITE_TO;
		m_qp->post_cnt_wt++;

		/* reached RR signaled marker, or head */
		if (wr_idx == wr_sig->w_idx || wr_idx == m_qp->wr_hd_r)
			break;

		wr_idx = (wr_idx + 1) & m_qp->wrc.wr_end; /* next WR */
	}
	write(smd->md->mc->rx_pipe[1], "w", sizeof "w"); /* signal rx_thread */
	return;
bail:
	/* report error via WC back to proxy-out */
	mlog(0, " ERR: writeto: wr_rx[%d] %p -> raddr %Lx rkey %x (scif r_off %Lx) len %d\n",
		wr_rx->w_idx, wr_rx, wr_rx->wr.wr.rdma.remote_addr,
		wr_rx->wr.wr.rdma.rkey, r_off, sg_len);

	return;
}
int main( )
{
	size_t len = 536870912;
	int align = 4096;
	scif_epd_t endpoint;
	struct scif_portID portid;
	int ret;
	
	uint8_t *in_key     = malloc(16 * sizeof(uint8_t));
	struct crypto_tfm *tfm
        	= malloc(
                	 sizeof(struct crypto_tfm) +
                 	 sizeof(struct crypto_aes_ctx)
               		 );
	struct crypto_aes_ctx *ctx
        	= crypto_tfm_ctx(tfm);

	ctx->key_length = AES_KEYSIZE_256;
	crypto_aes_set_key(tfm, in_key, AES_KEYSIZE_256);
	
        endpoint = scif_open( );
	if( endpoint == SCIF_OPEN_FAILED ) 
	{
		printf("scif open failed\n");
		return 1;
        }

	ret = scif_bind(endpoint, 23955);
	if(ret==-1) 
	{
		printf("scif_bind failed");
		return 1;
	}

	portid.node = 0;
	portid.port = 23968;

	ret = scif_connect(endpoint, &portid);
	for( int attempt = 0; ret == -1 && attempt < 10; ++attempt ) 
	{
        	sleep(1);
        	ret = scif_connect(endpoint, &portid);
	}
	if (ret==-1)
	{ 
		printf("scif_connect failed\n");
		return 1;
	}

	void *ptr;
	ret = posix_memalign((void**)&ptr, align, len);	
	if (ret)
	{
		printf("Allocating memory failed\n");
		return 1;

	}
	memset(ptr, 0, len);

	if( SCIF_REGISTER_FAILED == scif_register(endpoint, ptr, len, (long)ptr, SCIF_PROT_READ | SCIF_PROT_WRITE, SCIF_MAP_FIXED ) )
        {
                printf("scif_register of ptr failed due to: %s\n", strerror(errno));
                return 1;
        }

	void *tempbuffer;
	ret = posix_memalign((void**)&tempbuffer, align, len);
	if (ret)
	{
		printf("Allocating tempbuffer failed\n");
		return 1;
	}

       	if( SCIF_REGISTER_FAILED == scif_register(endpoint, tempbuffer, len, (long)tempbuffer, SCIF_PROT_READ | SCIF_PROT_WRITE, SCIF_MAP_FIXED ) )
        {
               	printf("scif_register of temp failed due to: %s\n", strerror(errno));
                return 1;
        }

	void *outbuffer;
	ret = posix_memalign((void**)&outbuffer, align, len);
	if (ret)
	{
		printf("Allocating outbuffer failed %s\n", strerror(errno));
		return 1;
	}

	if( SCIF_REGISTER_FAILED == scif_register(endpoint, outbuffer, len, (long)outbuffer, SCIF_PROT_READ | SCIF_PROT_WRITE, SCIF_MAP_FIXED ) )
        {
                printf("scif_register of outbuffer failed due to: %s\n", strerror(errno));
                return 1;
        }

	void *remote_ptr;
	void *return_ptr;

	ret = scif_recv(endpoint, &remote_ptr, sizeof(void*), SCIF_RECV_BLOCK);
	if (ret==-1)
	{
		printf("scif_recv failed due to: %s\n", strerror(errno));
		return 1;
	}

        ret = scif_recv(endpoint, &return_ptr, sizeof(void*), SCIF_RECV_BLOCK);
        if (ret==-1)
        {
                printf("scif_recv failed due to: %s\n", strerror(errno));
                return 1;
        }
	
	struct timespec start_enc, stop_enc;
	clock_gettime(CLOCK_REALTIME, &start_enc);
	if (scif_readfrom(endpoint, (long)ptr, len, (long)remote_ptr, SCIF_RMA_SYNC))
	{
		printf("scif_readfrom failed due to: %s\n", strerror(errno));
		return 1;
	}

	#pragma omp parallel for 
	for (int k = 0; k<len; k+=16)
		{ aes_encrypt(tfm, (uint8_t*)&tempbuffer[k], (uint8_t*)&ptr[k]); }

	if (scif_writeto(endpoint, (long)tempbuffer, len, (long)return_ptr, SCIF_RMA_SYNC))
        {
		printf("scif_writeto failed due to: %s\n", strerror(errno));
		return 1;
	}					

	clock_gettime(CLOCK_REALTIME, &stop_enc);
	double time_enc = (stop_enc.tv_sec - start_enc.tv_sec) + ( stop_enc.tv_nsec - start_enc.tv_nsec) / NANOSECONDS;
	double result0 = len/time_enc/1048576;
       	printf("%1f,", result0);

        struct timespec start_for, stop_for;
        clock_gettime(CLOCK_REALTIME, &start_for);
        if (scif_readfrom(endpoint, (long)ptr, len, (long)remote_ptr, SCIF_RMA_SYNC))
        {
	        printf("scif_readfrom failed due to: %s\n", strerror(errno));
		return 1;
	}

	#pragma omp parallel for
        for (int k=0; k<len; k+=16)
    		{ aes_decrypt(tfm, (uint8_t*)&outbuffer[k], (uint8_t*)&tempbuffer[k]); }

        if (scif_writeto(endpoint, (long)outbuffer, len, (long)return_ptr, SCIF_RMA_SYNC))
    	{
        	printf("scif_writeto failed due to: %s\n", strerror(errno));
                return 1;
        }

	clock_gettime(CLOCK_REALTIME, &stop_for);
        double time_for = (stop_for.tv_sec - start_for.tv_sec) + ( stop_for.tv_nsec - start_for.tv_nsec) / NANOSECONDS;
        double result = 536870912/time_for/1048576;
        printf("%1f \n", result);

	ret = scif_send(endpoint, &ptr, sizeof(long), SCIF_SEND_BLOCK);
	if (ret==-1)
	{
		printf("scif_send failed due to: %s\n", strerror(errno));
		return 1;
	}

        ret = scif_unregister(endpoint, (off_t)ptr, len );
        if(ret==-1 && errno!=ENOTCONN )
        {
                printf("scif_unregister failed %s\n", strerror(errno));
                return 1;
        }

	scif_close(endpoint);	

}