From nobody Sun Feb 8 23:35:17 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3BB4BEB64D8 for ; Fri, 16 Jun 2023 05:53:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241340AbjFPFxO (ORCPT ); Fri, 16 Jun 2023 01:53:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41392 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232766AbjFPFxF (ORCPT ); Fri, 16 Jun 2023 01:53:05 -0400 Received: from inva020.nxp.com (inva020.nxp.com [92.121.34.13]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2D4B22D54 for ; Thu, 15 Jun 2023 22:53:03 -0700 (PDT) Received: from inva020.nxp.com (localhost [127.0.0.1]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 478071A249D; Fri, 16 Jun 2023 07:43:08 +0200 (CEST) Received: from aprdc01srsp001v.ap-rdc01.nxp.com (aprdc01srsp001v.ap-rdc01.nxp.com [165.114.16.16]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id D99421A068F; Fri, 16 Jun 2023 07:43:07 +0200 (CEST) Received: from localhost.localdomain (mega.ap.freescale.net [10.192.208.232]) by aprdc01srsp001v.ap-rdc01.nxp.com (Postfix) with ESMTP id D56D91820F58; Fri, 16 Jun 2023 13:43:06 +0800 (+08) From: Alison Wang To: gregkh@linuxfoundation.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: leoyang.li@nxp.com, xuelin.shi@nxp.com, xiaofeng.ren@nxp.com, feng.guo@nxp.com, Alison Wang Subject: [PATCH 7/8] ethosu: Add core message about inference cancellation Date: Fri, 16 Jun 2023 13:59:12 +0800 Message-Id: <20230616055913.2360-8-alison.wang@nxp.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20230616055913.2360-1-alison.wang@nxp.com> References: <20230616055913.2360-1-alison.wang@nxp.com> X-Virus-Scanned: ClamAV using ClamSMTP Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" This patch adds core message about sending cancel inference message to Ethos-U subsystem to abort inference execution. Signed-off-by: Davide Grohmann Signed-off-by: Alison Wang Reviewed-by: Peng Fan --- drivers/firmware/ethosu/Makefile | 3 +- .../firmware/ethosu/ethosu_cancel_inference.c | 185 ++++++++++++++++++ .../firmware/ethosu/ethosu_cancel_inference.h | 55 ++++++ .../firmware/ethosu/ethosu_core_interface.h | 37 ++-- drivers/firmware/ethosu/ethosu_inference.c | 16 ++ drivers/firmware/ethosu/ethosu_rpmsg.c | 33 ++++ drivers/firmware/ethosu/ethosu_rpmsg.h | 9 + drivers/firmware/ethosu/uapi/ethosu.h | 29 +++ 8 files changed, 349 insertions(+), 18 deletions(-) create mode 100644 drivers/firmware/ethosu/ethosu_cancel_inference.c create mode 100644 drivers/firmware/ethosu/ethosu_cancel_inference.h diff --git a/drivers/firmware/ethosu/Makefile b/drivers/firmware/ethosu/Mak= efile index a162a3bd32e3..88a352690ddd 100644 --- a/drivers/firmware/ethosu/Makefile +++ b/drivers/firmware/ethosu/Makefile @@ -27,4 +27,5 @@ ethosu-objs :=3D ethosu_driver.o \ ethosu_rpmsg.o \ ethosu_network.o \ ethosu_network_info.o \ - ethosu_capabilities.o + ethosu_capabilities.o \ + ethosu_cancel_inference.o diff --git a/drivers/firmware/ethosu/ethosu_cancel_inference.c b/drivers/fi= rmware/ethosu/ethosu_cancel_inference.c new file mode 100644 index 000000000000..911955889197 --- /dev/null +++ b/drivers/firmware/ethosu/ethosu_cancel_inference.c @@ -0,0 +1,185 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2022 Arm Limited. + */ + +/*************************************************************************= *** + * Includes + *************************************************************************= ***/ + +#include "ethosu_cancel_inference.h" + +#include "ethosu_core_interface.h" +#include "ethosu_device.h" +#include "ethosu_inference.h" + +#include + +/*************************************************************************= *** + * Defines + *************************************************************************= ***/ + +#define CANCEL_INFERENCE_RESP_TIMEOUT_MS 2000 + +/*************************************************************************= *** + * Functions + *************************************************************************= ***/ + +static int ethosu_cancel_inference_send(struct ethosu_cancel_inference *ca= ncellation) +{ + return ethosu_rpmsg_cancel_inference(&cancellation->edev->erp, + &cancellation->msg, + cancellation->inf->msg.id); +} + +static void ethosu_cancel_inference_fail(struct ethosu_rpmsg_msg *msg) +{ + struct ethosu_cancel_inference *cancellation =3D + container_of(msg, typeof(*cancellation), msg); + + if (completion_done(&cancellation->done)) + return; + + cancellation->errno =3D -EFAULT; + cancellation->uapi->status =3D ETHOSU_UAPI_STATUS_ERROR; + complete(&cancellation->done); +} + +static int ethosu_cancel_inference_complete(struct ethosu_rpmsg_msg *msg) +{ + struct ethosu_cancel_inference *cancellation =3D + container_of(msg, typeof(*cancellation), msg); + + if (completion_done(&cancellation->done)) + return 0; + + cancellation->errno =3D 0; + cancellation->uapi->status =3D + cancellation->inf->done && + cancellation->inf->status !=3D ETHOSU_UAPI_STATUS_OK ? + ETHOSU_UAPI_STATUS_OK : + ETHOSU_UAPI_STATUS_ERROR; + complete(&cancellation->done); + + return 0; +} + +int ethosu_cancel_inference_request(struct ethosu_inference *inf, + struct ethosu_uapi_cancel_inference_status *uapi) +{ + struct ethosu_cancel_inference *cancellation; + int ret; + int timeout; + + if (inf->done) { + uapi->status =3D ETHOSU_UAPI_STATUS_ERROR; + + return 0; + } + + cancellation =3D + devm_kzalloc(inf->edev->dev, + sizeof(struct ethosu_cancel_inference), + GFP_KERNEL); + if (!cancellation) + return -ENOMEM; + + /* increase ref count on the inference we are referring to */ + ethosu_inference_get(inf); + /* mark inference ABORTING to avoid resending the inference message */ + inf->status =3D ETHOSU_UAPI_STATUS_ABORTING; + + cancellation->edev =3D inf->edev; + cancellation->inf =3D inf; + cancellation->uapi =3D uapi; + init_completion(&cancellation->done); + cancellation->msg.fail =3D ethosu_cancel_inference_fail; + + /* Never resend messages but always complete, since we have restart the + * whole firmware and marked the inference as aborted + */ + cancellation->msg.resend =3D ethosu_cancel_inference_complete; + + ret =3D ethosu_rpmsg_register(&cancellation->edev->erp, + &cancellation->msg); + if (ret < 0) + goto kfree; + + dev_dbg(cancellation->edev->dev, + "Inference cancellation create. cancel=3D0x%pK, msg.id=3D%d\n", + cancellation, cancellation->msg.id); + + ret =3D ethosu_cancel_inference_send(cancellation); + if (ret !=3D 0) + goto deregister; + + /* Unlock the mutex before going to block on the condition */ + mutex_unlock(&cancellation->edev->mutex); + /* wait for response to arrive back */ + timeout =3D wait_for_completion_timeout(&cancellation->done, + msecs_to_jiffies(CANCEL_INFERENCE_RESP_TIMEOUT_MS)); + + /* take back the mutex before resuming to do anything */ + ret =3D mutex_lock_interruptible(&cancellation->edev->mutex); + if (ret !=3D 0) + goto deregister; + + if (timeout =3D=3D 0) { + dev_warn(inf->edev->dev, + "Msg: Cancel Inference response lost - timeout\n"); + ret =3D -EIO; + goto deregister; + } + + if (cancellation->errno) { + ret =3D cancellation->errno; + goto deregister; + } + +deregister: + ethosu_rpmsg_deregister(&cancellation->edev->erp, + &cancellation->msg); + +kfree: + dev_dbg(cancellation->edev->dev, + "Cancel inference destroy. cancel=3D0x%pK\n", cancellation); + /* decrease the reference on the inference we are referring to */ + ethosu_inference_put(cancellation->inf); + devm_kfree(cancellation->edev->dev, cancellation); + + return ret; +} + +void ethosu_cancel_inference_rsp(struct ethosu_device *edev, + struct ethosu_core_cancel_inference_rsp *rsp) +{ + int id =3D (int)rsp->user_arg; + struct ethosu_rpmsg_msg *msg; + struct ethosu_cancel_inference *cancellation; + + msg =3D ethosu_rpmsg_find(&edev->erp, id); + if (IS_ERR(msg)) { + dev_warn(edev->dev, + "Handle not found in cancel inference list. handle=3D0x%p\n", + rsp); + + return; + } + + cancellation =3D container_of(msg, typeof(*cancellation), msg); + + if (completion_done(&cancellation->done)) + return; + + cancellation->errno =3D 0; + switch (rsp->status) { + case ETHOSU_CORE_STATUS_OK: + cancellation->uapi->status =3D ETHOSU_UAPI_STATUS_OK; + break; + case ETHOSU_CORE_STATUS_ERROR: + cancellation->uapi->status =3D ETHOSU_UAPI_STATUS_ERROR; + break; + } + + complete(&cancellation->done); +} diff --git a/drivers/firmware/ethosu/ethosu_cancel_inference.h b/drivers/fi= rmware/ethosu/ethosu_cancel_inference.h new file mode 100644 index 000000000000..940e0589959a --- /dev/null +++ b/drivers/firmware/ethosu/ethosu_cancel_inference.h @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022 Arm Limited. + */ + +#ifndef ETHOSU_CANCEL_INFERENCE_H +#define ETHOSU_CANCEL_INFERENCE_H + +/*************************************************************************= *** + * Includes + *************************************************************************= ***/ + +#include "ethosu_rpmsg.h" +#include "uapi/ethosu.h" + +#include +#include + +/*************************************************************************= *** + * Types + *************************************************************************= ***/ + +struct ethosu_core_cancel_inference_rsp; +struct ethosu_device; +struct ethosu_uapi_cancel_inference_status; +struct ethosu_inference; + +struct ethosu_cancel_inference { + struct ethosu_device *edev; + struct ethosu_inference *inf; + struct ethosu_uapi_cancel_inference_status *uapi; + struct completion done; + struct ethosu_rpmsg_msg msg; + int errno; +}; + +/*************************************************************************= *** + * Functions + *************************************************************************= ***/ + +/** + * ethosu_cancel_inference_request() - Send cancel inference request + * + * Return: 0 on success, error code otherwise. + */ +int ethosu_cancel_inference_request(struct ethosu_inference *inf, + struct ethosu_uapi_cancel_inference_status *uapi); + +/** + * ethosu_cancel_inference_rsp() - Handle cancel inference response + */ +void ethosu_cancel_inference_rsp(struct ethosu_device *edev, + struct ethosu_core_cancel_inference_rsp *rsp); + +#endif /* ETHOSU_CANCEL_INFERENCE_H */ diff --git a/drivers/firmware/ethosu/ethosu_core_interface.h b/drivers/firm= ware/ethosu/ethosu_core_interface.h index f804de40b004..b1244ce28d39 100644 --- a/drivers/firmware/ethosu/ethosu_core_interface.h +++ b/drivers/firmware/ethosu/ethosu_core_interface.h @@ -1,21 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2020-2022 Arm Limited. - * - * This program is free software and is provided to you under the terms of= the - * GNU General Public License version 2 as published by the Free Software - * Foundation, and any use by you of this program is subject to the terms - * of such GNU licence. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can access it online at - * http://www.gnu.org/licenses/gpl-2.0.html. - * - * SPDX-License-Identifier: GPL-2.0-only + * Copyright (c) 2022 Arm Limited. */ =20 #ifndef ETHOSU_CORE_INTERFACE_H @@ -64,6 +49,8 @@ enum ethosu_core_msg_type { ETHOSU_CORE_MSG_CAPABILITIES_RSP, ETHOSU_CORE_MSG_NETWORK_INFO_REQ, ETHOSU_CORE_MSG_NETWORK_INFO_RSP, + ETHOSU_CORE_MSG_CANCEL_INFERENCE_REQ, + ETHOSU_CORE_MSG_CANCEL_INFERENCE_RSP, ETHOSU_CORE_MSG_POWER_REQ, ETHOSU_CORE_MSG_POWER_RSP, ETHOSU_CORE_MSG_MAX @@ -235,6 +222,22 @@ struct ethosu_core_msg_capabilities_rsp { uint32_t custom_dma; }; =20 +/** + * struct ethosu_core_cancel_inference_req - Message cancel inference requ= est + */ +struct ethosu_core_cancel_inference_req { + u64 user_arg; + u64 inference_handle; +}; + +/** + * struct ethosu_core_cancel_inference_rsp - Message cancel inference resp= onse + */ +struct ethosu_core_cancel_inference_rsp { + u64 user_arg; + u32 status; +}; + enum ethosu_core_power_req_type { ETHOSU_CORE_POWER_REQ_SUSPEND =3D 0, ETHOSU_CORE_POWER_REQ_RESUME diff --git a/drivers/firmware/ethosu/ethosu_inference.c b/drivers/firmware/= ethosu/ethosu_inference.c index 4e5fa214c5d6..8c0c59242650 100644 --- a/drivers/firmware/ethosu/ethosu_inference.c +++ b/drivers/firmware/ethosu/ethosu_inference.c @@ -28,6 +28,7 @@ #include "ethosu_core_interface.h" #include "ethosu_device.h" #include "ethosu_network.h" +#include "ethosu_cancel_inference.h" #include "uapi/ethosu.h" =20 #include @@ -267,6 +268,21 @@ static long ethosu_inference_ioctl(struct file *file, =20 break; } + case ETHOSU_IOCTL_INFERENCE_CANCEL: { + struct ethosu_uapi_cancel_inference_status uapi; + + dev_dbg(inf->edev->dev, + "Inference ioctl: Cancel Inference. Handle=3D%p\n", + inf); + + ret =3D ethosu_cancel_inference_request(inf, &uapi); + if (ret) + break; + + ret =3D copy_to_user(udata, &uapi, sizeof(uapi)) ? -EFAULT : 0; + + break; + } default: { dev_err(inf->edev->dev, "Invalid ioctl. cmd=3D%u, arg=3D%lu\n", cmd, arg); diff --git a/drivers/firmware/ethosu/ethosu_rpmsg.c b/drivers/firmware/etho= su/ethosu_rpmsg.c index 368a519e36b1..351a1046e65e 100644 --- a/drivers/firmware/ethosu/ethosu_rpmsg.c +++ b/drivers/firmware/ethosu/ethosu_rpmsg.c @@ -294,6 +294,39 @@ int ethosu_rpmsg_network_info_request(struct ethosu_rp= msg *erp, return 0; } =20 +int ethosu_rpmsg_cancel_inference(struct ethosu_rpmsg *erp, + struct ethosu_rpmsg_msg *rpmsg, + int inference_handle) +{ + struct ethosu_core_msg msg =3D { + .magic =3D ETHOSU_CORE_MSG_MAGIC, + .type =3D ETHOSU_CORE_MSG_CAPABILITIES_REQ, + .length =3D sizeof(struct ethosu_core_cancel_inference_req) + }; + struct ethosu_core_cancel_inference_req req; + struct rpmsg_device *rpdev =3D erp->rpdev; + u8 data[sizeof(struct ethosu_core_msg) + + sizeof(struct ethosu_core_cancel_inference_req)]; + int ret; + + req.user_arg =3D rpmsg->id; + req.inference_handle =3D inference_handle; + + memcpy(data, &msg, sizeof(struct ethosu_core_msg)); + memcpy(data + sizeof(struct ethosu_core_msg), &req, + sizeof(struct ethosu_core_cancel_inference_req)); + + ret =3D rpmsg_send(rpdev->ept, (void *)&data, + sizeof(struct ethosu_core_msg) + + sizeof(struct ethosu_core_cancel_inference_req)); + if (ret) { + dev_err(&rpdev->dev, "rpmsg_send failed: %d\n", ret); + return ret; + } + + return 0; +} + static int rpmsg_ethosu_cb(struct rpmsg_device *rpdev, void *data, int len, void *priv, u32 src) { diff --git a/drivers/firmware/ethosu/ethosu_rpmsg.h b/drivers/firmware/etho= su/ethosu_rpmsg.h index ba6fb8fd5869..283d401a0dbf 100644 --- a/drivers/firmware/ethosu/ethosu_rpmsg.h +++ b/drivers/firmware/ethosu/ethosu_rpmsg.h @@ -101,6 +101,15 @@ int ethosu_rpmsg_network_info_request(struct ethosu_rp= msg *erp, struct ethosu_buffer *network, uint32_t network_index); =20 +/** + * ethosu_rpmsg_cancel_inference() - Send inference cancellation + * + * Return: 0 on success, else error code. + */ +int ethosu_rpmsg_cancel_inference(struct ethosu_rpmsg *erp, + struct ethosu_rpmsg_msg *rpmsg, + int inference_handle); + int ethosu_rpmsg_init(struct ethosu_rpmsg *erp, ethosu_rpmsg_cb callback, void *user_arg); =20 diff --git a/drivers/firmware/ethosu/uapi/ethosu.h b/drivers/firmware/ethos= u/uapi/ethosu.h index 64a7d9d4885e..3375b1d83ab0 100644 --- a/drivers/firmware/ethosu/uapi/ethosu.h +++ b/drivers/firmware/ethosu/uapi/ethosu.h @@ -60,10 +60,15 @@ namespace EthosU { struct ethosu_uapi_inference_create) #define ETHOSU_IOCTL_INFERENCE_STATUS ETHOSU_IOR(0x31, \ struct ethosu_uapi_result_status) +#define ETHOSU_IOCTL_INFERENCE_CANCEL ETHOSU_IOR(0x32, \ + struct ethosu_uapi_cancel_inference_status) =20 /* Maximum number of IFM/OFM file descriptors per network */ #define ETHOSU_FD_MAX 16 =20 +/* Maximum number of dimensions for input and output */ +#define ETHOSU_DIM_MAX 8 + /* Maximum number of PMUs available */ #define ETHOSU_PMU_EVENT_MAX 4 =20 @@ -133,15 +138,31 @@ struct ethosu_uapi_network_create { * @desc: Network description * @ifm_count: Number of IFM buffers * @ifm_size: IFM buffer sizes + * @ifm_types: IFM data types + * @ifm_offset: IFM data offset in arena + * @ifm_dims: IFM buffer dimensions + * @ifm_shapes: IFM buffer shapes * @ofm_count: Number of OFM buffers * @ofm_size: OFM buffer sizes + * @ofm_offset: OFM data offset in arena + * @ofm_dims: OFM buffer dimensions + * @ofm_shapes: OFM buffer shapes */ struct ethosu_uapi_network_info { char desc[32]; + __u32 is_vela; __u32 ifm_count; __u32 ifm_size[ETHOSU_FD_MAX]; + __u32 ifm_types[ETHOSU_FD_MAX]; + __u32 ifm_offset[ETHOSU_FD_MAX]; + __u32 ifm_dims[ETHOSU_FD_MAX]; + __u32 ifm_shapes[ETHOSU_FD_MAX][ETHOSU_DIM_MAX]; __u32 ofm_count; __u32 ofm_size[ETHOSU_FD_MAX]; + __u32 ofm_types[ETHOSU_FD_MAX]; + __u32 ofm_offset[ETHOSU_FD_MAX]; + __u32 ofm_dims[ETHOSU_FD_MAX]; + __u32 ofm_shapes[ETHOSU_FD_MAX][ETHOSU_DIM_MAX]; }; =20 /** @@ -250,6 +271,14 @@ struct ethosu_uapi_result_status { struct ethosu_uapi_pmu_counts pmu_count; }; =20 +/** + * struct ethosu_uapi_cancel_status - Status of inference cancellation. + * @status OK if inference cancellation was performed, ERROR otherwise. + */ +struct ethosu_uapi_cancel_inference_status { + enum ethosu_uapi_status status; +}; + #ifdef __cplusplus } /* namespace EthosU */ #endif --=20 2.17.1