From patchwork Thu Jan 12 18:53:33 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cristian Dumitrescu X-Patchwork-Id: 121964 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 BD795423B9; Thu, 12 Jan 2023 19:54:45 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 4575642DF3; Thu, 12 Jan 2023 19:53:51 +0100 (CET) Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by mails.dpdk.org (Postfix) with ESMTP id 7AB2742DDD for ; Thu, 12 Jan 2023 19:53:48 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1673549628; x=1705085628; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=mdmXL2cbD3l8yR8XHArRH55YWsys/+iSzAkvl6Qd8jQ=; b=iijLPif2lp+v0Ae7pWe2ht76Kd0L0KFcehXZJ0KGuYtEKwW3EdJDYl/8 XPWsM9tdeAl6oo+TQ71EaKMLFvjPVGkI//qSNrDsKsnX2X1yponejdIKK TATu2t7tEzv0QrJGgvKNh3QrMIl2wXmN1WflzdgyCcIOWai3Fk1++63SL LFUE9wm9MRdBpj93FA2fhhgEole8rAMWnxTHz+Ghxgw+9vt2lF71oGj0h fVvklP6o8ezeFHdA9lzvgBNzP+Diaq4JJQBsBiEj3zBo8Hp3n6sYHyMl1 NfHhE80aspwpgVN3OHykWjYU6SWVFRdDp1mxi5nQ123hCYu+pZzn1Bf44 Q==; X-IronPort-AV: E=McAfee;i="6500,9779,10588"; a="303492924" X-IronPort-AV: E=Sophos;i="5.97,211,1669104000"; d="scan'208";a="303492924" Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Jan 2023 10:53:47 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10588"; a="746648054" X-IronPort-AV: E=Sophos;i="5.97,211,1669104000"; d="scan'208";a="746648054" Received: from silpixa00400573.ir.intel.com (HELO silpixa00400573.ger.corp.intel.com) ([10.237.222.53]) by FMSMGA003.fm.intel.com with ESMTP; 12 Jan 2023 10:53:46 -0800 From: Cristian Dumitrescu To: dev@dpdk.org Cc: Kamalakannan R Subject: [PATCH V4 09/11] examples/pipeline: support blocks other than pipelines Date: Thu, 12 Jan 2023 18:53:33 +0000 Message-Id: <20230112185335.247116-10-cristian.dumitrescu@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230112185335.247116-1-cristian.dumitrescu@intel.com> References: <20230111205608.87953-1-cristian.dumitrescu@intel.com> <20230112185335.247116-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. */