blob: ee630f577309ea7f62757611aaf770d51bf41d27 [file] [log] [blame]
Davide Grohmann7e8f5082022-03-23 12:48:45 +01001/*
Kristofer Jonssonb42bc0b2023-01-04 17:09:28 +01002 * Copyright 2022-2023 Arm Limited and/or its affiliates
Davide Grohmann7e8f5082022-03-23 12:48:45 +01003 *
4 * This program is free software and is provided to you under the terms of the
5 * GNU General Public License version 2 as published by the Free Software
6 * Foundation, and any use by you of this program is subject to the terms
7 * of such GNU licence.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, you can access it online at
16 * http://www.gnu.org/licenses/gpl-2.0.html.
17 *
18 * SPDX-License-Identifier: GPL-2.0-only
19 */
20
21/****************************************************************************
22 * Includes
23 ****************************************************************************/
24
25#include "ethosu_cancel_inference.h"
26
Kristofer Jonssond779a082023-01-04 17:09:47 +010027#include "ethosu_core_rpmsg.h"
Davide Grohmann7e8f5082022-03-23 12:48:45 +010028#include "ethosu_device.h"
29#include "ethosu_inference.h"
30
31#include <linux/wait.h>
32
33/****************************************************************************
34 * Defines
35 ****************************************************************************/
36
37#define CANCEL_INFERENCE_RESP_TIMEOUT_MS 2000
38
39/****************************************************************************
40 * Functions
41 ****************************************************************************/
42
Davide Grohmann7e8f5082022-03-23 12:48:45 +010043static int ethosu_cancel_inference_send(
Kristofer Jonssonec477042023-01-20 13:38:13 +010044 struct ethosu_cancel_inference *cancellation,
45 struct ethosu_mailbox *mailbox)
Davide Grohmann7e8f5082022-03-23 12:48:45 +010046{
Kristofer Jonssonec477042023-01-20 13:38:13 +010047 return ethosu_mailbox_cancel_inference(mailbox,
Davide Grohmann32660f92022-04-27 16:49:07 +020048 &cancellation->msg,
49 cancellation->inf->msg.id);
Davide Grohmann7e8f5082022-03-23 12:48:45 +010050}
51
52static void ethosu_cancel_inference_fail(struct ethosu_mailbox_msg *msg)
53{
54 struct ethosu_cancel_inference *cancellation =
55 container_of(msg, typeof(*cancellation), msg);
56
57 if (completion_done(&cancellation->done))
58 return;
59
60 cancellation->errno = -EFAULT;
61 cancellation->uapi->status = ETHOSU_UAPI_STATUS_ERROR;
62 complete(&cancellation->done);
63}
64
Kristofer Jonssonec477042023-01-20 13:38:13 +010065int ethosu_cancel_inference_request(struct device *dev,
66 struct ethosu_mailbox *mailbox,
67 struct ethosu_inference *inf,
Davide Grohmann7e8f5082022-03-23 12:48:45 +010068 struct ethosu_uapi_cancel_inference_status *uapi)
69{
70 struct ethosu_cancel_inference *cancellation;
71 int ret;
72 int timeout;
73
74 if (inf->done) {
75 uapi->status = ETHOSU_UAPI_STATUS_ERROR;
76
77 return 0;
78 }
79
80 cancellation =
Kristofer Jonssonec477042023-01-20 13:38:13 +010081 devm_kzalloc(dev,
Davide Grohmann7e8f5082022-03-23 12:48:45 +010082 sizeof(struct ethosu_cancel_inference),
83 GFP_KERNEL);
84 if (!cancellation)
85 return -ENOMEM;
86
87 /* increase ref count on the inference we are refering to */
88 ethosu_inference_get(inf);
89 /* mark inference ABORTING to avoid resending the inference message */
90 inf->status = ETHOSU_CORE_STATUS_ABORTING;
91
Kristofer Jonssonec477042023-01-20 13:38:13 +010092 cancellation->dev = dev;
Davide Grohmann7e8f5082022-03-23 12:48:45 +010093 cancellation->inf = inf;
94 cancellation->uapi = uapi;
Davide Grohmann7e8f5082022-03-23 12:48:45 +010095 init_completion(&cancellation->done);
96 cancellation->msg.fail = ethosu_cancel_inference_fail;
97
Kristofer Jonssonec477042023-01-20 13:38:13 +010098 ret = ethosu_mailbox_register(mailbox,
Davide Grohmann32660f92022-04-27 16:49:07 +020099 &cancellation->msg);
100 if (ret < 0)
101 goto kfree;
102
Kristofer Jonssonec477042023-01-20 13:38:13 +0100103 dev_info(dev,
104 "Inference cancellation create. cancel=0x%pK, msg.id=%ddev",
Kristofer Jonsson53fd03d2022-06-21 16:58:45 +0200105 cancellation, cancellation->msg.id);
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100106
Kristofer Jonssonec477042023-01-20 13:38:13 +0100107 ret = ethosu_cancel_inference_send(cancellation, mailbox);
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100108 if (0 != ret)
Davide Grohmann32660f92022-04-27 16:49:07 +0200109 goto deregister;
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100110
111 /* Unlock the mutex before going to block on the condition */
Kristofer Jonssonec477042023-01-20 13:38:13 +0100112 device_unlock(dev);
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100113 /* wait for response to arrive back */
114 timeout = wait_for_completion_timeout(&cancellation->done,
115 msecs_to_jiffies(
116 CANCEL_INFERENCE_RESP_TIMEOUT_MS));
117 /* take back the mutex before resuming to do anything */
Kristofer Jonssonec477042023-01-20 13:38:13 +0100118 ret = device_lock_interruptible(dev);
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100119 if (0 != ret)
Davide Grohmann32660f92022-04-27 16:49:07 +0200120 goto deregister;
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100121
122 if (0 == timeout /* timed out*/) {
Kristofer Jonssonec477042023-01-20 13:38:13 +0100123 dev_warn(dev,
124 "Msg: Cancel Inference response lost - timeoutdev");
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100125 ret = -EIO;
Davide Grohmann32660f92022-04-27 16:49:07 +0200126 goto deregister;
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100127 }
128
129 if (cancellation->errno) {
130 ret = cancellation->errno;
Davide Grohmann32660f92022-04-27 16:49:07 +0200131 goto deregister;
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100132 }
133
Davide Grohmann32660f92022-04-27 16:49:07 +0200134deregister:
Kristofer Jonssonec477042023-01-20 13:38:13 +0100135 ethosu_mailbox_deregister(mailbox,
Davide Grohmann32660f92022-04-27 16:49:07 +0200136 &cancellation->msg);
137
138kfree:
Kristofer Jonssonec477042023-01-20 13:38:13 +0100139 dev_info(dev,
140 "Cancel inference destroy. cancel=0x%pK", cancellation);
Davide Grohmann32660f92022-04-27 16:49:07 +0200141 /* decrease the reference on the inference we are refering to */
142 ethosu_inference_put(cancellation->inf);
Kristofer Jonssonec477042023-01-20 13:38:13 +0100143 devm_kfree(dev, cancellation);
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100144
145 return ret;
146}
147
Kristofer Jonssonec477042023-01-20 13:38:13 +0100148void ethosu_cancel_inference_rsp(struct ethosu_mailbox *mailbox,
Kristofer Jonssond779a082023-01-04 17:09:47 +0100149 int msg_id,
150 struct ethosu_core_msg_cancel_inference_rsp *rsp)
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100151{
Kristofer Jonssonec477042023-01-20 13:38:13 +0100152 struct device *dev = mailbox->dev;
Davide Grohmann32660f92022-04-27 16:49:07 +0200153 struct ethosu_mailbox_msg *msg;
154 struct ethosu_cancel_inference *cancellation;
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100155
Kristofer Jonssonec477042023-01-20 13:38:13 +0100156 msg = ethosu_mailbox_find(mailbox, msg_id);
Davide Grohmann32660f92022-04-27 16:49:07 +0200157 if (IS_ERR(msg)) {
Kristofer Jonssonec477042023-01-20 13:38:13 +0100158 dev_warn(dev,
159 "Id for cancel inference msg not found. id=%ddev",
Kristofer Jonssond779a082023-01-04 17:09:47 +0100160 msg_id);
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100161
162 return;
163 }
164
Davide Grohmann32660f92022-04-27 16:49:07 +0200165 cancellation = container_of(msg, typeof(*cancellation), msg);
166
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100167 if (completion_done(&cancellation->done))
168 return;
169
170 cancellation->errno = 0;
171 switch (rsp->status) {
172 case ETHOSU_CORE_STATUS_OK:
173 cancellation->uapi->status = ETHOSU_UAPI_STATUS_OK;
174 break;
175 case ETHOSU_CORE_STATUS_ERROR:
176 cancellation->uapi->status = ETHOSU_UAPI_STATUS_ERROR;
177 break;
178 }
179
180 complete(&cancellation->done);
181}