Commit f11869c4 authored by Ben Walker's avatar Ben Walker Committed by Tomasz Zawadzki
Browse files

idxd: Add support for vectored compare operations



Compare two scattered memory regions

Change-Id: I6ce5c9e7bc1ee1ef0e9173c00e86628d43a1e41f
Signed-off-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/10287


Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Community-CI: Mellanox Build Bot
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
parent fe705480
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -652,8 +652,11 @@ _submit_ops(struct idxd_chan_entry *t, struct idxd_task *task)
				task->expected_status = 0;
				*(uint8_t *)task->dst = DATA_PATTERN;
			}
			rc = spdk_idxd_submit_compare(t->ch, task->dst, task->src,
						      g_xfer_size_bytes, idxd_done, task);
			siov.iov_base = task->src;
			siov.iov_len = g_xfer_size_bytes;
			diov.iov_base = task->dst;
			diov.iov_len = g_xfer_size_bytes;
			rc = spdk_idxd_submit_compare(t->ch, &siov, 1, &diov, 1, idxd_done, task);
			break;
		case IDXD_DUALCAST:
			rc = spdk_idxd_submit_dualcast(t->ch, task->dst, task->dst2,
+6 −4
Original line number Diff line number Diff line
@@ -281,9 +281,10 @@ int spdk_idxd_batch_prep_compare(struct spdk_idxd_io_channel *chan, struct idxd_
 * by writing to the proper device portal.
 *
 * \param chan IDXD channel to submit request.
 * \param src1 First source to compare.
 * \param src2 Second source to compare.
 * \param nbytes Number of bytes to compare.
 * \param siov1 First source iovec
 * \param siov1cnt Number of elements in siov1
 * \param siov2 Second source iovec
 * \param siov2cnt Number of elements in siov2
 * \param cb_fn Callback function which will be called when the request is complete.
 * \param cb_arg Opaque value which will be passed back as the arg parameter in
 * the completion callback.
@@ -291,7 +292,8 @@ int spdk_idxd_batch_prep_compare(struct spdk_idxd_io_channel *chan, struct idxd_
 * \return 0 on success, negative errno on failure.
 */
int spdk_idxd_submit_compare(struct spdk_idxd_io_channel *chan,
			     void *src1, const void *src2, uint64_t nbytes,
			     struct iovec *siov1, size_t siov1cnt,
			     struct iovec *siov2, size_t siov2cnt,
			     spdk_idxd_req_cb cb_fn, void *cb_arg);

/**
+64 −3
Original line number Diff line number Diff line
@@ -625,8 +625,8 @@ error:
	return rc;
}

int
spdk_idxd_submit_compare(struct spdk_idxd_io_channel *chan, void *src1, const void *src2,
static inline int
_idxd_submit_compare_single(struct spdk_idxd_io_channel *chan, void *src1, const void *src2,
			    uint64_t nbytes, spdk_idxd_req_cb cb_fn, void *cb_arg)
{
	struct idxd_hw_desc *desc;
@@ -669,6 +669,67 @@ error:
	return rc;
}

int
spdk_idxd_submit_compare(struct spdk_idxd_io_channel *chan,
			 struct iovec *siov1, size_t siov1cnt,
			 struct iovec *siov2, size_t siov2cnt,
			 spdk_idxd_req_cb cb_fn, void *cb_arg)
{
	struct idxd_hw_desc *desc;
	struct idxd_ops *op;
	void *src1, *src2;
	uint64_t src1_addr, src2_addr;
	int rc;
	size_t len;
	struct idxd_batch *batch;
	struct spdk_ioviter iter;

	if (siov1cnt == 1 && siov2cnt == 1) {
		/* Simple case - comparing one buffer to another */
		if (siov1[0].iov_len != siov2[0].iov_len) {
			return -EINVAL;
		}

		return _idxd_submit_compare_single(chan, siov1[0].iov_base, siov2[0].iov_base, siov1[0].iov_len,
						   cb_fn, cb_arg);
	}

	batch = spdk_idxd_batch_create(chan);
	if (!batch) {
		return -EBUSY;
	}

	for (len = spdk_ioviter_first(&iter, siov1, siov1cnt, siov2, siov2cnt, &src1, &src2);
	     len > 0;
	     len = spdk_ioviter_next(&iter, &src1, &src2)) {
		rc = _idxd_prep_batch_cmd(chan, NULL, NULL, batch, &desc, &op);
		if (rc) {
			goto err;
		}

		rc = _vtophys(src1, &src1_addr, len);
		if (rc) {
			goto err;
		}

		rc = _vtophys(src2, &src2_addr, len);
		if (rc) {
			goto err;
		}

		desc->opcode = IDXD_OPCODE_COMPARE;
		desc->src_addr = src1_addr;
		desc->src2_addr = src2_addr;
		desc->xfer_size = len;
	}

	return spdk_idxd_batch_submit(chan, batch, cb_fn, cb_arg);

err:
	spdk_idxd_batch_cancel(chan, batch);
	return rc;
}

int
spdk_idxd_submit_fill(struct spdk_idxd_io_channel *chan, void *dst, uint64_t fill_pattern,
		      uint64_t nbytes, spdk_idxd_req_cb cb_fn, void *cb_arg)
+5 −1
Original line number Diff line number Diff line
@@ -173,7 +173,11 @@ _process_single_task(struct spdk_io_channel *ch, struct spdk_accel_task *task)
					       idxd_done, task);
		break;
	case ACCEL_OPCODE_COMPARE:
		rc = spdk_idxd_submit_compare(chan->chan, task->src, task->src2, task->nbytes, idxd_done, task);
		siov.iov_base = task->src;
		siov.iov_len = task->nbytes;
		diov.iov_base = task->dst;
		diov.iov_len = task->nbytes;
		rc = spdk_idxd_submit_compare(chan->chan, &siov, 1, &diov, 1, idxd_done, task);
		break;
	case ACCEL_OPCODE_MEMFILL:
		memset(&task->fill_pattern, fill_pattern, sizeof(uint64_t));