From patchwork Fri Jul 30 13:55:32 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Monjalon X-Patchwork-Id: 96466 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 BEC3BA0A0C; Fri, 30 Jul 2021 15:56:40 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id AD474410E2; Fri, 30 Jul 2021 15:56:40 +0200 (CEST) Received: from out1-smtp.messagingengine.com (out1-smtp.messagingengine.com [66.111.4.25]) by mails.dpdk.org (Postfix) with ESMTP id 1847A40040 for ; Fri, 30 Jul 2021 15:56:39 +0200 (CEST) Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.nyi.internal (Postfix) with ESMTP id C23EF5C00B8; Fri, 30 Jul 2021 09:56:38 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute4.internal (MEProxy); Fri, 30 Jul 2021 09:56:38 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=monjalon.net; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; s=fm1; bh=1CySdw3+Nmv89 hVEzhIEgJtGbnnFp7hd2UN57q2q99A=; b=XbSWvrtPtJ1/gGfGuZB/uiCUYfLUK pXDXw6pR0tNwqbWQ9obRvVHJvz5Ph99A/gEIU4Qo284e8O5zNEzF7k++6f11YRkG Hy9ggxmJbbNra79jRpetkGCt9EDdXXSyPBwgdT0E3OYFsXJdYLdt/dvb2p4zl13S +JR2+cSJ6adZYI5keI9N80F9Zou9rSqWN6cSg4MwC/LBFlOI/ig5arZ6HlDfJTRI GK6SoIap6dJ83jFKbczKGN8PsByGXv4hQpeqq8rmak1GZlNsqcSqEz2w1GcSxcjX ZnACgz47Kwp/jxkVuHzbx+zFEJ9vzq9cpQbw2bwNgfNwwrTkaeMMHmXFg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm3; bh=1CySdw3+Nmv89hVEzhIEgJtGbnnFp7hd2UN57q2q99A=; b=v6xnVgyz v4PPgP/NKRCL5FhKZdw+VXLJn2yevcdSKa46bUiqMA3y4nE6VWYfBBOsXqBUd1Bj m/kGgcj+2QtStOjqUoVgp2pgadbKXGMDDbbfx+tGJ47XBLfmIF84hrguchHqPxXa GCRAeK7lFwquO4bFspzxcF7L4ItsDsuf6RFBMd+fx7kZ6kD9JkGkISZJujJ/mFks QiLk2q+8E976/6ldrPWAD/PieTxVaFF3GesWUQjO40dSYrn/OV42oCzkGApD0GDf VXB4KTuChPOC83wsTq+0tKGO8nuZk/cNGBYHw/UkFmKpE1eEe3Ktcp8OSlRKtxDN FpMSKqAHyLw6/w== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvtddrheehgdeiiecutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpefhvffufffkofgjfhgggfestdekredtredttdenucfhrhhomhepvfhhohhmrghs ucfoohhnjhgrlhhonhcuoehthhhomhgrshesmhhonhhjrghlohhnrdhnvghtqeenucggtf frrghtthgvrhhnpedvhefgiedvjeegtdevheefhfetleefgfeivefgffevfeejgedtgfeu tdehtdegveenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhroh hmpehthhhomhgrshesmhhonhhjrghlohhnrdhnvght X-ME-Proxy: Received: by mail.messagingengine.com (Postfix) with ESMTPA; Fri, 30 Jul 2021 09:56:36 -0400 (EDT) From: Thomas Monjalon To: dev@dpdk.org Cc: Stephen Hemminger , David Marchand , Andrew Rybchenko , Haiyue Wang , Honnappa Nagarahalli , Jerin Jacob , Ferruh Yigit , Elena Agostini , Ray Kinsella Date: Fri, 30 Jul 2021 15:55:32 +0200 Message-Id: <20210730135533.417611-7-thomas@monjalon.net> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210730135533.417611-1-thomas@monjalon.net> References: <20210602203531.2288645-1-thomas@monjalon.net> <20210730135533.417611-1-thomas@monjalon.net> MIME-Version: 1.0 Subject: [dpdk-dev] [RFC PATCH v2 6/7] hcdev: add communication flag 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 Sender: "dev" From: Elena Agostini In heterogeneous computing system, processing is not only in the CPU. Some tasks can be delegated to devices working in parallel. When mixing network activity with task processing there may be the need to put in communication the CPU with the device in order to synchronize operations. The purpose of this flag is to allow the CPU and the device to exchange ACKs. A possible use-case is described below. CPU: - Trigger some task on the device - Prepare some data - Signal to the device the data is ready updating the communication flag Device: - Do some pre-processing - Wait for more data from the CPU polling on the communication flag - Consume the data prepared by the CPU Signed-off-by: Elena Agostini --- lib/hcdev/hcdev.c | 71 ++++++++++++++++++++++++++++ lib/hcdev/rte_hcdev.h | 107 ++++++++++++++++++++++++++++++++++++++++++ lib/hcdev/version.map | 4 ++ 3 files changed, 182 insertions(+) diff --git a/lib/hcdev/hcdev.c b/lib/hcdev/hcdev.c index 621e0b99bd..e391988e73 100644 --- a/lib/hcdev/hcdev.c +++ b/lib/hcdev/hcdev.c @@ -589,3 +589,74 @@ rte_hcdev_free(int16_t dev_id, void *ptr) /* TODO unregister callback */ /* TODO rte_free CPU memory */ } + +int +rte_hcdev_comm_create_flag(uint16_t dev_id, struct rte_hcdev_comm_flag *hcflag, + enum rte_hcdev_comm_flag_type mtype) +{ + size_t flag_size; + + if (hcflag == NULL) { + rte_errno = EINVAL; + return -rte_errno; + } + if (mtype != RTE_HCDEV_COMM_FLAG_CPU) { + rte_errno = EINVAL; + return -rte_errno; + } + + flag_size = sizeof(uint32_t); + + hcflag->ptr = rte_hcdev_malloc(dev_id, flag_size, + RTE_HCDEV_MALLOC_REGISTER_FROM_CPU); + if (hcflag->ptr == NULL) + return -rte_errno; + + hcflag->mtype = mtype; + return 0; +} + +int +rte_hcdev_comm_destroy_flag(uint16_t dev_id, struct rte_hcdev_comm_flag *hcflag) +{ + if (hcflag == NULL) { + rte_errno = EINVAL; + return -rte_errno; + } + + return rte_hcdev_free(dev_id, hcflag->ptr); +} + +int +rte_hcdev_comm_set_flag(struct rte_hcdev_comm_flag *hcflag, uint32_t val) +{ + if (hcflag == NULL) { + rte_errno = EINVAL; + return -rte_errno; + } + if (hcflag->mtype != RTE_HCDEV_COMM_FLAG_CPU) { + rte_errno = EINVAL; + return -rte_errno; + } + + RTE_HCDEV_VOLATILE(*hcflag->ptr) = val; + + return 0; +} + +int +rte_hcdev_comm_get_flag_value(struct rte_hcdev_comm_flag *hcflag, uint32_t *val) +{ + if (hcflag == NULL) { + rte_errno = EINVAL; + return -rte_errno; + } + if (hcflag->mtype != RTE_HCDEV_COMM_FLAG_CPU) { + rte_errno = EINVAL; + return -rte_errno; + } + + *val = RTE_HCDEV_VOLATILE(*hcflag->ptr); + + return 0; +} diff --git a/lib/hcdev/rte_hcdev.h b/lib/hcdev/rte_hcdev.h index 11895d9486..7b58041b3c 100644 --- a/lib/hcdev/rte_hcdev.h +++ b/lib/hcdev/rte_hcdev.h @@ -38,6 +38,9 @@ extern "C" { /** Catch-all callback data. */ #define RTE_HCDEV_CALLBACK_ANY_DATA ((void *)-1) +/** Access variable as volatile. */ +#define RTE_HCDEV_VOLATILE(x) (*(volatile typeof(x)*)&(x)) + /** Store device info. */ struct rte_hcdev_info { /** Unique identifier name. */ @@ -68,6 +71,18 @@ enum rte_hcdev_event { typedef void (rte_hcdev_callback_t)(int16_t dev_id, enum rte_hcdev_event event, void *user_data); +/** Memory where communication flag is allocated. */ +enum rte_hcdev_comm_flag_type { + /** Allocate flag on CPU memory visible from device. */ + RTE_HCDEV_COMM_FLAG_CPU = 0, +}; + +/** Communication flag to coordinate CPU with the device. */ +struct rte_hcdev_comm_flag { + uint32_t *ptr; + enum rte_hcdev_comm_flag_type mtype; +}; + /** * @warning * @b EXPERIMENTAL: this API may change without prior notice. @@ -346,6 +361,98 @@ __rte_alloc_size(2); __rte_experimental int rte_hcdev_free(int16_t dev_id, void *ptr); +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Create a communication flag that can be shared + * between CPU threads and device workload to exchange some status info + * (e.g. work is done, processing can start, etc..). + * + * @param dev_id + * Reference device ID. + * @param hcflag + * Pointer to the memory area of the hcflag structure. + * @param mtype + * Type of memory to allocate the communication flag. + * + * @return + * 0 on success, -rte_errno otherwise: + * - ENODEV if invalid dev_id + * - EINVAL if invalid inputs + * - ENOTSUP if operation not supported by the driver + * - ENOMEM if out of space + * - EPERM if driver error + */ +__rte_experimental +int rte_hcdev_comm_create_flag(uint16_t dev_id, + struct rte_hcdev_comm_flag *hcflag, + enum rte_hcdev_comm_flag_type mtype); + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Deallocate a communication flag. + * + * @param dev_id + * Reference device ID. + * @param hcflag + * Pointer to the memory area of the hcflag structure. + * + * @return + * 0 on success, -rte_errno otherwise: + * - ENODEV if invalid dev_id + * - EINVAL if NULL hcflag + * - ENOTSUP if operation not supported by the driver + * - EPERM if driver error + */ +__rte_experimental +int rte_hcdev_comm_destroy_flag(uint16_t dev_id, + struct rte_hcdev_comm_flag *hcflag); + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Set the value of a communication flag as the input value. + * Flag memory area is treated as volatile. + * The flag must have been allocated with RTE_HCDEV_COMM_FLAG_CPU. + * + * @param hcflag + * Pointer to the memory area of the hcflag structure. + * @param val + * Value to set in the flag. + * + * @return + * 0 on success, -rte_errno otherwise: + * - EINVAL if invalid input params + */ +__rte_experimental +int rte_hcdev_comm_set_flag(struct rte_hcdev_comm_flag *hcflag, + uint32_t val); + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Get the value of the communication flag. + * Flag memory area is treated as volatile. + * The flag must have been allocated with RTE_HCDEV_COMM_FLAG_CPU. + * + * @param hcflag + * Pointer to the memory area of the hcflag structure. + * @param val + * Flag output value. + * + * @return + * 0 on success, -rte_errno otherwise: + * - EINVAL if invalid input params + */ +__rte_experimental +int rte_hcdev_comm_get_flag_value(struct rte_hcdev_comm_flag *hcflag, + uint32_t *val); + #ifdef __cplusplus } #endif diff --git a/lib/hcdev/version.map b/lib/hcdev/version.map index 9195f4f747..da969c7f1f 100644 --- a/lib/hcdev/version.map +++ b/lib/hcdev/version.map @@ -6,6 +6,10 @@ EXPERIMENTAL { rte_hcdev_callback_register; rte_hcdev_callback_unregister; rte_hcdev_close; + rte_hcdev_comm_create_flag; + rte_hcdev_comm_destroy_flag; + rte_hcdev_comm_get_flag_value; + rte_hcdev_comm_set_flag; rte_hcdev_count_avail; rte_hcdev_find_next; rte_hcdev_free;