diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/Kbuild | 5 | ||||
-rw-r--r-- | kernel/Kconfig | 2 | ||||
-rw-r--r-- | kernel/ethosu_buffer.c | 2 | ||||
-rw-r--r-- | kernel/ethosu_buffer.h | 2 | ||||
-rw-r--r-- | kernel/ethosu_core_interface.h | 23 | ||||
-rw-r--r-- | kernel/ethosu_device.c | 31 | ||||
-rw-r--r-- | kernel/ethosu_device.h | 1 | ||||
-rw-r--r-- | kernel/ethosu_inference.c | 2 | ||||
-rw-r--r-- | kernel/ethosu_inference.h | 2 | ||||
-rw-r--r-- | kernel/ethosu_mailbox.c | 21 | ||||
-rw-r--r-- | kernel/ethosu_mailbox.h | 10 | ||||
-rw-r--r-- | kernel/ethosu_network.c | 43 | ||||
-rw-r--r-- | kernel/ethosu_network.h | 2 | ||||
-rw-r--r-- | kernel/ethosu_network_info.c | 179 | ||||
-rw-r--r-- | kernel/ethosu_network_info.h | 90 | ||||
-rw-r--r-- | kernel/uapi/ethosu.h | 18 |
16 files changed, 417 insertions, 16 deletions
diff --git a/kernel/Kbuild b/kernel/Kbuild index 933efee..a6664ac 100644 --- a/kernel/Kbuild +++ b/kernel/Kbuild @@ -1,5 +1,5 @@ # -# (C) COPYRIGHT 2020 ARM Limited. All rights reserved. +# 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 @@ -25,4 +25,5 @@ ethosu-objs := ethosu_driver.o \ ethosu_device.o \ ethosu_inference.o \ ethosu_mailbox.o \ - ethosu_network.o + ethosu_network.o \ + ethosu_network_info.o diff --git a/kernel/Kconfig b/kernel/Kconfig index 695bd37..f9c839f 100644 --- a/kernel/Kconfig +++ b/kernel/Kconfig @@ -1,5 +1,5 @@ # -# (C) COPYRIGHT 2020 ARM Limited. All rights reserved. +# (C) COPYRIGHT 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 diff --git a/kernel/ethosu_buffer.c b/kernel/ethosu_buffer.c index 43a4333..cad73b2 100644 --- a/kernel/ethosu_buffer.c +++ b/kernel/ethosu_buffer.c @@ -1,5 +1,5 @@ /* - * (C) COPYRIGHT 2020-2021 Arm Limited. All rights reserved. + * 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 diff --git a/kernel/ethosu_buffer.h b/kernel/ethosu_buffer.h index 14f26c2..7a21fcb 100644 --- a/kernel/ethosu_buffer.h +++ b/kernel/ethosu_buffer.h @@ -1,5 +1,5 @@ /* - * (C) COPYRIGHT 2020 ARM Limited. All rights reserved. + * 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 diff --git a/kernel/ethosu_core_interface.h b/kernel/ethosu_core_interface.h index cc4fca4..5a6e55d 100644 --- a/kernel/ethosu_core_interface.h +++ b/kernel/ethosu_core_interface.h @@ -57,6 +57,8 @@ enum ethosu_core_msg_type { ETHOSU_CORE_MSG_VERSION_RSP, ETHOSU_CORE_MSG_CAPABILITIES_REQ, ETHOSU_CORE_MSG_CAPABILITIES_RSP, + ETHOSU_CORE_MSG_NETWORK_INFO_REQ, + ETHOSU_CORE_MSG_NETWORK_INFO_RSP, ETHOSU_CORE_MSG_MAX }; @@ -155,6 +157,27 @@ struct ethosu_core_inference_rsp { }; /** + * struct ethosu_core_network_info_req - Network information request + */ +struct ethosu_core_network_info_req { + uint64_t user_arg; + struct ethosu_core_network_buffer network; +}; + +/** + * struct ethosu_core_network_info_rsp - Network information response + */ +struct ethosu_core_network_info_rsp { + uint64_t user_arg; + char desc[32]; + uint32_t ifm_count; + uint32_t ifm_size[ETHOSU_CORE_BUFFER_MAX]; + uint32_t ofm_count; + uint32_t ofm_size[ETHOSU_CORE_BUFFER_MAX]; + uint32_t status; +}; + +/** * struct ethosu_core_msg_version - Message protocol version */ struct ethosu_core_msg_version { diff --git a/kernel/ethosu_device.c b/kernel/ethosu_device.c index 54d70f8..dfdaa58 100644 --- a/kernel/ethosu_device.c +++ b/kernel/ethosu_device.c @@ -28,6 +28,7 @@ #include "ethosu_core_interface.h" #include "ethosu_inference.h" #include "ethosu_network.h" +#include "ethosu_network_info.h" #include "uapi/ethosu.h" #include <linux/delay.h> @@ -49,10 +50,6 @@ #define CAPABILITIES_RESP_TIMEOUT_MS 2000 /**************************************************************************** - * Types - ****************************************************************************/ - -/**************************************************************************** * Functions ****************************************************************************/ @@ -131,6 +128,7 @@ static int ethosu_handle_msg(struct ethosu_device *edev) struct ethosu_core_inference_rsp inf; struct ethosu_core_msg_version version; struct ethosu_core_msg_capabilities_rsp capabilities; + struct ethosu_core_network_info_rsp network_info; } data; /* Read message */ @@ -227,6 +225,23 @@ static int ethosu_handle_msg(struct ethosu_device *edev) ret = ethosu_capability_rsp(edev, &data.capabilities); break; + case ETHOSU_CORE_MSG_NETWORK_INFO_RSP: + if (header.length != sizeof(data.network_info)) { + dev_warn(edev->dev, + "Msg: Network info response of incorrect size. size=%u, expected=%zu\n", header.length, + sizeof(data.network_info)); + ret = -EBADMSG; + break; + } + + dev_info(edev->dev, + "Msg: Network info response. user_arg=0x%llx, status=%u", + data.network_info.user_arg, + data.network_info.status); + + ethosu_network_info_rsp(edev, &data.network_info); + + break; default: /* This should not happen due to version checks */ dev_warn(edev->dev, "Msg: Protocol error\n"); @@ -282,18 +297,21 @@ static int ethosu_send_capabilities_request(struct ethosu_device *edev, * NOTE: if no response is received back, the memory is leaked. */ kref_get(&cap->refcount); + /* Unlock the mutex before going to block on the condition */ mutex_unlock(&edev->mutex); + /* wait for response to arrive back */ timeout = wait_for_completion_timeout(&cap->done, msecs_to_jiffies( CAPABILITIES_RESP_TIMEOUT_MS)); + /* take back the mutex before resuming to do anything */ ret = mutex_lock_interruptible(&edev->mutex); if (0 != ret) goto put_kref; - if (0 == timeout /* timed out*/) { + if (0 == timeout) { dev_warn(edev->dev, "Msg: Capabilities response lost - timeout\n"); ret = -EIO; @@ -320,7 +338,7 @@ static long ethosu_ioctl(struct file *file, if (ret) return ret; - dev_info(edev->dev, "Ioctl. cmd=%u, arg=%lu\n", cmd, arg); + dev_info(edev->dev, "Ioctl. cmd=0x%x, arg=0x%lx\n", cmd, arg); switch (cmd) { case ETHOSU_IOCTL_VERSION_REQ: @@ -416,6 +434,7 @@ int ethosu_dev_init(struct ethosu_device *edev, mutex_init(&edev->mutex); INIT_LIST_HEAD(&edev->capabilities_list); INIT_LIST_HEAD(&edev->inference_list); + INIT_LIST_HEAD(&edev->network_info_list); ret = of_reserved_mem_device_init(edev->dev); if (ret) diff --git a/kernel/ethosu_device.h b/kernel/ethosu_device.h index e1d7034..d096e23 100644 --- a/kernel/ethosu_device.h +++ b/kernel/ethosu_device.h @@ -51,6 +51,7 @@ struct ethosu_device { struct ethosu_mailbox mailbox; struct list_head capabilities_list; struct list_head inference_list; + struct list_head network_info_list; }; /** diff --git a/kernel/ethosu_inference.c b/kernel/ethosu_inference.c index 17beef4..ad31f06 100644 --- a/kernel/ethosu_inference.c +++ b/kernel/ethosu_inference.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022 Arm Limited. + * 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 diff --git a/kernel/ethosu_inference.h b/kernel/ethosu_inference.h index 07370ca..a41043a 100644 --- a/kernel/ethosu_inference.h +++ b/kernel/ethosu_inference.h @@ -1,5 +1,5 @@ /* - * (C) COPYRIGHT 2020 ARM Limited. All rights reserved. + * 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 diff --git a/kernel/ethosu_mailbox.c b/kernel/ethosu_mailbox.c index ef9a07d..e3d31fe 100644 --- a/kernel/ethosu_mailbox.c +++ b/kernel/ethosu_mailbox.c @@ -275,6 +275,27 @@ int ethosu_mailbox_inference(struct ethosu_mailbox *mbox, &inf, sizeof(inf)); } +int ethosu_mailbox_network_info_request(struct ethosu_mailbox *mbox, + void *user_arg, + struct ethosu_buffer *network, + uint32_t network_index) +{ + struct ethosu_core_network_info_req info; + + info.user_arg = (ptrdiff_t)user_arg; + + if (network != NULL) { + info.network.type = ETHOSU_CORE_NETWORK_BUFFER; + ethosu_core_set_size(network, &info.network.buffer); + } else { + info.network.type = ETHOSU_CORE_NETWORK_INDEX; + info.network.index = network_index; + } + + return ethosu_queue_write_msg(mbox, ETHOSU_CORE_MSG_NETWORK_INFO_REQ, + &info, sizeof(info)); +} + static void ethosu_mailbox_rx_work(struct work_struct *work) { struct ethosu_mailbox *mbox = container_of(work, typeof(*mbox), work); diff --git a/kernel/ethosu_mailbox.h b/kernel/ethosu_mailbox.h index af3d986..f004f92 100644 --- a/kernel/ethosu_mailbox.h +++ b/kernel/ethosu_mailbox.h @@ -138,4 +138,14 @@ int ethosu_mailbox_inference(struct ethosu_mailbox *mbox, uint8_t pmu_event_config_count, uint8_t pmu_cycle_counter_enable); +/** + * ethosu_mailbox_network_info_request() - Send network info request + * + * Return: 0 on success, else error code. + */ +int ethosu_mailbox_network_info_request(struct ethosu_mailbox *mbox, + void *user_arg, + struct ethosu_buffer *network, + uint32_t network_index); + #endif /* ETHOSU_MAILBOX_H */ diff --git a/kernel/ethosu_network.c b/kernel/ethosu_network.c index 57ccb62..0654a79 100644 --- a/kernel/ethosu_network.c +++ b/kernel/ethosu_network.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022 Arm Limited. + * 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 @@ -27,6 +27,7 @@ #include "ethosu_buffer.h" #include "ethosu_device.h" #include "ethosu_inference.h" +#include "ethosu_network_info.h" #include "uapi/ethosu.h" #include <linux/anon_inodes.h> @@ -87,6 +88,27 @@ static int ethosu_network_release(struct inode *inode, return 0; } +static int ethosu_network_info_request(struct ethosu_network *net, + struct ethosu_uapi_network_info *uapi) +{ + struct ethosu_network_info *info; + int ret; + + /* Create network info request */ + info = ethosu_network_info_create(net->edev, net, uapi); + if (IS_ERR(info)) + return PTR_ERR(info); + + /* Unlock the device mutex and wait for completion */ + mutex_unlock(&net->edev->mutex); + ret = ethosu_network_info_wait(info, 3000); + mutex_lock(&net->edev->mutex); + + ethosu_network_info_put(info); + + return ret; +} + static long ethosu_network_ioctl(struct file *file, unsigned int cmd, unsigned long arg) @@ -99,9 +121,26 @@ static long ethosu_network_ioctl(struct file *file, if (ret) return ret; - dev_info(net->edev->dev, "Ioctl: cmd=%u, arg=%lu\n", cmd, arg); + dev_info(net->edev->dev, "Ioctl: cmd=0x%x, arg=0x%lx\n", cmd, arg); switch (cmd) { + case ETHOSU_IOCTL_NETWORK_INFO: { + struct ethosu_uapi_network_info uapi; + + if (copy_from_user(&uapi, udata, sizeof(uapi))) + break; + + dev_info(net->edev->dev, + "Ioctl: Network info. handle=%p\n", + net); + + ret = ethosu_network_info_request(net, &uapi); + if (ret) + break; + + ret = copy_to_user(udata, &uapi, sizeof(uapi)) ? -EFAULT : 0; + break; + } case ETHOSU_IOCTL_INFERENCE_CREATE: { struct ethosu_uapi_inference_create uapi; diff --git a/kernel/ethosu_network.h b/kernel/ethosu_network.h index e70b46f..7ddffb5 100644 --- a/kernel/ethosu_network.h +++ b/kernel/ethosu_network.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022 Arm Limited. + * 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 diff --git a/kernel/ethosu_network_info.c b/kernel/ethosu_network_info.c new file mode 100644 index 0000000..2b1f841 --- /dev/null +++ b/kernel/ethosu_network_info.c @@ -0,0 +1,179 @@ +/* + * Copyright (c) 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 + */ + +/**************************************************************************** + * Includes + ****************************************************************************/ + +#include "ethosu_network_info.h" + +#include "ethosu_device.h" +#include "ethosu_network.h" +#include "ethosu_mailbox.h" +#include "uapi/ethosu.h" + +/**************************************************************************** + * Functions + ****************************************************************************/ + +static void ethosu_network_info_destroy(struct kref *kref) +{ + struct ethosu_network_info *info = + container_of(kref, struct ethosu_network_info, kref); + + dev_info(info->edev->dev, "Network info destroy. handle=0x%pK\n", info); + + list_del(&info->list); + + ethosu_network_put(info->net); + + devm_kfree(info->edev->dev, info); +} + +struct ethosu_network_info *ethosu_network_info_create( + struct ethosu_device *edev, + struct ethosu_network *net, + struct ethosu_uapi_network_info *uapi) +{ + struct ethosu_network_info *info; + int ret; + + info = devm_kzalloc(edev->dev, sizeof(*info), GFP_KERNEL); + if (!info) + return ERR_PTR(-ENOMEM); + + info->edev = edev; + info->net = net; + info->uapi = uapi; + kref_init(&info->kref); + init_completion(&info->done); + + /* Insert network info to network info list */ + list_add(&info->list, &edev->network_info_list); + + /* Get reference to network */ + ethosu_network_get(net); + + /* Send network info request to firmware */ + ret = ethosu_mailbox_network_info_request(&info->edev->mailbox, + info, + info->net->buf, + info->net->index); + if (ret) + goto put_info; + + /* Increase reference count for the pending network info response */ + ethosu_network_info_get(info); + + dev_info(edev->dev, "Network info create. handle=%p\n", info); + + return info; + +put_info: + ethosu_network_info_put(info); + + return ERR_PTR(ret); +} + +static int ethosu_network_info_find(struct ethosu_network_info *info, + struct list_head *network_info_list) +{ + struct ethosu_network_info *cur; + + list_for_each_entry(cur, network_info_list, list) { + if (cur == info) + return 0; + } + + return -EINVAL; +} + +void ethosu_network_info_get(struct ethosu_network_info *info) +{ + kref_get(&info->kref); +} + +void ethosu_network_info_put(struct ethosu_network_info *info) +{ + kref_put(&info->kref, ethosu_network_info_destroy); +} + +int ethosu_network_info_wait(struct ethosu_network_info *info, + int timeout_ms) +{ + int timeout; + + timeout = wait_for_completion_timeout(&info->done, + msecs_to_jiffies(timeout_ms)); + + if (!timeout) { + dev_warn(info->edev->dev, + "Network info timed out."); + + return -ETIME; + } + + return info->errno; +} + +void ethosu_network_info_rsp(struct ethosu_device *edev, + struct ethosu_core_network_info_rsp *rsp) +{ + struct ethosu_network_info *info = + (struct ethosu_network_info *)rsp->user_arg; + uint32_t i; + int ret; + + ret = ethosu_network_info_find(info, &edev->network_info_list); + if (0 != ret) { + dev_warn(edev->dev, + "Handle not found in network info list. handle=0x%p\n", + info); + + return; + } + + info->errno = 0; + + if (rsp->status != ETHOSU_CORE_STATUS_OK) { + info->errno = -EBADF; + goto signal_complete; + } + + if (rsp->ifm_count > ETHOSU_FD_MAX || rsp->ofm_count > ETHOSU_FD_MAX) { + info->errno = -ENFILE; + goto signal_complete; + } + + strncpy(info->uapi->desc, rsp->desc, sizeof(info->uapi->desc)); + + info->uapi->ifm_count = rsp->ifm_count; + for (i = 0; i < rsp->ifm_count; i++) + info->uapi->ifm_size[i] = rsp->ifm_size[i]; + + info->uapi->ofm_count = rsp->ofm_count; + for (i = 0; i < rsp->ofm_count; i++) + info->uapi->ofm_size[i] = rsp->ofm_size[i]; + +signal_complete: + complete(&info->done); + + ethosu_network_info_put(info); +} diff --git a/kernel/ethosu_network_info.h b/kernel/ethosu_network_info.h new file mode 100644 index 0000000..2a333a6 --- /dev/null +++ b/kernel/ethosu_network_info.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 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 + */ + +#ifndef ETHOSU_NETWORK_INFO_H +#define ETHOSU_NETWORK_INFO_H + +/**************************************************************************** + * Includes + ****************************************************************************/ + +#include "ethosu_core_interface.h" + +#include <linux/kref.h> +#include <linux/types.h> +#include <linux/completion.h> + +/**************************************************************************** + * Types + ****************************************************************************/ + +struct ethosu_device; +struct ethosu_network; +struct ethosu_uapi_network_info; + +struct ethosu_network_info { + struct ethosu_device *edev; + struct ethosu_network *net; + struct ethosu_uapi_network_info *uapi; + struct kref kref; + struct list_head list; + struct completion done; + int errno; +}; + +/**************************************************************************** + * Functions + ****************************************************************************/ + +/** + * ethosu_network_info_create() - Create network info + * + * This function must be called in the context of a user space process. + * + * Return: Valid pointer on success, else ERR_PTR. + */ +struct ethosu_network_info *ethosu_network_info_create( + struct ethosu_device *edev, + struct ethosu_network *net, + struct ethosu_uapi_network_info *uapi); + +/** + * ethosu_network_info_get() - Get network info + */ +void ethosu_network_info_get(struct ethosu_network_info *info); + +/** + * ethosu_network_info_put() - Put network info + */ +void ethosu_network_info_put(struct ethosu_network_info *info); + +/** + * ethosu_network_info_wait() - Get network info + */ +int ethosu_network_info_wait(struct ethosu_network_info *info, + int timeout); + +/** + * ethosu_network_info_rsp() - Handle network info response. + */ +void ethosu_network_info_rsp(struct ethosu_device *edev, + struct ethosu_core_network_info_rsp *rsp); + +#endif /* ETHOSU_NETWORK_INFO_H */ diff --git a/kernel/uapi/ethosu.h b/kernel/uapi/ethosu.h index 335c769..fda7fc2 100644 --- a/kernel/uapi/ethosu.h +++ b/kernel/uapi/ethosu.h @@ -53,6 +53,8 @@ namespace EthosU { struct ethosu_uapi_buffer) #define ETHOSU_IOCTL_NETWORK_CREATE ETHOSU_IOR(0x20, \ struct ethosu_uapi_network_create) +#define ETHOSU_IOCTL_NETWORK_INFO ETHOSU_IOR(0x21, \ + struct ethosu_uapi_network_info) #define ETHOSU_IOCTL_INFERENCE_CREATE ETHOSU_IOR(0x30, \ struct ethosu_uapi_inference_create) #define ETHOSU_IOCTL_INFERENCE_STATUS ETHOSU_IOR(0x31, \ @@ -122,6 +124,22 @@ struct ethosu_uapi_network_create { }; /** + * struct ethosu_uapi_network_info - Network info + * @desc: Network description + * @ifm_count: Number of IFM buffers + * @ifm_size: IFM buffer sizes + * @ofm_count: Number of OFM buffers + * @ofm_size: OFM buffer sizes + */ +struct ethosu_uapi_network_info { + char desc[32]; + __u32 ifm_count; + __u32 ifm_size[ETHOSU_FD_MAX]; + __u32 ofm_count; + __u32 ofm_size[ETHOSU_FD_MAX]; +}; + +/** * struct ethosu_uapi_pmu_config - Configure performance counters * @events: Array of counters to configure, set to non-zero for * each counter to enable corresponding event. |