blob: 5d46434195be443c8aa0684c3806d03ab7213fa2 [file] [log] [blame]
Davide Grohmann7e8f5082022-03-23 12:48:45 +01001/*
Mikael Olsson6d5e2d22024-01-16 11:19:09 +01002 * SPDX-FileCopyrightText: Copyright 2022-2024 Arm Limited and/or its affiliates <open-source-office@arm.com>
Ledion Dajaedd25502023-10-17 09:15:32 +02003 * SPDX-License-Identifier: GPL-2.0-only
Davide Grohmann7e8f5082022-03-23 12:48:45 +01004 *
5 * This program is free software and is provided to you under the terms of the
6 * GNU General Public License version 2 as published by the Free Software
7 * Foundation, and any use by you of this program is subject to the terms
8 * of such GNU licence.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, you can access it online at
17 * http://www.gnu.org/licenses/gpl-2.0.html.
18 *
Davide Grohmann7e8f5082022-03-23 12:48:45 +010019 */
20
21/****************************************************************************
22 * Includes
23 ****************************************************************************/
24
Mikael Olssond4ad9e52024-02-07 11:22:26 +010025#include <rpmsg/ethosu_rpmsg_cancel_inference.h>
Davide Grohmann7e8f5082022-03-23 12:48:45 +010026
Mikael Olssond4ad9e52024-02-07 11:22:26 +010027#include <common/ethosu_device.h>
28#include <rpmsg/ethosu_rpmsg.h>
29#include <rpmsg/ethosu_rpmsg_inference.h>
Davide Grohmann7e8f5082022-03-23 12:48:45 +010030
Kristofer Jonsson074ef902023-01-23 13:05:36 +010031#include <linux/remoteproc.h>
Davide Grohmann7e8f5082022-03-23 12:48:45 +010032#include <linux/wait.h>
33
34/****************************************************************************
35 * Defines
36 ****************************************************************************/
37
38#define CANCEL_INFERENCE_RESP_TIMEOUT_MS 2000
39
40/****************************************************************************
41 * Functions
42 ****************************************************************************/
43
Davide Grohmann7e8f5082022-03-23 12:48:45 +010044static int ethosu_cancel_inference_send(
Kristofer Jonssonec477042023-01-20 13:38:13 +010045 struct ethosu_cancel_inference *cancellation,
46 struct ethosu_mailbox *mailbox)
Davide Grohmann7e8f5082022-03-23 12:48:45 +010047{
Kristofer Jonssonec477042023-01-20 13:38:13 +010048 return ethosu_mailbox_cancel_inference(mailbox,
Davide Grohmann32660f92022-04-27 16:49:07 +020049 &cancellation->msg,
50 cancellation->inf->msg.id);
Davide Grohmann7e8f5082022-03-23 12:48:45 +010051}
52
53static void ethosu_cancel_inference_fail(struct ethosu_mailbox_msg *msg)
54{
55 struct ethosu_cancel_inference *cancellation =
56 container_of(msg, typeof(*cancellation), msg);
57
58 if (completion_done(&cancellation->done))
59 return;
60
61 cancellation->errno = -EFAULT;
62 cancellation->uapi->status = ETHOSU_UAPI_STATUS_ERROR;
63 complete(&cancellation->done);
64}
65
Kristofer Jonssonec477042023-01-20 13:38:13 +010066int ethosu_cancel_inference_request(struct device *dev,
67 struct ethosu_mailbox *mailbox,
68 struct ethosu_inference *inf,
Davide Grohmann7e8f5082022-03-23 12:48:45 +010069 struct ethosu_uapi_cancel_inference_status *uapi)
70{
71 struct ethosu_cancel_inference *cancellation;
72 int ret;
73 int timeout;
74
75 if (inf->done) {
76 uapi->status = ETHOSU_UAPI_STATUS_ERROR;
77
78 return 0;
79 }
80
81 cancellation =
Kristofer Jonssonec477042023-01-20 13:38:13 +010082 devm_kzalloc(dev,
Davide Grohmann7e8f5082022-03-23 12:48:45 +010083 sizeof(struct ethosu_cancel_inference),
84 GFP_KERNEL);
85 if (!cancellation)
86 return -ENOMEM;
87
88 /* increase ref count on the inference we are refering to */
89 ethosu_inference_get(inf);
90 /* mark inference ABORTING to avoid resending the inference message */
Mikael Olsson6d5e2d22024-01-16 11:19:09 +010091 inf->status = ETHOSU_UAPI_STATUS_ABORTING;
Davide Grohmann7e8f5082022-03-23 12:48:45 +010092
Kristofer Jonssonec477042023-01-20 13:38:13 +010093 cancellation->dev = dev;
Davide Grohmann7e8f5082022-03-23 12:48:45 +010094 cancellation->inf = inf;
95 cancellation->uapi = uapi;
Davide Grohmann7e8f5082022-03-23 12:48:45 +010096 init_completion(&cancellation->done);
97 cancellation->msg.fail = ethosu_cancel_inference_fail;
98
Kristofer Jonssonec477042023-01-20 13:38:13 +010099 ret = ethosu_mailbox_register(mailbox,
Davide Grohmann32660f92022-04-27 16:49:07 +0200100 &cancellation->msg);
101 if (ret < 0)
102 goto kfree;
103
Ledion Dajaedd25502023-10-17 09:15:32 +0200104 dev_dbg(dev,
105 "Inference cancellation create. cancel=0x%pK, msg.id=%ddev",
106 cancellation, cancellation->msg.id);
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100107
Kristofer Jonssonec477042023-01-20 13:38:13 +0100108 ret = ethosu_cancel_inference_send(cancellation, mailbox);
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100109 if (0 != ret)
Davide Grohmann32660f92022-04-27 16:49:07 +0200110 goto deregister;
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100111
112 /* Unlock the mutex before going to block on the condition */
Kristofer Jonssonec477042023-01-20 13:38:13 +0100113 device_unlock(dev);
Kristofer Jonsson074ef902023-01-23 13:05:36 +0100114
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100115 /* wait for response to arrive back */
116 timeout = wait_for_completion_timeout(&cancellation->done,
117 msecs_to_jiffies(
118 CANCEL_INFERENCE_RESP_TIMEOUT_MS));
119 /* take back the mutex before resuming to do anything */
Kristofer Jonssonec477042023-01-20 13:38:13 +0100120 ret = device_lock_interruptible(dev);
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100121 if (0 != ret)
Davide Grohmann32660f92022-04-27 16:49:07 +0200122 goto deregister;
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100123
124 if (0 == timeout /* timed out*/) {
Kristofer Jonssonec477042023-01-20 13:38:13 +0100125 dev_warn(dev,
126 "Msg: Cancel Inference response lost - timeoutdev");
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100127 ret = -EIO;
Kristofer Jonsson074ef902023-01-23 13:05:36 +0100128
129 rproc_report_crash(rproc_get_by_child(dev), RPROC_FATAL_ERROR);
Davide Grohmann32660f92022-04-27 16:49:07 +0200130 goto deregister;
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100131 }
132
133 if (cancellation->errno) {
134 ret = cancellation->errno;
Kristofer Jonsson074ef902023-01-23 13:05:36 +0100135 rproc_report_crash(rproc_get_by_child(dev), RPROC_FATAL_ERROR);
Davide Grohmann32660f92022-04-27 16:49:07 +0200136 goto deregister;
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100137 }
138
Mikael Olsson6d5e2d22024-01-16 11:19:09 +0100139 if (inf->status != ETHOSU_UAPI_STATUS_ABORTED)
140 inf->status = ETHOSU_UAPI_STATUS_ABORTED;
141
Davide Grohmann32660f92022-04-27 16:49:07 +0200142deregister:
Kristofer Jonssonec477042023-01-20 13:38:13 +0100143 ethosu_mailbox_deregister(mailbox,
Davide Grohmann32660f92022-04-27 16:49:07 +0200144 &cancellation->msg);
145
146kfree:
Ledion Dajaedd25502023-10-17 09:15:32 +0200147 dev_dbg(dev,
148 "Cancel inference destroy. cancel=0x%pK", cancellation);
Kristofer Jonsson074ef902023-01-23 13:05:36 +0100149
Davide Grohmann32660f92022-04-27 16:49:07 +0200150 /* decrease the reference on the inference we are refering to */
151 ethosu_inference_put(cancellation->inf);
Kristofer Jonssonec477042023-01-20 13:38:13 +0100152 devm_kfree(dev, cancellation);
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100153
154 return ret;
155}
156
Kristofer Jonssonec477042023-01-20 13:38:13 +0100157void ethosu_cancel_inference_rsp(struct ethosu_mailbox *mailbox,
Kristofer Jonssond779a082023-01-04 17:09:47 +0100158 int msg_id,
159 struct ethosu_core_msg_cancel_inference_rsp *rsp)
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100160{
Kristofer Jonssonec477042023-01-20 13:38:13 +0100161 struct device *dev = mailbox->dev;
Davide Grohmann32660f92022-04-27 16:49:07 +0200162 struct ethosu_mailbox_msg *msg;
163 struct ethosu_cancel_inference *cancellation;
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100164
Mikael Olsson09965b02023-06-13 12:17:04 +0200165 msg = ethosu_mailbox_find(mailbox, msg_id,
166 ETHOSU_CORE_MSG_CANCEL_INFERENCE_REQ);
Davide Grohmann32660f92022-04-27 16:49:07 +0200167 if (IS_ERR(msg)) {
Kristofer Jonssonec477042023-01-20 13:38:13 +0100168 dev_warn(dev,
Mikael Olsson09965b02023-06-13 12:17:04 +0200169 "Id for cancel inference msg not found. Id=0x%x: %ld",
170 msg_id, PTR_ERR(msg));
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100171
172 return;
173 }
174
Davide Grohmann32660f92022-04-27 16:49:07 +0200175 cancellation = container_of(msg, typeof(*cancellation), msg);
176
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100177 if (completion_done(&cancellation->done))
178 return;
179
180 cancellation->errno = 0;
181 switch (rsp->status) {
182 case ETHOSU_CORE_STATUS_OK:
183 cancellation->uapi->status = ETHOSU_UAPI_STATUS_OK;
184 break;
185 case ETHOSU_CORE_STATUS_ERROR:
186 cancellation->uapi->status = ETHOSU_UAPI_STATUS_ERROR;
187 break;
188 }
189
190 complete(&cancellation->done);
191}