Exemple #1
0
/*---------------------------------------------------------------------------*/
int xio_validate_rdma_op(struct xio_vmsg *vmsg,
			 struct xio_sge *rsg_list, size_t rsize,
			 int max_sge,
			 int op_size,
			 int *tasks_used)
{
	struct sg_table *sgtbl;
	struct scatterlist *liov;
	uint64_t	raddr;
	uint32_t	rlen;
	uint64_t	laddr;
	uint32_t	llen;
	uint32_t	tot_len = 0;
	size_t		lsize, lnents;
	int		l, r;
	int		k = 0;

	if (rsize < 1) {
		ERROR_LOG("rsize:%zu\n", rsize);
		*tasks_used = 0;
		return -1;
	}
	sgtbl		= &vmsg->data_tbl;
	lnents		= sgtbl->nents;


	if (lnents > XIO_MAX_IOV || lnents == 0) {
		WARN_LOG("IOV size %zu\n", lnents);
		*tasks_used = 0;
		return -EINVAL;
	}


	lsize = lnents;
	liov  = sgtbl->sgl;

	r = 0;
	rlen  = rsg_list[r].length;
	raddr = rsg_list[r].addr;

	l = 0;
	laddr = uint64_from_ptr(sg_virt(liov));
	llen  = liov->length;

	/* At least one task */
	*tasks_used = 1;

	while (1) {
		if (rlen < llen) {
			r++;
			tot_len	+= rlen;
			if (r == rsize)
				break;
			llen	-= rlen;
			laddr	+= rlen;
			raddr	= rsg_list[r].addr;
			rlen	= rsg_list[r].length;
			(*tasks_used)++;
			k = 0;
		} else if (llen < rlen) {
			/* check page alignment when source buff spans more
			 * then one destination buffer */
			l++;
			tot_len += llen;
			if (l == lsize)
				break;
			k++;
			if (k == max_sge - 1) {
				/* reached last index */
				(*tasks_used)++;
				k = 0;
			}
			rlen	-= llen;
			raddr	+= llen;
			laddr	= uint64_from_ptr(sg_virt(liov));
			llen	= liov->length;
		} else {
			l++;
			r++;
			tot_len	+= llen;
			if ((l == lsize) || (r == rsize))
				break;

			laddr	= uint64_from_ptr(sg_virt(liov));
			llen	= liov->length;
			raddr	= rsg_list[r].addr;
			rlen	= rsg_list[r].length;
			(*tasks_used)++;
			k = 0;
		}
	}

	/* not enough buffers to complete */
	if (tot_len < op_size) {
		*tasks_used = 0;
		ERROR_LOG("iovec exhausted\n");
		return -1;
	}

	return 0;
}
Exemple #2
0
int xio_validate_rdma_op(struct xio_vmsg *vmsg,
			 struct xio_sge *rsg_list, size_t rsize,
			 int op_size)
{
	struct xio_iovec_ex *liov;
	uint64_t	raddr;
	uint32_t	rlen;
	uint64_t	laddr;
	uint32_t	llen;
	uint32_t	tot_len = 0;
	size_t lsize;
	int l, r;

	if (rsize < 1) {
		ERROR_LOG("rsize:%zu\n", rsize);
		return -1;
	}

	if (vmsg->data_iovlen > XIO_MAX_IOV || vmsg->data_iovlen == 0) {
		WARN_LOG("IOV size %zu\n", vmsg->data_iovlen);
		return -EINVAL;
	}

	lsize = vmsg->data_iovlen;
	liov  = vmsg->data_iov;

	r = 0;
	rlen  = rsg_list[r].length;
	raddr = rsg_list[r].addr;

	l = 0;
	laddr = uint64_from_ptr(liov[l].iov_base);
	llen  = liov[l].iov_len;

	while (1) {
		if (rlen < llen) {
			r++;
			tot_len	+= rlen;
			if (r == rsize)
				break;
			llen	-= rlen;
			laddr	+= rlen;
			raddr	= rsg_list[r].addr;
			rlen	= rsg_list[r].length;
		} else if (llen < rlen) {
			/* check page alignment when source buff spans more
			 * then one destination buffer */
			l++;
			tot_len += llen;
			if (l == lsize)
				break;
			rlen	-= llen;
			raddr	+= llen;
			laddr	= uint64_from_ptr(liov[l].iov_base);
			llen	= liov[l].iov_len;
		} else {
			l++;
			r++;
			tot_len	+= llen;
			if ((l == lsize) || (r == rsize))
				break;

			laddr	= uint64_from_ptr(liov[l].iov_base);
			llen	= liov[l].iov_len;
			raddr	= rsg_list[r].addr;
			rlen	= rsg_list[r].length;
		}
	}

	/* not enough buffers to complete */
	if (tot_len < op_size) {
		ERROR_LOG("iovec exausted\n");
		return -1;
	}

	return 0;
}