From patchwork Wed Jan 11 23:43:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cristian Dumitrescu X-Patchwork-Id: 121863 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id E86064237C; Thu, 12 Jan 2023 00:45:01 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 599BF42D54; Thu, 12 Jan 2023 00:44:15 +0100 (CET) Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by mails.dpdk.org (Postfix) with ESMTP id F3D8E42D49 for ; Thu, 12 Jan 2023 00:44:12 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1673480653; x=1705016653; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=mdmXL2cbD3l8yR8XHArRH55YWsys/+iSzAkvl6Qd8jQ=; b=oAqU+bQeyItRmE/bTH/nomqawz+Kmd5wGtELnEfMmKCzk3PeVCmTrL+x fj6O9cSAwk+JteiYZiys6tfAgSE/kq5sXR7lSFfWCdMG9tx9rdwuxLEj4 lzI/QBC4Sz66cgQFy0uB661VRq9xBdWkNzDKFBVGcDrPE1oejTkdeUXe2 jxwUKy5iK49A2lzeZ4Inxs3wj7Es3ye9qAHPGggUBjyoVcR2sD9pAZeO5 N210fQOOP2oh9HaQE23fu7gWWR2zn3Bd76dSDu5wexxXFyhR4rGH7+gUC 4UOnehp+AeP+v2NHbEelS6Kqh7wyy2pcPrzQw69pRCkrGfIxCK7MeScTT w==; X-IronPort-AV: E=McAfee;i="6500,9779,10586"; a="307088407" X-IronPort-AV: E=Sophos;i="5.96,318,1665471600"; d="scan'208";a="307088407" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Jan 2023 15:44:12 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10586"; a="688129164" X-IronPort-AV: E=Sophos;i="5.96,318,1665471600"; d="scan'208";a="688129164" Received: from silpixa00400573.ir.intel.com (HELO silpixa00400573.ger.corp.intel.com) ([10.237.222.53]) by orsmga008.jf.intel.com with ESMTP; 11 Jan 2023 15:44:11 -0800 From: Cristian Dumitrescu To: dev@dpdk.org Cc: Kamalakannan R Subject: [PATCH V2 09/11] examples/pipeline: support blocks other than pipelines Date: Wed, 11 Jan 2023 23:43:56 +0000 Message-Id: <20230111234358.133395-10-cristian.dumitrescu@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230111234358.133395-1-cristian.dumitrescu@intel.com> References: <20230111205608.87953-1-cristian.dumitrescu@intel.com> <20230111234358.133395-1-cristian.dumitrescu@intel.com> MIME-Version: 1.0 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. */