aboutsummaryrefslogtreecommitdiff
path: root/kernel/ethosu_inference.c
diff options
context:
space:
mode:
authorDavide Grohmann <davide.grohmann@arm.com>2022-03-23 12:48:45 +0100
committerDavide Grohmann <davide.grohmann@arm.com>2022-05-05 11:13:04 +0200
commit7e8f508765632c42cc44fd8ad704c9d90943ab32 (patch)
tree42dcfb929accf5470d6aa61810da20356c39eb75 /kernel/ethosu_inference.c
parent82d225899bd3d4fd07d70cac80f50c1b288dc4a3 (diff)
downloadethos-u-linux-driver-stack-7e8f508765632c42cc44fd8ad704c9d90943ab32.tar.gz
Add support for inference cancellation
Send cancel inference messages to the ethosu subsystem to abort inference execution there. Also mark inference as aborted in the linux driver stack itself, so pending inference messages are not resent when resetting the firmware. Change-Id: I244c2b119fd7995d14e3859815abf2a00c7f0583
Diffstat (limited to 'kernel/ethosu_inference.c')
-rw-r--r--kernel/ethosu_inference.c51
1 files changed, 42 insertions, 9 deletions
diff --git a/kernel/ethosu_inference.c b/kernel/ethosu_inference.c
index 73a8c06..0599b53 100644
--- a/kernel/ethosu_inference.c
+++ b/kernel/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 <linux/anon_inodes.h>
#include <linux/file.h>
@@ -76,6 +77,12 @@ static const char *status_to_string(const enum ethosu_uapi_status status)
case ETHOSU_UAPI_STATUS_REJECTED: {
return "Rejected";
}
+ case ETHOSU_UAPI_STATUS_ABORTED: {
+ return "Aborted";
+ }
+ case ETHOSU_UAPI_STATUS_ABORTING: {
+ return "Aborting";
+ }
default: {
return "Unknown";
}
@@ -112,15 +119,19 @@ static void ethosu_inference_fail(struct ethosu_mailbox_msg *msg)
container_of(msg, typeof(*inf), msg);
int ret;
+ if (inf->done)
+ return;
+
/* Decrement reference count if inference was pending reponse */
- if (!inf->done) {
- ret = ethosu_inference_put(inf);
- if (ret)
- return;
- }
+ ret = ethosu_inference_put(inf);
+ if (ret)
+ return;
- /* Fail inference and wake up any waiting process */
- inf->status = ETHOSU_UAPI_STATUS_ERROR;
+ /* Set status accordingly to the inference state */
+ inf->status = inf->status == ETHOSU_UAPI_STATUS_ABORTING ?
+ ETHOSU_UAPI_STATUS_ABORTED :
+ ETHOSU_UAPI_STATUS_ERROR;
+ /* Mark it done and wake up the waiting process */
inf->done = true;
wake_up_interruptible(&inf->waitq);
}
@@ -135,6 +146,13 @@ static int ethosu_inference_resend(struct ethosu_mailbox_msg *msg)
if (inf->done)
return 0;
+ /* If marked as ABORTING simply fail it and return */
+ if (inf->status == ETHOSU_UAPI_STATUS_ABORTING) {
+ ethosu_inference_fail(msg);
+
+ return 0;
+ }
+
/* Decrement reference count for pending request */
ret = ethosu_inference_put(inf);
if (ret)
@@ -241,8 +259,22 @@ static long ethosu_inference_ioctl(struct file *file,
break;
}
+ case ETHOSU_IOCTL_INFERENCE_CANCEL: {
+ struct ethosu_uapi_cancel_inference_status uapi;
+
+ dev_info(inf->edev->dev, "Ioctl: Cancel Inference. Handle=%p\n",
+ inf);
+
+ ret = ethosu_cancel_inference_request(inf, &uapi);
+ if (ret)
+ break;
+
+ ret = copy_to_user(udata, &uapi, sizeof(uapi)) ? -EFAULT : 0;
+
+ break;
+ }
default: {
- dev_err(inf->edev->dev, "Invalid ioctl. cmd=%u, arg=%lu",
+ dev_err(inf->edev->dev, "Invalid ioctl. cmd=%u, arg=%lu\n",
cmd, arg);
break;
}
@@ -422,6 +454,8 @@ void ethosu_inference_rsp(struct ethosu_device *edev,
}
} else if (rsp->status == ETHOSU_CORE_STATUS_REJECTED) {
inf->status = ETHOSU_UAPI_STATUS_REJECTED;
+ } else if (rsp->status == ETHOSU_CORE_STATUS_ABORTED) {
+ inf->status = ETHOSU_UAPI_STATUS_ABORTED;
} else {
inf->status = ETHOSU_UAPI_STATUS_ERROR;
}
@@ -450,6 +484,5 @@ void ethosu_inference_rsp(struct ethosu_device *edev,
inf->done = true;
wake_up_interruptible(&inf->waitq);
-
ethosu_inference_put(inf);
}