예제 #1
0
static int krping_setup_buffers(struct krping_cb *cb)
{
	int ret;
	struct ib_phys_buf buf;
	u64 iovbase;

	DEBUG_LOG(PFX "krping_setup_buffers called on cb %p\n", cb);

	if (cb->use_dmamr) {
		cb->dma_mr = ib_get_dma_mr(cb->pd, IB_ACCESS_LOCAL_WRITE|
					   IB_ACCESS_REMOTE_READ|
				           IB_ACCESS_REMOTE_WRITE);
		if (IS_ERR(cb->dma_mr)) {
			log(LOG_ERR, "reg_dmamr failed\n");
			return PTR_ERR(cb->dma_mr);
		}
	} else {

		buf.addr = vtophys(&cb->recv_buf);
		buf.size = sizeof cb->recv_buf;
		iovbase = vtophys(&cb->recv_buf);
		cb->recv_mr = ib_reg_phys_mr(cb->pd, &buf, 1, 
					     IB_ACCESS_LOCAL_WRITE, 
					     &iovbase);

		if (IS_ERR(cb->recv_mr)) {
			log(LOG_ERR, "recv_buf reg_mr failed\n");
			return PTR_ERR(cb->recv_mr);
		}

		buf.addr = vtophys(&cb->send_buf);
		buf.size = sizeof cb->send_buf;
		iovbase = vtophys(&cb->send_buf);
		cb->send_mr = ib_reg_phys_mr(cb->pd, &buf, 1, 
					     0, &iovbase);

		if (IS_ERR(cb->send_mr)) {
			log(LOG_ERR, "send_buf reg_mr failed\n");
			ib_dereg_mr(cb->recv_mr);
			return PTR_ERR(cb->send_mr);
		}
	}

	/* RNIC adapters have a limit upto which it can register physical memory
	 * If DMA-MR memory mode is set then normally driver registers maximum
	 * supported memory. After that if contigmalloc allocates memory beyond the
	 * specified RNIC limit then Krping may not work.
	 */
	if (cb->use_dmamr && cb->memlimit)
		cb->rdma_buf = contigmalloc(cb->size, M_DEVBUF, M_WAITOK, 0, cb->memlimit,
					    PAGE_SIZE, 0);
	else 
		cb->rdma_buf = contigmalloc(cb->size, M_DEVBUF, M_WAITOK, 0, -1UL,
					    PAGE_SIZE, 0);

	if (!cb->rdma_buf) {
		log(LOG_ERR, "rdma_buf malloc failed\n");
		ret = ENOMEM;
		goto err1;
	}
	if (!cb->use_dmamr) {

		buf.addr = vtophys(cb->rdma_buf);
		buf.size = cb->size;
		iovbase = vtophys(cb->rdma_buf);
		cb->rdma_mr = ib_reg_phys_mr(cb->pd, &buf, 1, 
					     IB_ACCESS_REMOTE_READ| 
					     IB_ACCESS_REMOTE_WRITE, 
					     &iovbase);

		if (IS_ERR(cb->rdma_mr)) {
			log(LOG_ERR, "rdma_buf reg_mr failed\n");
			ret = PTR_ERR(cb->rdma_mr);
			goto err2;
		}
	}

	if (!cb->server || cb->wlat || cb->rlat || cb->bw) {
		if (cb->use_dmamr && cb->memlimit)
			cb->start_buf = contigmalloc(cb->size, M_DEVBUF, M_WAITOK,
						     0, cb->memlimit, PAGE_SIZE, 0);
		else
			cb->start_buf = contigmalloc(cb->size, M_DEVBUF, M_WAITOK,
						     0, -1UL, PAGE_SIZE, 0);
		if (!cb->start_buf) {
			log(LOG_ERR, "start_buf malloc failed\n");
			ret = ENOMEM;
			goto err2;
		}
		if (!cb->use_dmamr) {
			unsigned flags = IB_ACCESS_REMOTE_READ;

			if (cb->wlat || cb->rlat || cb->bw) 
				flags |= IB_ACCESS_REMOTE_WRITE;
			buf.addr = vtophys(cb->start_buf);
			buf.size = cb->size;
			iovbase = vtophys(cb->start_buf);
			cb->start_mr = ib_reg_phys_mr(cb->pd, &buf, 1, 
					     flags,
					     &iovbase);

			if (IS_ERR(cb->start_mr)) {
				log(LOG_ERR, "start_buf reg_mr failed\n");
				ret = PTR_ERR(cb->start_mr);
				goto err3;
			}
		}
	}

	krping_setup_wr(cb);
	DEBUG_LOG(PFX "allocated & registered buffers...\n");
	return 0;
err3:
	contigfree(cb->start_buf, cb->size, M_DEVBUF);

	if (!cb->use_dmamr)
		ib_dereg_mr(cb->rdma_mr);
err2:
	contigfree(cb->rdma_buf, cb->size, M_DEVBUF);
err1:
	if (cb->use_dmamr)
		ib_dereg_mr(cb->dma_mr);
	else {
		ib_dereg_mr(cb->recv_mr);
		ib_dereg_mr(cb->send_mr);
	}
	return ret;
}
예제 #2
0
static int krping_setup_buffers(struct krping_cb *cb)
{
	int ret;
	struct ib_phys_buf buf;
	u64 iovbase;

	DEBUG_LOG(PFX "krping_setup_buffers called on cb %p\n", cb);

	if (cb->use_dmamr) {
		cb->dma_mr = ib_get_dma_mr(cb->pd, IB_ACCESS_LOCAL_WRITE|
					   IB_ACCESS_REMOTE_READ|
				           IB_ACCESS_REMOTE_WRITE);
		if (IS_ERR(cb->dma_mr)) {
			log(LOG_ERR, "reg_dmamr failed\n");
			return PTR_ERR(cb->dma_mr);
		}
	} else {

		buf.addr = vtophys(&cb->recv_buf);
		buf.size = sizeof cb->recv_buf;
		iovbase = vtophys(&cb->recv_buf);
		cb->recv_mr = ib_reg_phys_mr(cb->pd, &buf, 1, 
					     IB_ACCESS_LOCAL_WRITE, 
					     &iovbase);

		if (IS_ERR(cb->recv_mr)) {
			log(LOG_ERR, "recv_buf reg_mr failed\n");
			return PTR_ERR(cb->recv_mr);
		}

		buf.addr = vtophys(&cb->send_buf);
		buf.size = sizeof cb->send_buf;
		iovbase = vtophys(&cb->send_buf);
		cb->send_mr = ib_reg_phys_mr(cb->pd, &buf, 1, 
					     0, &iovbase);

		if (IS_ERR(cb->send_mr)) {
			log(LOG_ERR, "send_buf reg_mr failed\n");
			ib_dereg_mr(cb->recv_mr);
			return PTR_ERR(cb->send_mr);
		}
	}

	cb->rdma_buf = contigmalloc(cb->size, M_DEVBUF, M_WAITOK, 0, -1UL,
		PAGE_SIZE, 0);

	if (!cb->rdma_buf) {
		log(LOG_ERR, "rdma_buf malloc failed\n");
		ret = ENOMEM;
		goto err1;
	}
	if (!cb->use_dmamr) {

		buf.addr = vtophys(cb->rdma_buf);
		buf.size = cb->size;
		iovbase = vtophys(cb->rdma_buf);
		cb->rdma_mr = ib_reg_phys_mr(cb->pd, &buf, 1, 
					     IB_ACCESS_REMOTE_READ| 
					     IB_ACCESS_REMOTE_WRITE, 
					     &iovbase);

		if (IS_ERR(cb->rdma_mr)) {
			log(LOG_ERR, "rdma_buf reg_mr failed\n");
			ret = PTR_ERR(cb->rdma_mr);
			goto err2;
		}
	}

	if (!cb->server || cb->wlat || cb->rlat || cb->bw) {
		cb->start_buf = contigmalloc(cb->size, M_DEVBUF, M_WAITOK,
			0, -1UL, PAGE_SIZE, 0);
		if (!cb->start_buf) {
			log(LOG_ERR, "start_buf malloc failed\n");
			ret = ENOMEM;
			goto err2;
		}
		if (!cb->use_dmamr) {
			unsigned flags = IB_ACCESS_REMOTE_READ;

			if (cb->wlat || cb->rlat || cb->bw) 
				flags |= IB_ACCESS_REMOTE_WRITE;
			buf.addr = vtophys(cb->start_buf);
			buf.size = cb->size;
			iovbase = vtophys(cb->start_buf);
			cb->start_mr = ib_reg_phys_mr(cb->pd, &buf, 1, 
					     flags,
					     &iovbase);

			if (IS_ERR(cb->start_mr)) {
				log(LOG_ERR, "start_buf reg_mr failed\n");
				ret = PTR_ERR(cb->start_mr);
				goto err3;
			}
		}
	}

	krping_setup_wr(cb);
	DEBUG_LOG(PFX "allocated & registered buffers...\n");
	return 0;
err3:
	contigfree(cb->start_buf, cb->size, M_DEVBUF);

	if (!cb->use_dmamr)
		ib_dereg_mr(cb->rdma_mr);
err2:
	contigfree(cb->rdma_buf, cb->size, M_DEVBUF);
err1:
	if (cb->use_dmamr)
		ib_dereg_mr(cb->dma_mr);
	else {
		ib_dereg_mr(cb->recv_mr);
		ib_dereg_mr(cb->send_mr);
	}
	return ret;
}