[Accel-config] [PATCH v1 9/9] accel-config/test: add cache flush operation support
Tony Zhu <tony.zhu at intel.com> Fri, 11 Feb 2022 21:16:33 +0800
| Newsgroups | dev.linux.lists.accel-config |
|---|---|
| Message-ID | <[email protected]> |
The Cache Flush operation, 0x20, flushes the processor caches at
the Destination Address.
Signed-off-by: Tony Zhu <tony.zhu(a)intel.com>
---
test/dsa.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++
test/dsa.h | 5 +++++
test/dsa_test.c | 7 +++++++
test/prep.c | 30 ++++++++++++++++++++++++++
4 files changed, 98 insertions(+)
diff --git a/test/dsa.c b/test/dsa.c
index ecda9a3..6cf7f80 100644
--- a/test/dsa.c
+++ b/test/dsa.c
@@ -964,6 +964,62 @@ int dsa_drain_multi_task_nodes(struct dsa_context *ctx)
return ret;
}
+int dsa_wait_cflush(struct dsa_context *ctx, struct task *tsk)
+{
+ struct dsa_hw_desc *desc = tsk->desc;
+ struct dsa_completion_record *comp = tsk->comp;
+
+ int rc;
+
+again:
+ rc = dsa_wait_on_desc_timeout(comp, ms_timeout);
+ if (rc < 0) {
+ err("cflush desc timeout\n");
+ return DSA_STATUS_TIMEOUT;
+ }
+
+ /* re-submit if PAGE_FAULT reported by HW && BOF is off */
+ if (stat_val(comp->status) == DSA_COMP_PAGE_FAULT_NOBOF &&
+ !(desc->flags & IDXD_OP_FLAG_BOF)) {
+ dsa_reprep_cflush(ctx, tsk);
+ goto again;
+ }
+
+ return DSA_STATUS_OK;
+}
+
+int dsa_cflush_multi_task_nodes(struct dsa_context *ctx)
+{
+ struct task_node *tsk_node = ctx->multi_task_node;
+ int ret = DSA_STATUS_OK;
+
+ while (tsk_node) {
+ tsk_node->tsk->dflags = IDXD_OP_FLAG_CRAV | IDXD_OP_FLAG_RCR;
+ if ((tsk_node->tsk->test_flags & TEST_FLAGS_BOF) && ctx->bof)
+ tsk_node->tsk->dflags |= IDXD_OP_FLAG_BOF;
+
+ dsa_prep_cflush(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 cflush jobs\n");
+
+ while (tsk_node) {
+ ret = dsa_wait_cflush(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_batch(struct batch_task *btsk)
{
int rc;
diff --git a/test/dsa.h b/test/dsa.h
index 6cceb62..e77f818 100644
--- a/test/dsa.h
+++ b/test/dsa.h
@@ -268,6 +268,9 @@ 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_cflush_multi_task_nodes(struct dsa_context *ctx);
+int dsa_wait_cflush(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);
@@ -303,6 +306,8 @@ int dsa_wait_dif(struct dsa_context *ctx, struct task *tsk);
void dsa_prep_noop(struct task *tsk);
void dsa_prep_drain(struct task *tsk);
+void dsa_prep_cflush(struct task *tsk);
+void dsa_reprep_cflush(struct dsa_context *ctx, 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 9b56160..0de762c 100644
--- a/test/dsa_test.c
+++ b/test/dsa_test.c
@@ -399,6 +399,12 @@ static int test_memory(struct dsa_context *ctx, size_t buf_size,
if (rc != DSA_STATUS_OK)
return rc;
break;
+ case DSA_OPCODE_CFLUSH:
+ rc = dsa_cflush_multi_task_nodes(ctx);
+ if (rc != DSA_STATUS_OK)
+ return rc;
+ break;
+
default:
err("Unsupported op %#x\n", opcode);
return -EINVAL;
@@ -726,6 +732,7 @@ int main(int argc, char *argv[])
case DSA_OPCODE_COMPARE:
case DSA_OPCODE_COMPVAL:
case DSA_OPCODE_DUALCAST:
+ case DSA_OPCODE_CFLUSH:
rc = test_memory(dsa, buf_size, tflags, opcode, num_desc);
if (rc != DSA_STATUS_OK)
goto error;
diff --git a/test/prep.c b/test/prep.c
index 48e0a7e..c427109 100644
--- a/test/prep.c
+++ b/test/prep.c
@@ -53,6 +53,36 @@ void dsa_prep_drain(struct task *tsk)
tsk->comp->status = 0;
}
+void dsa_prep_cflush(struct task *tsk)
+{
+ info("preparing descriptor for cflush\n");
+
+ 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);
+ tsk->comp->status = 0;
+}
+
+void dsa_reprep_cflush(struct dsa_context *ctx, struct task *tsk)
+{
+ struct dsa_completion_record *compl = tsk->comp;
+ struct dsa_hw_desc *hw = tsk->desc;
+
+ info("PF addr %#lx dir %d bc %#x\n",
+ compl->fault_addr, compl->result,
+ compl->bytes_completed);
+
+ hw->xfer_size -= compl->bytes_completed;
+
+ hw->src_addr += compl->bytes_completed;
+
+ resolve_page_fault(compl->fault_addr, compl->status);
+
+ compl->status = 0;
+
+ dsa_desc_submit(ctx, hw);
+}
+
void dsa_prep_memcpy(struct task *tsk)
{
info("preparing descriptor for memcpy\n");
--
2.27.0