[Accel-config] [PATCH v4 3/7] accel-config/test: add drain operation support for single submission

Tony Zhu <tony.zhu at intel.com> Mon, 21 Feb 2022 09:34:19 +0800
Newsgroups dev.linux.lists.accel-config
Message-ID <[email protected]>
A Drain descriptor could not be included in a batch. It is treated
as an unsupported operation type. Block on fault is reserved for
Drain operation.

Signed-off-by: Tony Zhu <tony.zhu(a)intel.com>
---
 test/dsa.c      | 47 +++++++++++++++++++++++++++++++++++++++++++++++
 test/dsa.h      |  4 ++++
 test/dsa_test.c | 15 +++++++++++++++
 test/prep.c     | 16 ++++++++++++++++
 4 files changed, 82 insertions(+)

diff --git a/test/dsa.c b/test/dsa.c
index 8498d01..1ac925b 100644
--- a/test/dsa.c
+++ b/test/dsa.c
@@ -397,6 +397,8 @@ int init_task(struct task *tsk, int tflags, int opcode,
 	dbg("initilizing task %#lx\n", tsk);
 
 	switch (opcode) {
+	/* After memory move, do drain opcode test */
+	case DSA_OPCODE_DRAIN:
 	case DSA_OPCODE_MEMMOVE:
 		rc = init_memcpy(tsk, tflags, opcode, xfer_size);
 		break;
@@ -785,6 +787,51 @@ int dsa_wait_batch(struct batch_task *btsk)
 	return DSA_STATUS_OK;
 }
 
+int dsa_wait_drain(struct dsa_context *ctx, struct task *tsk)
+{
+	struct dsa_completion_record *comp = tsk->comp;
+	int rc;
+
+	rc = dsa_wait_on_desc_timeout(comp, ms_timeout);
+	if (rc < 0) {
+		err("drain desc timeout\n");
+		return DSA_STATUS_TIMEOUT;
+	}
+
+	return DSA_STATUS_OK;
+}
+
+int dsa_drain_multi_task_nodes(struct dsa_context *ctx)
+{
+	struct task_node *tsk_node = ctx->multi_task_node;
+	int ret = DSA_STATUS_OK;
+
+	while (tsk_node) {
+		/* Block on fault is reserved for Drain */
+		tsk_node->tsk->dflags = IDXD_OP_FLAG_CRAV | IDXD_OP_FLAG_RCR;
+
+		dsa_prep_drain(tsk_node->tsk);
+		tsk_node = tsk_node->next;
+	}
+
+	tsk_node = ctx->multi_task_node;
+	while (tsk_node) {
+		dsa_desc_submit(ctx, tsk_node->tsk->desc);
+		tsk_node = tsk_node->next;
+	}
+	tsk_node = ctx->multi_task_node;
+	info("Submitted all drain jobs\n");
+
+	while (tsk_node) {
+		ret = dsa_wait_drain(ctx, tsk_node->tsk);
+		if (ret != DSA_STATUS_OK)
+			info("Desc: %p failed with ret: %d\n",
+			     tsk_node->tsk->desc, tsk_node->tsk->comp->status);
+		tsk_node = tsk_node->next;
+	}
+	return ret;
+}
+
 int dsa_wait_memcpy(struct dsa_context *ctx, struct task *tsk)
 {
 	struct dsa_hw_desc *desc = tsk->desc;
diff --git a/test/dsa.h b/test/dsa.h
index 9a4016b..59b3ef5 100644
--- a/test/dsa.h
+++ b/test/dsa.h
@@ -241,6 +241,9 @@ int init_task(struct task *tsk, int tflags, int opcode,
 int dsa_noop_multi_task_nodes(struct dsa_context *ctx);
 int dsa_wait_noop(struct dsa_context *ctx, struct task *tsk);
 
+int dsa_drain_multi_task_nodes(struct dsa_context *ctx);
+int dsa_wait_drain(struct dsa_context *ctx, struct task *tsk);
+
 int dsa_memcpy_multi_task_nodes(struct dsa_context *ctx);
 int dsa_wait_memcpy(struct dsa_context *ctx, struct task *tsk);
 
@@ -257,6 +260,7 @@ int dsa_dualcast_multi_task_nodes(struct dsa_context *ctx);
 int dsa_wait_dualcast(struct dsa_context *ctx, struct task *tsk);
 
 void dsa_prep_noop(struct task *tsk);
+void dsa_prep_drain(struct task *tsk);
 void dsa_prep_memcpy(struct task *tsk);
 void dsa_reprep_memcpy(struct dsa_context *ctx, struct task *tsk);
 void dsa_prep_memfill(struct task *tsk);
diff --git a/test/dsa_test.c b/test/dsa_test.c
index eccf89c..82f624d 100644
--- a/test/dsa_test.c
+++ b/test/dsa_test.c
@@ -221,6 +221,20 @@ static int test_memory(struct dsa_context *ctx, size_t buf_size,
 		}
 
 		switch (opcode) {
+		case DSA_OPCODE_DRAIN:
+			rc = dsa_memcpy_multi_task_nodes(ctx);
+			if (rc != DSA_STATUS_OK)
+				return rc;
+
+			rc = dsa_drain_multi_task_nodes(ctx);
+			if (rc != DSA_STATUS_OK)
+				return rc;
+
+			rc = task_result_verify_task_nodes(ctx, 0);
+			if (rc != DSA_STATUS_OK)
+				return rc;
+			break;
+
 		case DSA_OPCODE_MEMMOVE:
 			rc = dsa_memcpy_multi_task_nodes(ctx);
 			if (rc != DSA_STATUS_OK)
@@ -420,6 +434,7 @@ int main(int argc, char *argv[])
 			goto error;
 		break;
 
+	case DSA_OPCODE_DRAIN:
 	case DSA_OPCODE_MEMMOVE:
 	case DSA_OPCODE_MEMFILL:
 	case DSA_OPCODE_COMPARE:
diff --git a/test/prep.c b/test/prep.c
index 80e977c..c39ff11 100644
--- a/test/prep.c
+++ b/test/prep.c
@@ -41,10 +41,26 @@ void dsa_prep_noop(struct task *tsk)
 	tsk->comp->status = 0;
 }
 
+void dsa_prep_drain(struct task *tsk)
+{
+	info("preparing descriptor for drain\n");
+
+	if (tsk->opcode == DSA_OPCODE_MEMMOVE)
+		tsk->opcode = DSA_OPCODE_DRAIN;
+
+	dsa_prep_desc_common(tsk->desc, tsk->opcode, (uint64_t)(tsk->dst1),
+			     (uint64_t)(tsk->src1), 0, tsk->dflags);
+	tsk->desc->completion_addr = (uint64_t)(tsk->comp);
+	tsk->comp->status = 0;
+}
+
 void dsa_prep_memcpy(struct task *tsk)
 {
 	info("preparing descriptor for memcpy\n");
 
+	if (tsk->opcode == DSA_OPCODE_DRAIN)
+		tsk->opcode = DSA_OPCODE_MEMMOVE;
+
 	dsa_prep_desc_common(tsk->desc, tsk->opcode, (uint64_t)(tsk->dst1),
 			     (uint64_t)(tsk->src1), tsk->xfer_size, tsk->dflags);
 	tsk->desc->completion_addr = (uint64_t)(tsk->comp);
-- 
2.27.0