[v2,27/41] pipeline: add SWX instruction verifier

Message ID 20200907214032.95052-28-cristian.dumitrescu@intel.com (mailing list archive)
State Superseded, archived
Delegated to: Thomas Monjalon
Headers
Series Pipeline alignment with the P4 language |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Cristian Dumitrescu Sept. 7, 2020, 9:40 p.m. UTC
  Instruction verifier. Executes at instruction translation time during
SWX pipeline build, i.e. at initialization instead of run-time.

Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
---
 lib/librte_pipeline/rte_swx_pipeline.c | 51 ++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)
  

Patch

diff --git a/lib/librte_pipeline/rte_swx_pipeline.c b/lib/librte_pipeline/rte_swx_pipeline.c
index ef388fec1..d51fec821 100644
--- a/lib/librte_pipeline/rte_swx_pipeline.c
+++ b/lib/librte_pipeline/rte_swx_pipeline.c
@@ -5653,6 +5653,53 @@  instr_jmp_resolve(struct instruction *instructions,
 	return 0;
 }
 
+static int
+instr_verify(struct rte_swx_pipeline *p __rte_unused,
+	     struct action *a,
+	     struct instruction *instr,
+	     struct instruction_data *data __rte_unused,
+	     uint32_t n_instructions)
+{
+	if (!a) {
+		enum instruction_type type;
+		uint32_t i;
+
+		/* Check that the first instruction is rx. */
+		CHECK(instr[0].type == INSTR_RX, EINVAL);
+
+		/* Check that there is at least one tx instruction. */
+		for (i = 0; i < n_instructions; i++) {
+			type = instr[i].type;
+
+			if (instr[i].type == INSTR_TX)
+				break;
+		}
+		CHECK(i < n_instructions, EINVAL);
+
+		/* Check that the last instruction is either tx or unconditional
+		 * jump.
+		 */
+		type = instr[n_instructions - 1].type;
+		CHECK((type == INSTR_TX) || (type == INSTR_JMP), EINVAL);
+	}
+
+	if (a) {
+		enum instruction_type type;
+		uint32_t i;
+
+		/* Check that there is at least one return or tx instruction. */
+		for (i = 0; i < n_instructions; i++) {
+			type = instr[i].type;
+
+			if ((type == INSTR_RETURN) || (type == INSTR_TX))
+				break;
+		}
+		CHECK(i < n_instructions, EINVAL);
+	}
+
+	return 0;
+}
+
 static int
 instruction_config(struct rte_swx_pipeline *p,
 		   struct action *a,
@@ -5701,6 +5748,10 @@  instruction_config(struct rte_swx_pipeline *p,
 	if (err)
 		goto error;
 
+	err = instr_verify(p, a, instr, data, n_instructions);
+	if (err)
+		goto error;
+
 	err = instr_jmp_resolve(instr, data, n_instructions);
 	if (err)
 		goto error;