From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 96EC942492; Thu, 26 Jan 2023 14:36:01 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id AC68C42D97; Thu, 26 Jan 2023 14:35:14 +0100 (CET) Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by mails.dpdk.org (Postfix) with ESMTP id D4C7D42D8C for ; Thu, 26 Jan 2023 14:35:09 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1674740110; x=1706276110; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=mdmXL2cbD3l8yR8XHArRH55YWsys/+iSzAkvl6Qd8jQ=; b=cDKMWYJfcreFvp3mxuvDniC6qZi80LUX7VDJ9cQhRKnHvfG3TE67Gid6 u00buplX8NjbPjkIZAjBRXVWuqAnzpKUqsqb/jBpSQF4xh6CzTPJIeeEB BBaK6yUKQhz7l1jZOtTg3eEWBqj7Y8YVTfuIQBXXreGmEuo3Npb3CEpo6 A3YpEcIRcq6v8Sh1mw7GKC6ZV9NtlidJDgd3eQGUmTO/q/vSj4cvV31KT k6fSx20ctm4wAEFmwocO05fJRM0maWGOPapZzA0PTWcBC1m6+JvxVzCAV uRY+Ef9UmWC8ywCvTyYDb65ZPr9/42N58c0jTZtpJ/4ZdG02J2pmT8qgO A==; X-IronPort-AV: E=McAfee;i="6500,9779,10602"; a="307155152" X-IronPort-AV: E=Sophos;i="5.97,248,1669104000"; d="scan'208";a="307155152" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Jan 2023 05:34:40 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10602"; a="612789724" X-IronPort-AV: E=Sophos;i="5.97,248,1669104000"; d="scan'208";a="612789724" Received: from silpixa00400573.ir.intel.com (HELO silpixa00400573.ger.corp.intel.com) ([10.237.222.53]) by orsmga003.jf.intel.com with ESMTP; 26 Jan 2023 05:34:39 -0800 From: Cristian Dumitrescu To: dev@dpdk.org Cc: Kamalakannan R Subject: [PATCH V5 09/11] examples/pipeline: support blocks other than pipelines Date: Thu, 26 Jan 2023 13:34:25 +0000 Message-Id: <20230126133427.379941-10-cristian.dumitrescu@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230126133427.379941-1-cristian.dumitrescu@intel.com> References: <20230111205608.87953-1-cristian.dumitrescu@intel.com> <20230126133427.379941-1-cristian.dumitrescu@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Previously, the data plane threads only supported the execution of pipelines assigned to them through configuration updates. Now, the data plane threads also support running blocks such as IPsec. Signed-off-by: Cristian Dumitrescu Signed-off-by: Kamalakannan R --- examples/pipeline/thread.c | 143 +++++++++++++++++++++++++++++++++++++ examples/pipeline/thread.h | 9 +++ 2 files changed, 152 insertions(+) diff --git a/examples/pipeline/thread.c b/examples/pipeline/thread.c index 3001bc0858..dc3ea73fbf 100644 --- a/examples/pipeline/thread.c +++ b/examples/pipeline/thread.c @@ -16,6 +16,10 @@ #define THREAD_PIPELINES_MAX 256 #endif +#ifndef THREAD_BLOCKS_MAX +#define THREAD_BLOCKS_MAX 256 +#endif + /* Pipeline instruction quanta: Needs to be big enough to do some meaningful * work, but not too big to avoid starving any other pipelines mapped to the * same thread. For a pipeline that executes 10 instructions per packet, a @@ -38,9 +42,16 @@ * - Read-write by the CP thread; * - Read-only by the DP thread. */ +struct block { + block_run_f block_func; + void *block; +}; + struct thread { struct rte_swx_pipeline *pipelines[THREAD_PIPELINES_MAX]; + struct block *blocks[THREAD_BLOCKS_MAX]; volatile uint64_t n_pipelines; + volatile uint64_t n_blocks; int enabled; } __rte_cache_aligned; @@ -53,14 +64,43 @@ int thread_init(void) { uint32_t thread_id; + int status = 0; RTE_LCORE_FOREACH_WORKER(thread_id) { struct thread *t = &threads[thread_id]; + uint32_t i; t->enabled = 1; + + for (i = 0; i < THREAD_BLOCKS_MAX; i++) { + struct block *b; + + b = calloc(1, sizeof(struct block)); + if (!b) { + status = -ENOMEM; + goto error; + } + + t->blocks[i] = b; + } } return 0; + +error: + RTE_LCORE_FOREACH_WORKER(thread_id) { + struct thread *t = &threads[thread_id]; + uint32_t i; + + t->enabled = 0; + + for (i = 0; i < THREAD_BLOCKS_MAX; i++) { + free(t->blocks[i]); + t->blocks[i] = NULL; + } + } + + return status; } static uint32_t @@ -83,6 +123,26 @@ pipeline_find(struct rte_swx_pipeline *p) return thread_id; } +static uint32_t +block_find(void *b) +{ + uint32_t thread_id; + + for (thread_id = 0; thread_id < RTE_MAX_LCORE; thread_id++) { + struct thread *t = &threads[thread_id]; + uint32_t i; + + if (!t->enabled) + continue; + + for (i = 0; i < t->n_blocks; i++) + if (t->blocks[i]->block == b) + break; + } + + return thread_id; +} + /** * Enable a given pipeline to run on a specific DP thread. * @@ -201,9 +261,85 @@ pipeline_disable(struct rte_swx_pipeline *p) return; } +int +block_enable(block_run_f block_func, void *block, uint32_t thread_id) +{ + struct thread *t; + uint64_t n_blocks; + + /* Check input params */ + if (!block_func || !block || thread_id >= RTE_MAX_LCORE) + return -EINVAL; + + if (block_find(block) < RTE_MAX_LCORE) + return -EEXIST; + + t = &threads[thread_id]; + if (!t->enabled) + return -EINVAL; + + n_blocks = t->n_blocks; + + /* Check there is room for at least one more block. */ + if (n_blocks >= THREAD_BLOCKS_MAX) + return -ENOSPC; + + /* Install the new block. */ + t->blocks[n_blocks]->block_func = block_func; + t->blocks[n_blocks]->block = block; + + rte_wmb(); + t->n_blocks = n_blocks + 1; + + return 0; +} + +void +block_disable(void *block) +{ + struct thread *t; + uint64_t n_blocks; + uint32_t thread_id, i; + + /* Check input params */ + if (!block) + return; + + /* Find the thread that runs this block. */ + thread_id = block_find(block); + if (thread_id == RTE_MAX_LCORE) + return; + + t = &threads[thread_id]; + n_blocks = t->n_blocks; + + for (i = 0; i < n_blocks; i++) { + struct block *b = t->blocks[i]; + + if (block != b->block) + continue; + + if (i < n_blocks - 1) { + struct block *block_last = t->blocks[n_blocks - 1]; + + t->blocks[i] = block_last; + } + + rte_wmb(); + t->n_blocks = n_blocks - 1; + + rte_wmb(); + t->blocks[n_blocks - 1] = b; + + return; + } +} + /** * Data plane (DP) threads. * + + * The t->n_pipelines variable is modified by the CP thread every time changes to the t->pipeline[] * array are operated, so it is therefore very important that the latest value of t->n_pipelines is * read by the DP thread at the beginning of every new dispatch loop iteration, otherwise a stale @@ -229,6 +365,13 @@ thread_main(void *arg __rte_unused) /* Pipelines. */ for (i = 0; i < t->n_pipelines; i++) rte_swx_pipeline_run(t->pipelines[i], PIPELINE_INSTR_QUANTA); + + /* Blocks. */ + for (i = 0; i < t->n_blocks; i++) { + struct block *b = t->blocks[i]; + + b->block_func(b->block); + } } return 0; diff --git a/examples/pipeline/thread.h b/examples/pipeline/thread.h index 338d480abb..f2e643def5 100644 --- a/examples/pipeline/thread.h +++ b/examples/pipeline/thread.h @@ -21,6 +21,15 @@ pipeline_enable(struct rte_swx_pipeline *p, uint32_t thread_id); void pipeline_disable(struct rte_swx_pipeline *p); +typedef void +(*block_run_f)(void *block); + +int +block_enable(block_run_f block_func, void *block, uint32_t thread_id); + +void +block_disable(void *block); + /** * Data plane (DP) threads. */ -- 2.34.1