blob: c1d31b34694cd0b15283b7be649ba8a6287cd73e [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
27#include "ethosu_core_interface.h"
28#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(
44 struct ethosu_cancel_inference *cancellation)
45{
46 return ethosu_mailbox_cancel_inference(&cancellation->edev->mailbox,
Davide Grohmann32660f92022-04-27 16:49:07 +020047 &cancellation->msg,
48 cancellation->inf->msg.id);
Davide Grohmann7e8f5082022-03-23 12:48:45 +010049}
50
51static void ethosu_cancel_inference_fail(struct ethosu_mailbox_msg *msg)
52{
53 struct ethosu_cancel_inference *cancellation =
54 container_of(msg, typeof(*cancellation), msg);
55
56 if (completion_done(&cancellation->done))
57 return;
58
59 cancellation->errno = -EFAULT;
60 cancellation->uapi->status = ETHOSU_UAPI_STATUS_ERROR;
61 complete(&cancellation->done);
62}
63
Davide Grohmann7e8f5082022-03-23 12:48:45 +010064int ethosu_cancel_inference_request(struct ethosu_inference *inf,
65 struct ethosu_uapi_cancel_inference_status *uapi)
66{
67 struct ethosu_cancel_inference *cancellation;
68 int ret;
69 int timeout;
70
71 if (inf->done) {
72 uapi->status = ETHOSU_UAPI_STATUS_ERROR;
73
74 return 0;
75 }
76
77 cancellation =
78 devm_kzalloc(inf->edev->dev,
79 sizeof(struct ethosu_cancel_inference),
80 GFP_KERNEL);
81 if (!cancellation)
82 return -ENOMEM;
83
84 /* increase ref count on the inference we are refering to */
85 ethosu_inference_get(inf);
86 /* mark inference ABORTING to avoid resending the inference message */
87 inf->status = ETHOSU_CORE_STATUS_ABORTING;
88
89 cancellation->edev = inf->edev;
90 cancellation->inf = inf;
91 cancellation->uapi = uapi;
Davide Grohmann7e8f5082022-03-23 12:48:45 +010092 init_completion(&cancellation->done);
93 cancellation->msg.fail = ethosu_cancel_inference_fail;
94
Davide Grohmann32660f92022-04-27 16:49:07 +020095 ret = ethosu_mailbox_register(&cancellation->edev->mailbox,
96 &cancellation->msg);
97 if (ret < 0)
98 goto kfree;
99
100 dev_info(cancellation->edev->dev,
Kristofer Jonsson53fd03d2022-06-21 16:58:45 +0200101 "Inference cancellation create. cancel=0x%pK, msg.id=%d\n",
102 cancellation, cancellation->msg.id);
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100103
104 ret = ethosu_cancel_inference_send(cancellation);
105 if (0 != ret)
Davide Grohmann32660f92022-04-27 16:49:07 +0200106 goto deregister;
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100107
108 /* Unlock the mutex before going to block on the condition */
109 mutex_unlock(&cancellation->edev->mutex);
110 /* wait for response to arrive back */
111 timeout = wait_for_completion_timeout(&cancellation->done,
112 msecs_to_jiffies(
113 CANCEL_INFERENCE_RESP_TIMEOUT_MS));
114 /* take back the mutex before resuming to do anything */
115 ret = mutex_lock_interruptible(&cancellation->edev->mutex);
116 if (0 != ret)
Davide Grohmann32660f92022-04-27 16:49:07 +0200117 goto deregister;
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100118
119 if (0 == timeout /* timed out*/) {
120 dev_warn(inf->edev->dev,
121 "Msg: Cancel Inference response lost - timeout\n");
122 ret = -EIO;
Davide Grohmann32660f92022-04-27 16:49:07 +0200123 goto deregister;
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100124 }
125
126 if (cancellation->errno) {
127 ret = cancellation->errno;
Davide Grohmann32660f92022-04-27 16:49:07 +0200128 goto deregister;
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100129 }
130
Davide Grohmann32660f92022-04-27 16:49:07 +0200131deregister:
132 ethosu_mailbox_deregister(&cancellation->edev->mailbox,
133 &cancellation->msg);
134
135kfree:
136 dev_info(cancellation->edev->dev,
Kristofer Jonsson53fd03d2022-06-21 16:58:45 +0200137 "Cancel inference destroy. cancel=0x%pK\n", cancellation);
Davide Grohmann32660f92022-04-27 16:49:07 +0200138 /* decrease the reference on the inference we are refering to */
139 ethosu_inference_put(cancellation->inf);
140 devm_kfree(cancellation->edev->dev, cancellation);
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100141
142 return ret;
143}
144
145void ethosu_cancel_inference_rsp(struct ethosu_device *edev,
146 struct ethosu_core_cancel_inference_rsp *rsp)
147{
Davide Grohmann32660f92022-04-27 16:49:07 +0200148 int id = (int)rsp->user_arg;
149 struct ethosu_mailbox_msg *msg;
150 struct ethosu_cancel_inference *cancellation;
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100151
Davide Grohmann32660f92022-04-27 16:49:07 +0200152 msg = ethosu_mailbox_find(&edev->mailbox, id);
153 if (IS_ERR(msg)) {
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100154 dev_warn(edev->dev,
155 "Handle not found in cancel inference list. handle=0x%p\n",
156 rsp);
157
158 return;
159 }
160
Davide Grohmann32660f92022-04-27 16:49:07 +0200161 cancellation = container_of(msg, typeof(*cancellation), msg);
162
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100163 if (completion_done(&cancellation->done))
164 return;
165
166 cancellation->errno = 0;
167 switch (rsp->status) {
168 case ETHOSU_CORE_STATUS_OK:
169 cancellation->uapi->status = ETHOSU_UAPI_STATUS_OK;
170 break;
171 case ETHOSU_CORE_STATUS_ERROR:
172 cancellation->uapi->status = ETHOSU_UAPI_STATUS_ERROR;
173 break;
174 }
175
176 complete(&cancellation->done);
177}