From c1eb9c525857b56de20f43f872276768fcdb87ee Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Tue, 12 Sep 2023 10:35:14 +0800 Subject: [PATCH 01/89] ub: init uburma cmd function that support handle ioctl from user mode. driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Init uburma cmd function, which is to handle ioctl cmd from user mode. Add ioctl support for uburma file operation. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/uburma/Makefile | 1 + drivers/ub/urma/uburma/uburma_cmd.c | 106 +++++++++++++++++++++++ drivers/ub/urma/uburma/uburma_cmd.h | 91 +++++++++++++++++++ drivers/ub/urma/uburma/uburma_file_ops.h | 30 +++++++ drivers/ub/urma/uburma/uburma_main.c | 5 ++ drivers/ub/urma/uburma/uburma_types.h | 29 +++++++ 6 files changed, 262 insertions(+) create mode 100644 drivers/ub/urma/uburma/uburma_cmd.c create mode 100644 drivers/ub/urma/uburma/uburma_cmd.h create mode 100644 drivers/ub/urma/uburma/uburma_file_ops.h diff --git a/drivers/ub/urma/uburma/Makefile b/drivers/ub/urma/uburma/Makefile index 72038c480241..f59835ca2683 100644 --- a/drivers/ub/urma/uburma/Makefile +++ b/drivers/ub/urma/uburma/Makefile @@ -4,6 +4,7 @@ # uburma-objs := uburma_main.o \ + uburma_cmd.o \ uburma_cdev_file.o obj-$(CONFIG_UB) += uburma.o diff --git a/drivers/ub/urma/uburma/uburma_cmd.c b/drivers/ub/urma/uburma/uburma_cmd.c new file mode 100644 index 000000000000..6958bf63db25 --- /dev/null +++ b/drivers/ub/urma/uburma/uburma_cmd.c @@ -0,0 +1,106 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + * + * Description: uburma cmd implementation + * Author: Qian Guoxin + * Create: 2021-08-04 + * Note: + * History: 2021-08-04: Create file + * History: 2022-07-25: Yan Fangfang Change the prefix uburma_ioctl_ to uburma_cmd_ + */ + +#include +#include +#include +#include +#include "uburma_log.h" +#include "uburma_types.h" +#include "uburma_cmd.h" + +#define UBURMA_INVALID_TPN UINT_MAX + +void uburma_cmd_inc(struct uburma_device *ubu_dev) +{ + atomic_inc(&ubu_dev->cmdcnt); +} + +void uburma_cmd_dec(struct uburma_device *ubu_dev) +{ + if (atomic_dec_and_test(&ubu_dev->cmdcnt)) + complete(&ubu_dev->cmddone); +} + +void uburma_cmd_flush(struct uburma_device *ubu_dev) +{ + uburma_cmd_dec(ubu_dev); + wait_for_completion(&ubu_dev->cmddone); +} + +typedef int (*uburma_cmd_handler)(struct ubcore_device *ubc_dev, struct uburma_file *file, + struct uburma_cmd_hdr *hdr); + +static uburma_cmd_handler g_uburma_cmd_handlers[] = { + [0] = NULL, +}; + +static int uburma_cmd_parse(struct ubcore_device *ubc_dev, struct uburma_file *file, + struct uburma_cmd_hdr *hdr) +{ + if (hdr->command < UBURMA_CMD_CREATE_CTX || hdr->command > UBURMA_CMD_USER_CTL || + g_uburma_cmd_handlers[hdr->command] == NULL) { + uburma_log_err("bad uburma command: %d.\n", (int)hdr->command); + return -EINVAL; + } + return g_uburma_cmd_handlers[hdr->command](ubc_dev, file, hdr); +} + +long uburma_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + struct uburma_cmd_hdr *user_hdr = (struct uburma_cmd_hdr *)arg; + struct uburma_file *file = filp->private_data; + struct uburma_device *ubu_dev = file->ubu_dev; + struct ubcore_device *ubc_dev; + struct uburma_cmd_hdr hdr; + int srcu_idx; + long ret; + + uburma_cmd_inc(ubu_dev); + srcu_idx = srcu_read_lock(&ubu_dev->ubc_dev_srcu); + ubc_dev = srcu_dereference(ubu_dev->ubc_dev, &ubu_dev->ubc_dev_srcu); + if (!ubc_dev) { + uburma_log_err("can not find ubcore device.\n"); + ret = -EIO; + goto srcu_unlock; + } + + if (cmd == UBURMA_CMD) { + ret = (long)copy_from_user(&hdr, user_hdr, sizeof(struct uburma_cmd_hdr)); + if ((ret != 0) || (hdr.args_len > UBURMA_CMD_MAX_ARGS_SIZE) || + (hdr.command > UBURMA_CMD_CREATE_CTX && file->ucontext == NULL)) { + uburma_log_err( + "invalid input, hdr.command: %d, ret:%ld, hdr.args_len: %d\n", + hdr.command, ret, hdr.args_len); + ret = -EINVAL; + } else { + ret = (long)uburma_cmd_parse(ubc_dev, file, &hdr); + } + } else { + uburma_log_err("bad ioctl command.\n"); + ret = -ENOIOCTLCMD; + } + +srcu_unlock: + srcu_read_unlock(&ubu_dev->ubc_dev_srcu, srcu_idx); + uburma_cmd_dec(ubu_dev); + return ret; +} diff --git a/drivers/ub/urma/uburma/uburma_cmd.h b/drivers/ub/urma/uburma/uburma_cmd.h new file mode 100644 index 000000000000..e0d18722a3a6 --- /dev/null +++ b/drivers/ub/urma/uburma/uburma_cmd.h @@ -0,0 +1,91 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + * + * Description: uburma cmd header file + * Author: Qian Guoxin + * Create: 2023-2-28 + * Note: + * History: 2023-2-28: Create file + */ + +#ifndef UBURMA_CMD_H +#define UBURMA_CMD_H +#include +#include + +#include "uburma_types.h" + +struct uburma_cmd_hdr { + uint32_t command; + uint32_t args_len; + uint64_t args_addr; +}; + +#define UBURMA_CMD_MAX_ARGS_SIZE 4096 + +/* only for uburma device ioctl */ +#define UBURMA_CMD_MAGIC 'U' +#define UBURMA_CMD _IOWR(UBURMA_CMD_MAGIC, 1, struct uburma_cmd_hdr) + +enum uburma_cmd { + UBURMA_CMD_CREATE_CTX = 1, + UBURMA_CMD_DESTROY_CTX, + UBURMA_CMD_USER_CTL +}; + +struct uburma_cmd_udrv_priv { + uint64_t in_addr; + uint32_t in_len; + uint64_t out_addr; + uint32_t out_len; +}; + +struct uburma_cmd_create_ctx { + struct { + uint32_t uasid; + } in; + struct { + int async_fd; + } out; + struct uburma_cmd_udrv_priv udata; +}; + +/* copy from user_space addr to kernel args */ +static inline int uburma_copy_from_user(void *args, const void *args_addr, unsigned long args_size) +{ + int ret = (int)copy_from_user(args, args_addr, args_size); + + if (ret != 0) { + uburma_log_err("copy from user failed, ret:%d.\n", ret); + return -EFAULT; + } + return 0; +} + +/* copy kernel args to user_space addr */ +static inline int uburma_copy_to_user(void *args_addr, const void *args, unsigned long args_size) +{ + int ret = (int)copy_to_user(args_addr, args, args_size); + + if (ret != 0) { + uburma_log_err("copy to user failed ret:%d.\n", ret); + return -EFAULT; + } + return 0; +} + +void uburma_cmd_inc(struct uburma_device *ubu_dev); +void uburma_cmd_dec(struct uburma_device *ubu_dev); +void uburma_cmd_flush(struct uburma_device *ubu_dev); + +#endif /* UBURMA_CMD_H */ diff --git a/drivers/ub/urma/uburma/uburma_file_ops.h b/drivers/ub/urma/uburma/uburma_file_ops.h new file mode 100644 index 000000000000..dd2377f9e5a0 --- /dev/null +++ b/drivers/ub/urma/uburma/uburma_file_ops.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + * + * Description: uburma device file ops file + * Author: Qian Guoxin + * Create: 2021-8-4 + * Note: + * History: 2021-8-4: Create file + */ + +#ifndef UBURMA_FILE_OPS_H +#define UBURMA_FILE_OPS_H + +#include +#include +#include + +long uburma_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); + +#endif /* UBURMA_FILE_OPS_H */ diff --git a/drivers/ub/urma/uburma/uburma_main.c b/drivers/ub/urma/uburma/uburma_main.c index 06c0c0c5b039..97994f647362 100644 --- a/drivers/ub/urma/uburma/uburma_main.c +++ b/drivers/ub/urma/uburma/uburma_main.c @@ -34,7 +34,9 @@ #include "uburma_log.h" #include "uburma_types.h" +#include "uburma_file_ops.h" #include "uburma_cdev_file.h" +#include "uburma_cmd.h" #define UBURMA_MAX_DEVICE 1024 #define UBURMA_DYNAMIC_MINOR_NUM UBURMA_MAX_DEVICE @@ -50,6 +52,8 @@ static const struct file_operations g_uburma_fops = { .owner = THIS_MODULE, // .write = uburma_write, .llseek = no_llseek, + .unlocked_ioctl = uburma_ioctl, + .compat_ioctl = uburma_ioctl, }; static int uburma_add_device(struct ubcore_device *ubc_dev); @@ -208,6 +212,7 @@ static void uburma_remove_device(struct ubcore_device *ubc_dev, void *client_ctx complete(&ubu_dev->comp); /* do not wait_for_completion(&ubu_dev->comp) */ + uburma_cmd_flush(ubu_dev); kobject_put(&ubu_dev->kobj); } diff --git a/drivers/ub/urma/uburma/uburma_types.h b/drivers/ub/urma/uburma/uburma_types.h index fb691e2b14d8..9fda1bb2251e 100644 --- a/drivers/ub/urma/uburma/uburma_types.h +++ b/drivers/ub/urma/uburma/uburma_types.h @@ -30,6 +30,35 @@ #include +enum uburma_remove_reason { + /* Userspace requested uobject deletion. Call could fail */ + UBURMA_REMOVE_DESTROY, + /* Context deletion. This call should delete the actual object itself */ + UBURMA_REMOVE_CLOSE, + /* Driver is being hot-unplugged. This call should delete the actual object itself */ + UBURMA_REMOVE_DRIVER_REMOVE, + /* Context is being cleaned-up, but commit was just completed */ + UBURMA_REMOVE_DURING_CLEANUP +}; + +struct uburma_file { + struct kref ref; + struct mutex mutex; + struct uburma_device *ubu_dev; + struct ubcore_ucontext *ucontext; + + /* uobj */ + struct mutex uobjects_lock; + struct list_head uobjects; + struct idr idr; + spinlock_t idr_lock; + struct rw_semaphore cleanup_rwsem; + enum uburma_remove_reason cleanup_reason; + + struct list_head list; + int is_closed; +}; + struct uburma_device { atomic_t refcnt; struct completion comp; /* When refcnt becomes 0, it will wake up */ -- Gitee From cd637a6dded9c0dce5f8d79898bb25be2edb927a Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Tue, 12 Sep 2023 11:30:09 +0800 Subject: [PATCH 02/89] ub: uburma support open/release file ops driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Uburma support open/release file ops. In open operation, it will init uburma_file struct and store it in private date of file. In release operation, it will release this struct. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/uburma/Makefile | 1 + drivers/ub/urma/uburma/uburma_dev_ops.c | 123 +++++++++++++++++++++++ drivers/ub/urma/uburma/uburma_file_ops.h | 3 + drivers/ub/urma/uburma/uburma_main.c | 2 + 4 files changed, 129 insertions(+) create mode 100644 drivers/ub/urma/uburma/uburma_dev_ops.c diff --git a/drivers/ub/urma/uburma/Makefile b/drivers/ub/urma/uburma/Makefile index f59835ca2683..147ae203480e 100644 --- a/drivers/ub/urma/uburma/Makefile +++ b/drivers/ub/urma/uburma/Makefile @@ -4,6 +4,7 @@ # uburma-objs := uburma_main.o \ + uburma_dev_ops.o \ uburma_cmd.o \ uburma_cdev_file.o diff --git a/drivers/ub/urma/uburma/uburma_dev_ops.c b/drivers/ub/urma/uburma/uburma_dev_ops.c new file mode 100644 index 000000000000..102af8670771 --- /dev/null +++ b/drivers/ub/urma/uburma/uburma_dev_ops.c @@ -0,0 +1,123 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + * + * Description: uburma device ops file + * Author: Qian Guoxin + * Create: 2021-08-04 + * Note: + * History: 2021-08-04: Create file + */ + +#include +#include +#include + +#include +#include + +#include "uburma_log.h" +#include "uburma_types.h" +#include "uburma_cmd.h" + +void uburma_release_file(struct kref *ref) +{ + struct uburma_file *file = container_of(ref, struct uburma_file, ref); + int srcu_idx; + + srcu_idx = srcu_read_lock(&file->ubu_dev->ubc_dev_srcu); + srcu_dereference(file->ubu_dev->ubc_dev, &file->ubu_dev->ubc_dev_srcu); + + srcu_read_unlock(&file->ubu_dev->ubc_dev_srcu, srcu_idx); + + if (atomic_dec_and_test(&file->ubu_dev->refcnt)) + complete(&file->ubu_dev->comp); + + kobject_put(&file->ubu_dev->kobj); + kfree(file); +} + +int uburma_open(struct inode *inode, struct file *filp) +{ + struct uburma_device *ubu_dev; + struct ubcore_device *ubc_dev; + struct uburma_file *file; + int srcu_idx; + int ret; + + ubu_dev = container_of(inode->i_cdev, struct uburma_device, cdev); + if (!atomic_inc_not_zero(&ubu_dev->refcnt)) { + uburma_log_err("device was not ready.\n"); + return -ENXIO; + } + + srcu_idx = srcu_read_lock(&ubu_dev->ubc_dev_srcu); + mutex_lock(&ubu_dev->lists_mutex); + ubc_dev = srcu_dereference(ubu_dev->ubc_dev, &ubu_dev->ubc_dev_srcu); + if (ubc_dev == NULL || ubc_dev->dev_name == NULL) { + uburma_log_err("can not find ubcore device.\n"); + ret = EIO; + goto err; + } + + file = kzalloc(sizeof(struct uburma_file), GFP_KERNEL); + if (!file) { + ret = -ENOMEM; + uburma_log_err("can not alloc memory.\n"); + goto err; + } + + file->ubu_dev = ubu_dev; + file->ucontext = NULL; + kref_init(&file->ref); + mutex_init(&file->mutex); + filp->private_data = file; + + list_add_tail(&file->list, &ubu_dev->uburma_file_list); + kobject_get(&ubu_dev->kobj); // Increase reference count for file. + + mutex_unlock(&ubu_dev->lists_mutex); + srcu_read_unlock(&ubu_dev->ubc_dev_srcu, srcu_idx); + + uburma_log_info("device: %s open succeed.\n", ubc_dev->dev_name); + return nonseekable_open(inode, filp); + +err: + mutex_unlock(&ubu_dev->lists_mutex); + srcu_read_unlock(&ubu_dev->ubc_dev_srcu, srcu_idx); + if (atomic_dec_and_test(&ubu_dev->refcnt)) + complete(&ubu_dev->comp); + return ret; +} + +int uburma_close(struct inode *inode, struct file *filp) +{ + struct uburma_file *file = filp->private_data; + + mutex_lock(&file->mutex); + if (file->ucontext) { + ubcore_free_ucontext(file->ubu_dev->ubc_dev, file->ucontext); + file->ucontext = NULL; + } + mutex_unlock(&file->mutex); + + mutex_lock(&file->ubu_dev->lists_mutex); + if (file->is_closed == 0) { + list_del(&file->list); + file->is_closed = 1; + } + mutex_unlock(&file->ubu_dev->lists_mutex); + + kref_put(&file->ref, uburma_release_file); + + return 0; +} diff --git a/drivers/ub/urma/uburma/uburma_file_ops.h b/drivers/ub/urma/uburma/uburma_file_ops.h index dd2377f9e5a0..dcb5a7459cf0 100644 --- a/drivers/ub/urma/uburma/uburma_file_ops.h +++ b/drivers/ub/urma/uburma/uburma_file_ops.h @@ -25,6 +25,9 @@ #include #include +void uburma_release_file(struct kref *ref); +int uburma_open(struct inode *inode, struct file *filp); +int uburma_close(struct inode *inode, struct file *filp); long uburma_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); #endif /* UBURMA_FILE_OPS_H */ diff --git a/drivers/ub/urma/uburma/uburma_main.c b/drivers/ub/urma/uburma/uburma_main.c index 97994f647362..ba64341aa34a 100644 --- a/drivers/ub/urma/uburma/uburma_main.c +++ b/drivers/ub/urma/uburma/uburma_main.c @@ -51,6 +51,8 @@ static struct class *g_uburma_class; static const struct file_operations g_uburma_fops = { .owner = THIS_MODULE, // .write = uburma_write, + .open = uburma_open, + .release = uburma_close, .llseek = no_llseek, .unlocked_ioctl = uburma_ioctl, .compat_ioctl = uburma_ioctl, -- Gitee From 7d130c6018dbfd09c6e1c5d91b347fdbf3924321 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Tue, 12 Sep 2023 11:41:16 +0800 Subject: [PATCH 03/89] ub: add mmap ops support in ubcore and uburma driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- In ubcore: Add mmap ops. UBN drivers will register it to mmap physical space like doorbell of jetty or others based on urma context. In uburma: Add mmap ops support in uburma file_operations. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/uburma/uburma_dev_ops.c | 32 ++++++++++++++++++++++++ drivers/ub/urma/uburma/uburma_file_ops.h | 1 + drivers/ub/urma/uburma/uburma_main.c | 1 + 3 files changed, 34 insertions(+) diff --git a/drivers/ub/urma/uburma/uburma_dev_ops.c b/drivers/ub/urma/uburma/uburma_dev_ops.c index 102af8670771..487c63634466 100644 --- a/drivers/ub/urma/uburma/uburma_dev_ops.c +++ b/drivers/ub/urma/uburma/uburma_dev_ops.c @@ -29,6 +29,38 @@ #include "uburma_types.h" #include "uburma_cmd.h" +int uburma_mmap(struct file *filp, struct vm_area_struct *vma) +{ + struct uburma_file *file = filp->private_data; + struct uburma_device *ubu_dev; + struct ubcore_device *ubc_dev; + int srcu_idx; + int ret; + + if (file == NULL || file->ucontext == NULL) { + uburma_log_err("can not find ucontext.\n"); + return -EINVAL; + } + + ubu_dev = file->ubu_dev; + uburma_cmd_inc(ubu_dev); + + srcu_idx = srcu_read_lock(&ubu_dev->ubc_dev_srcu); + ubc_dev = srcu_dereference(ubu_dev->ubc_dev, &ubu_dev->ubc_dev_srcu); + if (ubc_dev == NULL || ubc_dev->ops == NULL || ubc_dev->ops->mmap == NULL) { + uburma_log_err("can not find ubcore device.\n"); + ret = -ENODEV; + goto out; + } + + ret = ubc_dev->ops->mmap(file->ucontext, vma); + +out: + srcu_read_unlock(&ubu_dev->ubc_dev_srcu, srcu_idx); + uburma_cmd_dec(ubu_dev); + return ret; +} + void uburma_release_file(struct kref *ref) { struct uburma_file *file = container_of(ref, struct uburma_file, ref); diff --git a/drivers/ub/urma/uburma/uburma_file_ops.h b/drivers/ub/urma/uburma/uburma_file_ops.h index dcb5a7459cf0..62a1a10399bf 100644 --- a/drivers/ub/urma/uburma/uburma_file_ops.h +++ b/drivers/ub/urma/uburma/uburma_file_ops.h @@ -26,6 +26,7 @@ #include void uburma_release_file(struct kref *ref); +int uburma_mmap(struct file *filp, struct vm_area_struct *vma); int uburma_open(struct inode *inode, struct file *filp); int uburma_close(struct inode *inode, struct file *filp); long uburma_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); diff --git a/drivers/ub/urma/uburma/uburma_main.c b/drivers/ub/urma/uburma/uburma_main.c index ba64341aa34a..80496f210de3 100644 --- a/drivers/ub/urma/uburma/uburma_main.c +++ b/drivers/ub/urma/uburma/uburma_main.c @@ -51,6 +51,7 @@ static struct class *g_uburma_class; static const struct file_operations g_uburma_fops = { .owner = THIS_MODULE, // .write = uburma_write, + .mmap = uburma_mmap, .open = uburma_open, .release = uburma_close, .llseek = no_llseek, -- Gitee From c099f4fc02628782749e5dce0f0be919c724bb94 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Tue, 12 Sep 2023 15:27:20 +0800 Subject: [PATCH 04/89] ub: add uobj basic function in uburma to manage resource release process driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Add uobj feature in uburma to manage resource release process together. ** Context to use uobj: ** There are some dependencies between various objects provided by the URMA. Due to active or passive reasons, dependency conditions may not be met during object creation or deletion, or residual objects may fail to be deleted, resulting in unpredictable problems. These objects need to be managed in a unified manner. ** Scenarios: ** - After an object is created, it is not manually released and exits the program. - Program crashes unexpectedly after object creation - After the object is created, the driver is uninstalled. - When an object is being used, other threads delete the object (for example, event processing). - When an object is deleted, other objects depend on the object. ** Design Key Points of uobj: ** - Create urma context/file by process --- open device - UOBJ-related structures are initialized when uburma_open is used. - Stores the uobjects list in the uburma_file structure. - When a user uses the ioctl interface to create, associate, and destroy an object, the uobj object can be created, associated, and destroyed. - Use usecnt to record associations when creating objects. - Record the uobj object to the uobjects list when the creation is successful. - Use the get/put operation to ensure object accessibility. - Number of associated resources that are released when an object is destroyed. - After the object is destroyed, the corresponding uobj object is deleted from the uobjects list. - Invoke the uburma_close function when the process exits normally or abnormally. - Release all undestructed uobj resources in the uburma_close function. - All undestructed UOBJ resources are released during driver uninstallation. ** This patch include: ** - Structure definition of uobj - uobj_alloc(): alloc uobj to associate with an obj of urma. - uobj_alloc_commit(): after obj successfully created, commit the uobj alloc. - uobj_alloc_abort(): abort the uobj alloc when obj failed to create. - uobj_remove_commit(): remove the committed uobj when obj deleted. - uobj_get(): get obj and add refcnt - uobj_put(): sub refcnt and see if uobj can be freed. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/uburma/Makefile | 3 +- drivers/ub/urma/uburma/uburma_uobj.c | 151 +++++++++++++++++++++++++++ drivers/ub/urma/uburma/uburma_uobj.h | 83 +++++++++++++++ 3 files changed, 236 insertions(+), 1 deletion(-) create mode 100644 drivers/ub/urma/uburma/uburma_uobj.c create mode 100644 drivers/ub/urma/uburma/uburma_uobj.h diff --git a/drivers/ub/urma/uburma/Makefile b/drivers/ub/urma/uburma/Makefile index 147ae203480e..7194d916b527 100644 --- a/drivers/ub/urma/uburma/Makefile +++ b/drivers/ub/urma/uburma/Makefile @@ -6,6 +6,7 @@ uburma-objs := uburma_main.o \ uburma_dev_ops.o \ uburma_cmd.o \ - uburma_cdev_file.o + uburma_cdev_file.o \ + uburma_uobj.o obj-$(CONFIG_UB) += uburma.o diff --git a/drivers/ub/urma/uburma/uburma_uobj.c b/drivers/ub/urma/uburma/uburma_uobj.c new file mode 100644 index 000000000000..8621a6beb5d0 --- /dev/null +++ b/drivers/ub/urma/uburma/uburma_uobj.c @@ -0,0 +1,151 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + * + * Description: uobj framework in uburma + * Author: Chen yujie + * Create: 2022-09-07 + * Note: + * History: 2022-09-07: create file + */ + +#include +#include +#include +#include + +#include +#include + +#include "uburma_types.h" +#include "uburma_file_ops.h" +#include "uburma_log.h" +#include "uburma_uobj.h" + +static void uobj_free(struct kref *ref) +{ + kfree_rcu(container_of(ref, struct uburma_uobj, ref), rcu); +} + +struct uburma_uobj *uobj_alloc_begin(const struct uobj_type *type, struct uburma_file *ufile) +{ + struct uburma_uobj *uobj; + + /* Cleanup is running. Calling this should have been impossible */ + if (!down_read_trylock(&ufile->cleanup_rwsem)) { + uburma_log_warn("uobj: cleanup is running while allocating an uobject\n"); + return ERR_PTR(-EIO); + } + uobj = type->type_class->alloc_begin(type, ufile); + if (IS_ERR(uobj)) + up_read(&ufile->cleanup_rwsem); + return uobj; +} + +int uobj_alloc_commit(struct uburma_uobj *uobj) +{ + /* relase write lock */ + atomic_set(&uobj->rcnt, 0); + + /* add uobj to list */ + mutex_lock(&uobj->ufile->uobjects_lock); + list_add(&uobj->list, &uobj->ufile->uobjects); + mutex_unlock(&uobj->ufile->uobjects_lock); + + uobj->type->type_class->alloc_commit(uobj); + + up_read(&uobj->ufile->cleanup_rwsem); + return 0; +} + +void uobj_alloc_abort(struct uburma_uobj *uobj) +{ + uburma_log_info("%s.\n", __func__); + uobj->type->type_class->alloc_abort(uobj); + up_read(&uobj->ufile->cleanup_rwsem); +} + +void uobj_get(struct uburma_uobj *uobj) +{ + kref_get(&uobj->ref); +} + +void uobj_put(struct uburma_uobj *uobj) +{ + kref_put(&uobj->ref, uobj_free); +} + +static int uobj_try_lock(struct uburma_uobj *uobj, bool exclusive) +{ + /* + * When a shared access is required, we use a positive counter. Each + * shared access request checks that the value != -1 and increment it. + * Exclusive access is required for operations like write or destroy. + * In exclusive access mode, we check that the counter is zero (nobody + * claimed this object) and we set it to -1. Releasing a shared access + * lock is done simply by decreasing the counter. As for exclusive + * access locks, since only a single one of them is allowed + * concurrently, setting the counter to zero is enough for releasing + * this lock. + */ + if (!exclusive) + return atomic_add_unless(&uobj->rcnt, 1, -1) ? 0 : -EBUSY; + + /* lock is either WRITE or DESTROY - should be exclusive */ + return atomic_cmpxchg(&uobj->rcnt, 0, -1) == 0 ? 0 : -EBUSY; +} + +static int __must_check uobj_remove_commit_internal(struct uburma_uobj *uobj, + enum uburma_remove_reason why) +{ + struct uburma_file *ufile = uobj->ufile; + int ret; + + ret = uobj->type->type_class->remove_commit(uobj, why); + if (ret && why == UBURMA_REMOVE_DESTROY) { + /* We couldn't remove the object, so just unlock the uobject */ + atomic_set(&uobj->rcnt, 0); + uobj->type->type_class->lookup_put(uobj, true); + } else if (!list_empty(&uobj->list)) { + mutex_lock(&ufile->uobjects_lock); + list_del_init(&uobj->list); + mutex_unlock(&ufile->uobjects_lock); + /* put the ref we took when we created the object */ + uobj_put(uobj); + } + + return ret; +} + +int __must_check uobj_remove_commit(struct uburma_uobj *uobj) +{ + struct uburma_file *ufile = uobj->ufile; + int ret; + + /* put the ref count we took at lookup_get */ + uobj_put(uobj); + + down_read(&ufile->cleanup_rwsem); + /* try Lock uobj for write with cleanup_rwsem locked */ + ret = uobj_try_lock(uobj, true); + if (ret) { + /* Do not rollback uobj_put here */ + up_read(&ufile->cleanup_rwsem); + uburma_log_warn("Failed to lock uobj\n"); + return ret; + } + + ret = uobj_remove_commit_internal(uobj, UBURMA_REMOVE_DESTROY); + + up_read(&ufile->cleanup_rwsem); + return ret; +} diff --git a/drivers/ub/urma/uburma/uburma_uobj.h b/drivers/ub/urma/uburma/uburma_uobj.h new file mode 100644 index 000000000000..5f1fdffd9455 --- /dev/null +++ b/drivers/ub/urma/uburma/uburma_uobj.h @@ -0,0 +1,83 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + * + * Description: uobj framework in uburma + * Author: Chen yujie + * Create: 2022-8-11 + * Note: + * History: 2022-8-11: Create file + */ + +#ifndef UBURMA_UOBJ_H +#define UBURMA_UOBJ_H + +#include + +enum UOBJ_CLASS_ID { + UOBJ_CLASS_ROOT, /* used by framework */ +}; + +enum uobj_access { + UOBJ_ACCESS_NOLOCK, + UOBJ_ACCESS_READ, /* LOCK READ */ + UOBJ_ACCESS_WRITE /* LOCK WRITE */ +}; + +struct uburma_uobj { + struct uburma_file *ufile; /* associated uburma file */ + void *object; /* containing object */ + struct list_head list; /* link to context's list */ + int id; /* index into kernel idr */ + struct kref ref; /* ref of object associated with uobj */ + atomic_t rcnt; /* protects exclusive access */ + struct rcu_head rcu; /* kfree_rcu() overhead */ + + const struct uobj_type *type; +}; + +struct uobj_type { + const struct uobj_type_class *const type_class; + size_t obj_size; + unsigned int destroy_order; +}; + +struct uobj_type_class { + struct uburma_uobj *(*alloc_begin)(const struct uobj_type *type, struct uburma_file *ufile); + void (*alloc_commit)(struct uburma_uobj *uobj); + void (*alloc_abort)(struct uburma_uobj *uobj); + struct uburma_uobj *(*lookup_get)(const struct uobj_type *type, struct uburma_file *ufile, + int id, enum uobj_access flag); + void (*lookup_put)(struct uburma_uobj *uobj, enum uobj_access flag); + int __must_check (*remove_commit)(struct uburma_uobj *uobj, enum uburma_remove_reason why); +}; + +struct uobj_class_def { + uint16_t id; + const struct uobj_type *type_attrs; +}; + +/* uobj base ops */ +struct uburma_uobj *uobj_alloc_begin(const struct uobj_type *type, struct uburma_file *ufile); +int uobj_alloc_commit(struct uburma_uobj *uobj); +void uobj_alloc_abort(struct uburma_uobj *uobj); +int __must_check uobj_remove_commit(struct uburma_uobj *uobj); +void uobj_get(struct uburma_uobj *uobj); +void uobj_put(struct uburma_uobj *uobj); + +#define uobj_class_name(class_id) uobj_class_##class_id + +#define uobj_get_type(class_id) uobj_class_name(class_id).type_attrs + +#define uobj_alloc(class_id, ufile) uobj_alloc_begin(uobj_get_type(class_id), ufile) + +#endif /* UBURMA_UOBJ_H */ -- Gitee From 0ba385dd365fb2af0bbe8f3f867e3527c70c6e5a Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Tue, 12 Sep 2023 15:40:52 +0800 Subject: [PATCH 05/89] ub: provide basic ops uobj_lookup_get and put for uobj. driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Provide basic operation api of uobj: - uobj_lookup_get(): lookup and get uobj. - uobj_lookup_put(): lookup and put uobj. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/uburma/uburma_uobj.c | 63 ++++++++++++++++++++++++++++ drivers/ub/urma/uburma/uburma_uobj.h | 21 ++++++++++ 2 files changed, 84 insertions(+) diff --git a/drivers/ub/urma/uburma/uburma_uobj.c b/drivers/ub/urma/uburma/uburma_uobj.c index 8621a6beb5d0..bc8024d6969c 100644 --- a/drivers/ub/urma/uburma/uburma_uobj.c +++ b/drivers/ub/urma/uburma/uburma_uobj.c @@ -104,6 +104,19 @@ static int uobj_try_lock(struct uburma_uobj *uobj, bool exclusive) return atomic_cmpxchg(&uobj->rcnt, 0, -1) == 0 ? 0 : -EBUSY; } +static void uobj_unlock(struct uburma_uobj *uobj, bool exclusive) +{ + /* + * In order to unlock an object, either decrease its rcnt for + * read access or zero it in case of exclusive access. See + * uverbs_try_lock_object for locking schema information. + */ + if (!exclusive) + atomic_dec(&uobj->rcnt); + else + atomic_set(&uobj->rcnt, 0); +} + static int __must_check uobj_remove_commit_internal(struct uburma_uobj *uobj, enum uburma_remove_reason why) { @@ -126,6 +139,56 @@ static int __must_check uobj_remove_commit_internal(struct uburma_uobj *uobj, return ret; } +struct uburma_uobj *uobj_lookup_get(const struct uobj_type *type, struct uburma_file *ufile, int id, + enum uobj_access flag) +{ + struct ubcore_device *ubc_dev; + struct uburma_uobj *uobj; + int ret; + + uobj = type->type_class->lookup_get(type, ufile, id, flag); + if (IS_ERR(uobj)) + return uobj; + + if (uobj->type != type) { + ret = -EINVAL; + goto free; + } + + /* block read and write uobj if we are removing device */ + ubc_dev = srcu_dereference(ufile->ubu_dev->ubc_dev, &ufile->ubu_dev->ubc_dev_srcu); + if (!ubc_dev) { + ret = -EIO; + goto free; + } + + if (flag == UOBJ_ACCESS_NOLOCK) + return uobj; + + ret = uobj_try_lock(uobj, flag == UOBJ_ACCESS_WRITE); + if (ret) { + WARN(ufile->cleanup_reason, "uburma: Trying to lookup_get while cleanup context\n"); + goto free; + } + + return uobj; +free: + uobj->type->type_class->lookup_put(uobj, flag); + /* pair with uobj_get in uobj_fd_lookup_get */ + uobj_put(uobj); + return ERR_PTR(ret); +} + +void uobj_lookup_put(struct uburma_uobj *uobj, enum uobj_access flag) +{ + uobj->type->type_class->lookup_put(uobj, flag); + + if (flag != UOBJ_ACCESS_NOLOCK) + uobj_unlock(uobj, flag == UOBJ_ACCESS_WRITE); /* match with uobj_try_lock */ + + uobj_put(uobj); +} + int __must_check uobj_remove_commit(struct uburma_uobj *uobj) { struct uburma_file *ufile = uobj->ufile; diff --git a/drivers/ub/urma/uburma/uburma_uobj.h b/drivers/ub/urma/uburma/uburma_uobj.h index 5f1fdffd9455..f525af1b0f82 100644 --- a/drivers/ub/urma/uburma/uburma_uobj.h +++ b/drivers/ub/urma/uburma/uburma_uobj.h @@ -70,6 +70,9 @@ struct uobj_class_def { struct uburma_uobj *uobj_alloc_begin(const struct uobj_type *type, struct uburma_file *ufile); int uobj_alloc_commit(struct uburma_uobj *uobj); void uobj_alloc_abort(struct uburma_uobj *uobj); +struct uburma_uobj *uobj_lookup_get(const struct uobj_type *type, struct uburma_file *ufile, int id, + enum uobj_access flag); +void uobj_lookup_put(struct uburma_uobj *uobj, enum uobj_access flag); int __must_check uobj_remove_commit(struct uburma_uobj *uobj); void uobj_get(struct uburma_uobj *uobj); void uobj_put(struct uburma_uobj *uobj); @@ -80,4 +83,22 @@ void uobj_put(struct uburma_uobj *uobj); #define uobj_alloc(class_id, ufile) uobj_alloc_begin(uobj_get_type(class_id), ufile) +#define uobj_get_read(class_id, _id, ufile) \ + uobj_lookup_get(uobj_get_type(class_id), ufile, _id, UOBJ_ACCESS_READ) + +#define uobj_put_read(uobj) uobj_lookup_put(uobj, UOBJ_ACCESS_READ) + +#define uobj_get_write(class_id, _id, ufile) \ + uobj_lookup_get(uobj_get_type(class_id), ufile, _id, UOBJ_ACCESS_WRITE) + +#define uobj_put_write(uobj) uobj_lookup_put(uobj, UOBJ_ACCESS_WRITE) + +/* Do not lock uobj without cleanup_rwsem locked */ +#define uobj_get_del(class_id, _id, ufile) \ + uobj_lookup_get(uobj_get_type(class_id), ufile, _id, UOBJ_ACCESS_NOLOCK) + +/* Do not lock uobj without cleanup_rwsem locked */ +#define uobj_get_del(class_id, _id, ufile) \ + uobj_lookup_get(uobj_get_type(class_id), ufile, _id, UOBJ_ACCESS_NOLOCK) + #endif /* UBURMA_UOBJ_H */ -- Gitee From aa1d61dca285fedea08d23e6ea15858547047313 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Tue, 12 Sep 2023 16:18:42 +0800 Subject: [PATCH 06/89] ub: add fd impl of uobj api in uburma driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Add fd implementation of uobj api in uburma, which support uobj to manage fd obj in urma(e.x. urma event obj). Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/uburma/uburma_uobj.c | 144 +++++++++++++++++++++++++++ drivers/ub/urma/uburma/uburma_uobj.h | 28 ++++++ 2 files changed, 172 insertions(+) diff --git a/drivers/ub/urma/uburma/uburma_uobj.c b/drivers/ub/urma/uburma/uburma_uobj.c index bc8024d6969c..09afe05626a2 100644 --- a/drivers/ub/urma/uburma/uburma_uobj.c +++ b/drivers/ub/urma/uburma/uburma_uobj.c @@ -84,6 +84,30 @@ void uobj_put(struct uburma_uobj *uobj) kref_put(&uobj->ref, uobj_free); } +/* Alloc buffer and init params. */ +static struct uburma_uobj *alloc_uobj(struct uburma_file *ufile, const struct uobj_type *type) +{ + struct ubcore_device *ubc_dev; + struct uburma_uobj *uobj; + + /* block read and write uobj if we are removing device */ + ubc_dev = srcu_dereference(ufile->ubu_dev->ubc_dev, &ufile->ubu_dev->ubc_dev_srcu); + if (!ubc_dev) + return ERR_PTR(-EIO); + + uobj = kzalloc(type->obj_size, GFP_KERNEL); + if (uobj == NULL) + return ERR_PTR(-ENOMEM); + + uobj->ufile = ufile; + uobj->type = type; + + atomic_set(&uobj->rcnt, -1); + kref_init(&uobj->ref); + + return uobj; +} + static int uobj_try_lock(struct uburma_uobj *uobj, bool exclusive) { /* @@ -139,6 +163,117 @@ static int __must_check uobj_remove_commit_internal(struct uburma_uobj *uobj, return ret; } +static struct uburma_uobj *uobj_fd_alloc_begin(const struct uobj_type *type, + struct uburma_file *ufile) +{ + const struct uobj_fd_type *fd_type = container_of(type, struct uobj_fd_type, type); + struct uburma_uobj *uobj; + struct file *filp; + int new_fd; + + new_fd = get_unused_fd_flags(O_RDWR | O_CLOEXEC); + if (new_fd < 0) + return ERR_PTR(new_fd); + + uobj = alloc_uobj(ufile, type); + if (IS_ERR(uobj)) { + put_unused_fd(new_fd); + return uobj; + } + + filp = anon_inode_getfile(fd_type->name, fd_type->fops, uobj, fd_type->flags); + if (IS_ERR(filp)) { + put_unused_fd(new_fd); + uobj_put(uobj); + return (void *)filp; + } + + uobj->id = new_fd; + uobj->object = filp; + + kref_get(&ufile->ref); + + return uobj; +} + +static void uobj_fd_alloc_commit(struct uburma_uobj *uobj) +{ + struct file *filp = (struct file *)uobj->object; + + fd_install(uobj->id, filp); + + /* Do not set uobj->id = 0 as it may be read when remove uobj */ + + /* Get another reference as we export this to the fops */ + uobj_get(uobj); +} + +static void uobj_fd_alloc_abort(struct uburma_uobj *uobj) +{ + struct file *filp = uobj->object; + + /* Unsuccessful NEW */ + fput(filp); + put_unused_fd(uobj->id); +} + +static struct uburma_uobj *uobj_fd_lookup_get(const struct uobj_type *type, + struct uburma_file *ufile, int id, + enum uobj_access flag) +{ + const struct uobj_fd_type *fd_type = container_of(type, struct uobj_fd_type, type); + struct uburma_uobj *uobj; + struct file *f; + + if (flag != UOBJ_ACCESS_READ) + return ERR_PTR(-EOPNOTSUPP); + + f = fget(id); + if (f == NULL) + return ERR_PTR(-EBADF); + + uobj = f->private_data; + /* + * fget(id) ensures we are not currently running close_fd, + * and the caller is expected to ensure that close_fd is never + * done while a call top lookup is possible. + */ + if (f->f_op != fd_type->fops) { + fput(f); + return ERR_PTR(-EBADF); + } + + uobj_get(uobj); + return uobj; +} + +static void uobj_fd_lookup_put(struct uburma_uobj *uobj, enum uobj_access flag) +{ + struct file *filp = uobj->object; + + WARN_ON(flag != UOBJ_ACCESS_READ); + /* This indirectly calls close_fd and free the object */ + fput(filp); +} + +static int __must_check uobj_fd_remove_commit(struct uburma_uobj *uobj, + enum uburma_remove_reason why) +{ + const struct uobj_fd_type *fd_type = container_of(uobj->type, struct uobj_fd_type, type); + /* Call user close function. */ + int ret = fd_type->context_closed(uobj, why); + + if (why == UBURMA_REMOVE_DESTROY && ret) + return ret; + + if (why == UBURMA_REMOVE_DURING_CLEANUP) { + uobj_fd_alloc_abort(uobj); + return ret; + } + + return ret; +} + struct uburma_uobj *uobj_lookup_get(const struct uobj_type *type, struct uburma_file *ufile, int id, enum uobj_access flag) { @@ -212,3 +347,12 @@ int __must_check uobj_remove_commit(struct uburma_uobj *uobj) up_read(&ufile->cleanup_rwsem); return ret; } + +const struct uobj_type_class uobj_fd_type_class = { + .alloc_begin = uobj_fd_alloc_begin, + .alloc_commit = uobj_fd_alloc_commit, + .alloc_abort = uobj_fd_alloc_abort, + .lookup_get = uobj_fd_lookup_get, + .lookup_put = uobj_fd_lookup_put, + .remove_commit = uobj_fd_remove_commit, +}; diff --git a/drivers/ub/urma/uburma/uburma_uobj.h b/drivers/ub/urma/uburma/uburma_uobj.h index f525af1b0f82..5ca003c6e61f 100644 --- a/drivers/ub/urma/uburma/uburma_uobj.h +++ b/drivers/ub/urma/uburma/uburma_uobj.h @@ -61,11 +61,21 @@ struct uobj_type_class { int __must_check (*remove_commit)(struct uburma_uobj *uobj, enum uburma_remove_reason why); }; +struct uobj_fd_type { + struct uobj_type type; + const char *name; + const struct file_operations *fops; + int flags; + int (*context_closed)(struct uburma_uobj *uobj, enum uburma_remove_reason why); +}; + struct uobj_class_def { uint16_t id; const struct uobj_type *type_attrs; }; +extern const struct uobj_type_class uobj_fd_type_class; + /* uobj base ops */ struct uburma_uobj *uobj_alloc_begin(const struct uobj_type *type, struct uburma_file *ufile); int uobj_alloc_commit(struct uburma_uobj *uobj); @@ -81,6 +91,24 @@ void uobj_put(struct uburma_uobj *uobj); #define uobj_get_type(class_id) uobj_class_name(class_id).type_attrs +#define uobj_type_alloc_fd(_order, _obj_size, _context_closed, _fops, _name, _flags) \ + ((&((const struct uobj_fd_type) { \ + .type = { \ + .destroy_order = (_order), \ + .type_class = &uobj_fd_type_class, \ + .obj_size = (_obj_size), \ + }, \ + .context_closed = (_context_closed), \ + .fops = (_fops), \ + .name = (_name), \ + .flags = (_flags) \ + }))->type) + +static inline bool uobj_type_is_fd(const struct uburma_uobj *uobj) +{ + return uobj->type->type_class == &uobj_fd_type_class; +} + #define uobj_alloc(class_id, ufile) uobj_alloc_begin(uobj_get_type(class_id), ufile) #define uobj_get_read(class_id, _id, ufile) \ -- Gitee From 2e0fdb2e284829f6ec5e5a166ed264f38d86e8c0 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Tue, 12 Sep 2023 16:31:01 +0800 Subject: [PATCH 07/89] ub: add idr impl of uobj api in uburma driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Add idr implementation of uobj api in uburma, which support uobj to use idr to manage non-fd obj in urma. (e.x. jetty, segment obj in urma) Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/uburma/uburma_uobj.c | 111 +++++++++++++++++++++++++++ drivers/ub/urma/uburma/uburma_uobj.h | 16 ++++ 2 files changed, 127 insertions(+) diff --git a/drivers/ub/urma/uburma/uburma_uobj.c b/drivers/ub/urma/uburma/uburma_uobj.c index 09afe05626a2..593755f7f1fd 100644 --- a/drivers/ub/urma/uburma/uburma_uobj.c +++ b/drivers/ub/urma/uburma/uburma_uobj.c @@ -108,6 +108,33 @@ static struct uburma_uobj *alloc_uobj(struct uburma_file *ufile, const struct uo return uobj; } +static int uobj_alloc_idr(struct uburma_uobj *uobj) +{ + int ret; + + idr_preload(GFP_KERNEL); + spin_lock(&uobj->ufile->idr_lock); + + /* Alloc idr pointing to NULL. Will replace it once we commit. */ + ret = idr_alloc(&uobj->ufile->idr, NULL, 0, min_t(unsigned long, U32_MAX - 1U, INT_MAX), + GFP_NOWAIT); + if (ret >= 0) + uobj->id = ret; + + spin_unlock(&uobj->ufile->idr_lock); + idr_preload_end(); + + return ret < 0 ? ret : 0; +} + +static void uobj_remove_idr(struct uburma_uobj *uobj) +{ + spin_lock(&uobj->ufile->idr_lock); + idr_remove(&uobj->ufile->idr, uobj->id); + spin_unlock(&uobj->ufile->idr_lock); +} + + static int uobj_try_lock(struct uburma_uobj *uobj, bool exclusive) { /* @@ -163,6 +190,81 @@ static int __must_check uobj_remove_commit_internal(struct uburma_uobj *uobj, return ret; } +static struct uburma_uobj *uobj_idr_alloc_begin(const struct uobj_type *type, + struct uburma_file *ufile) +{ + struct uburma_uobj *uobj; + int ret; + + uobj = alloc_uobj(ufile, type); + if (IS_ERR(uobj)) + return uobj; + + ret = uobj_alloc_idr(uobj); + if (ret) { + uobj_put(uobj); + return ERR_PTR(ret); + } + + return uobj; +} + +static void uobj_idr_alloc_commit(struct uburma_uobj *uobj) +{ + spin_lock(&uobj->ufile->idr_lock); + WARN_ON(idr_replace(&uobj->ufile->idr, uobj, uobj->id)); + spin_unlock(&uobj->ufile->idr_lock); +} + +static void uobj_idr_alloc_abort(struct uburma_uobj *uobj) +{ + uobj_remove_idr(uobj); + uobj_put(uobj); +} + +static struct uburma_uobj *uobj_idr_lookup_get(const struct uobj_type *type, + struct uburma_file *ufile, int id, + enum uobj_access flag) +{ + struct uburma_uobj *uobj = NULL; + + rcu_read_lock(); + /* Object won't be released as we're protected in rcu. */ + uobj = idr_find(&ufile->idr, id); + if (uobj == NULL) { + uobj = ERR_PTR(-ENOENT); + goto free; + } + + /* Object associated with uobj may have been released. */ + if (!kref_get_unless_zero(&uobj->ref)) + uobj = ERR_PTR(-ENOENT); + +free: + rcu_read_unlock(); + return uobj; +} + +static void uobj_idr_lookup_put(struct uburma_uobj *uobj, enum uobj_access flag) +{ + /* Empty for now. */ +} + +static int __must_check uobj_idr_remove_commit(struct uburma_uobj *uobj, + enum uburma_remove_reason why) +{ + const struct uobj_idr_type *idr_type = container_of(uobj->type, struct uobj_idr_type, type); + /* Call object destroy function. */ + int ret = idr_type->destroy_func(uobj, why); + + /* Only user req destroy may fail. */ + if (why == UBURMA_REMOVE_DESTROY && ret) + return ret; + + uobj_remove_idr(uobj); + return ret; +} + static struct uburma_uobj *uobj_fd_alloc_begin(const struct uobj_type *type, struct uburma_file *ufile) { @@ -348,6 +450,15 @@ int __must_check uobj_remove_commit(struct uburma_uobj *uobj) return ret; } +const struct uobj_type_class uobj_idr_type_class = { + .alloc_begin = uobj_idr_alloc_begin, + .alloc_commit = uobj_idr_alloc_commit, + .alloc_abort = uobj_idr_alloc_abort, + .lookup_get = uobj_idr_lookup_get, + .lookup_put = uobj_idr_lookup_put, + .remove_commit = uobj_idr_remove_commit, +}; + const struct uobj_type_class uobj_fd_type_class = { .alloc_begin = uobj_fd_alloc_begin, .alloc_commit = uobj_fd_alloc_commit, diff --git a/drivers/ub/urma/uburma/uburma_uobj.h b/drivers/ub/urma/uburma/uburma_uobj.h index 5ca003c6e61f..fbfe74522ac8 100644 --- a/drivers/ub/urma/uburma/uburma_uobj.h +++ b/drivers/ub/urma/uburma/uburma_uobj.h @@ -61,6 +61,11 @@ struct uobj_type_class { int __must_check (*remove_commit)(struct uburma_uobj *uobj, enum uburma_remove_reason why); }; +struct uobj_idr_type { + struct uobj_type type; + int __must_check (*destroy_func)(struct uburma_uobj *uobj, enum uburma_remove_reason why); +}; + struct uobj_fd_type { struct uobj_type type; const char *name; @@ -74,6 +79,7 @@ struct uobj_class_def { const struct uobj_type *type_attrs; }; +extern const struct uobj_type_class uobj_idr_type_class; extern const struct uobj_type_class uobj_fd_type_class; /* uobj base ops */ @@ -91,6 +97,16 @@ void uobj_put(struct uburma_uobj *uobj); #define uobj_get_type(class_id) uobj_class_name(class_id).type_attrs +#define uobj_type_alloc_idr(_size, _order, _destroy_func) \ + ((&((const struct uobj_idr_type) { \ + .type = { \ + .type_class = &uobj_idr_type_class, \ + .obj_size = (_size), \ + .destroy_order = (_order), \ + }, \ + .destroy_func = (_destroy_func), \ + }))->type) + #define uobj_type_alloc_fd(_order, _obj_size, _context_closed, _fops, _name, _flags) \ ((&((const struct uobj_fd_type) { \ .type = { \ -- Gitee From 95daa9db17d7abd67e1830a3b6d1641987633718 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Tue, 12 Sep 2023 16:58:21 +0800 Subject: [PATCH 08/89] ub: uburma add uobj init and exit process in uburma open and close driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Add uobj init and exit function which will be used in uburma open and close process to init and uninit uobj list. Add uobj macro declare_uobj_class() which will be used when we want to create a new type of uobj class. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/uburma/uburma_dev_ops.c | 3 + drivers/ub/urma/uburma/uburma_uobj.c | 80 +++++++++++++++++++++++++ drivers/ub/urma/uburma/uburma_uobj.h | 20 +++++-- 3 files changed, 99 insertions(+), 4 deletions(-) diff --git a/drivers/ub/urma/uburma/uburma_dev_ops.c b/drivers/ub/urma/uburma/uburma_dev_ops.c index 487c63634466..c2c3c4e0adb0 100644 --- a/drivers/ub/urma/uburma/uburma_dev_ops.c +++ b/drivers/ub/urma/uburma/uburma_dev_ops.c @@ -27,6 +27,7 @@ #include "uburma_log.h" #include "uburma_types.h" +#include "uburma_uobj.h" #include "uburma_cmd.h" int uburma_mmap(struct file *filp, struct vm_area_struct *vma) @@ -112,6 +113,7 @@ int uburma_open(struct inode *inode, struct file *filp) file->ucontext = NULL; kref_init(&file->ref); mutex_init(&file->mutex); + uburma_init_uobj_context(file); filp->private_data = file; list_add_tail(&file->list, &ubu_dev->uburma_file_list); @@ -136,6 +138,7 @@ int uburma_close(struct inode *inode, struct file *filp) struct uburma_file *file = filp->private_data; mutex_lock(&file->mutex); + uburma_cleanup_uobjs(file, UBURMA_REMOVE_CLOSE); if (file->ucontext) { ubcore_free_ucontext(file->ubu_dev->ubc_dev, file->ucontext); file->ucontext = NULL; diff --git a/drivers/ub/urma/uburma/uburma_uobj.c b/drivers/ub/urma/uburma/uburma_uobj.c index 593755f7f1fd..291701837344 100644 --- a/drivers/ub/urma/uburma/uburma_uobj.c +++ b/drivers/ub/urma/uburma/uburma_uobj.c @@ -450,6 +450,86 @@ int __must_check uobj_remove_commit(struct uburma_uobj *uobj) return ret; } +void uburma_init_uobj_context(struct uburma_file *ufile) +{ + ufile->cleanup_reason = 0; + idr_init(&ufile->idr); + spin_lock_init(&ufile->idr_lock); + INIT_LIST_HEAD(&ufile->uobjects); + mutex_init(&ufile->uobjects_lock); + init_rwsem(&ufile->cleanup_rwsem); +} + +void uburma_cleanup_uobjs(struct uburma_file *ufile, enum uburma_remove_reason why) +{ + unsigned int cur_order = 0; + + ufile->cleanup_reason = why; + down_write(&ufile->cleanup_rwsem); + + while (!list_empty(&ufile->uobjects)) { + struct uburma_uobj *obj, *next_obj; + unsigned int next_order = UINT_MAX; + + mutex_lock(&ufile->uobjects_lock); + list_for_each_entry_safe(obj, next_obj, &ufile->uobjects, list) { + if (obj->type->destroy_order == cur_order) { + int ret; + /* if we hit this WARN_ON, + * that means we are racing with a lookup_get. + */ + WARN_ON(uobj_try_lock(obj, true)); + ret = obj->type->type_class->remove_commit(obj, why); + if (ret) + pr_warn("uburma: failed to remove uobject id %d order %u\n", + obj->id, cur_order); + + list_del_init(&obj->list); + + /* uburma_close_uobj_fd will also try lock the uobj for write */ + if (uobj_type_is_fd(obj)) + uobj_unlock(obj, true); /* match with uobj_try_lock */ + + /* put the ref we took when we created the object */ + uobj_put(obj); + } else { + next_order = min(next_order, obj->type->destroy_order); + } + } + mutex_unlock(&ufile->uobjects_lock); + cur_order = next_order; + } + + up_write(&ufile->cleanup_rwsem); +} + +void uburma_close_uobj_fd(struct file *f) +{ + struct uburma_uobj *uobj = f->private_data; + struct uburma_file *ufile = uobj->ufile; + int ret; + + if (down_read_trylock(&ufile->cleanup_rwsem)) { + /* + * uobj_fd_lookup_get holds the kref on the struct file any + * time a FD uobj is locked, which prevents this release + * method from being invoked. Meaning we can always get the + * write lock here, or we have a kernel bug. + */ + WARN_ON(uobj_try_lock(uobj, true)); + ret = uobj_remove_commit_internal(uobj, UBURMA_REMOVE_CLOSE); + up_read(&ufile->cleanup_rwsem); + if (ret) + pr_warn("uburma: unable to clean up uobj file.\n"); + } + + /* Matches the get in alloc_begin_fd_uobject */ + kref_put(&ufile->ref, uburma_release_file); + + /* Pairs with filp->private_data in alloc_begin_fd_uobject */ + uobj_put(uobj); +} + const struct uobj_type_class uobj_idr_type_class = { .alloc_begin = uobj_idr_alloc_begin, .alloc_commit = uobj_idr_alloc_commit, diff --git a/drivers/ub/urma/uburma/uburma_uobj.h b/drivers/ub/urma/uburma/uburma_uobj.h index fbfe74522ac8..e480db501cdf 100644 --- a/drivers/ub/urma/uburma/uburma_uobj.h +++ b/drivers/ub/urma/uburma/uburma_uobj.h @@ -93,10 +93,26 @@ int __must_check uobj_remove_commit(struct uburma_uobj *uobj); void uobj_get(struct uburma_uobj *uobj); void uobj_put(struct uburma_uobj *uobj); +/* internal api */ +void uburma_init_uobj_context(struct uburma_file *ufile); +void uburma_cleanup_uobjs(struct uburma_file *ufile, enum uburma_remove_reason why); + +void uburma_close_uobj_fd(struct file *f); + #define uobj_class_name(class_id) uobj_class_##class_id #define uobj_get_type(class_id) uobj_class_name(class_id).type_attrs +#define _uobj_class_set(_id, _type_attrs) \ + ((const struct uobj_class_def){ .id = (_id), .type_attrs = (_type_attrs) }) + +#define _declare_uobj_class(_name, _id, _type_attrs) \ + const struct uobj_class_def _name = _uobj_class_set(_id, _type_attrs) + +#define declare_uobj_class(class_id, ...) \ + _declare_uobj_class(uobj_class_name(class_id), class_id, ##__VA_ARGS__) + + #define uobj_type_alloc_idr(_size, _order, _destroy_func) \ ((&((const struct uobj_idr_type) { \ .type = { \ @@ -137,10 +153,6 @@ static inline bool uobj_type_is_fd(const struct uburma_uobj *uobj) #define uobj_put_write(uobj) uobj_lookup_put(uobj, UOBJ_ACCESS_WRITE) -/* Do not lock uobj without cleanup_rwsem locked */ -#define uobj_get_del(class_id, _id, ufile) \ - uobj_lookup_get(uobj_get_type(class_id), ufile, _id, UOBJ_ACCESS_NOLOCK) - /* Do not lock uobj without cleanup_rwsem locked */ #define uobj_get_del(class_id, _id, ufile) \ uobj_lookup_get(uobj_get_type(class_id), ufile, _id, UOBJ_ACCESS_NOLOCK) -- Gitee From 1395d9fc4a17d31e43ecef2c5fcf14bfaa688ceb Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Tue, 12 Sep 2023 19:44:02 +0800 Subject: [PATCH 09/89] ub: add hash table basic function in ubcore driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Add hash table basic function in ubcore, which will be used to store info in ubcore device. Use hlist_head and hlist_node as the implementation of hash table. Provided ops: - hashtable alloc/free - add/remove/lookup node Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/ubcore/Makefile | 1 + drivers/ub/urma/ubcore/ubcore_hash_table.c | 140 +++++++++++++++++++++ drivers/ub/urma/ubcore/ubcore_hash_table.h | 48 +++++++ 3 files changed, 189 insertions(+) create mode 100644 drivers/ub/urma/ubcore/ubcore_hash_table.c create mode 100644 drivers/ub/urma/ubcore/ubcore_hash_table.h diff --git a/drivers/ub/urma/ubcore/Makefile b/drivers/ub/urma/ubcore/Makefile index eba8e210fda3..e5387924241c 100644 --- a/drivers/ub/urma/ubcore/Makefile +++ b/drivers/ub/urma/ubcore/Makefile @@ -7,6 +7,7 @@ ubcore-objs := ubcore_main.o \ ubcore_device.o \ ubcore_umem.o \ ubcore_tp.o \ + ubcore_hash_table.o \ ubcore_netlink.o obj-$(CONFIG_UB) += ubcore.o diff --git a/drivers/ub/urma/ubcore/ubcore_hash_table.c b/drivers/ub/urma/ubcore/ubcore_hash_table.c new file mode 100644 index 000000000000..228bf5644e1b --- /dev/null +++ b/drivers/ub/urma/ubcore/ubcore_hash_table.c @@ -0,0 +1,140 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + * + * Description: implement hash table ops + * Author: Yan Fangfang + * Create: 2022-08-03 + * Note: + * History: 2022-08-03 Yan Fangfang Add base code + */ + +#include +#include "ubcore_log.h" +#include "ubcore_hash_table.h" + +int ubcore_hash_table_alloc(struct ubcore_hash_table *ht, const struct ubcore_ht_param *p) +{ + uint32_t i; + + if (p == NULL || p->size == 0) + return -1; + ht->p = *p; + ht->head = kcalloc(p->size, sizeof(struct hlist_head), GFP_KERNEL); + if (ht->head == NULL) { + ubcore_log_err("hash table allocation failed.\n"); + return -1; + } + for (i = 0; i < p->size; i++) + INIT_HLIST_HEAD(&ht->head[i]); + + spin_lock_init(&ht->lock); + kref_init(&ht->kref); + return 0; +} + +void ubcore_hash_table_free_with_cb(struct ubcore_hash_table *ht, void (*free_cb)(void *)) +{ + struct hlist_node *pos = NULL, *next = NULL; + struct hlist_head *head; + uint32_t i; + void *obj; + + spin_lock(&ht->lock); + if (ht->head == NULL) { + spin_unlock(&ht->lock); + return; + } + for (i = 0; i < ht->p.size; i++) { + hlist_for_each_safe(pos, next, &ht->head[i]) { + obj = ubcore_ht_obj(ht, pos); + hlist_del(pos); + if (free_cb != NULL) + free_cb(obj); + else if (ht->p.free_f != NULL) + ht->p.free_f(obj); + else + kfree(obj); + } + } + head = ht->head; + ht->head = NULL; + spin_unlock(&ht->lock); + if (head != NULL) + kfree(head); +} + +void ubcore_hash_table_free(struct ubcore_hash_table *ht) +{ + ubcore_hash_table_free_with_cb(ht, NULL); +} + +void ubcore_hash_table_add_nolock(struct ubcore_hash_table *ht, struct hlist_node *hnode, + uint32_t hash) +{ + INIT_HLIST_NODE(hnode); + hlist_add_head(hnode, &ht->head[hash % ht->p.size]); +} + +void ubcore_hash_table_add(struct ubcore_hash_table *ht, struct hlist_node *hnode, uint32_t hash) +{ + spin_lock(&ht->lock); + if (ht->head == NULL) { + spin_unlock(&ht->lock); + return; + } + ubcore_hash_table_add_nolock(ht, hnode, hash); + spin_unlock(&ht->lock); +} + +void ubcore_hash_table_remove(struct ubcore_hash_table *ht, struct hlist_node *hnode) +{ + spin_lock(&ht->lock); + if (ht->head == NULL) { + spin_unlock(&ht->lock); + return; + } + hlist_del(hnode); + spin_unlock(&ht->lock); +} + +void *ubcore_hash_table_lookup_nolock(struct ubcore_hash_table *ht, uint32_t hash, const void *key) +{ + struct hlist_node *pos = NULL; + void *obj = NULL; + + hlist_for_each(pos, &ht->head[hash % ht->p.size]) { + obj = ubcore_ht_obj(ht, pos); + if (ht->p.cmp_f != NULL && ht->p.cmp_f(obj, key) == 0) { + break; + } else if (ht->p.key_size > 0 && + memcmp(ubcore_ht_key(ht, pos), key, ht->p.key_size) == 0) { + break; + } + obj = NULL; + } + return obj; +} + +void *ubcore_hash_table_lookup(struct ubcore_hash_table *ht, uint32_t hash, const void *key) +{ + void *obj = NULL; + + spin_lock(&ht->lock); + if (ht->head == NULL) { + spin_unlock(&ht->lock); + return NULL; + } + obj = ubcore_hash_table_lookup_nolock(ht, hash, key); + spin_unlock(&ht->lock); + return obj; +} diff --git a/drivers/ub/urma/ubcore/ubcore_hash_table.h b/drivers/ub/urma/ubcore/ubcore_hash_table.h new file mode 100644 index 000000000000..9a1a787defa9 --- /dev/null +++ b/drivers/ub/urma/ubcore/ubcore_hash_table.h @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + * + * Description: define hash table ops + * Author: Yan Fangfang + * Create: 2022-08-03 + * Note: + * History: 2022-08-03 Yan Fangfang Add base code + */ + +#ifndef UBCORE_HASH_TABLE_H +#define UBCORE_HASH_TABLE_H + +#include + +static inline void *ubcore_ht_obj(const struct ubcore_hash_table *ht, + const struct hlist_node *hnode) +{ + return (char *)hnode - ht->p.node_offset; +} + +static inline void *ubcore_ht_key(const struct ubcore_hash_table *ht, + const struct hlist_node *hnode) +{ + return ((char *)hnode - ht->p.node_offset) + ht->p.key_offset; +} +/* Init ht head, not calloc hash table itself */ +int ubcore_hash_table_alloc(struct ubcore_hash_table *ht, const struct ubcore_ht_param *p); +/* Free ht head, not release hash table itself */ +void ubcore_hash_table_free(struct ubcore_hash_table *ht); +void ubcore_hash_table_free_with_cb(struct ubcore_hash_table *ht, void (*free_cb)(void *)); +void ubcore_hash_table_add(struct ubcore_hash_table *ht, struct hlist_node *hnode, uint32_t hash); +void ubcore_hash_table_add_nolock(struct ubcore_hash_table *ht, struct hlist_node *hnode, + uint32_t hash); +void ubcore_hash_table_remove(struct ubcore_hash_table *ht, struct hlist_node *hnode); +void *ubcore_hash_table_lookup(struct ubcore_hash_table *ht, uint32_t hash, const void *key); +void *ubcore_hash_table_lookup_nolock(struct ubcore_hash_table *ht, uint32_t hash, const void *key); +#endif -- Gitee From 2837dc8723c7fcbb5eef87ba4b0e1fc2e5dcf210 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Tue, 12 Sep 2023 19:51:44 +0800 Subject: [PATCH 10/89] ub: add advanced hash table ops and add hash table into ubcore init process driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Add hash table ops: - ubcore_hash_table_find_remove() - ubcore_hash_table_find_add() Add hash table initialization into ubcore device init process. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/ubcore/ubcore_device.c | 37 ++++++++++++++++++ drivers/ub/urma/ubcore/ubcore_hash_table.c | 45 ++++++++++++++++++++++ drivers/ub/urma/ubcore/ubcore_hash_table.h | 4 ++ 3 files changed, 86 insertions(+) diff --git a/drivers/ub/urma/ubcore/ubcore_device.c b/drivers/ub/urma/ubcore/ubcore_device.c index 56f8ac5364b7..1a5b732d2e36 100644 --- a/drivers/ub/urma/ubcore/ubcore_device.c +++ b/drivers/ub/urma/ubcore/ubcore_device.c @@ -32,6 +32,7 @@ #include #include #include "ubcore_priv.h" +#include "ubcore_hash_table.h" static LIST_HEAD(g_client_list); static LIST_HEAD(g_device_list); @@ -309,6 +310,37 @@ void ubcore_put_device(struct ubcore_device *dev) complete(&dev->comp); } +static struct ubcore_ht_param g_ht_params[] = { +}; + +static int ubcore_alloc_hash_tables(struct ubcore_device *dev) +{ + uint32_t i, j; + int ret; + + for (i = 0; i < ARRAY_SIZE(g_ht_params); i++) { + ret = ubcore_hash_table_alloc(&dev->ht[i], &g_ht_params[i]); + if (ret != 0) { + ubcore_log_err("alloc hash tables failed.\n"); + goto free_tables; + } + } + return 0; + +free_tables: + for (j = 0; j < i; j++) + ubcore_hash_table_free(&dev->ht[j]); + return -1; +} + +static void ubcore_free_hash_tables(struct ubcore_device *dev) +{ + uint32_t i; + + for (i = 0; i < ARRAY_SIZE(g_ht_params); i++) + ubcore_hash_table_free(&dev->ht[i]); +} + static void ubcore_device_release(struct device *device) { } @@ -336,12 +368,17 @@ static int init_ubcore_device(struct ubcore_device *dev) init_completion(&dev->comp); atomic_set(&dev->use_cnt, 1); + if (ubcore_alloc_hash_tables(dev) != 0) { + ubcore_log_err("alloc hash tables failed.\n"); + return -1; + } ubcore_set_default_eid(dev); return 0; } static void uninit_ubcore_device(struct ubcore_device *dev) { + ubcore_free_hash_tables(dev); put_device(&dev->dev); } diff --git a/drivers/ub/urma/ubcore/ubcore_hash_table.c b/drivers/ub/urma/ubcore/ubcore_hash_table.c index 228bf5644e1b..c3d66301c22c 100644 --- a/drivers/ub/urma/ubcore/ubcore_hash_table.c +++ b/drivers/ub/urma/ubcore/ubcore_hash_table.c @@ -138,3 +138,48 @@ void *ubcore_hash_table_lookup(struct ubcore_hash_table *ht, uint32_t hash, cons spin_unlock(&ht->lock); return obj; } + +/* Do not insert a new entry if an old entry with the same key exists */ +int ubcore_hash_table_find_add(struct ubcore_hash_table *ht, struct hlist_node *hnode, + uint32_t hash) +{ + spin_lock(&ht->lock); + if (ht->head == NULL) { + spin_unlock(&ht->lock); + return -1; + } + /* Old entry with the same key exists */ + if (ubcore_hash_table_lookup_nolock(ht, hash, ubcore_ht_key(ht, hnode)) != NULL) { + spin_unlock(&ht->lock); + return -1; + } + ubcore_hash_table_add_nolock(ht, hnode, hash); + spin_unlock(&ht->lock); + return 0; +} + +void *ubcore_hash_table_find_remove(struct ubcore_hash_table *ht, uint32_t hash, const void *key) +{ + struct hlist_node *pos = NULL, *next = NULL; + void *obj = NULL; + + spin_lock(&ht->lock); + if (ht->head == NULL) { + spin_unlock(&ht->lock); + return NULL; + } + hlist_for_each_safe(pos, next, &ht->head[hash % ht->p.size]) { + obj = ubcore_ht_obj(ht, pos); + if (ht->p.cmp_f != NULL && ht->p.cmp_f(obj, key) == 0) { + hlist_del(pos); + break; + } else if (ht->p.key_size > 0 && + memcmp(ubcore_ht_key(ht, pos), key, ht->p.key_size) == 0) { + hlist_del(pos); + break; + } + obj = NULL; + } + spin_unlock(&ht->lock); + return obj; +} diff --git a/drivers/ub/urma/ubcore/ubcore_hash_table.h b/drivers/ub/urma/ubcore/ubcore_hash_table.h index 9a1a787defa9..cdf136e74fa6 100644 --- a/drivers/ub/urma/ubcore/ubcore_hash_table.h +++ b/drivers/ub/urma/ubcore/ubcore_hash_table.h @@ -45,4 +45,8 @@ void ubcore_hash_table_add_nolock(struct ubcore_hash_table *ht, struct hlist_nod void ubcore_hash_table_remove(struct ubcore_hash_table *ht, struct hlist_node *hnode); void *ubcore_hash_table_lookup(struct ubcore_hash_table *ht, uint32_t hash, const void *key); void *ubcore_hash_table_lookup_nolock(struct ubcore_hash_table *ht, uint32_t hash, const void *key); +void *ubcore_hash_table_find_remove(struct ubcore_hash_table *ht, uint32_t hash, const void *key); +/* Do not insert a new entry if an old entry with the same key exists */ +int ubcore_hash_table_find_add(struct ubcore_hash_table *ht, struct hlist_node *hnode, + uint32_t hash); #endif -- Gitee From be93bcaeab48f4c111ae4c1a5b527ae6b39cacc7 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Tue, 12 Sep 2023 20:15:42 +0800 Subject: [PATCH 11/89] ub: ubcore provide add and delete eid ops driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Ubcore provide add_eid and delete_eid ops which will call UBN vendor driver registered methods to set/unset eid. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/ubcore/ubcore_device.c | 36 ++++++++++++++++++++++++++ include/urma/ubcore_uapi.h | 16 ++++++++++++ 2 files changed, 52 insertions(+) diff --git a/drivers/ub/urma/ubcore/ubcore_device.c b/drivers/ub/urma/ubcore/ubcore_device.c index 1a5b732d2e36..32eeed18bca1 100644 --- a/drivers/ub/urma/ubcore/ubcore_device.c +++ b/drivers/ub/urma/ubcore/ubcore_device.c @@ -523,6 +523,42 @@ int ubcore_set_eid(struct ubcore_device *dev, union ubcore_eid *eid) } EXPORT_SYMBOL(ubcore_set_eid); +int ubcore_add_eid(struct ubcore_device *dev, union ubcore_eid *eid) +{ + int ret; + + if (dev == NULL || eid == NULL || dev->ops == NULL || dev->ops->add_eid == NULL) { + ubcore_log_err("Invalid argument.\n"); + return -EINVAL; + } + + ret = dev->ops->add_eid(dev, eid); + if (ret != 0) { + ubcore_log_err("failed to add eid, ret: %d.\n", ret); + return -EPERM; + } + return ret; +} +EXPORT_SYMBOL(ubcore_add_eid); + +int ubcore_delete_eid(struct ubcore_device *dev, uint16_t idx) +{ + int ret; + + if (dev == NULL || dev->ops == NULL || dev->ops->delete_eid_by_idx == NULL) { + ubcore_log_err("Invalid argument.\n"); + return -EINVAL; + } + + ret = dev->ops->delete_eid_by_idx(dev, idx); + if (ret != 0) { + ubcore_log_err("failed to delete eid, ret: %d.\n", ret); + return -EPERM; + } + return ret; +} +EXPORT_SYMBOL(ubcore_delete_eid); + int ubcore_query_device_attr(struct ubcore_device *dev, struct ubcore_device_attr *attr) { int ret; diff --git a/include/urma/ubcore_uapi.h b/include/urma/ubcore_uapi.h index 008915072ad2..58ce192ec748 100644 --- a/include/urma/ubcore_uapi.h +++ b/include/urma/ubcore_uapi.h @@ -51,6 +51,22 @@ void ubcore_free_ucontext(const struct ubcore_device *dev, struct ubcore_ucontex * @return: 0 on success, other value on error */ int ubcore_set_eid(struct ubcore_device *dev, union ubcore_eid *eid); +/** + * add a function entity id (eid) to ub device, the upi of vf to which the eid belongs + * can be specified + * @param[in] dev: the ubcore_device handle; + * @param[in] eid: function entity id (eid) to be added; + * @param[in] upi: upi of vf; + * @return: the index of eid/upi, less than 0 indicating error + */ +int ubcore_add_eid(struct ubcore_device *dev, union ubcore_eid *eid); +/** + * remove a function entity id (eid) specified by idx from ub device + * @param[in] dev: the ubcore_device handle; + * @param[in] idx: the idx of function entity id (eid) to be deleted; + * @return: 0 on success, other value on error + */ +int ubcore_delete_eid(struct ubcore_device *dev, uint16_t idx); /** * query device attributes * @param[in] dev: the ubcore_device handle; -- Gitee From 13f371177a176d48733a6bfa4666e8a5a5b4b208 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Tue, 12 Sep 2023 20:45:52 +0800 Subject: [PATCH 12/89] ub: ubcore provide query device status ops driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Ubcore provide query_device_status ops. - query_device_status: ubcore will call UBN vendor driver registered methods to query device status(device port status, including mtu, speed, etc). Input parameter: dev: contains vendor-defined private device data. status: device status defined by the UB protocol stack. The UBN driver queries the device status from the chip and fills it in this field. Return value: The value 0 indicates that the query is successful. The value other than 0 indicates that the query fails. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/ubcore/ubcore_device.c | 18 ++++++++++++++++++ include/urma/ubcore_uapi.h | 26 +++++++++++++++++--------- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/drivers/ub/urma/ubcore/ubcore_device.c b/drivers/ub/urma/ubcore/ubcore_device.c index 32eeed18bca1..66bc71419fe9 100644 --- a/drivers/ub/urma/ubcore/ubcore_device.c +++ b/drivers/ub/urma/ubcore/ubcore_device.c @@ -577,6 +577,24 @@ int ubcore_query_device_attr(struct ubcore_device *dev, struct ubcore_device_att } EXPORT_SYMBOL(ubcore_query_device_attr); +int ubcore_query_device_status(const struct ubcore_device *dev, struct ubcore_device_status *status) +{ + int ret; + + if (dev == NULL || dev->ops == NULL || dev->ops->query_device_status == NULL) { + ubcore_log_err("Invalid argument.\n"); + return -EINVAL; + } + + ret = dev->ops->query_device_status(dev, status); + if (ret != 0) { + ubcore_log_err("failed to query device status, ret: %d.\n", ret); + return -EPERM; + } + return 0; +} +EXPORT_SYMBOL(ubcore_query_device_status); + int ubcore_config_device(struct ubcore_device *dev, const struct ubcore_device_cfg *cfg) { int ret; diff --git a/include/urma/ubcore_uapi.h b/include/urma/ubcore_uapi.h index 58ce192ec748..ae64c0e546c7 100644 --- a/include/urma/ubcore_uapi.h +++ b/include/urma/ubcore_uapi.h @@ -74,6 +74,23 @@ int ubcore_delete_eid(struct ubcore_device *dev, uint16_t idx); * @return: 0 on success, other value on error */ int ubcore_query_device_attr(struct ubcore_device *dev, struct ubcore_device_attr *attr); +/** + * query device status + * @param[in] dev: the ubcore_device handle; + * @param[out] status: status returned to client + * @return: 0 on success, other value on error + */ +int ubcore_query_device_status(const struct ubcore_device *dev, + struct ubcore_device_status *status); +/** + * query stats + * @param[in] dev: the ubcore_device handle; + * @param[in] key: stats type and key; + * @param[in/out] val: addr and len of value + * @return: 0 on success, other value on error + */ +int ubcore_query_stats(const struct ubcore_device *dev, struct ubcore_stats_key *key, + struct ubcore_stats_val *val); /** * config device * @param[in] dev: the ubcore_device handle; @@ -110,14 +127,5 @@ int ubcore_register_client(struct ubcore_client *new_client); * @param[in] rm_client: ubcore client to be unregistered */ void ubcore_unregister_client(struct ubcore_client *rm_client); -/** - * query stats - * @param[in] dev: the ubcore_device handle; - * @param[in] key: stats type and key; - * @param[in/out] val: addr and len of value - * @return: 0 on success, other value on error - */ -int ubcore_query_stats(const struct ubcore_device *dev, struct ubcore_stats_key *key, - struct ubcore_stats_val *val); #endif -- Gitee From c78fba3cdc68e37c95799c3ac73b1454056efead Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Tue, 12 Sep 2023 20:47:20 +0800 Subject: [PATCH 13/89] ub: ubcore provide query resources ops driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Ubcore provide query_res ops. - query_res: ubcore will call UBN vendor driver registered methods to query specified res info like tp, jetty, etc. Input parameter: dev: contains vendor-defined private device data. key: specifies the type and key value of the information to be queried. Multiple consecutive keys can be queried. val: specifies the address for storing query results and the total length of the allocated buffer. In the case of consecutive key queries, ensure that the buffer can store the query results of a specified number of keys. Output parameter: val: indicates the address for storing the query result and the length of the actual data. Return value: The value 0 indicates that the query is successful. The value other than 0 indicates that the query fails. If the buffer specified in Val is sufficient, the query is successful and the actual data length is returned. If the buffer is insufficient, a failure message is returned. The driver fills in the expected buffer length. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/ubcore/ubcore_device.c | 20 ++++++++++++++++++++ include/urma/ubcore_uapi.h | 9 +++++++++ 2 files changed, 29 insertions(+) diff --git a/drivers/ub/urma/ubcore/ubcore_device.c b/drivers/ub/urma/ubcore/ubcore_device.c index 66bc71419fe9..e0ff33850f45 100644 --- a/drivers/ub/urma/ubcore/ubcore_device.c +++ b/drivers/ub/urma/ubcore/ubcore_device.c @@ -595,6 +595,26 @@ int ubcore_query_device_status(const struct ubcore_device *dev, struct ubcore_de } EXPORT_SYMBOL(ubcore_query_device_status); +int ubcore_query_resource(const struct ubcore_device *dev, struct ubcore_res_key *key, + struct ubcore_res_val *val) +{ + int ret; + + if (dev == NULL || key == NULL || val == NULL || dev->ops == NULL || + dev->ops->query_res == NULL) { + ubcore_log_err("Invalid argument.\n"); + return -EINVAL; + } + + ret = dev->ops->query_res(dev, key, val); + if (ret != 0) { + ubcore_log_err("failed to query res, ret: %d.\n", ret); + return -EPERM; + } + return 0; +} +EXPORT_SYMBOL(ubcore_query_resource); + int ubcore_config_device(struct ubcore_device *dev, const struct ubcore_device_cfg *cfg) { int ret; diff --git a/include/urma/ubcore_uapi.h b/include/urma/ubcore_uapi.h index ae64c0e546c7..5afc5a398d41 100644 --- a/include/urma/ubcore_uapi.h +++ b/include/urma/ubcore_uapi.h @@ -91,6 +91,15 @@ int ubcore_query_device_status(const struct ubcore_device *dev, */ int ubcore_query_stats(const struct ubcore_device *dev, struct ubcore_stats_key *key, struct ubcore_stats_val *val); +/** + * query resource + * @param[in] dev: the ubcore_device handle; + * @param[in] key: resource type and key; + * @param[in/out] val: addr and len of value + * @return: 0 on success, other value on error + */ +int ubcore_query_resource(const struct ubcore_device *dev, struct ubcore_res_key *key, + struct ubcore_res_val *val); /** * config device * @param[in] dev: the ubcore_device handle; -- Gitee From 93d19f2f4406691652828e5121db693724056a2d Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Tue, 12 Sep 2023 21:48:25 +0800 Subject: [PATCH 14/89] ub: uburma support query port status and write in cdev driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Uburma support query port status and write in cdev. Uburma will query port status when uburma device creates, and write port related attrs under /dev/uburma/dev_name>/port* */ Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/uburma/uburma_cdev_file.c | 61 +++++++++++++++++++++++ drivers/ub/urma/uburma/uburma_cdev_file.h | 14 ++++++ drivers/ub/urma/uburma/uburma_main.c | 13 +++++ drivers/ub/urma/uburma/uburma_types.h | 7 +++ 4 files changed, 95 insertions(+) diff --git a/drivers/ub/urma/uburma/uburma_cdev_file.c b/drivers/ub/urma/uburma/uburma_cdev_file.c index cfc317dab628..a78c284b646a 100644 --- a/drivers/ub/urma/uburma/uburma_cdev_file.c +++ b/drivers/ub/urma/uburma/uburma_cdev_file.c @@ -155,6 +155,62 @@ static const struct attribute_group uburma_dev_attr_group = { .attrs = uburma_dev_attrs, }; +static struct attribute *uburma_port_attrs[] = { +}; + +static ssize_t uburma_port_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) +{ + struct uburma_port_attribute *port_attr = + container_of(attr, struct uburma_port_attribute, attr); + struct uburma_port *p = container_of(kobj, struct uburma_port, kobj); + + if (!port_attr->show) + return -EIO; + + return port_attr->show(p, port_attr, buf); +} + +static ssize_t uburma_port_attr_store(struct kobject *kobj, struct attribute *attr, const char *buf, + size_t count) +{ + struct uburma_port_attribute *port_attr = + container_of(attr, struct uburma_port_attribute, attr); + struct uburma_port *p = container_of(kobj, struct uburma_port, kobj); + + if (!port_attr->store) + return -EIO; + + return port_attr->store(p, port_attr, buf, count); +} + +static const struct sysfs_ops uburma_port_sysfs_ops = { .show = uburma_port_attr_show, + .store = uburma_port_attr_store }; + +static void uburma_port_release(struct kobject *kobj) +{ +} + +static const struct attribute_group uburma_port_groups = { + .attrs = uburma_port_attrs, +}; + +static struct kobj_type uburma_port_type = { .release = uburma_port_release, + .sysfs_ops = &uburma_port_sysfs_ops, + .default_attrs = uburma_port_attrs +}; + +int uburma_create_port_attr_files(struct uburma_device *ubu_dev, uint8_t port_num) +{ + struct uburma_port *p; + + p = &ubu_dev->port[port_num]; + p->ubu_dev = ubu_dev; + p->port_num = port_num; + + return kobject_init_and_add(&p->kobj, &uburma_port_type, &ubu_dev->dev->kobj, "port%hhu", + port_num); +} + int uburma_create_dev_attr_files(struct uburma_device *ubu_dev) { int ret; @@ -168,6 +224,11 @@ int uburma_create_dev_attr_files(struct uburma_device *ubu_dev) return 0; } +void uburma_remove_port_attr_files(struct uburma_device *ubu_dev, uint8_t port_num) +{ + kobject_put(&ubu_dev->port[port_num].kobj); +} + void uburma_remove_dev_attr_files(struct uburma_device *ubu_dev) { sysfs_remove_group(&ubu_dev->dev->kobj, &uburma_dev_attr_group); diff --git a/drivers/ub/urma/uburma/uburma_cdev_file.h b/drivers/ub/urma/uburma/uburma_cdev_file.h index 4207358f1f9a..ee9c8c9630ba 100644 --- a/drivers/ub/urma/uburma/uburma_cdev_file.h +++ b/drivers/ub/urma/uburma/uburma_cdev_file.h @@ -23,7 +23,21 @@ #include "uburma_types.h" +struct uburma_port_attribute { + struct attribute attr; + ssize_t (*show)(struct uburma_port *p, struct uburma_port_attribute *attr, char *buf); + ssize_t (*store)(struct uburma_port *p, struct uburma_port_attribute *attr, const char *buf, + size_t count); +}; + +#define PORT_ATTR(_name, _mode, _show, _store) \ + struct uburma_port_attribute port_attr_##_name = __ATTR(_name, _mode, _show, _store) + +#define PORT_ATTR_RO(_name) struct uburma_port_attribute port_attr_##_name = __ATTR_RO(_name) + +int uburma_create_port_attr_files(struct uburma_device *ubu_dev, uint8_t port_num); int uburma_create_dev_attr_files(struct uburma_device *ubu_dev); +void uburma_remove_port_attr_files(struct uburma_device *ubu_dev, uint8_t port_num); void uburma_remove_dev_attr_files(struct uburma_device *ubu_dev); #endif /* UBURMA_CDEV_FILE_H */ diff --git a/drivers/ub/urma/uburma/uburma_main.c b/drivers/ub/urma/uburma/uburma_main.c index 80496f210de3..d7d15547ec76 100644 --- a/drivers/ub/urma/uburma/uburma_main.c +++ b/drivers/ub/urma/uburma/uburma_main.c @@ -95,6 +95,8 @@ static int uburma_get_devt(dev_t *devt) static int uburma_device_create(struct uburma_device *ubu_dev, struct ubcore_device *ubc_dev) { + uint8_t i, j; + /* create /dev/uburma/dev_name> */ ubu_dev->dev = device_create(g_uburma_class, ubc_dev->dev.parent, ubu_dev->cdev.dev, ubu_dev, "%s", ubc_dev->dev_name); @@ -108,8 +110,19 @@ static int uburma_device_create(struct uburma_device *ubu_dev, struct ubcore_dev goto destroy_dev; } + /* create /dev/uburma/dev_name>/port* */ + for (i = 0; i < ubc_dev->attr.port_cnt; i++) { + if (uburma_create_port_attr_files(ubu_dev, i) != 0) + goto err_port_attr; + } + return 0; +err_port_attr: + for (j = 0; j < i; j++) + uburma_remove_port_attr_files(ubu_dev, j); + + uburma_remove_dev_attr_files(ubu_dev); destroy_dev: device_destroy(g_uburma_class, ubu_dev->cdev.dev); return -EPERM; diff --git a/drivers/ub/urma/uburma/uburma_types.h b/drivers/ub/urma/uburma/uburma_types.h index 9fda1bb2251e..5d453ef8f40c 100644 --- a/drivers/ub/urma/uburma/uburma_types.h +++ b/drivers/ub/urma/uburma/uburma_types.h @@ -59,6 +59,12 @@ struct uburma_file { int is_closed; }; +struct uburma_port { + struct kobject kobj; + struct uburma_device *ubu_dev; + uint8_t port_num; +}; + struct uburma_device { atomic_t refcnt; struct completion comp; /* When refcnt becomes 0, it will wake up */ @@ -68,6 +74,7 @@ struct uburma_device { unsigned int devnum; struct cdev cdev; struct device *dev; + struct uburma_port port[UBCORE_MAX_PORT_CNT]; struct ubcore_device *__rcu ubc_dev; struct srcu_struct ubc_dev_srcu; /* protect ubc_dev */ struct kobject kobj; /* when equal to 0 , free uburma_device. */ -- Gitee From f771796ffe86a3edea291e89da8a5933d4bd7463 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Tue, 12 Sep 2023 21:57:45 +0800 Subject: [PATCH 15/89] ub: uburma query max mtu, stat and speed attrs, then store in cdev. driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Uburma query max mtu, stat and speed attrs, then store in cdev. All these attributes will be obtained by ubcore_query_device_status(). Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/uburma/uburma_cdev_file.c | 83 +++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/drivers/ub/urma/uburma/uburma_cdev_file.c b/drivers/ub/urma/uburma/uburma_cdev_file.c index a78c284b646a..43b768ebedb4 100644 --- a/drivers/ub/urma/uburma/uburma_cdev_file.c +++ b/drivers/ub/urma/uburma/uburma_cdev_file.c @@ -35,6 +35,8 @@ /* callback information */ typedef ssize_t (*uburma_show_attr_cb)(const struct ubcore_device *ubc_dev, char *buf); typedef ssize_t (*uburma_store_attr_cb)(struct ubcore_device *ubc_dev, const char *buf, size_t len); +typedef ssize_t (*uburma_show_port_attr_cb)(const struct ubcore_device *ubc_dev, char *buf, + uint8_t port_num); static ssize_t uburma_show_dev_attr(struct device *dev, struct device_attribute *attr, char *buf, uburma_show_attr_cb show_cb) @@ -155,7 +157,88 @@ static const struct attribute_group uburma_dev_attr_group = { .attrs = uburma_dev_attrs, }; +static ssize_t uburma_show_port_attr(struct uburma_port *p, struct uburma_port_attribute *attr, + char *buf, uburma_show_port_attr_cb show_cb) +{ + struct uburma_device *ubu_dev = p->ubu_dev; + struct ubcore_device *ubc_dev; + ssize_t ret = -ENODEV; + int srcu_idx; + + if (!ubu_dev || !buf) { + uburma_log_err("Invalid argument.\n"); + return -EINVAL; + } + + srcu_idx = srcu_read_lock(&ubu_dev->ubc_dev_srcu); + ubc_dev = srcu_dereference(ubu_dev->ubc_dev, &ubu_dev->ubc_dev_srcu); + if (ubc_dev == NULL) { + srcu_read_unlock(&ubu_dev->ubc_dev_srcu, srcu_idx); + return -ENODEV; + } + + ret = show_cb(ubc_dev, buf, p->port_num); + srcu_read_unlock(&ubu_dev->ubc_dev_srcu, srcu_idx); + return ret; +} + +static ssize_t max_mtu_show_cb(const struct ubcore_device *ubc_dev, char *buf, uint8_t port_num) +{ + return snprintf(buf, UBURMA_MAX_VALUE_LEN, "%d\n", + (int)ubc_dev->attr.port_attr[port_num].max_mtu); +} + +static ssize_t max_mtu_show(struct uburma_port *p, struct uburma_port_attribute *attr, char *buf) +{ + return uburma_show_port_attr(p, attr, buf, max_mtu_show_cb); +} + +static PORT_ATTR_RO(max_mtu); + +static ssize_t state_show_cb(const struct ubcore_device *ubc_dev, char *buf, uint8_t port_num) +{ + struct ubcore_device_status status; + + if (ubcore_query_device_status(ubc_dev, &status) != 0) { + uburma_log_err("query device status for state failed.\n"); + return -EPERM; + } + + return snprintf(buf, UBURMA_MAX_VALUE_LEN, "%u\n", + (uint32_t)status.port_status[port_num].state); +} + +static ssize_t state_show(struct uburma_port *p, struct uburma_port_attribute *attr, char *buf) +{ + return uburma_show_port_attr(p, attr, buf, state_show_cb); +} + +static PORT_ATTR_RO(state); + +static ssize_t active_speed_show_cb(const struct ubcore_device *ubc_dev, char *buf, + uint8_t port_num) +{ + struct ubcore_device_status status; + + if (ubcore_query_device_status(ubc_dev, &status) != 0) { + uburma_log_err("query device status for active speed failed.\n"); + return -EPERM; + } + + return snprintf(buf, UBURMA_MAX_VALUE_LEN, "%u\n", + status.port_status[port_num].active_speed); +} + +static ssize_t active_speed_show(struct uburma_port *p, struct uburma_port_attribute *attr, + char *buf) +{ + return uburma_show_port_attr(p, attr, buf, active_speed_show_cb); +} + +static PORT_ATTR_RO(active_speed); + static struct attribute *uburma_port_attrs[] = { + &port_attr_max_mtu.attr, &port_attr_state.attr, &port_attr_active_speed.attr, }; static ssize_t uburma_port_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) -- Gitee From 796c95fe1a8b300be87742492cc11a4a7768f558 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Tue, 12 Sep 2023 22:01:24 +0800 Subject: [PATCH 16/89] ub: uburma query active width and mtu, then store in cdev. driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Uburma query active width and mtu attrs, then store in cdev. All these attributes will be obtained by ubcore_query_device_status(). Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/uburma/uburma_cdev_file.c | 43 +++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/drivers/ub/urma/uburma/uburma_cdev_file.c b/drivers/ub/urma/uburma/uburma_cdev_file.c index 43b768ebedb4..3941525d07df 100644 --- a/drivers/ub/urma/uburma/uburma_cdev_file.c +++ b/drivers/ub/urma/uburma/uburma_cdev_file.c @@ -237,8 +237,51 @@ static ssize_t active_speed_show(struct uburma_port *p, struct uburma_port_attri static PORT_ATTR_RO(active_speed); +static ssize_t active_width_show_cb(const struct ubcore_device *ubc_dev, char *buf, + uint8_t port_num) +{ + struct ubcore_device_status status; + + if (ubcore_query_device_status(ubc_dev, &status) != 0) { + uburma_log_err("query device status for active width failed.\n"); + return -EPERM; + } + + return snprintf(buf, UBURMA_MAX_VALUE_LEN, "%u\n", + status.port_status[port_num].active_width); +} + +static ssize_t active_width_show(struct uburma_port *p, struct uburma_port_attribute *attr, + char *buf) +{ + return uburma_show_port_attr(p, attr, buf, active_width_show_cb); +} + +static PORT_ATTR_RO(active_width); + +static ssize_t active_mtu_show_cb(const struct ubcore_device *ubc_dev, char *buf, uint8_t port_num) +{ + struct ubcore_device_status status; + + if (ubcore_query_device_status(ubc_dev, &status) != 0) { + uburma_log_err("query device status for active mtu failed.\n"); + return -EPERM; + } + + return snprintf(buf, UBURMA_MAX_VALUE_LEN, "%u\n", + (uint32_t)status.port_status[port_num].active_mtu); +} + +static ssize_t active_mtu_show(struct uburma_port *p, struct uburma_port_attribute *attr, char *buf) +{ + return uburma_show_port_attr(p, attr, buf, active_mtu_show_cb); +} + +static PORT_ATTR_RO(active_mtu); + static struct attribute *uburma_port_attrs[] = { &port_attr_max_mtu.attr, &port_attr_state.attr, &port_attr_active_speed.attr, + &port_attr_active_width.attr, &port_attr_active_mtu.attr, NULL, }; static ssize_t uburma_port_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) -- Gitee From 59c6a073947fa6e15a877ee6663fb7c09aeafe17 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Tue, 12 Sep 2023 22:16:43 +0800 Subject: [PATCH 17/89] ub: uburma query guid, trans type and driver name, then store in cdev. driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- uburma query guid, trans type and driver name, then store in cdev. These are device attrs, and values set by UBN driver. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/uburma/uburma_cdev_file.c | 42 +++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/drivers/ub/urma/uburma/uburma_cdev_file.c b/drivers/ub/urma/uburma/uburma_cdev_file.c index 3941525d07df..12e773463acc 100644 --- a/drivers/ub/urma/uburma/uburma_cdev_file.c +++ b/drivers/ub/urma/uburma/uburma_cdev_file.c @@ -147,9 +147,51 @@ static ssize_t eid_store(struct device *dev, struct device_attribute *attr, cons static DEVICE_ATTR_RW(eid); // 0644 +static ssize_t guid_show_cb(const struct ubcore_device *ubc_dev, char *buf) +{ + return snprintf(buf, UBURMA_MAX_VALUE_LEN, "%llu\n", ubc_dev->attr.guid); +} + +static ssize_t guid_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + return uburma_show_dev_attr(dev, attr, buf, guid_show_cb); +} + +static DEVICE_ATTR_RO(guid); + +static ssize_t transport_type_show_cb(const struct ubcore_device *ubc_dev, char *buf) +{ + return snprintf(buf, UBURMA_MAX_VALUE_LEN, "%d\n", (int)ubc_dev->transport_type); +} + +static ssize_t transport_type_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + return uburma_show_dev_attr(dev, attr, buf, transport_type_show_cb); +} + +static DEVICE_ATTR_RO(transport_type); + +static ssize_t driver_name_show_cb(const struct ubcore_device *ubc_dev, char *buf) +{ + if (ubc_dev->ops == NULL) + return -EINVAL; + + return snprintf(buf, UBCORE_MAX_DRIVER_NAME, "%s\n", ubc_dev->ops->driver_name); +} + +static ssize_t driver_name_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + return uburma_show_dev_attr(dev, attr, buf, driver_name_show_cb); +} + +static DEVICE_ATTR_RO(driver_name); + static struct attribute *uburma_dev_attrs[] = { &dev_attr_ubdev.attr, &dev_attr_eid.attr, + &dev_attr_guid.attr, + &dev_attr_transport_type.attr, + &dev_attr_driver_name.attr, NULL, }; -- Gitee From 88a02968df41b34cffe105faa37503accaadfb43 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Wed, 13 Sep 2023 10:17:30 +0800 Subject: [PATCH 18/89] ub: ubcore add jfc, jfr, jfs and event definition. driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Ubcore add jfc, jfs, jfr (jetty for completion/send/recv) and event definition. Introduce of Jetty: Jetty is a logical concept, an I/O unit that provides end-to-end communication services. Jetty is classified into three types: Jetty for Send, Jetty for Receive, and Jetty for Completion. Each Jetty has a queue that maintains its sending and receiving requests. 1. JFS (Jetty for send): used to submit a DMA task or send a message on the user side. 2. JFR (jetty for receive): used to prepare a resource for receiving a message on the home side. 3. JFC (jetty for complete): stores JFS/JFR completion events. It can be bound to JFS or JFR, or specified separately in specific URMA commands. A Jetty for Send (JFS) can implement the remote memory DMA service on one side. JFS (source end) + JFR (destination end) can implement bilateral message services. Event in ubcore: There are 2 types of event in ubcore: - JFCE (jetty for completion event): JFS/JFR completion events. The jfc_comp_callback interrupt processing function is used to set the JFC completion type during kernel-mode driver loading. This callback function searches for the kernel-mode JFC pointer based on the jfc_id reported by the hardware, and invokes the comp_handler stored in the JFC data structure. - JFAE (jetty for async event): Kernel-Mode Exception Events. Once a Jetty exception occurs, the chip reports a hardware interrupt to the UBN driver. The UBN driver parses the interrupt information, finds the abnormal Jetty, and invokes ubcore_event_callback to report the exception to the UB Core protocol stack. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/ubcore/ubcore_device.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/ub/urma/ubcore/ubcore_device.c b/drivers/ub/urma/ubcore/ubcore_device.c index e0ff33850f45..4666e54753ee 100644 --- a/drivers/ub/urma/ubcore/ubcore_device.c +++ b/drivers/ub/urma/ubcore/ubcore_device.c @@ -311,6 +311,14 @@ void ubcore_put_device(struct ubcore_device *dev) } static struct ubcore_ht_param g_ht_params[] = { + [UBCORE_HT_JFS] = { UBCORE_HASH_TABLE_SIZE, offsetof(struct ubcore_jfs, hnode), + offsetof(struct ubcore_jfs, id), sizeof(uint32_t), NULL, NULL }, + + [UBCORE_HT_JFR] = { UBCORE_HASH_TABLE_SIZE, offsetof(struct ubcore_jfr, hnode), + offsetof(struct ubcore_jfr, id), sizeof(uint32_t), NULL, NULL }, + + [UBCORE_HT_JFC] = { UBCORE_HASH_TABLE_SIZE, offsetof(struct ubcore_jfc, hnode), + offsetof(struct ubcore_jfc, id), sizeof(uint32_t), NULL, NULL }, }; static int ubcore_alloc_hash_tables(struct ubcore_device *dev) -- Gitee From eb6204de0cd31ef31676df714acfaafb31decd80 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Wed, 13 Sep 2023 11:03:53 +0800 Subject: [PATCH 19/89] ub: ubcore add jetty, tjetty, jetty id definition. driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Ubcore add jetty, tjetty(target jetty), jetty id definition. jetty: Jetty is duplex and contains both jfs and jfr functions. tjetty (target jetty): represent remote JFR/Jetty imported to local. jetty id: represent a unique jetty in global, contructed by eid, uasid and id itself. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/ubcore/ubcore_device.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/ub/urma/ubcore/ubcore_device.c b/drivers/ub/urma/ubcore/ubcore_device.c index 4666e54753ee..45fed657eaec 100644 --- a/drivers/ub/urma/ubcore/ubcore_device.c +++ b/drivers/ub/urma/ubcore/ubcore_device.c @@ -319,6 +319,9 @@ static struct ubcore_ht_param g_ht_params[] = { [UBCORE_HT_JFC] = { UBCORE_HASH_TABLE_SIZE, offsetof(struct ubcore_jfc, hnode), offsetof(struct ubcore_jfc, id), sizeof(uint32_t), NULL, NULL }, + + [UBCORE_HT_JETTY] = { UBCORE_HASH_TABLE_SIZE, offsetof(struct ubcore_jetty, hnode), + offsetof(struct ubcore_jetty, id), sizeof(uint32_t), NULL, NULL }, }; static int ubcore_alloc_hash_tables(struct ubcore_device *dev) -- Gitee From 5c6b553bcde5c77bc456ef116c61913ea1ac4d91 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Wed, 13 Sep 2023 11:27:04 +0800 Subject: [PATCH 20/89] ub: add device attr feature, max jetty to query, and store in cdev driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Ubcore add device attr device_cap. In device_cap add feature, max jfc/jfr/jfs/jetty attributes. In uburma store the above-mentioned attributes in cdev. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/uburma/uburma_cdev_file.c | 65 +++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/drivers/ub/urma/uburma/uburma_cdev_file.c b/drivers/ub/urma/uburma/uburma_cdev_file.c index 12e773463acc..23e81e270a9f 100644 --- a/drivers/ub/urma/uburma/uburma_cdev_file.c +++ b/drivers/ub/urma/uburma/uburma_cdev_file.c @@ -159,6 +159,66 @@ static ssize_t guid_show(struct device *dev, struct device_attribute *attr, char static DEVICE_ATTR_RO(guid); +static ssize_t feature_show_cb(const struct ubcore_device *ubc_dev, char *buf) +{ + return snprintf(buf, UBURMA_MAX_VALUE_LEN, "0x%x\n", ubc_dev->attr.dev_cap.feature.value); +} + +static ssize_t feature_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + return uburma_show_dev_attr(dev, attr, buf, feature_show_cb); +} + +static DEVICE_ATTR_RO(feature); + +static ssize_t max_jfc_show_cb(const struct ubcore_device *ubc_dev, char *buf) +{ + return snprintf(buf, UBURMA_MAX_VALUE_LEN, "%u\n", ubc_dev->attr.dev_cap.max_jfc); +} + +static ssize_t max_jfc_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + return uburma_show_dev_attr(dev, attr, buf, max_jfc_show_cb); +} + +static DEVICE_ATTR_RO(max_jfc); + +static ssize_t max_jfs_show_cb(const struct ubcore_device *ubc_dev, char *buf) +{ + return snprintf(buf, UBURMA_MAX_VALUE_LEN, "%u\n", ubc_dev->attr.dev_cap.max_jfs); +} + +static ssize_t max_jfs_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + return uburma_show_dev_attr(dev, attr, buf, max_jfs_show_cb); +} + +static DEVICE_ATTR_RO(max_jfs); + +static ssize_t max_jfr_show_cb(const struct ubcore_device *ubc_dev, char *buf) +{ + return snprintf(buf, UBURMA_MAX_VALUE_LEN, "%u\n", ubc_dev->attr.dev_cap.max_jfr); +} + +static ssize_t max_jfr_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + return uburma_show_dev_attr(dev, attr, buf, max_jfr_show_cb); +} + +static DEVICE_ATTR_RO(max_jfr); + +static ssize_t max_jetty_show_cb(const struct ubcore_device *ubc_dev, char *buf) +{ + return snprintf(buf, UBURMA_MAX_VALUE_LEN, "%u\n", ubc_dev->attr.dev_cap.max_jetty); +} + +static ssize_t max_jetty_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + return uburma_show_dev_attr(dev, attr, buf, max_jetty_show_cb); +} + +static DEVICE_ATTR_RO(max_jetty); + static ssize_t transport_type_show_cb(const struct ubcore_device *ubc_dev, char *buf) { return snprintf(buf, UBURMA_MAX_VALUE_LEN, "%d\n", (int)ubc_dev->transport_type); @@ -190,6 +250,11 @@ static struct attribute *uburma_dev_attrs[] = { &dev_attr_ubdev.attr, &dev_attr_eid.attr, &dev_attr_guid.attr, + &dev_attr_feature.attr, + &dev_attr_max_jfc.attr, + &dev_attr_max_jfs.attr, + &dev_attr_max_jfr.attr, + &dev_attr_max_jetty.attr, &dev_attr_transport_type.attr, &dev_attr_driver_name.attr, NULL, -- Gitee From 555f201e7e6b8d04668907d7fc160ff303c9ff09 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Wed, 13 Sep 2023 11:35:12 +0800 Subject: [PATCH 21/89] ub: add jetty-related device attributes, and store in cdev driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Ubcore add jetty-related device attributes, including: - max_jfc_depth - max_jfs_depth - max_jfr_depth - max_jfs_inline_size - max_jfs_sge - max_jfs_rsge - max_jfr_sge - max_msg_size - max_rc_outstd_cnt In uburma store the above-mentioned attributes in cdev. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/uburma/uburma_cdev_file.c | 133 ++++++++++++++++++++++ 1 file changed, 133 insertions(+) diff --git a/drivers/ub/urma/uburma/uburma_cdev_file.c b/drivers/ub/urma/uburma/uburma_cdev_file.c index 23e81e270a9f..77a4f955b414 100644 --- a/drivers/ub/urma/uburma/uburma_cdev_file.c +++ b/drivers/ub/urma/uburma/uburma_cdev_file.c @@ -219,6 +219,129 @@ static ssize_t max_jetty_show(struct device *dev, struct device_attribute *attr, static DEVICE_ATTR_RO(max_jetty); +static ssize_t max_jfc_depth_show_cb(const struct ubcore_device *ubc_dev, char *buf) +{ + return snprintf(buf, UBURMA_MAX_VALUE_LEN, "%u\n", ubc_dev->attr.dev_cap.max_jfc_depth); +} + +static ssize_t max_jfc_depth_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + return uburma_show_dev_attr(dev, attr, buf, max_jfc_depth_show_cb); +} + +static DEVICE_ATTR_RO(max_jfc_depth); + +static ssize_t max_jfs_depth_show_cb(const struct ubcore_device *ubc_dev, char *buf) +{ + return snprintf(buf, UBURMA_MAX_VALUE_LEN, "%u\n", ubc_dev->attr.dev_cap.max_jfs_depth); +} + +static ssize_t max_jfs_depth_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + return uburma_show_dev_attr(dev, attr, buf, max_jfs_depth_show_cb); +} + +static DEVICE_ATTR_RO(max_jfs_depth); + +static ssize_t max_jfr_depth_show_cb(const struct ubcore_device *ubc_dev, char *buf) +{ + return snprintf(buf, UBURMA_MAX_VALUE_LEN, "%u\n", ubc_dev->attr.dev_cap.max_jfr_depth); +} + +static ssize_t max_jfr_depth_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + return uburma_show_dev_attr(dev, attr, buf, max_jfr_depth_show_cb); +} + +static DEVICE_ATTR_RO(max_jfr_depth); + +static ssize_t show_max_jfs_inline_size_cb(const struct ubcore_device *ubc_dev, char *buf) +{ + return snprintf(buf, UBURMA_MAX_VALUE_LEN, "%u\n", + ubc_dev->attr.dev_cap.max_jfs_inline_size); +} + +static ssize_t max_jfs_inline_size_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + return uburma_show_dev_attr(dev, attr, buf, show_max_jfs_inline_size_cb); +} + +static DEVICE_ATTR_RO(max_jfs_inline_size); + +static ssize_t max_jfs_sge_show_cb(const struct ubcore_device *ubc_dev, char *buf) +{ + return snprintf(buf, UBURMA_MAX_VALUE_LEN, "%u\n", ubc_dev->attr.dev_cap.max_jfs_sge); +} + +static ssize_t max_jfs_sge_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + return uburma_show_dev_attr(dev, attr, buf, max_jfs_sge_show_cb); +} + +static DEVICE_ATTR_RO(max_jfs_sge); + +static ssize_t max_jfs_rsge_show_cb(const struct ubcore_device *ubc_dev, char *buf) +{ + return snprintf(buf, UBURMA_MAX_VALUE_LEN, "%u\n", ubc_dev->attr.dev_cap.max_jfs_rsge); +} + +static ssize_t max_jfs_rsge_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + return uburma_show_dev_attr(dev, attr, buf, max_jfs_rsge_show_cb); +} + +static DEVICE_ATTR_RO(max_jfs_rsge); + +static ssize_t max_jfr_sge_show_cb(const struct ubcore_device *ubc_dev, char *buf) +{ + return snprintf(buf, UBURMA_MAX_VALUE_LEN, "%u\n", ubc_dev->attr.dev_cap.max_jfr_sge); +} + +static ssize_t max_jfr_sge_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + return uburma_show_dev_attr(dev, attr, buf, max_jfr_sge_show_cb); +} + +static DEVICE_ATTR_RO(max_jfr_sge); + +static ssize_t max_msg_size_show_cb(const struct ubcore_device *ubc_dev, char *buf) +{ + return snprintf(buf, UBURMA_MAX_VALUE_LEN, "%llu\n", ubc_dev->attr.dev_cap.max_msg_size); +} + +static ssize_t max_msg_size_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + return uburma_show_dev_attr(dev, attr, buf, max_msg_size_show_cb); +} + +static DEVICE_ATTR_RO(max_msg_size); + +static ssize_t max_rc_outstd_cnt_show_cb(const struct ubcore_device *ubc_dev, char *buf) +{ + return snprintf(buf, UBURMA_MAX_VALUE_LEN, "%llu\n", + ubc_dev->attr.dev_cap.max_rc_outstd_cnt); +} + +static ssize_t max_rc_outstd_cnt_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + return uburma_show_dev_attr(dev, attr, buf, max_rc_outstd_cnt_show_cb); +} + +static DEVICE_ATTR_RO(max_rc_outstd_cnt); + +static ssize_t trans_mode_show_cb(const struct ubcore_device *ubc_dev, char *buf) +{ + return snprintf(buf, UBURMA_MAX_VALUE_LEN, "%u\n", ubc_dev->attr.dev_cap.trans_mode); +} + +static ssize_t trans_mode_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + return uburma_show_dev_attr(dev, attr, buf, trans_mode_show_cb); +} + +static DEVICE_ATTR_RO(trans_mode); + static ssize_t transport_type_show_cb(const struct ubcore_device *ubc_dev, char *buf) { return snprintf(buf, UBURMA_MAX_VALUE_LEN, "%d\n", (int)ubc_dev->transport_type); @@ -255,6 +378,16 @@ static struct attribute *uburma_dev_attrs[] = { &dev_attr_max_jfs.attr, &dev_attr_max_jfr.attr, &dev_attr_max_jetty.attr, + &dev_attr_max_jfc_depth.attr, + &dev_attr_max_jfs_depth.attr, + &dev_attr_max_jfr_depth.attr, + &dev_attr_max_jfs_inline_size.attr, + &dev_attr_max_jfs_sge.attr, + &dev_attr_max_jfs_rsge.attr, + &dev_attr_max_jfr_sge.attr, + &dev_attr_max_msg_size.attr, + &dev_attr_max_rc_outstd_cnt.attr, + &dev_attr_trans_mode.attr, &dev_attr_transport_type.attr, &dev_attr_driver_name.attr, NULL, -- Gitee From 494ea63571de4244115986706e4957f653559ded Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Wed, 13 Sep 2023 15:31:11 +0800 Subject: [PATCH 22/89] ub: ubcore add query resources impl in ubcore_main driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Ubcore add query resources impl in ubcore_main to allow handle query resources cmd from user layer. The query_res command is used to query device-level resource usage, such as the number of created Jetty and VF UPI. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/ubcore/ubcore_cmd.h | 14 +++ drivers/ub/urma/ubcore/ubcore_main.c | 128 +++++++++++++++++++++++++++ 2 files changed, 142 insertions(+) diff --git a/drivers/ub/urma/ubcore/ubcore_cmd.h b/drivers/ub/urma/ubcore/ubcore_cmd.h index 51dbbb8aae76..1e4ab2f71290 100644 --- a/drivers/ub/urma/ubcore/ubcore_cmd.h +++ b/drivers/ub/urma/ubcore/ubcore_cmd.h @@ -81,6 +81,20 @@ struct ubcore_cmd_query_stats { } out; }; +struct ubcore_cmd_query_res { + struct { + char dev_name[UBCORE_MAX_DEV_NAME]; + uint8_t eid[UBCORE_CMD_EID_SIZE]; + uint32_t tp_type; + uint32_t type; + uint32_t key; + } in; + struct { + uint64_t addr; + uint32_t len; + } out; +}; + /* copy from user_space addr to kernel args */ static inline int ubcore_copy_from_user(void *args, const void *args_addr, unsigned long args_size) { diff --git a/drivers/ub/urma/ubcore/ubcore_main.c b/drivers/ub/urma/ubcore/ubcore_main.c index db1f82d62275..42de94f81df7 100644 --- a/drivers/ub/urma/ubcore/ubcore_main.c +++ b/drivers/ub/urma/ubcore/ubcore_main.c @@ -195,6 +195,132 @@ static int ubcore_cmd_query_stats(struct ubcore_cmd_hdr *hdr) sizeof(struct ubcore_cmd_query_stats)); } +static uint32_t ubcore_get_query_res_len(uint32_t type) +{ + return 0; +} + +static void ubcore_dealloc_res_dev(struct ubcore_res_dev_val *ubcore_addr) +{ +} + +static int ubcore_fill_res_addr(struct ubcore_res_dev_val *ubcore_addr) +{ + return 0; +} + +static int ubcore_fill_user_res_dev(struct ubcore_res_dev_val *dev_val, + struct ubcore_res_dev_val *ubcore_addr) +{ + return 0; +} + +static int ubcore_query_res_dev(const struct ubcore_device *dev, struct ubcore_res_key *key, + struct ubcore_res_dev_val *dev_val) +{ + struct ubcore_res_dev_val ubcore_addr = { 0 }; + struct ubcore_res_val val = { 0 }; + int ret = 0; + + (void)memcpy(&ubcore_addr, dev_val, + sizeof(struct ubcore_res_dev_val)); // save + + if (ubcore_fill_res_addr(&ubcore_addr) != 0) { + ubcore_log_err("Failed to fill dev dev_val.\n"); + return -ENOMEM; + } + + val.addr = (uint64_t)&ubcore_addr; + val.len = sizeof(struct ubcore_res_dev_val); + + ret = ubcore_query_resource(dev, key, &val); + if (ret != 0) + goto ubcore_free_dev; + + ret = ubcore_fill_user_res_dev(dev_val, &ubcore_addr); +ubcore_free_dev: + ubcore_dealloc_res_dev(&ubcore_addr); + return ret; +} + +static int ubcore_query_res_arg(const struct ubcore_device *dev, struct ubcore_cmd_query_res *arg, + uint32_t res_len) +{ + struct ubcore_res_key key = { 0 }; + struct ubcore_res_val val = { 0 }; + void *addr; + int ret; + + addr = kzalloc(res_len, GFP_KERNEL); + if (addr == NULL) + return -1; + + ret = ubcore_copy_from_user(addr, (void __user *)(uintptr_t)arg->out.addr, res_len); + if (ret != 0) + goto kfree_addr; + + key.type = (uint8_t)arg->in.type; + key.key = arg->in.key; + val.addr = (uint64_t)addr; + val.len = res_len; + + if (arg->in.type == UBCORE_RES_KEY_URMA_DEV) + ret = ubcore_query_res_dev(dev, &key, (struct ubcore_res_dev_val *)addr); + else + ret = ubcore_query_resource(dev, &key, &val); + + if (ret != 0) + goto kfree_addr; + + ret = ubcore_copy_to_user((void __user *)(uintptr_t)arg->out.addr, addr, res_len); + +kfree_addr: + kfree(addr); + return ret; +} + +static int ubcore_cmd_query_res(struct ubcore_cmd_hdr *hdr) +{ + enum ubcore_transport_type trans_type; + struct ubcore_cmd_query_res arg = { 0 }; + struct ubcore_device *dev; + union ubcore_eid eid; + uint32_t res_len; + int ret; + + ret = ubcore_copy_from_user(&arg, (void __user *)(uintptr_t)hdr->args_addr, + sizeof(struct ubcore_cmd_query_res)); + if (ret != 0) + return ret; + + res_len = ubcore_get_query_res_len((uint32_t)arg.in.type); + if (res_len != arg.out.len) { + ubcore_log_err("Failed to check res len, type: %u, res_len: %u, len: %u.\n", + (uint32_t)arg.in.type, res_len, arg.out.len); + return -1; + } + (void)memcpy(eid.raw, arg.in.eid, UBCORE_EID_SIZE); + trans_type = (enum ubcore_transport_type)arg.in.tp_type; + + dev = ubcore_find_device(&eid, trans_type); + if (dev == NULL || ubcore_check_dev_name_invalid(dev, arg.in.dev_name)) { + ubcore_log_err("find dev failed, dev:%s, arg_in: %s.\n", + dev == NULL ? "NULL" : dev->dev_name, arg.in.dev_name); + return -EINVAL; + } + + ret = ubcore_query_res_arg(dev, &arg, res_len); + if (ret != 0) { + ubcore_put_device(dev); + ubcore_log_err("Failed to query res by arg, tp_type: %d.\n", (int)trans_type); + return -1; + } + + ubcore_put_device(dev); + return ubcore_copy_to_user((void __user *)(uintptr_t)hdr->args_addr, &arg, + sizeof(struct ubcore_cmd_query_res)); +} + static int ubcore_cmd_parse(struct ubcore_cmd_hdr *hdr) { switch (hdr->command) { @@ -204,6 +330,8 @@ static int ubcore_cmd_parse(struct ubcore_cmd_hdr *hdr) return ubcore_cmd_put_uasid(hdr); case UBCORE_CMD_QUERY_STATS: return ubcore_cmd_query_stats(hdr); + case UBCORE_CMD_QUERY_RES: + return ubcore_cmd_query_res(hdr); default: ubcore_log_err("bad ubcore command: %d.\n", (int)hdr->command); return -EINVAL; -- Gitee From ae9e470857a2ff360712bb7c93cc3098826d840e Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Thu, 14 Sep 2023 21:33:57 +0800 Subject: [PATCH 23/89] ub: ubcore add query jetty resources impl in query_res driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Ubcore add query jetty resources impl in ubcore_cmd_query_res, including count of jfr/jfs/jetty. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/ubcore/ubcore_main.c | 100 +++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) diff --git a/drivers/ub/urma/ubcore/ubcore_main.c b/drivers/ub/urma/ubcore/ubcore_main.c index 42de94f81df7..9494a18207d1 100644 --- a/drivers/ub/urma/ubcore/ubcore_main.c +++ b/drivers/ub/urma/ubcore/ubcore_main.c @@ -197,21 +197,121 @@ static int ubcore_cmd_query_stats(struct ubcore_cmd_hdr *hdr) static uint32_t ubcore_get_query_res_len(uint32_t type) { + switch (type) { + case UBCORE_RES_KEY_JFS: + return (uint32_t)sizeof(struct ubcore_res_jfs_val); + case UBCORE_RES_KEY_JFR: + return (uint32_t)sizeof(struct ubcore_res_jfr_val); + case UBCORE_RES_KEY_JETTY: + return (uint32_t)sizeof(struct ubcore_res_jetty_val); + case UBCORE_RES_KEY_JETTY_GROUP: + return (uint32_t)sizeof(struct ubcore_res_jetty_group_val); + case UBCORE_RES_KEY_JFC: + return (uint32_t)sizeof(struct ubcore_res_jfc_val); + case UBCORE_RES_KEY_URMA_DEV: + return (uint32_t)sizeof(struct ubcore_res_dev_val); + default: + break; + } return 0; } static void ubcore_dealloc_res_dev(struct ubcore_res_dev_val *ubcore_addr) { + if (ubcore_addr->jfs_list != NULL) { + vfree(ubcore_addr->jfs_list); + ubcore_addr->jfs_list = NULL; + } + if (ubcore_addr->jfr_list != NULL) { + vfree(ubcore_addr->jfr_list); + ubcore_addr->jfr_list = NULL; + } + if (ubcore_addr->jfc_list != NULL) { + vfree(ubcore_addr->jfc_list); + ubcore_addr->jfc_list = NULL; + } + if (ubcore_addr->jetty_list != NULL) { + vfree(ubcore_addr->jetty_list); + ubcore_addr->jetty_list = NULL; + } + if (ubcore_addr->jetty_group_list != NULL) { + vfree(ubcore_addr->jetty_group_list); + ubcore_addr->jetty_group_list = NULL; + } } static int ubcore_fill_res_addr(struct ubcore_res_dev_val *ubcore_addr) { + ubcore_addr->jfs_list = vmalloc(sizeof(uint32_t) * ubcore_addr->jfs_cnt); + if (ubcore_addr->jfs_list == NULL) + goto free_seg_list; + + ubcore_addr->jfr_list = vmalloc(sizeof(uint32_t) * ubcore_addr->jfr_cnt); + if (ubcore_addr->jfr_list == NULL) + goto free_jfs_list; + + ubcore_addr->jfc_list = vmalloc(sizeof(uint32_t) * ubcore_addr->jfc_cnt); + if (ubcore_addr->jfc_list == NULL) + goto free_jfr_list; + + ubcore_addr->jetty_list = vmalloc(sizeof(uint32_t) * ubcore_addr->jetty_cnt); + if (ubcore_addr->jetty_list == NULL) + goto free_jfc_list; + + ubcore_addr->jetty_group_list = vmalloc(sizeof(uint32_t) * ubcore_addr->jetty_group_cnt); + if (ubcore_addr->jetty_group_list == NULL) + goto free_jetty_list; + return 0; +free_jetty_list: + vfree(ubcore_addr->jetty_list); +free_jfc_list: + vfree(ubcore_addr->jfc_list); +free_jfr_list: + vfree(ubcore_addr->jfr_list); +free_jfs_list: + vfree(ubcore_addr->jfs_list); +free_seg_list: + vfree(ubcore_addr->seg_list); + return -ENOMEM; } static int ubcore_fill_user_res_dev(struct ubcore_res_dev_val *dev_val, struct ubcore_res_dev_val *ubcore_addr) { + int ret; + + dev_val->jfs_cnt = ubcore_addr->jfs_cnt; + ret = ubcore_copy_to_user((void __user *)(uintptr_t)(uint64_t)dev_val->jfs_list, + ubcore_addr->jfs_list, dev_val->jfs_cnt * sizeof(uint32_t)); + if (ret != 0) + return ret; + + dev_val->jfr_cnt = ubcore_addr->jfr_cnt; + ret = ubcore_copy_to_user((void __user *)(uintptr_t)(uint64_t)dev_val->jfr_list, + ubcore_addr->jfr_list, dev_val->jfr_cnt * sizeof(uint32_t)); + if (ret != 0) + return ret; + + dev_val->jfc_cnt = ubcore_addr->jfc_cnt; + ret = ubcore_copy_to_user((void __user *)(uintptr_t)(uint64_t)dev_val->jfc_list, + ubcore_addr->jfc_list, dev_val->jfc_cnt * sizeof(uint32_t)); + if (ret != 0) + return ret; + + dev_val->jetty_cnt = ubcore_addr->jetty_cnt; + ret = ubcore_copy_to_user((void __user *)(uintptr_t)(uint64_t)dev_val->jetty_list, + ubcore_addr->jetty_list, dev_val->jetty_cnt * sizeof(uint32_t)); + if (ret != 0) + return ret; + + dev_val->jetty_group_cnt = ubcore_addr->jetty_group_cnt; + ret = ubcore_copy_to_user((void __user *)(uintptr_t)(uint64_t)dev_val->jetty_group_list, + ubcore_addr->jetty_group_list, + dev_val->jetty_group_cnt * sizeof(uint32_t)); + if (ret != 0) + return ret; + return 0; } -- Gitee From 55199be04ef6ef7ec1a4e79b0f5b00d51cdf140f Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Thu, 14 Sep 2023 21:50:30 +0800 Subject: [PATCH 24/89] ub: ubcore add create/modify/delete jfc api impls driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Ubcore add create/modify/delete jfc, which will finally call hw driver's registered method to create/modify/delete jfc. Create jfc will also add jfc in hash table to manage. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/ubcore/ubcore_jetty.c | 140 ++++++++++++++++++++++++++ drivers/ub/urma/ubcore/ubcore_priv.h | 5 + include/urma/ubcore_uapi.h | 28 ++++++ 3 files changed, 173 insertions(+) create mode 100644 drivers/ub/urma/ubcore/ubcore_jetty.c diff --git a/drivers/ub/urma/ubcore/ubcore_jetty.c b/drivers/ub/urma/ubcore/ubcore_jetty.c new file mode 100644 index 000000000000..998ac3e9e2a2 --- /dev/null +++ b/drivers/ub/urma/ubcore/ubcore_jetty.c @@ -0,0 +1,140 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + * + * Description: ubcore jetty kernel module + * Author: Ouyang Changchun + * Create: 2021-11-25 + * Note: + * History: 2021-11-25: create file + * History: 2022-07-28: Yan Fangfang move jetty implementation here + */ + +#include +#include +#include +#include +#include +#include "ubcore_log.h" +#include +#include +#include "ubcore_priv.h" + +static uint32_t ubcore_get_eq_id(const struct ubcore_device *dev) +{ + uint32_t eq_id = 0; + int cpu; + + if (dev->num_comp_vectors > 0) { + cpu = get_cpu(); + eq_id = (uint32_t)(cpu % dev->num_comp_vectors); + put_cpu(); + } + return eq_id; +} + +static int check_and_fill_jfc_attr(struct ubcore_jfc_cfg *cfg, const struct ubcore_jfc_cfg *user) +{ + if (cfg->depth < user->depth) + return -1; + + /* store the immutable and skip the driver updated depth */ + cfg->flag = user->flag; + cfg->jfc_context = user->jfc_context; + return 0; +} + +struct ubcore_jfc *ubcore_create_jfc(struct ubcore_device *dev, const struct ubcore_jfc_cfg *cfg, + ubcore_comp_callback_t jfce_handler, + ubcore_event_callback_t jfae_handler, + struct ubcore_udata *udata) +{ + struct ubcore_jfc *jfc; + uint32_t eq_id; + + if (dev == NULL || cfg == NULL || dev->ops->create_jfc == NULL || + dev->ops->destroy_jfc == NULL) + return NULL; + + eq_id = ubcore_get_eq_id(dev); + + ((struct ubcore_jfc_cfg *)cfg)->eq_id = eq_id; + jfc = dev->ops->create_jfc(dev, cfg, udata); + if (jfc == NULL) { + ubcore_log_err("failed to create jfc.\n"); + return NULL; + } + + if (check_and_fill_jfc_attr(&jfc->jfc_cfg, cfg) != 0) { + (void)dev->ops->destroy_jfc(jfc); + ubcore_log_err("jfc cfg is not qualified.\n"); + return NULL; + } + jfc->jfc_cfg.eq_id = eq_id; + jfc->jfce_handler = jfce_handler; + jfc->jfae_handler = jfae_handler; + jfc->ub_dev = dev; + jfc->uctx = ubcore_get_uctx(udata); + atomic_set(&jfc->use_cnt, 0); + + if (ubcore_hash_table_find_add(&dev->ht[UBCORE_HT_JFC], &jfc->hnode, jfc->id) != 0) { + (void)dev->ops->destroy_jfc(jfc); + ubcore_log_err("Failed to add jfc.\n"); + return NULL; + } + return jfc; +} +EXPORT_SYMBOL(ubcore_create_jfc); + +int ubcore_modify_jfc(struct ubcore_jfc *jfc, const struct ubcore_jfc_attr *attr, + struct ubcore_udata *udata) +{ + struct ubcore_device *dev; + uint32_t jfc_id; + int ret; + + if (jfc == NULL || jfc->ub_dev == NULL || jfc->ub_dev->ops->modify_jfc == NULL) + return -EINVAL; + + jfc_id = jfc->id; + dev = jfc->ub_dev; + + ret = dev->ops->modify_jfc(jfc, attr, udata); + if (ret < 0) + ubcore_log_err("UBEP failed to modify jfc, jfc_id:%u.\n", jfc_id); + + return ret; +} +EXPORT_SYMBOL(ubcore_modify_jfc); + +int ubcore_delete_jfc(struct ubcore_jfc *jfc) +{ + struct ubcore_device *dev; + uint32_t jfc_id; + int ret; + + if (jfc == NULL || jfc->ub_dev == NULL || jfc->ub_dev->ops->destroy_jfc == NULL) + return -1; + + if (WARN_ON_ONCE(atomic_read(&jfc->use_cnt))) + return -EBUSY; + + jfc_id = jfc->id; + dev = jfc->ub_dev; + ubcore_hash_table_remove(&dev->ht[UBCORE_HT_JFC], &jfc->hnode); + ret = dev->ops->destroy_jfc(jfc); + if (ret < 0) + ubcore_log_err("UBEP failed to destroy jfc, jfc_id:%u.\n", jfc_id); + + return ret; +} +EXPORT_SYMBOL(ubcore_delete_jfc); diff --git a/drivers/ub/urma/ubcore/ubcore_priv.h b/drivers/ub/urma/ubcore/ubcore_priv.h index 28c78d000cb0..6c507e9602c5 100644 --- a/drivers/ub/urma/ubcore/ubcore_priv.h +++ b/drivers/ub/urma/ubcore/ubcore_priv.h @@ -24,6 +24,11 @@ #include #include +static inline struct ubcore_ucontext *ubcore_get_uctx(struct ubcore_udata *udata) +{ + return udata == NULL ? NULL : udata->uctx; +} + static inline bool ubcore_check_dev_name_invalid(struct ubcore_device *dev, char *dev_name) { return (strcmp(dev->dev_name, dev_name) != 0); diff --git a/include/urma/ubcore_uapi.h b/include/urma/ubcore_uapi.h index 5afc5a398d41..dadecd6b7311 100644 --- a/include/urma/ubcore_uapi.h +++ b/include/urma/ubcore_uapi.h @@ -136,5 +136,33 @@ int ubcore_register_client(struct ubcore_client *new_client); * @param[in] rm_client: ubcore client to be unregistered */ void ubcore_unregister_client(struct ubcore_client *rm_client); +/** + * create jfc with ubcore device. + * @param[in] dev: the ubcore device handle; + * @param[in] cfg: jfc attributes and configurations + * @param[in] jfce_handler (optional): completion event handler + * @param[in] jfae_handler (optional): jfc async_event handler + * @param[in] udata (optional): ucontext and user space driver data + * @return: jfc pointer on success, NULL on error + */ +struct ubcore_jfc *ubcore_create_jfc(struct ubcore_device *dev, const struct ubcore_jfc_cfg *cfg, + ubcore_comp_callback_t jfce_handler, + ubcore_event_callback_t jfae_handler, + struct ubcore_udata *udata); +/** + * modify jfc from ubcore device. + * @param[in] jfc: the jfc created before; + * @param[in] attr: ubcore jfc attributes; + * @param[in] udata (optional): ucontext and user space driver data + * @return: 0 on success, other value on error + */ +int ubcore_modify_jfc(struct ubcore_jfc *jfc, const struct ubcore_jfc_attr *attr, + struct ubcore_udata *udata); +/** + * destroy jfc from ubcore device. + * @param[in] jfc: the jfc created before; + * @return: 0 on success, other value on error + */ +int ubcore_delete_jfc(struct ubcore_jfc *jfc); #endif -- Gitee From 9932ae1af0ad6c136effdbd800029aaf0472f0c5 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Thu, 14 Sep 2023 22:00:17 +0800 Subject: [PATCH 25/89] ub: ubcore add create/delete jfs api impls driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Ubcore add create/delete jfs, which will finally call hw driver's registered method to create/delete jfs. Create jfs will also add jfs in hash table to manage. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/ubcore/ubcore_jetty.c | 88 +++++++++++++++++++++++++++ include/urma/ubcore_uapi.h | 18 ++++++ 2 files changed, 106 insertions(+) diff --git a/drivers/ub/urma/ubcore/ubcore_jetty.c b/drivers/ub/urma/ubcore/ubcore_jetty.c index 998ac3e9e2a2..a4e417a8a187 100644 --- a/drivers/ub/urma/ubcore/ubcore_jetty.c +++ b/drivers/ub/urma/ubcore/ubcore_jetty.c @@ -138,3 +138,91 @@ int ubcore_delete_jfc(struct ubcore_jfc *jfc) return ret; } EXPORT_SYMBOL(ubcore_delete_jfc); + +static int check_and_fill_jfs_attr(struct ubcore_jfs_cfg *cfg, const struct ubcore_jfs_cfg *user) +{ + if (cfg->depth < user->depth || cfg->max_sge < user->max_sge || + cfg->max_rsge < user->max_rsge || cfg->max_inline_data < user->max_inline_data) + return -1; + + /* store the immutable and skip the driver updated attributes including depth, + * max_sge and max_inline_data + */ + cfg->flag = user->flag; + cfg->priority = user->priority; + cfg->retry_cnt = user->retry_cnt; + cfg->rnr_retry = user->rnr_retry; + cfg->err_timeout = user->err_timeout; + cfg->trans_mode = user->trans_mode; + cfg->jfs_context = user->jfs_context; + cfg->jfc = user->jfc; + return 0; +} + +struct ubcore_jfs *ubcore_create_jfs(struct ubcore_device *dev, const struct ubcore_jfs_cfg *cfg, + ubcore_event_callback_t jfae_handler, + struct ubcore_udata *udata) +{ + struct ubcore_jfs *jfs; + + if (dev == NULL || cfg == NULL || dev->ops->create_jfs == NULL || + dev->ops->destroy_jfs == NULL) + return NULL; + + if (((uint16_t)cfg->trans_mode & dev->attr.dev_cap.trans_mode) == 0) { + ubcore_log_err("jfs cfg is not supported.\n"); + return NULL; + } + + jfs = dev->ops->create_jfs(dev, cfg, udata); + if (jfs == NULL) { + ubcore_log_err("failed to create jfs.\n"); + return NULL; + } + + /* Prevent ubcore private data from being modified */ + if (check_and_fill_jfs_attr(&jfs->jfs_cfg, cfg) != 0) { + (void)dev->ops->destroy_jfs(jfs); + ubcore_log_err("jfs cfg is not qualified.\n"); + return NULL; + } + jfs->ub_dev = dev; + jfs->uctx = ubcore_get_uctx(udata); + jfs->jfae_handler = jfae_handler; + + atomic_set(&jfs->use_cnt, 0); + + if (ubcore_hash_table_find_add(&dev->ht[UBCORE_HT_JFS], &jfs->hnode, jfs->id) != 0) { + (void)dev->ops->destroy_jfs(jfs); + ubcore_log_err("Failed to add jfs.\n"); + return NULL; + } + + atomic_inc(&cfg->jfc->use_cnt); + return jfs; +} +EXPORT_SYMBOL(ubcore_create_jfs); + +int ubcore_delete_jfs(struct ubcore_jfs *jfs) +{ + struct ubcore_device *dev; + struct ubcore_jfc *jfc; + uint32_t jfs_id; + int ret; + + if (jfs == NULL || jfs->ub_dev == NULL || jfs->ub_dev->ops->destroy_jfs == NULL) + return -EINVAL; + + jfc = jfs->jfs_cfg.jfc; + jfs_id = jfs->id; + dev = jfs->ub_dev; + ubcore_hash_table_remove(&dev->ht[UBCORE_HT_JFS], &jfs->hnode); + ret = dev->ops->destroy_jfs(jfs); + if (ret < 0) + ubcore_log_err("UBEP failed to destroy jfs, jfs_id:%u.\n", jfs_id); + else + atomic_dec(&jfc->use_cnt); + + return ret; +} +EXPORT_SYMBOL(ubcore_delete_jfs); diff --git a/include/urma/ubcore_uapi.h b/include/urma/ubcore_uapi.h index dadecd6b7311..ef6f303990ad 100644 --- a/include/urma/ubcore_uapi.h +++ b/include/urma/ubcore_uapi.h @@ -164,5 +164,23 @@ int ubcore_modify_jfc(struct ubcore_jfc *jfc, const struct ubcore_jfc_attr *attr * @return: 0 on success, other value on error */ int ubcore_delete_jfc(struct ubcore_jfc *jfc); +/** + * create jfs with ubcore device. + * @param[in] dev: the ubcore device handle; + * @param[in] cfg: jfs configurations + * @param[in] jfae_handler (optional): jfs async_event handler + * @param[in] udata (optional): ucontext and user space driver data + * @return: jfs pointer on success, NULL on error + */ +struct ubcore_jfs *ubcore_create_jfs(struct ubcore_device *dev, const struct ubcore_jfs_cfg *cfg, + ubcore_event_callback_t jfae_handler, + struct ubcore_udata *udata); + +/** + * destroy jfs from ubcore device. + * @param[in] jfs: the jfs created before; + * @return: 0 on success, other value on error + */ +int ubcore_delete_jfs(struct ubcore_jfs *jfs); #endif -- Gitee From 7160dc4e3e8d2f781788897291f265cbb8ac6cf2 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Fri, 15 Sep 2023 10:26:54 +0800 Subject: [PATCH 26/89] ub: ubcore add query/modify/flush jfs api impls driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Ubcore add query/modify/flush jfs, which will finally call hw driver's registered method to query/modify/flush jfs. ubcore_query_jfs: query jfs from ubcore device. ubcore_modify_jfs: modify jfs attr from ubcore device. ubcore_flush_jfs: return the wrs in JFS that is not consumed to the application through cr. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/ubcore/ubcore_jetty.c | 55 +++++++++++++++++++++++++++ include/urma/ubcore_uapi.h | 28 +++++++++++++- 2 files changed, 82 insertions(+), 1 deletion(-) diff --git a/drivers/ub/urma/ubcore/ubcore_jetty.c b/drivers/ub/urma/ubcore/ubcore_jetty.c index a4e417a8a187..db333f0ca5c0 100644 --- a/drivers/ub/urma/ubcore/ubcore_jetty.c +++ b/drivers/ub/urma/ubcore/ubcore_jetty.c @@ -203,6 +203,46 @@ struct ubcore_jfs *ubcore_create_jfs(struct ubcore_device *dev, const struct ubc } EXPORT_SYMBOL(ubcore_create_jfs); +int ubcore_modify_jfs(struct ubcore_jfs *jfs, const struct ubcore_jfs_attr *attr, + struct ubcore_udata *udata) +{ + struct ubcore_device *dev; + uint32_t jfs_id; + int ret; + + if (jfs == NULL || jfs->ub_dev == NULL || jfs->ub_dev->ops->modify_jfs == NULL) + return -EINVAL; + + jfs_id = jfs->id; + dev = jfs->ub_dev; + ret = dev->ops->modify_jfs(jfs, attr, udata); + if (ret < 0) + ubcore_log_err("UBEP failed to modify jfs, jfs_id:%u.\n", jfs_id); + + return ret; +} +EXPORT_SYMBOL(ubcore_modify_jfs); + +int ubcore_query_jfs(struct ubcore_jfs *jfs, struct ubcore_jfs_cfg *cfg, + struct ubcore_jfs_attr *attr) +{ + struct ubcore_device *dev; + uint32_t jfs_id; + int ret; + + if (jfs == NULL || jfs->ub_dev == NULL || jfs->ub_dev->ops->query_jfs == NULL) + return -EINVAL; + + jfs_id = jfs->id; + dev = jfs->ub_dev; + ret = dev->ops->query_jfs(jfs, cfg, attr); + if (ret < 0) + ubcore_log_err("UBEP failed to query jfs, jfs_id:%u.\n", jfs_id); + + return ret; +} +EXPORT_SYMBOL(ubcore_query_jfs); + int ubcore_delete_jfs(struct ubcore_jfs *jfs) { struct ubcore_device *dev; @@ -226,3 +266,18 @@ int ubcore_delete_jfs(struct ubcore_jfs *jfs) return ret; } EXPORT_SYMBOL(ubcore_delete_jfs); + +int ubcore_flush_jfs(struct ubcore_jfs *jfs, int cr_cnt, struct ubcore_cr *cr) +{ + struct ubcore_ops *dev_ops; + + if (jfs == NULL || jfs->ub_dev == NULL || jfs->ub_dev->ops == NULL || + jfs->ub_dev->ops->flush_jfs == NULL || cr == NULL) { + ubcore_log_err("Invalid parameter"); + return -EINVAL; + } + + dev_ops = jfs->ub_dev->ops; + return dev_ops->flush_jfs(jfs, cr_cnt, cr); +} +EXPORT_SYMBOL(ubcore_flush_jfs); diff --git a/include/urma/ubcore_uapi.h b/include/urma/ubcore_uapi.h index ef6f303990ad..5f6c4c9e242b 100644 --- a/include/urma/ubcore_uapi.h +++ b/include/urma/ubcore_uapi.h @@ -175,12 +175,38 @@ int ubcore_delete_jfc(struct ubcore_jfc *jfc); struct ubcore_jfs *ubcore_create_jfs(struct ubcore_device *dev, const struct ubcore_jfs_cfg *cfg, ubcore_event_callback_t jfae_handler, struct ubcore_udata *udata); - +/** + * modify jfs from ubcore device. + * @param[in] jfs: the jfs created before; + * @param[in] attr: ubcore jfs attributes; + * @param[in] udata (optional): ucontext and user space driver data + * @return: 0 on success, other value on error + */ +int ubcore_modify_jfs(struct ubcore_jfs *jfs, const struct ubcore_jfs_attr *attr, + struct ubcore_udata *udata); +/** + * query jfs from ubcore device. + * @param[in] jfs: the jfs created before; + * @param[out] cfg: jfs configurations; + * @param[out] attr: ubcore jfs attributes; + * @return: 0 on success, other value on error + */ +int ubcore_query_jfs(struct ubcore_jfs *jfs, struct ubcore_jfs_cfg *cfg, + struct ubcore_jfs_attr *attr); /** * destroy jfs from ubcore device. * @param[in] jfs: the jfs created before; * @return: 0 on success, other value on error */ int ubcore_delete_jfs(struct ubcore_jfs *jfs); +/** + * return the wrs in JFS that is not consumed to the application through cr. + * @param[in] jfs: the jfs created before; + * @param[in] cr_cnt: the maximum number of CRs expected to be returned; + * @param[out] cr: the addr of returned CRs; + * @return: the number of completion record returned, 0 means no completion record returned, + * -1 on error + */ +int ubcore_flush_jfs(struct ubcore_jfs *jfs, int cr_cnt, struct ubcore_cr *cr); #endif -- Gitee From 48e761d3c2d92011baa5512c1b5ee13c84f14aac Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Fri, 15 Sep 2023 10:35:34 +0800 Subject: [PATCH 27/89] ub: ubcore add create/query/modify/delete jfr api impls driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Ubcore add create/query/modify/delete jfr, which will finally call hw driver's registered method to create/query/modify/delete jfr. Create jfr will also add jfr in hash table to manage. ubcore_query_jfr: query jfr from ubcore device. ubcore_modify_jfr: modify jfr attr from ubcore device. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/ubcore/ubcore_jetty.c | 121 ++++++++++++++++++++++++++ include/urma/ubcore_uapi.h | 36 +++++++- 2 files changed, 156 insertions(+), 1 deletion(-) diff --git a/drivers/ub/urma/ubcore/ubcore_jetty.c b/drivers/ub/urma/ubcore/ubcore_jetty.c index db333f0ca5c0..30dfe19b74e5 100644 --- a/drivers/ub/urma/ubcore/ubcore_jetty.c +++ b/drivers/ub/urma/ubcore/ubcore_jetty.c @@ -281,3 +281,124 @@ int ubcore_flush_jfs(struct ubcore_jfs *jfs, int cr_cnt, struct ubcore_cr *cr) return dev_ops->flush_jfs(jfs, cr_cnt, cr); } EXPORT_SYMBOL(ubcore_flush_jfs); + +static int check_and_fill_jfr_attr(struct ubcore_jfr_cfg *cfg, const struct ubcore_jfr_cfg *user) +{ + if (cfg->depth < user->depth || cfg->max_sge < user->max_sge) + return -1; + + /* store the immutable and skip the driver updated attributes including depth, max_sge */ + cfg->flag = user->flag; + cfg->min_rnr_timer = user->min_rnr_timer; + cfg->trans_mode = user->trans_mode; + cfg->ukey = user->ukey; + cfg->jfr_context = user->jfr_context; + cfg->jfc = user->jfc; + return 0; +} + +struct ubcore_jfr *ubcore_create_jfr(struct ubcore_device *dev, const struct ubcore_jfr_cfg *cfg, + ubcore_event_callback_t jfae_handler, + struct ubcore_udata *udata) +{ + struct ubcore_jfr *jfr; + + if (dev == NULL || cfg == NULL || dev->ops->create_jfr == NULL || + dev->ops->destroy_jfr == NULL) + return NULL; + + jfr = dev->ops->create_jfr(dev, cfg, udata); + if (jfr == NULL) { + ubcore_log_err("failed to create jfr.\n"); + return NULL; + } + + if (check_and_fill_jfr_attr(&jfr->jfr_cfg, cfg) != 0) { + ubcore_log_err("jfr cfg is not qualified.\n"); + (void)dev->ops->destroy_jfr(jfr); + return NULL; + } + jfr->ub_dev = dev; + jfr->uctx = ubcore_get_uctx(udata); + jfr->jfae_handler = jfae_handler; + if (ubcore_jfr_need_advise(jfr)) { + jfr->tptable = ubcore_create_tptable(); + if (jfr->tptable == NULL) { + (void)dev->ops->destroy_jfr(jfr); + ubcore_log_err("Failed to create tp table in the jfr.\n"); + return NULL; + } + } + atomic_set(&jfr->use_cnt, 0); + + atomic_inc(&cfg->jfc->use_cnt); + return jfr; +} +EXPORT_SYMBOL(ubcore_create_jfr); + +int ubcore_modify_jfr(struct ubcore_jfr *jfr, const struct ubcore_jfr_attr *attr, + struct ubcore_udata *udata) +{ + struct ubcore_device *dev; + uint32_t jfr_id; + int ret; + + if (jfr == NULL || jfr->ub_dev == NULL || jfr->ub_dev->ops->modify_jfr == NULL) + return -EINVAL; + + jfr_id = jfr->id; + dev = jfr->ub_dev; + ret = dev->ops->modify_jfr(jfr, attr, udata); + if (ret < 0) + ubcore_log_err("UBEP failed to modify jfr, jfr_id:%u.\n", jfr_id); + + return ret; +} +EXPORT_SYMBOL(ubcore_modify_jfr); + +int ubcore_query_jfr(struct ubcore_jfr *jfr, struct ubcore_jfr_cfg *cfg, + struct ubcore_jfr_attr *attr) +{ + struct ubcore_device *dev; + uint32_t jfr_id; + int ret; + + if (jfr == NULL || jfr->ub_dev == NULL || jfr->ub_dev->ops->query_jfr == NULL) + return -EINVAL; + + jfr_id = jfr->id; + dev = jfr->ub_dev; + ret = dev->ops->query_jfr(jfr, cfg, attr); + if (ret < 0) + ubcore_log_err("UBEP failed to query jfr, jfr_id:%u.\n", jfr_id); + + return ret; +} +EXPORT_SYMBOL(ubcore_query_jfr); + +int ubcore_delete_jfr(struct ubcore_jfr *jfr) +{ + struct ubcore_device *dev; + struct ubcore_jfc *jfc; + uint32_t jfr_id; + int ret; + + if (jfr == NULL || jfr->ub_dev == NULL || jfr->ub_dev->ops->destroy_jfr == NULL) + return -EINVAL; + + if (WARN_ON_ONCE(atomic_read(&jfr->use_cnt))) + return -EBUSY; + + jfc = jfr->jfr_cfg.jfc; + jfr_id = jfr->id; + dev = jfr->ub_dev; + ubcore_hash_table_remove(&dev->ht[UBCORE_HT_JFR], &jfr->hnode); + ret = dev->ops->destroy_jfr(jfr); + if (ret < 0) + ubcore_log_err("UBEP failed to destroy jfr, jfr_id:%u.\n", jfr_id); + else + atomic_dec(&jfc->use_cnt); + + return ret; +} +EXPORT_SYMBOL(ubcore_delete_jfr); diff --git a/include/urma/ubcore_uapi.h b/include/urma/ubcore_uapi.h index 5f6c4c9e242b..bb10b2255d65 100644 --- a/include/urma/ubcore_uapi.h +++ b/include/urma/ubcore_uapi.h @@ -208,5 +208,39 @@ int ubcore_delete_jfs(struct ubcore_jfs *jfs); * -1 on error */ int ubcore_flush_jfs(struct ubcore_jfs *jfs, int cr_cnt, struct ubcore_cr *cr); - +/** + * create jfr with ubcore device. + * @param[in] dev: the ubcore device handle; + * @param[in] cfg: jfr configurations + * @param[in] jfae_handler (optional): jfr async_event handler + * @param[in] udata (optional): ucontext and user space driver data + * @return: jfr pointer on success, NULL on error + */ +struct ubcore_jfr *ubcore_create_jfr(struct ubcore_device *dev, const struct ubcore_jfr_cfg *cfg, + ubcore_event_callback_t jfae_handler, + struct ubcore_udata *udata); +/** + * modify jfr from ubcore device. + * @param[in] jfr: the jfr created before; + * @param[in] attr: ubcore jfr attr; + * @param[in] udata (optional): ucontext and user space driver data + * @return: 0 on success, other value on error + */ +int ubcore_modify_jfr(struct ubcore_jfr *jfr, const struct ubcore_jfr_attr *attr, + struct ubcore_udata *udata); +/** + * query jfr from ubcore device. + * @param[in] jfr: the jfr created before; + * @param[out] cfg: jfr configurations; + * @param[out] attr: ubcore jfr attributes; + * @return: 0 on success, other value on error + */ +int ubcore_query_jfr(struct ubcore_jfr *jfr, struct ubcore_jfr_cfg *cfg, + struct ubcore_jfr_attr *attr); +/** + * destroy jfr from ubcore device. + * @param[in] jfr: the jfr created before; + * @return: 0 on success, other value on error + */ +int ubcore_delete_jfr(struct ubcore_jfr *jfr); #endif -- Gitee From e74897977b5b31ac7dd66c4c013e7ac4290b2a81 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Fri, 15 Sep 2023 10:41:49 +0800 Subject: [PATCH 28/89] ub: ubcore add create/delete jetty api impls driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Ubcore add create/delete jetty, which will finally call hw driver's registered method to create/delete jetty. Create jetty will also add jetty in hash table to manage. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/ubcore/ubcore_jetty.c | 102 ++++++++++++++++++++++++++ include/urma/ubcore_uapi.h | 18 +++++ 2 files changed, 120 insertions(+) diff --git a/drivers/ub/urma/ubcore/ubcore_jetty.c b/drivers/ub/urma/ubcore/ubcore_jetty.c index 30dfe19b74e5..fa30235f6860 100644 --- a/drivers/ub/urma/ubcore/ubcore_jetty.c +++ b/drivers/ub/urma/ubcore/ubcore_jetty.c @@ -402,3 +402,105 @@ int ubcore_delete_jfr(struct ubcore_jfr *jfr) return ret; } EXPORT_SYMBOL(ubcore_delete_jfr); + +static int check_and_fill_jetty_attr(struct ubcore_jetty_cfg *cfg, + const struct ubcore_jetty_cfg *user) +{ + if (cfg->jfs_depth < user->jfs_depth || cfg->max_send_sge < user->max_send_sge || + cfg->max_send_rsge < user->max_send_rsge || + cfg->max_inline_data < user->max_inline_data) { + ubcore_log_err("send attributes are not qualified.\n"); + return -1; + } + if (cfg->jfr_depth < user->jfr_depth || cfg->max_recv_sge < user->max_recv_sge) { + ubcore_log_err("recv attributes are not qualified.\n"); + return -1; + } + /* store the immutable and skip the driver updated send and recv attributes */ + cfg->flag = user->flag; + cfg->send_jfc = user->send_jfc; + cfg->recv_jfc = user->recv_jfc; + cfg->jfr = user->jfr; + cfg->priority = user->priority; + cfg->retry_cnt = user->retry_cnt; + cfg->rnr_retry = user->rnr_retry; + cfg->err_timeout = user->err_timeout; + cfg->min_rnr_timer = user->min_rnr_timer; + cfg->trans_mode = user->trans_mode; + cfg->jetty_context = user->jetty_context; + cfg->ukey = user->ukey; + return 0; +} + +struct ubcore_jetty *ubcore_create_jetty(struct ubcore_device *dev, + const struct ubcore_jetty_cfg *cfg, + ubcore_event_callback_t jfae_handler, + struct ubcore_udata *udata) +{ + struct ubcore_jetty *jetty; + + if (dev == NULL || cfg == NULL || dev->ops->create_jetty == NULL || + dev->ops->destroy_jetty == NULL) + return NULL; + + jetty = dev->ops->create_jetty(dev, cfg, udata); + if (jetty == NULL) { + ubcore_log_err("failed to create jetty.\n"); + return NULL; + } + if (check_and_fill_jetty_attr(&jetty->jetty_cfg, cfg) != 0) { + ubcore_log_err("jetty cfg is not qualified.\n"); + (void)dev->ops->destroy_jetty(jetty); + return NULL; + } + jetty->ub_dev = dev; + jetty->uctx = ubcore_get_uctx(udata); + jetty->jfae_handler = jfae_handler; + atomic_set(&jetty->use_cnt, 0); + + if (ubcore_hash_table_find_add(&dev->ht[UBCORE_HT_JETTY], &jetty->hnode, jetty->id) != 0) { + ubcore_destroy_tptable(&jetty->tptable); + (void)dev->ops->destroy_jetty(jetty); + ubcore_log_err("Failed to add jetty.\n"); + } + + atomic_inc(&cfg->send_jfc->use_cnt); + atomic_inc(&cfg->recv_jfc->use_cnt); + if (cfg->jfr) + atomic_inc(&cfg->jfr->use_cnt); + return jetty; +} +EXPORT_SYMBOL(ubcore_create_jetty); + +int ubcore_delete_jetty(struct ubcore_jetty *jetty) +{ + struct ubcore_jfc *send_jfc; + struct ubcore_jfc *recv_jfc; + struct ubcore_device *dev; + struct ubcore_jfr *jfr; + uint32_t jetty_id; + int ret; + + if (jetty == NULL || jetty->ub_dev == NULL || jetty->ub_dev->ops->destroy_jetty == NULL) + return -1; + + send_jfc = jetty->jetty_cfg.send_jfc; + recv_jfc = jetty->jetty_cfg.recv_jfc; + jfr = jetty->jetty_cfg.jfr; + jetty_id = jetty->id; + dev = jetty->ub_dev; + ubcore_hash_table_remove(&dev->ht[UBCORE_HT_JETTY], &jetty->hnode); + ret = dev->ops->destroy_jetty(jetty); + if (ret < 0) { + ubcore_log_err("UBEP failed to destroy jetty, jetty_id:%u.\n", jetty_id); + } else { + if (send_jfc) + atomic_dec(&send_jfc->use_cnt); + if (recv_jfc) + atomic_dec(&recv_jfc->use_cnt); + if (jfr) + atomic_dec(&jfr->use_cnt); + } + return ret; +} +EXPORT_SYMBOL(ubcore_delete_jetty); diff --git a/include/urma/ubcore_uapi.h b/include/urma/ubcore_uapi.h index bb10b2255d65..f12c494a0b32 100644 --- a/include/urma/ubcore_uapi.h +++ b/include/urma/ubcore_uapi.h @@ -243,4 +243,22 @@ int ubcore_query_jfr(struct ubcore_jfr *jfr, struct ubcore_jfr_cfg *cfg, * @return: 0 on success, other value on error */ int ubcore_delete_jfr(struct ubcore_jfr *jfr); +/** + * create jetty with ubcore device. + * @param[in] dev: the ubcore device handle; + * @param[in] cfg: jetty attributes and configurations + * @param[in] jfae_handler (optional): jetty async_event handler + * @param[in] udata (optional): ucontext and user space driver data + * @return: jetty pointer on success, NULL on error + */ +struct ubcore_jetty *ubcore_create_jetty(struct ubcore_device *dev, + const struct ubcore_jetty_cfg *cfg, + ubcore_event_callback_t jfae_handler, + struct ubcore_udata *udata); +/** + * destroy jetty from ubcore device. + * @param[in] jetty: the jetty created before; + * @return: 0 on success, other value on error + */ +int ubcore_delete_jetty(struct ubcore_jetty *jetty); #endif -- Gitee From abe26f8443dc6650a518f7ceeafc29ec433f96bb Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Fri, 15 Sep 2023 10:46:44 +0800 Subject: [PATCH 29/89] ub: ubcore add query/modify/flush jetty api impls driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Ubcore add query/modify/flush jetty, which will finally call hw driver's registered method to query/modify/flush jetty. ubcore_query_jetty: query jetty from ubcore device. ubcore_modify_jetty: modify jetty attr from ubcore device. ubcore_flush_jetty: return the wrs in jetty that is not consumed to the application through cr. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/ubcore/ubcore_jetty.c | 57 +++++++++++++++++++++++++++ include/urma/ubcore_uapi.h | 27 +++++++++++++ 2 files changed, 84 insertions(+) diff --git a/drivers/ub/urma/ubcore/ubcore_jetty.c b/drivers/ub/urma/ubcore/ubcore_jetty.c index fa30235f6860..35f4dc167859 100644 --- a/drivers/ub/urma/ubcore/ubcore_jetty.c +++ b/drivers/ub/urma/ubcore/ubcore_jetty.c @@ -472,6 +472,48 @@ struct ubcore_jetty *ubcore_create_jetty(struct ubcore_device *dev, } EXPORT_SYMBOL(ubcore_create_jetty); +int ubcore_modify_jetty(struct ubcore_jetty *jetty, const struct ubcore_jetty_attr *attr, + struct ubcore_udata *udata) +{ + struct ubcore_device *dev; + uint32_t jetty_id; + int ret; + + if (jetty == NULL || jetty->ub_dev == NULL || jetty->ub_dev->ops->modify_jetty == NULL || + attr == NULL) + return -EINVAL; + + jetty_id = jetty->id; + dev = jetty->ub_dev; + + ret = dev->ops->modify_jetty(jetty, attr, udata); + if (ret < 0) + ubcore_log_err("UBEP failed to modify jetty, jetty_id:%u.\n", jetty_id); + + return ret; +} +EXPORT_SYMBOL(ubcore_modify_jetty); + +int ubcore_query_jetty(struct ubcore_jetty *jetty, struct ubcore_jetty_cfg *cfg, + struct ubcore_jetty_attr *attr) +{ + struct ubcore_device *dev; + uint32_t jetty_id; + int ret; + + if (jetty == NULL || jetty->ub_dev == NULL || jetty->ub_dev->ops->query_jetty == NULL) + return -EINVAL; + + jetty_id = jetty->id; + dev = jetty->ub_dev; + ret = dev->ops->query_jetty(jetty, cfg, attr); + if (ret < 0) + ubcore_log_err("UBEP failed to query jetty, jetty_id:%u.\n", jetty_id); + + return ret; +} +EXPORT_SYMBOL(ubcore_query_jetty); + int ubcore_delete_jetty(struct ubcore_jetty *jetty) { struct ubcore_jfc *send_jfc; @@ -504,3 +546,18 @@ int ubcore_delete_jetty(struct ubcore_jetty *jetty) return ret; } EXPORT_SYMBOL(ubcore_delete_jetty); + +int ubcore_flush_jetty(struct ubcore_jetty *jetty, int cr_cnt, struct ubcore_cr *cr) +{ + struct ubcore_ops *dev_ops; + + if (jetty == NULL || jetty->ub_dev == NULL || jetty->ub_dev->ops == NULL || + jetty->ub_dev->ops->flush_jetty == NULL || cr == NULL) { + ubcore_log_err("Invalid parameter"); + return -EINVAL; + } + + dev_ops = jetty->ub_dev->ops; + return dev_ops->flush_jetty(jetty, cr_cnt, cr); +} +EXPORT_SYMBOL(ubcore_flush_jetty); diff --git a/include/urma/ubcore_uapi.h b/include/urma/ubcore_uapi.h index f12c494a0b32..06f1bb72702b 100644 --- a/include/urma/ubcore_uapi.h +++ b/include/urma/ubcore_uapi.h @@ -255,10 +255,37 @@ struct ubcore_jetty *ubcore_create_jetty(struct ubcore_device *dev, const struct ubcore_jetty_cfg *cfg, ubcore_event_callback_t jfae_handler, struct ubcore_udata *udata); +/** + * modify jetty attributes. + * @param[in] jetty: the jetty created before; + * @param[in] attr: ubcore jetty attributes; + * @param[in] udata (optional): ucontext and user space driver data + * @return: 0 on success, other value on error + */ +int ubcore_modify_jetty(struct ubcore_jetty *jetty, const struct ubcore_jetty_attr *attr, + struct ubcore_udata *udata); +/** + * query jetty from ubcore device. + * @param[in] jetty: the jetty created before; + * @param[out] cfg: jetty configurations; + * @param[out] attr: ubcore jetty attributes; + * @return: 0 on success, other value on error + */ +int ubcore_query_jetty(struct ubcore_jetty *jetty, struct ubcore_jetty_cfg *cfg, + struct ubcore_jetty_attr *attr); /** * destroy jetty from ubcore device. * @param[in] jetty: the jetty created before; * @return: 0 on success, other value on error */ int ubcore_delete_jetty(struct ubcore_jetty *jetty); +/** + * return the wrs in JETTY that is not consumed to the application through cr. + * @param[in] jetty: the jetty created before; + * @param[in] cr_cnt: the maximum number of CRs expected to be returned; + * @param[out] cr: the addr of returned CRs; + * @return: the number of completion record returned, 0 means no completion record returned, + * -1 on error + */ +int ubcore_flush_jetty(struct ubcore_jetty *jetty, int cr_cnt, struct ubcore_cr *cr); #endif -- Gitee From 29a8b942b8c021f24eb1eed0753b4fcbef9fbae5 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Fri, 15 Sep 2023 11:15:01 +0800 Subject: [PATCH 30/89] ub: ubcore add import/unimport jetty/jfr api impls driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Ubcore add import/unimport jetty/jfr, which will finally call hw driver's registered method to import/unimport jetty/jfr. ubcore_import_jetty/jfr: import remote jetty/jfr to local. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/ubcore/ubcore_jetty.c | 83 +++++++++++++++++++++++++++ include/urma/ubcore_uapi.h | 32 +++++++++++ 2 files changed, 115 insertions(+) diff --git a/drivers/ub/urma/ubcore/ubcore_jetty.c b/drivers/ub/urma/ubcore/ubcore_jetty.c index 35f4dc167859..5307770dc9c2 100644 --- a/drivers/ub/urma/ubcore/ubcore_jetty.c +++ b/drivers/ub/urma/ubcore/ubcore_jetty.c @@ -403,6 +403,47 @@ int ubcore_delete_jfr(struct ubcore_jfr *jfr) } EXPORT_SYMBOL(ubcore_delete_jfr); +struct ubcore_tjetty *ubcore_import_jfr(struct ubcore_device *dev, + const struct ubcore_tjetty_cfg *cfg, + struct ubcore_udata *udata) +{ + struct ubcore_tjetty *tjfr; + + if (dev == NULL || cfg == NULL || dev->ops->import_jfr == NULL || + dev->ops->unimport_jfr == NULL || !ubcore_have_tp_ops(dev)) + return NULL; + + tjfr = dev->ops->import_jfr(dev, cfg, udata); + if (tjfr == NULL) { + ubcore_log_err("UBEP failed to import jfr, jfr_id:%u.\n", cfg->id.id); + return NULL; + } + tjfr->cfg = *cfg; + tjfr->ub_dev = dev; + tjfr->uctx = ubcore_get_uctx(udata); + tjfr->type = UBCORE_JFR; + atomic_set(&tjfr->use_cnt, 0); + + tjfr->tp = NULL; + + return tjfr; +} +EXPORT_SYMBOL(ubcore_import_jfr); + +int ubcore_unimport_jfr(struct ubcore_tjetty *tjfr) +{ + struct ubcore_device *dev; + + if (tjfr == NULL || tjfr->ub_dev == NULL || tjfr->ub_dev->ops->unimport_jfr == NULL || + !ubcore_have_tp_ops(tjfr->ub_dev)) + return -1; + + dev = tjfr->ub_dev; + + return dev->ops->unimport_jfr(tjfr); +} +EXPORT_SYMBOL(ubcore_unimport_jfr); + static int check_and_fill_jetty_attr(struct ubcore_jetty_cfg *cfg, const struct ubcore_jetty_cfg *user) { @@ -561,3 +602,45 @@ int ubcore_flush_jetty(struct ubcore_jetty *jetty, int cr_cnt, struct ubcore_cr return dev_ops->flush_jetty(jetty, cr_cnt, cr); } EXPORT_SYMBOL(ubcore_flush_jetty); + +struct ubcore_tjetty *ubcore_import_jetty(struct ubcore_device *dev, + const struct ubcore_tjetty_cfg *cfg, + struct ubcore_udata *udata) +{ + struct ubcore_tjetty *tjetty; + + if (dev == NULL || cfg == NULL || dev->ops->import_jetty == NULL || + dev->ops->unimport_jetty == NULL || !ubcore_have_tp_ops(dev)) + return NULL; + + tjetty = dev->ops->import_jetty(dev, cfg, udata); + if (tjetty == NULL) { + ubcore_log_err("UBEP failed to import jetty, jetty_id:%u.\n", cfg->id.id); + return NULL; + } + tjetty->cfg = *cfg; + tjetty->ub_dev = dev; + tjetty->uctx = ubcore_get_uctx(udata); + tjetty->type = UBCORE_JETTY; + atomic_set(&tjetty->use_cnt, 0); + + mutex_init(&tjetty->lock); + tjetty->tp = NULL; + + return tjetty; +} +EXPORT_SYMBOL(ubcore_import_jetty); + +int ubcore_unimport_jetty(struct ubcore_tjetty *tjetty) +{ + struct ubcore_device *dev; + + if (tjetty == NULL || tjetty->ub_dev == NULL || + tjetty->ub_dev->ops->unimport_jetty == NULL || !ubcore_have_tp_ops(tjetty->ub_dev)) + return -1; + + dev = tjetty->ub_dev; + + return dev->ops->unimport_jetty(tjetty); +} +EXPORT_SYMBOL(ubcore_unimport_jetty); diff --git a/include/urma/ubcore_uapi.h b/include/urma/ubcore_uapi.h index 06f1bb72702b..5bbd2b7bd683 100644 --- a/include/urma/ubcore_uapi.h +++ b/include/urma/ubcore_uapi.h @@ -288,4 +288,36 @@ int ubcore_delete_jetty(struct ubcore_jetty *jetty); * -1 on error */ int ubcore_flush_jetty(struct ubcore_jetty *jetty, int cr_cnt, struct ubcore_cr *cr); +/** + * import jfr to ubcore device. + * @param[in] dev: the ubcore device handle; + * @param[in] cfg: remote jfr attributes and import configurations + * @param[in] udata (optional): ucontext and user space driver data + * @return: target jfr pointer on success, NULL on error + */ +struct ubcore_tjetty *ubcore_import_jfr(struct ubcore_device *dev, + const struct ubcore_tjetty_cfg *cfg, + struct ubcore_udata *udata); +/** + * unimport jfr from ubcore device. + * @param[in] tjfr: the target jfr imported before; + * @return: 0 on success, other value on error + */ +int ubcore_unimport_jfr(struct ubcore_tjetty *tjfr); +/** + * import jetty to ubcore device. + * @param[in] dev: the ubcore device handle; + * @param[in] cfg: remote jetty attributes and import configurations + * @param[in] udata (optional): ucontext and user space driver data + * @return: target jetty pointer on success, NULL on error + */ +struct ubcore_tjetty *ubcore_import_jetty(struct ubcore_device *dev, + const struct ubcore_tjetty_cfg *cfg, + struct ubcore_udata *udata); +/** + * unimport jetty from ubcore device. + * @param[in] tjetty: the target jetty imported before; + * @return: 0 on success, other value on error + */ +int ubcore_unimport_jetty(struct ubcore_tjetty *tjetty); #endif -- Gitee From f0db14113534c66dd2bbb961353134aa72032354 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Fri, 15 Sep 2023 14:50:26 +0800 Subject: [PATCH 31/89] ub: ubcore add find jetty/jfr/jfs/jfc and user ctl api impls driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Ubcore add find jetty/jfr, and user ctl api, which will finally call hw driver's registered method. ubcore_find_jetty/jfr: find jetty/jfr/jfs/jfc in hashtable. ubcore_user_control: handle operation of user ioctl cmd. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/ubcore/ubcore_device.c | 26 ++++++++++++++++++++++++++ drivers/ub/urma/ubcore/ubcore_jetty.c | 24 ++++++++++++++++++++++++ include/urma/ubcore_uapi.h | 16 ++++++++++++++++ 3 files changed, 66 insertions(+) diff --git a/drivers/ub/urma/ubcore/ubcore_device.c b/drivers/ub/urma/ubcore/ubcore_device.c index 45fed657eaec..083f2ad4dce6 100644 --- a/drivers/ub/urma/ubcore/ubcore_device.c +++ b/drivers/ub/urma/ubcore/ubcore_device.c @@ -644,6 +644,32 @@ int ubcore_config_device(struct ubcore_device *dev, const struct ubcore_device_c } EXPORT_SYMBOL(ubcore_config_device); +int ubcore_user_control(struct ubcore_user_ctl *k_user_ctl) +{ + struct ubcore_device *dev; + int ret; + + if (k_user_ctl == NULL || k_user_ctl->uctx == NULL) { + ubcore_log_err("invalid parameter with input nullptr.\n"); + return -1; + } + + dev = k_user_ctl->uctx->ub_dev; + if (dev == NULL || dev->ops == NULL || dev->ops->user_ctl == NULL) { + ubcore_log_err("invalid parameter with dev nullptr.\n"); + return -1; + } + + ret = dev->ops->user_ctl(k_user_ctl); + if (ret != 0) { + ubcore_log_err("failed to exec kdrv_user_ctl in %s.\n", __func__); + return ret; + } + + return 0; +} +EXPORT_SYMBOL(ubcore_user_control); + int ubcore_query_stats(const struct ubcore_device *dev, struct ubcore_stats_key *key, struct ubcore_stats_val *val) { diff --git a/drivers/ub/urma/ubcore/ubcore_jetty.c b/drivers/ub/urma/ubcore/ubcore_jetty.c index 5307770dc9c2..450b82113181 100644 --- a/drivers/ub/urma/ubcore/ubcore_jetty.c +++ b/drivers/ub/urma/ubcore/ubcore_jetty.c @@ -29,6 +29,24 @@ #include #include "ubcore_priv.h" +struct ubcore_jfc *ubcore_find_jfc(struct ubcore_device *dev, uint32_t jfc_id) +{ + return ubcore_hash_table_lookup(&dev->ht[UBCORE_HT_JFC], jfc_id, &jfc_id); +} +EXPORT_SYMBOL(ubcore_find_jfc); + +struct ubcore_jfs *ubcore_find_jfs(struct ubcore_device *dev, uint32_t jfs_id) +{ + return ubcore_hash_table_lookup(&dev->ht[UBCORE_HT_JFS], jfs_id, &jfs_id); +} +EXPORT_SYMBOL(ubcore_find_jfs); + +struct ubcore_jfr *ubcore_find_jfr(struct ubcore_device *dev, uint32_t jfr_id) +{ + return ubcore_hash_table_lookup(&dev->ht[UBCORE_HT_JFR], jfr_id, &jfr_id); +} +EXPORT_SYMBOL(ubcore_find_jfr); + static uint32_t ubcore_get_eq_id(const struct ubcore_device *dev) { uint32_t eq_id = 0; @@ -644,3 +662,9 @@ int ubcore_unimport_jetty(struct ubcore_tjetty *tjetty) return dev->ops->unimport_jetty(tjetty); } EXPORT_SYMBOL(ubcore_unimport_jetty); + +struct ubcore_jetty *ubcore_find_jetty(struct ubcore_device *dev, uint32_t jetty_id) +{ + return ubcore_hash_table_lookup(&dev->ht[UBCORE_HT_JETTY], jetty_id, &jetty_id); +} +EXPORT_SYMBOL(ubcore_find_jetty); diff --git a/include/urma/ubcore_uapi.h b/include/urma/ubcore_uapi.h index 5bbd2b7bd683..d9c02a4fab79 100644 --- a/include/urma/ubcore_uapi.h +++ b/include/urma/ubcore_uapi.h @@ -320,4 +320,20 @@ struct ubcore_tjetty *ubcore_import_jetty(struct ubcore_device *dev, * @return: 0 on success, other value on error */ int ubcore_unimport_jetty(struct ubcore_tjetty *tjetty); +/** + * operation of user ioctl cmd. + * @param[in] k_user_ctl: kdrv user control command pointer; + * @return: 0 on success, other value on error + */ +int ubcore_user_control(struct ubcore_user_ctl *k_user_ctl); + +/* The APIs below are deprecated, should not be called by driver or ubcore client */ +struct ubcore_jfc *ubcore_find_jfc(struct ubcore_device *dev, uint32_t jfc_id); + +struct ubcore_jfs *ubcore_find_jfs(struct ubcore_device *dev, uint32_t jfs_id); + +struct ubcore_jfr *ubcore_find_jfr(struct ubcore_device *dev, uint32_t jfr_id); + +struct ubcore_jetty *ubcore_find_jetty(struct ubcore_device *dev, uint32_t jetty_id); + #endif -- Gitee From ad84f0a92e3fe282d8280d8c45f8d5b8aab1a2b4 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Fri, 15 Sep 2023 15:09:52 +0800 Subject: [PATCH 32/89] ub: ubcore add event api and add jetty and event api impls to compile driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Ubcore add event-related api implements, which will finally call hw driver's registered method. - ubcore_rearm_jfc: set jfc to the status of ready to receive events. - ubcore_register_event_handler: Client register an async_event handler to ubcore - ubcore_unregister_event_handler: Client unregister async_event handler from ubcore - ubcore_dispatch_async_event: Dispatch an asynchronous event to all registered handlers Add jetty and event related api to compile. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/ubcore/Makefile | 4 ++- drivers/ub/urma/ubcore/ubcore_device.c | 45 ++++++++++++++++++++++++++ drivers/ub/urma/ubcore/ubcore_dp.c | 39 ++++++++++++++++++++++ drivers/ub/urma/ubcore/ubcore_jetty.c | 16 ++------- drivers/ub/urma/ubcore/ubcore_tp.h | 32 ++++++++++++++++++ include/urma/ubcore_uapi.h | 22 +++++++++++++ 6 files changed, 143 insertions(+), 15 deletions(-) create mode 100644 drivers/ub/urma/ubcore/ubcore_dp.c create mode 100644 drivers/ub/urma/ubcore/ubcore_tp.h diff --git a/drivers/ub/urma/ubcore/Makefile b/drivers/ub/urma/ubcore/Makefile index e5387924241c..add2d10d23d6 100644 --- a/drivers/ub/urma/ubcore/Makefile +++ b/drivers/ub/urma/ubcore/Makefile @@ -5,9 +5,11 @@ ubcore-objs := ubcore_main.o \ ubcore_device.o \ + ubcore_jetty.o \ ubcore_umem.o \ ubcore_tp.o \ ubcore_hash_table.o \ - ubcore_netlink.o + ubcore_netlink.o \ + ubcore_dp.o obj-$(CONFIG_UB) += ubcore.o diff --git a/drivers/ub/urma/ubcore/ubcore_device.c b/drivers/ub/urma/ubcore/ubcore_device.c index 083f2ad4dce6..ee62b9010932 100644 --- a/drivers/ub/urma/ubcore/ubcore_device.c +++ b/drivers/ub/urma/ubcore/ubcore_device.c @@ -473,8 +473,53 @@ void ubcore_unregister_device(struct ubcore_device *dev) } EXPORT_SYMBOL(ubcore_unregister_device); +void ubcore_register_event_handler(struct ubcore_device *dev, struct ubcore_event_handler *handler) +{ + unsigned long flags; + + if (dev == NULL || handler == NULL) { + ubcore_log_err("Invalid argument.\n"); + return; + } + + spin_lock_irqsave(&dev->event_handler_lock, flags); + list_add_tail(&handler->node, &dev->event_handler_list); + spin_unlock_irqrestore(&dev->event_handler_lock, flags); +} +EXPORT_SYMBOL(ubcore_register_event_handler); + +void ubcore_unregister_event_handler(struct ubcore_device *dev, + struct ubcore_event_handler *handler) +{ + unsigned long flags; + + if (dev == NULL || handler == NULL) { + ubcore_log_err("Invalid argument.\n"); + return; + } + + spin_lock_irqsave(&dev->event_handler_lock, flags); + list_del(&handler->node); + spin_unlock_irqrestore(&dev->event_handler_lock, flags); +} +EXPORT_SYMBOL(ubcore_unregister_event_handler); + void ubcore_dispatch_async_event(struct ubcore_event *event) { + struct ubcore_event_handler *handler; + struct ubcore_device *dev; + unsigned long flags; + + if (event == NULL || event->ub_dev == NULL) { + ubcore_log_err("Invalid argument.\n"); + return; + } + + dev = event->ub_dev; + spin_lock_irqsave(&dev->event_handler_lock, flags); + list_for_each_entry(handler, &dev->event_handler_list, node) + handler->event_callback(event, handler); + spin_unlock_irqrestore(&dev->event_handler_lock, flags); } EXPORT_SYMBOL(ubcore_dispatch_async_event); diff --git a/drivers/ub/urma/ubcore/ubcore_dp.c b/drivers/ub/urma/ubcore/ubcore_dp.c new file mode 100644 index 000000000000..a70aad3013f2 --- /dev/null +++ b/drivers/ub/urma/ubcore/ubcore_dp.c @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + * + * Description: kmod ub data path API + * Author: sunfang + * Create: 2023-05-09 + * Note: + * History: 2023-05-09 + */ +#include +#include "ubcore_log.h" +#include +#include +#include + +int ubcore_rearm_jfc(struct ubcore_jfc *jfc, bool solicited_only) +{ + struct ubcore_ops *dev_ops; + + if (jfc == NULL || jfc->ub_dev == NULL || jfc->ub_dev->ops == NULL || + jfc->ub_dev->ops->rearm_jfc == NULL) { + ubcore_log_err("Invalid parameter"); + return -EINVAL; + } + + dev_ops = jfc->ub_dev->ops; + return dev_ops->rearm_jfc(jfc, solicited_only); +} +EXPORT_SYMBOL(ubcore_rearm_jfc); diff --git a/drivers/ub/urma/ubcore/ubcore_jetty.c b/drivers/ub/urma/ubcore/ubcore_jetty.c index 450b82113181..cb4c37c013c6 100644 --- a/drivers/ub/urma/ubcore/ubcore_jetty.c +++ b/drivers/ub/urma/ubcore/ubcore_jetty.c @@ -28,6 +28,8 @@ #include #include #include "ubcore_priv.h" +#include "ubcore_hash_table.h" +#include "ubcore_tp.h" struct ubcore_jfc *ubcore_find_jfc(struct ubcore_device *dev, uint32_t jfc_id) { @@ -339,14 +341,6 @@ struct ubcore_jfr *ubcore_create_jfr(struct ubcore_device *dev, const struct ubc jfr->ub_dev = dev; jfr->uctx = ubcore_get_uctx(udata); jfr->jfae_handler = jfae_handler; - if (ubcore_jfr_need_advise(jfr)) { - jfr->tptable = ubcore_create_tptable(); - if (jfr->tptable == NULL) { - (void)dev->ops->destroy_jfr(jfr); - ubcore_log_err("Failed to create tp table in the jfr.\n"); - return NULL; - } - } atomic_set(&jfr->use_cnt, 0); atomic_inc(&cfg->jfc->use_cnt); @@ -517,12 +511,6 @@ struct ubcore_jetty *ubcore_create_jetty(struct ubcore_device *dev, jetty->jfae_handler = jfae_handler; atomic_set(&jetty->use_cnt, 0); - if (ubcore_hash_table_find_add(&dev->ht[UBCORE_HT_JETTY], &jetty->hnode, jetty->id) != 0) { - ubcore_destroy_tptable(&jetty->tptable); - (void)dev->ops->destroy_jetty(jetty); - ubcore_log_err("Failed to add jetty.\n"); - } - atomic_inc(&cfg->send_jfc->use_cnt); atomic_inc(&cfg->recv_jfc->use_cnt); if (cfg->jfr) diff --git a/drivers/ub/urma/ubcore/ubcore_tp.h b/drivers/ub/urma/ubcore/ubcore_tp.h new file mode 100644 index 000000000000..5931220caf61 --- /dev/null +++ b/drivers/ub/urma/ubcore/ubcore_tp.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + * + * Description: ubcore tp header + * Author: Yan Fangfang + * Create: 2022-09-08 + * Note: + * History: 2022-09-208: Create file + */ + +#ifndef UBCORE_TP_H +#define UBCORE_TP_H + +#include +#include "ubcore_netlink.h" + +static inline bool ubcore_have_tp_ops(const struct ubcore_device *dev) +{ + return (dev != NULL && dev->ops->create_tp != NULL && dev->ops->modify_tp != NULL && + dev->ops->destroy_tp != NULL); +} +#endif diff --git a/include/urma/ubcore_uapi.h b/include/urma/ubcore_uapi.h index d9c02a4fab79..35abea2880e9 100644 --- a/include/urma/ubcore_uapi.h +++ b/include/urma/ubcore_uapi.h @@ -164,6 +164,13 @@ int ubcore_modify_jfc(struct ubcore_jfc *jfc, const struct ubcore_jfc_attr *attr * @return: 0 on success, other value on error */ int ubcore_delete_jfc(struct ubcore_jfc *jfc); +/** + * rearm jfc. + * @param[in] jfc: the jfc created before; + * @param[in] solicited_only: rearm notify by message marked with solicited flag + * @return: 0 on success, other value on error + */ +int ubcore_rearm_jfc(struct ubcore_jfc *jfc, bool solicited_only); /** * create jfs with ubcore device. * @param[in] dev: the ubcore device handle; @@ -326,6 +333,21 @@ int ubcore_unimport_jetty(struct ubcore_tjetty *tjetty); * @return: 0 on success, other value on error */ int ubcore_user_control(struct ubcore_user_ctl *k_user_ctl); +/** + * Client register an async_event handler to ubcore + * @param[in] dev: the ubcore device handle; + * @param[in] handler: async_event handler to be registered + * Note: the handler will be called when driver reports an async_event with + * ubcore_dispatch_async_event + */ +void ubcore_register_event_handler(struct ubcore_device *dev, struct ubcore_event_handler *handler); +/** + * Client unregister async_event handler from ubcore + * @param[in] dev: the ubcore device handle; + * @param[in] handler: async_event handler to be unregistered + */ +void ubcore_unregister_event_handler(struct ubcore_device *dev, + struct ubcore_event_handler *handler); /* The APIs below are deprecated, should not be called by driver or ubcore client */ struct ubcore_jfc *ubcore_find_jfc(struct ubcore_device *dev, uint32_t jfc_id); -- Gitee From aa1574d12e9b7034455b7dc70fa8659cd0900c29 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Fri, 15 Sep 2023 15:32:26 +0800 Subject: [PATCH 33/89] ub: uburma add jetty and event related uobj def and event api def driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Uburma add jetty and event related uobj definition, and also uburma event api definition. Jetty is a type idr uobj in uburma. Event is a type of fd uobj in uburma. In uburma we need to handle completion events and async events so that uburma can report events to user. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/uburma/uburma_event.h | 40 ++++++++++++++++ drivers/ub/urma/uburma/uburma_uobj.h | 67 +++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 drivers/ub/urma/uburma/uburma_event.h diff --git a/drivers/ub/urma/uburma/uburma_event.h b/drivers/ub/urma/uburma/uburma_event.h new file mode 100644 index 000000000000..96d92a1d0e5a --- /dev/null +++ b/drivers/ub/urma/uburma/uburma_event.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + * + * Description: uburma event header + * Author: Yan Fangfang + * Create: 2022-07-28 + * Note: + * History: 2022-07-28: create file + */ + +#ifndef UBURMA_EVENT_H +#define UBURMA_EVENT_H + +#include +#include "uburma_uobj.h" + +void uburma_init_jfe(struct uburma_jfe *jfe); +void uburma_uninit_jfe(struct uburma_jfe *jfe); +void uburma_write_event(struct uburma_jfe *jfe, uint64_t event_data, uint32_t event_type, + struct list_head *obj_event_list, uint32_t *counter); + +struct uburma_jfce_uobj *uburma_get_jfce_uobj(int fd, struct uburma_file *ufile); +void uburma_jfce_handler(struct ubcore_jfc *jfc); +void uburma_release_comp_event(struct uburma_jfce_uobj *jfce, struct list_head *event_list); + +void uburma_init_jfae(struct uburma_jfae_uobj *jfae, struct ubcore_device *ubc_dev); +void uburma_release_async_event(struct uburma_file *ufile, struct list_head *event_list); +int uburma_get_jfae(struct uburma_file *ufile); +void uburma_put_jfae(struct uburma_file *ufile); +#endif /* UBURMA_EVENT_H */ diff --git a/drivers/ub/urma/uburma/uburma_uobj.h b/drivers/ub/urma/uburma/uburma_uobj.h index e480db501cdf..10197a3757be 100644 --- a/drivers/ub/urma/uburma/uburma_uobj.h +++ b/drivers/ub/urma/uburma/uburma_uobj.h @@ -25,6 +25,14 @@ enum UOBJ_CLASS_ID { UOBJ_CLASS_ROOT, /* used by framework */ + UOBJ_CLASS_JFR, + UOBJ_CLASS_JFS, + UOBJ_CLASS_JFC, + UOBJ_CLASS_JFCE, + UOBJ_CLASS_JFAE, + UOBJ_CLASS_TARGET_JFR, + UOBJ_CLASS_JETTY, + UOBJ_CLASS_TARGET_JETTY }; enum uobj_access { @@ -79,6 +87,53 @@ struct uobj_class_def { const struct uobj_type *type_attrs; }; +struct uburma_jfe { + spinlock_t lock; + struct list_head event_list; + wait_queue_head_t poll_wait; + + bool deleting; +}; + +struct uburma_jfce_uobj { + struct uburma_uobj uobj; + struct uburma_jfe jfe; +}; + +struct uburma_jfc_uobj { + struct uburma_uobj uobj; /* base uobj struct */ + struct uburma_uobj *jfce; /* associated jfce uobj */ + struct list_head comp_event_list; + struct list_head async_event_list; + uint32_t comp_events_reported; + uint32_t async_events_reported; +}; + +struct uburma_jfs_uobj { + struct uburma_uobj uobj; /* base uobj struct */ + struct list_head async_event_list; + uint32_t async_events_reported; +}; + +struct uburma_jfr_uobj { + struct uburma_uobj uobj; /* base uobj struct */ + struct list_head async_event_list; + uint32_t async_events_reported; +}; + +struct uburma_jetty_uobj { + struct uburma_uobj uobj; /* base uobj struct */ + struct list_head async_event_list; + uint32_t async_events_reported; +}; + +struct uburma_jfae_uobj { + struct uburma_uobj uobj; + struct uburma_jfe jfe; + struct ubcore_event_handler event_handler; + struct ubcore_device *dev; +}; + extern const struct uobj_type_class uobj_idr_type_class; extern const struct uobj_type_class uobj_fd_type_class; @@ -157,4 +212,16 @@ static inline bool uobj_type_is_fd(const struct uburma_uobj *uobj) #define uobj_get_del(class_id, _id, ufile) \ uobj_lookup_get(uobj_get_type(class_id), ufile, _id, UOBJ_ACCESS_NOLOCK) +extern const struct uobj_class_def uobj_class_UOBJ_CLASS_JFCE; +extern const struct uobj_class_def uobj_class_UOBJ_CLASS_JFAE; +extern const struct uobj_class_def uobj_class_UOBJ_CLASS_JFC; +extern const struct uobj_class_def uobj_class_UOBJ_CLASS_JFR; +extern const struct uobj_class_def uobj_class_UOBJ_CLASS_JFS; +extern const struct uobj_class_def uobj_class_UOBJ_CLASS_JETTY; +extern const struct uobj_class_def uobj_class_UOBJ_CLASS_TARGET_JFR; +extern const struct uobj_class_def uobj_class_UOBJ_CLASS_TARGET_JETTY; + +extern const struct file_operations uburma_jfce_fops; +extern const struct file_operations uburma_jfae_fops; + #endif /* UBURMA_UOBJ_H */ -- Gitee From e96cb1fed7037a080256c7b598764f795e6c36e3 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Fri, 15 Sep 2023 17:08:44 +0800 Subject: [PATCH 34/89] ub: uburma add jfce and jfae uobj implementation. driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Uburma add jfce and jfae uobj implementation. To declare jfce and jfae as a fd uobj, it needs to define function of how to destroy jfae/jfce uobj, implement file ops of jfce/jfae fd. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/uburma/Makefile | 1 + drivers/ub/urma/uburma/uburma_event.c | 108 ++++++++++++++++++++++++++ drivers/ub/urma/uburma/uburma_uobj.c | 51 ++++++++++++ 3 files changed, 160 insertions(+) create mode 100644 drivers/ub/urma/uburma/uburma_event.c diff --git a/drivers/ub/urma/uburma/Makefile b/drivers/ub/urma/uburma/Makefile index 7194d916b527..4fea86fa790a 100644 --- a/drivers/ub/urma/uburma/Makefile +++ b/drivers/ub/urma/uburma/Makefile @@ -7,6 +7,7 @@ uburma-objs := uburma_main.o \ uburma_dev_ops.o \ uburma_cmd.o \ uburma_cdev_file.o \ + uburma_event.o \ uburma_uobj.o obj-$(CONFIG_UB) += uburma.o diff --git a/drivers/ub/urma/uburma/uburma_event.c b/drivers/ub/urma/uburma/uburma_event.c new file mode 100644 index 000000000000..2f60c396ac4b --- /dev/null +++ b/drivers/ub/urma/uburma/uburma_event.c @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + * + * Description: uburma event implementation + * Author: Yan Fangfang + * Create: 2022-07-28 + * Note: + * History: 2022-07-28: create file + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "uburma_log.h" +#include "uburma_types.h" +#include "uburma_cmd.h" +#include "uburma_uobj.h" +#include "uburma_event.h" + +#define UBURMA_JFCE_DELETE_EVENT 0 +struct uburma_jfe_event { + struct list_head node; + uint32_t event_type; /* support async event */ + uint64_t event_data; + struct list_head obj_node; + uint32_t *counter; +}; + +struct uburma_jfce_uobj *uburma_get_jfce_uobj(int fd, struct uburma_file *ufile) +{ + struct uburma_uobj *uobj; + struct uburma_jfce_uobj *jfce; + + if (fd < 0) + return ERR_PTR(-ENOENT); + + uobj = uobj_get_read(UOBJ_CLASS_JFCE, fd, ufile); + if (IS_ERR(uobj)) { + uburma_log_err("get jfce uobj fail with fd %d\n", fd); + return (void *)uobj; + } + + jfce = container_of(uobj, struct uburma_jfce_uobj, uobj); + uobj_get(uobj); // To keep the event file until jfce destroy. + uobj_put_read(uobj); + return jfce; +} + +void uburma_write_event(struct uburma_jfe *jfe, uint64_t event_data, uint32_t event_type, + struct list_head *obj_event_list, uint32_t *counter) +{ +} + +void uburma_jfce_handler(struct ubcore_jfc *jfc) +{ +} + +void uburma_uninit_jfe(struct uburma_jfe *jfe) +{ +} + +const struct file_operations uburma_jfce_fops = { +}; + +void uburma_init_jfe(struct uburma_jfe *jfe) +{ +} + +const struct file_operations uburma_jfae_fops = { +}; + +void uburma_init_jfae(struct uburma_jfae_uobj *jfae, struct ubcore_device *ubc_dev) +{ +} + +void uburma_release_comp_event(struct uburma_jfce_uobj *jfce, struct list_head *event_list) +{ +} + +void uburma_release_async_event(struct uburma_file *ufile, struct list_head *event_list) +{ +} + +int uburma_get_jfae(struct uburma_file *ufile) +{ + return 0; +} + +void uburma_put_jfae(struct uburma_file *ufile) +{ +} diff --git a/drivers/ub/urma/uburma/uburma_uobj.c b/drivers/ub/urma/uburma/uburma_uobj.c index 291701837344..bba3147209d8 100644 --- a/drivers/ub/urma/uburma/uburma_uobj.c +++ b/drivers/ub/urma/uburma/uburma_uobj.c @@ -29,6 +29,7 @@ #include "uburma_types.h" #include "uburma_file_ops.h" #include "uburma_log.h" +#include "uburma_event.h" #include "uburma_uobj.h" static void uobj_free(struct kref *ref) @@ -530,6 +531,47 @@ void uburma_close_uobj_fd(struct file *f) uobj_put(uobj); } +static int uburma_hot_unplug_jfce(struct uburma_uobj *uobj, enum uburma_remove_reason why) +{ + struct uburma_jfce_uobj *jfce = container_of(uobj, struct uburma_jfce_uobj, uobj); + struct uburma_jfe *jfe = &jfce->jfe; + + spin_lock_irq(&jfe->lock); + if (jfe->deleting == true) { + spin_unlock_irq(&jfe->lock); + return 0; + } + jfe->deleting = true; + spin_unlock_irq(&jfe->lock); + + if (why == UBURMA_REMOVE_DRIVER_REMOVE) + wake_up_interruptible(&jfe->poll_wait); + + uburma_uninit_jfe(jfe); + return 0; +} + +static int uburma_hot_unplug_jfae(struct uburma_uobj *uobj, enum uburma_remove_reason why) +{ + struct uburma_jfae_uobj *jfae = container_of(uobj, struct uburma_jfae_uobj, uobj); + struct uburma_jfe *jfe = &jfae->jfe; + + spin_lock_irq(&jfe->lock); + if (jfe->deleting == true) { + spin_unlock_irq(&jfe->lock); + return 0; + } + jfe->deleting = true; + spin_unlock_irq(&jfe->lock); + + ubcore_unregister_event_handler(jfae->dev, &jfae->event_handler); + + if (why == UBURMA_REMOVE_DRIVER_REMOVE) + uburma_write_event(&jfae->jfe, 0, UBCORE_EVENT_DEV_FATAL, NULL, NULL); + + return 0; +} + const struct uobj_type_class uobj_idr_type_class = { .alloc_begin = uobj_idr_alloc_begin, .alloc_commit = uobj_idr_alloc_commit, @@ -547,3 +589,12 @@ const struct uobj_type_class uobj_fd_type_class = { .lookup_put = uobj_fd_lookup_put, .remove_commit = uobj_fd_remove_commit, }; + +/* The destroy process start from order 0. */ +declare_uobj_class(UOBJ_CLASS_JFCE, + &uobj_type_alloc_fd(3, sizeof(struct uburma_jfce_uobj), uburma_hot_unplug_jfce, + &uburma_jfce_fops, "[jfce]", O_RDWR | O_CLOEXEC)); + +declare_uobj_class(UOBJ_CLASS_JFAE, + &uobj_type_alloc_fd(3, sizeof(struct uburma_jfae_uobj), uburma_hot_unplug_jfae, + &uburma_jfae_fops, "[jfae]", O_RDWR | O_CLOEXEC)); -- Gitee From 2522ff566c5ca84f36471deeda15b2f63c09ba61 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Fri, 15 Sep 2023 17:15:54 +0800 Subject: [PATCH 35/89] ub: uburma add jfc/jfr/jfs/jetty/tjfr/tjetty uobj implementation. driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Uburma add jfc/jfr/jfs/jetty/tjfr/tjetty uobj implementation. These uobjs are idr uobj. To declare as a idr uobj, it needs to define function of how to destroy it. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/uburma/uburma_uobj.c | 79 ++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/drivers/ub/urma/uburma/uburma_uobj.c b/drivers/ub/urma/uburma/uburma_uobj.c index bba3147209d8..9a379396409b 100644 --- a/drivers/ub/urma/uburma/uburma_uobj.c +++ b/drivers/ub/urma/uburma/uburma_uobj.c @@ -504,6 +504,72 @@ void uburma_cleanup_uobjs(struct uburma_file *ufile, enum uburma_remove_reason w up_write(&ufile->cleanup_rwsem); } +static int uburma_free_jfc(struct uburma_uobj *uobj, enum uburma_remove_reason why) +{ + struct uburma_jfc_uobj *jfc_uobj = container_of(uobj, struct uburma_jfc_uobj, uobj); + struct ubcore_jfc *jfc = (struct ubcore_jfc *)uobj->object; + struct uburma_jfce_uobj *jfce_uobj; + int ret = ubcore_delete_jfc(jfc); + + if (ret) + return ret; + + if (!IS_ERR(jfc_uobj->jfce)) { + jfce_uobj = container_of(jfc_uobj->jfce, struct uburma_jfce_uobj, uobj); + uburma_release_comp_event(jfce_uobj, &jfc_uobj->comp_event_list); + uobj_put(jfc_uobj->jfce); + } + + uburma_release_async_event(uobj->ufile, &jfc_uobj->async_event_list); + return ret; +} + +static int uburma_free_jfs(struct uburma_uobj *uobj, enum uburma_remove_reason why) +{ + struct uburma_jfs_uobj *jfs_uobj = container_of(uobj, struct uburma_jfs_uobj, uobj); + int ret = ubcore_delete_jfs((struct ubcore_jfs *)uobj->object); + + if (ret) + return ret; + + uburma_release_async_event(uobj->ufile, &jfs_uobj->async_event_list); + return ret; +} + +static int uburma_free_jfr(struct uburma_uobj *uobj, enum uburma_remove_reason why) +{ + struct uburma_jfr_uobj *jfr_uobj = container_of(uobj, struct uburma_jfr_uobj, uobj); + int ret = ubcore_delete_jfr((struct ubcore_jfr *)uobj->object); + + if (ret) + return ret; + + uburma_release_async_event(uobj->ufile, &jfr_uobj->async_event_list); + return ret; +} + +static int uburma_free_jetty(struct uburma_uobj *uobj, enum uburma_remove_reason why) +{ + struct uburma_jetty_uobj *jetty_uobj = container_of(uobj, struct uburma_jetty_uobj, uobj); + int ret = ubcore_delete_jetty((struct ubcore_jetty *)uobj->object); + + if (ret) + return ret; + + uburma_release_async_event(uobj->ufile, &jetty_uobj->async_event_list); + return ret; +} + +static int uburma_free_tjfr(struct uburma_uobj *uobj, enum uburma_remove_reason why) +{ + return ubcore_unimport_jfr((struct ubcore_tjetty *)uobj->object); +} + +static int uburma_free_tjetty(struct uburma_uobj *uobj, enum uburma_remove_reason why) +{ + return ubcore_unimport_jetty((struct ubcore_tjetty *)uobj->object); +} + void uburma_close_uobj_fd(struct file *f) { struct uburma_uobj *uobj = f->private_data; @@ -598,3 +664,16 @@ declare_uobj_class(UOBJ_CLASS_JFCE, declare_uobj_class(UOBJ_CLASS_JFAE, &uobj_type_alloc_fd(3, sizeof(struct uburma_jfae_uobj), uburma_hot_unplug_jfae, &uburma_jfae_fops, "[jfae]", O_RDWR | O_CLOEXEC)); + +declare_uobj_class(UOBJ_CLASS_JFC, + &uobj_type_alloc_idr(sizeof(struct uburma_jfc_uobj), 2, uburma_free_jfc)); +declare_uobj_class(UOBJ_CLASS_JFS, + &uobj_type_alloc_idr(sizeof(struct uburma_jfs_uobj), 1, uburma_free_jfs)); +declare_uobj_class(UOBJ_CLASS_JFR, + &uobj_type_alloc_idr(sizeof(struct uburma_jfr_uobj), 1, uburma_free_jfr)); +declare_uobj_class(UOBJ_CLASS_JETTY, + &uobj_type_alloc_idr(sizeof(struct uburma_jetty_uobj), 1, uburma_free_jetty)); +declare_uobj_class(UOBJ_CLASS_TARGET_JFR, + &uobj_type_alloc_idr(sizeof(struct uburma_uobj), 0, uburma_free_tjfr)); +declare_uobj_class(UOBJ_CLASS_TARGET_JETTY, + &uobj_type_alloc_idr(sizeof(struct uburma_uobj), 0, uburma_free_tjetty)); -- Gitee From 91ee8e415080473200a69363f9835ba53ef071ce Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Sat, 16 Sep 2023 10:27:21 +0800 Subject: [PATCH 36/89] ub: uburma add jfce-related event api implementation. driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Uburma add jfce-related event api implementation, including: uburma_init_jfe(): init an event. uburma_uninit_jfe(): release an event. uburma_write_event(): record the event into event list according to event type. uburma_release_comp_event(): release all the completion event in list. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/uburma/uburma_event.c | 60 +++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/drivers/ub/urma/uburma/uburma_event.c b/drivers/ub/urma/uburma/uburma_event.c index 2f60c396ac4b..98ca882dc480 100644 --- a/drivers/ub/urma/uburma/uburma_event.c +++ b/drivers/ub/urma/uburma/uburma_event.c @@ -66,14 +66,62 @@ struct uburma_jfce_uobj *uburma_get_jfce_uobj(int fd, struct uburma_file *ufile) void uburma_write_event(struct uburma_jfe *jfe, uint64_t event_data, uint32_t event_type, struct list_head *obj_event_list, uint32_t *counter) { + struct uburma_jfe_event *event; + unsigned long flags; + + spin_lock_irqsave(&jfe->lock, flags); + if (jfe->deleting) { + spin_unlock_irqrestore(&jfe->lock, flags); + return; + } + event = kmalloc(sizeof(struct uburma_jfe_event), GFP_ATOMIC); + if (event == NULL) { + spin_unlock_irqrestore(&jfe->lock, flags); + return; + } + event->event_data = event_data; + event->event_type = event_type; + event->counter = counter; + + list_add_tail(&event->node, &jfe->event_list); + if (obj_event_list) + list_add_tail(&event->obj_node, obj_event_list); + spin_unlock_irqrestore(&jfe->lock, flags); + wake_up_interruptible(&jfe->poll_wait); } void uburma_jfce_handler(struct ubcore_jfc *jfc) { + struct uburma_jfc_uobj *jfc_uobj; + struct uburma_jfce_uobj *jfce; + + if (jfc == NULL) + return; + + rcu_read_lock(); + jfc_uobj = rcu_dereference(jfc->jfc_cfg.jfc_context); + if (jfc_uobj != NULL && !IS_ERR(jfc_uobj) && !IS_ERR(jfc_uobj->jfce)) { + jfce = container_of(jfc_uobj->jfce, struct uburma_jfce_uobj, uobj); + uburma_write_event(&jfce->jfe, jfc->urma_jfc, 0, &jfc_uobj->comp_event_list, + &jfc_uobj->comp_events_reported); + } + + rcu_read_unlock(); } void uburma_uninit_jfe(struct uburma_jfe *jfe) { + struct list_head *p, *next; + struct uburma_jfe_event *event; + + spin_lock_irq(&jfe->lock); + list_for_each_safe(p, next, &jfe->event_list) { + event = list_entry(p, struct uburma_jfe_event, node); + if (event->counter) + list_del(&event->obj_node); + kfree(event); + } + spin_unlock_irq(&jfe->lock); } const struct file_operations uburma_jfce_fops = { @@ -81,6 +129,9 @@ const struct file_operations uburma_jfce_fops = { void uburma_init_jfe(struct uburma_jfe *jfe) { + spin_lock_init(&jfe->lock); + INIT_LIST_HEAD(&jfe->event_list); + init_waitqueue_head(&jfe->poll_wait); } const struct file_operations uburma_jfae_fops = { @@ -92,6 +143,15 @@ void uburma_init_jfae(struct uburma_jfae_uobj *jfae, struct ubcore_device *ubc_d void uburma_release_comp_event(struct uburma_jfce_uobj *jfce, struct list_head *event_list) { + struct uburma_jfe *jfe = &jfce->jfe; + struct uburma_jfe_event *event, *tmp; + + spin_lock_irq(&jfe->lock); + list_for_each_entry_safe(event, tmp, event_list, obj_node) { + list_del(&event->node); + kfree(event); + } + spin_unlock_irq(&jfe->lock); } void uburma_release_async_event(struct uburma_file *ufile, struct list_head *event_list) -- Gitee From b1f497da21f29888bb1acd1ed3bf8f25cfd18a2c Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Sat, 16 Sep 2023 10:40:27 +0800 Subject: [PATCH 37/89] ub: uburma add jfae-related event api implementation. driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Uburma add jfae-related event api implementation, including: uburma_init_jfae(): init a async event. uburma_uninit_jfae(): release a async event. uburma_get_jfae(): get the jfae from jfae uobj. uburma_put_jfae(): reduce the refcnt of jfae uobj. uburma_init_jfae_handler(): add jfae callback handler to write event. uburma_release_async_event(): release all the async events in list. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/uburma/uburma_event.c | 59 +++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/drivers/ub/urma/uburma/uburma_event.c b/drivers/ub/urma/uburma/uburma_event.c index 98ca882dc480..792bc039de80 100644 --- a/drivers/ub/urma/uburma/uburma_event.c +++ b/drivers/ub/urma/uburma/uburma_event.c @@ -137,8 +137,32 @@ void uburma_init_jfe(struct uburma_jfe *jfe) const struct file_operations uburma_jfae_fops = { }; +static void uburma_async_event_callback(struct ubcore_event *event, + struct ubcore_event_handler *handler) +{ + struct uburma_jfae_uobj *jfae = + container_of(handler, struct uburma_jfae_uobj, event_handler); + + if (WARN_ON(IS_ERR_OR_NULL(jfae))) + return; + + uburma_write_event(&jfae->jfe, event->element.port_id, event->event_type, NULL, NULL); +} + + +static inline void uburma_init_jfae_handler(struct ubcore_event_handler *handler) +{ + INIT_LIST_HEAD(&handler->node); + handler->event_callback = uburma_async_event_callback; +} + + void uburma_init_jfae(struct uburma_jfae_uobj *jfae, struct ubcore_device *ubc_dev) { + uburma_init_jfe(&jfae->jfe); + uburma_init_jfae_handler(&jfae->event_handler); + ubcore_register_event_handler(ubc_dev, &jfae->event_handler); + jfae->dev = ubc_dev; } void uburma_release_comp_event(struct uburma_jfce_uobj *jfce, struct list_head *event_list) @@ -156,13 +180,48 @@ void uburma_release_comp_event(struct uburma_jfce_uobj *jfce, struct list_head * void uburma_release_async_event(struct uburma_file *ufile, struct list_head *event_list) { + struct uburma_jfae_uobj *jfae = ufile->ucontext->jfae; + struct uburma_jfe *jfe = &jfae->jfe; + struct uburma_jfe_event *event, *tmp; + + spin_lock_irq(&jfe->lock); + list_for_each_entry_safe(event, tmp, event_list, obj_node) { + list_del(&event->node); + kfree(event); + } + spin_unlock_irq(&jfe->lock); + uburma_put_jfae(ufile); } int uburma_get_jfae(struct uburma_file *ufile) { + struct uburma_jfae_uobj *jfae; + + if (ufile->ucontext == NULL) { + uburma_log_err("ucontext is NULL"); + return -ENODEV; + } + + jfae = ufile->ucontext->jfae; + if (IS_ERR_OR_NULL(jfae)) { + uburma_log_err("Failed to get jfae"); + return -EINVAL; + } + + uobj_get(&jfae->uobj); return 0; } void uburma_put_jfae(struct uburma_file *ufile) { + struct uburma_jfae_uobj *jfae; + + if (ufile->ucontext == NULL) + return; + + jfae = ufile->ucontext->jfae; + if (IS_ERR_OR_NULL(jfae)) + return; + + uobj_put(&jfae->uobj); } -- Gitee From 8dc89ef2ea13657e1390a2c61d3648ec6d2a80ff Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Sat, 16 Sep 2023 10:49:56 +0800 Subject: [PATCH 38/89] ub: uburma add poll and release file ops impls for jfce and jfae event. driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Uburma add poll and release file ops impls for jfce and jfae event. poll ops: finally will use poll_wait to poll. release ops: finally will close fd, uninit event list, and release uobj. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/uburma/uburma_cmd.h | 27 ++++++++++++ drivers/ub/urma/uburma/uburma_event.c | 63 +++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) diff --git a/drivers/ub/urma/uburma/uburma_cmd.h b/drivers/ub/urma/uburma/uburma_cmd.h index e0d18722a3a6..3811aa93d219 100644 --- a/drivers/ub/urma/uburma/uburma_cmd.h +++ b/drivers/ub/urma/uburma/uburma_cmd.h @@ -60,6 +60,33 @@ struct uburma_cmd_create_ctx { struct uburma_cmd_udrv_priv udata; }; +/* only for event ioctl */ +#define MAX_JFCE_EVENT_CNT 16 +#define UBURMA_EVENT_CMD_MAGIC 'E' +#define JFCE_CMD_WAIT_EVENT 0 +#define JFAE_CMD_GET_ASYNC_EVENT 0 +#define UBURMA_CMD_WAIT_JFC \ + _IOWR(UBURMA_EVENT_CMD_MAGIC, JFCE_CMD_WAIT_EVENT, struct uburma_cmd_jfce_wait) +#define UBURMA_CMD_GET_ASYNC_EVENT \ + _IOWR(UBURMA_EVENT_CMD_MAGIC, JFAE_CMD_GET_ASYNC_EVENT, struct uburma_cmd_async_event) + +struct uburma_cmd_jfce_wait { + struct { + uint32_t max_event_cnt; + int time_out; + } in; + struct { + uint32_t event_cnt; + uint64_t event_data[MAX_JFCE_EVENT_CNT]; + } out; +}; + +struct uburma_cmd_async_event { + uint32_t event_type; + uint64_t event_data; + uint32_t pad; +}; + /* copy from user_space addr to kernel args */ static inline int uburma_copy_from_user(void *args, const void *args_addr, unsigned long args_size) { diff --git a/drivers/ub/urma/uburma/uburma_event.c b/drivers/ub/urma/uburma/uburma_event.c index 792bc039de80..8ff6bf73c7f3 100644 --- a/drivers/ub/urma/uburma/uburma_event.c +++ b/drivers/ub/urma/uburma/uburma_event.c @@ -124,7 +124,45 @@ void uburma_uninit_jfe(struct uburma_jfe *jfe) spin_unlock_irq(&jfe->lock); } +static int uburma_delete_jfce(struct inode *inode, struct file *filp) +{ + struct uburma_uobj *uobj = filp->private_data; + + uobj_get(uobj); + /* will call uburma_hot_unplug_jfce if clean up is not going on */ + uburma_close_uobj_fd(filp); + uobj_put(uobj); + return 0; +} + +static __poll_t uburma_jfe_poll(struct uburma_jfe *jfe, struct file *filp, + struct poll_table_struct *wait) +{ + __poll_t flag = 0; + + poll_wait(filp, &jfe->poll_wait, wait); + + spin_lock_irq(&jfe->lock); + if (!list_empty(&jfe->event_list)) + flag = EPOLLIN | EPOLLRDNORM; + + spin_unlock_irq(&jfe->lock); + + return flag; +} + +static __poll_t uburma_jfce_poll(struct file *filp, struct poll_table_struct *wait) +{ + struct uburma_uobj *uobj = filp->private_data; + struct uburma_jfce_uobj *jfce = container_of(uobj, struct uburma_jfce_uobj, uobj); + + return uburma_jfe_poll(&jfce->jfe, filp, wait); +} + const struct file_operations uburma_jfce_fops = { + .owner = THIS_MODULE, + .poll = uburma_jfce_poll, + .release = uburma_delete_jfce, }; void uburma_init_jfe(struct uburma_jfe *jfe) @@ -134,7 +172,32 @@ void uburma_init_jfe(struct uburma_jfe *jfe) init_waitqueue_head(&jfe->poll_wait); } +static int uburma_delete_jfae(struct inode *inode, struct file *filp) +{ + struct uburma_uobj *uobj = filp->private_data; + struct uburma_jfae_uobj *jfae = container_of(uobj, struct uburma_jfae_uobj, uobj); + + /* todonext: handle uobj == NULL */ + uobj_get(uobj); + /* call uburma_hot_unplug_jfae when cleanup is not going on */ + uburma_close_uobj_fd(filp); + uburma_uninit_jfe(&jfae->jfe); + uobj_put(uobj); + return 0; +} + +static __poll_t uburma_jfae_poll(struct file *filp, struct poll_table_struct *wait) +{ + struct uburma_uobj *uobj = filp->private_data; + struct uburma_jfae_uobj *jfae = container_of(uobj, struct uburma_jfae_uobj, uobj); + + return uburma_jfe_poll(&jfae->jfe, filp, wait); +} + const struct file_operations uburma_jfae_fops = { + .owner = THIS_MODULE, + .poll = uburma_jfae_poll, + .release = uburma_delete_jfae, }; static void uburma_async_event_callback(struct ubcore_event *event, -- Gitee From db863b4c3f05ab837cc6b578939d6422bb03fcb0 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Sat, 16 Sep 2023 11:02:14 +0800 Subject: [PATCH 39/89] ub: uburma add ioctl file ops impls for jfce event. driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Uburma add ioctl file ops impls for jfce event. Currently ioctl ops will only handle cmd wait jfce. wait jfce: get the specific num of completion events polled by poll ops. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/uburma/uburma_event.c | 158 ++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) diff --git a/drivers/ub/urma/uburma/uburma_event.c b/drivers/ub/urma/uburma/uburma_event.c index 8ff6bf73c7f3..9741a61d1d48 100644 --- a/drivers/ub/urma/uburma/uburma_event.c +++ b/drivers/ub/urma/uburma/uburma_event.c @@ -135,6 +135,93 @@ static int uburma_delete_jfce(struct inode *inode, struct file *filp) return 0; } +/* Read up to event_cnt events from jfe */ +static uint32_t uburma_read_jfe_event(struct uburma_jfe *jfe, uint32_t event_cnt, + struct list_head *event_list) +{ + struct list_head *p, *next; + struct uburma_jfe_event *event; + uint32_t cnt = 0; + + spin_lock_irq(&jfe->lock); + if (jfe->deleting) { + spin_unlock_irq(&jfe->lock); + return 0; + } + list_for_each_safe(p, next, &jfe->event_list) { + if (cnt == event_cnt) + break; + event = list_entry(p, struct uburma_jfe_event, node); + if (event->counter) { + ++(*event->counter); + list_del(&event->obj_node); + } + list_del(p); + list_add_tail(p, event_list); + cnt++; + } + spin_unlock_irq(&jfe->lock); + return cnt; +} + +static int uburma_wait_event_timeout(struct uburma_jfe *jfe, unsigned long max_timeout, + uint32_t max_event_cnt, uint32_t *event_cnt, + struct list_head *event_list) +{ + long timeout = (long)max_timeout; + + *event_cnt = 0; + while (!jfe->deleting) { + asm volatile("" : : : "memory"); + *event_cnt = uburma_read_jfe_event(jfe, max_event_cnt, event_list); + /* Stop waiting once we have read at least one event */ + if (jfe->deleting) + return -EIO; + else if (*event_cnt > 0) + break; + /* + * 0 if the @condition evaluated to %false after the @timeout elapsed, + * 1 if the @condition evaluated to %true after the @timeout elapsed, + * the remaining jiffies (at least 1) if the @condition evaluated to true + * before the @timeout elapsed, + * or -%ERESTARTSYS if it was interrupted by a signal. + */ + timeout = wait_event_interruptible_timeout( + jfe->poll_wait, (!list_empty(&jfe->event_list) || jfe->deleting), timeout); + if (timeout <= 0) + return timeout; + } + + return 0; +} + +static int uburma_wait_event(struct uburma_jfe *jfe, bool nonblock, uint32_t max_event_cnt, + uint32_t *event_cnt, struct list_head *event_list) +{ + int ret; + + *event_cnt = 0; + while (!jfe->deleting) { + asm volatile("" : : : "memory"); + *event_cnt = uburma_read_jfe_event(jfe, max_event_cnt, event_list); + /* Stop waiting once we have read at least one event */ + if (jfe->deleting) + return -EIO; + else if (nonblock && *event_cnt == 0) + return 0; + else if (*event_cnt > 0) + break; + /* The function will return -ERESTARTSYS if it was interrupted by a + * signal and 0 if @condition evaluated to true. + */ + ret = wait_event_interruptible(jfe->poll_wait, + (!list_empty(&jfe->event_list) || jfe->deleting)); + if (ret != 0) + return ret; + } + return 0; +} + static __poll_t uburma_jfe_poll(struct uburma_jfe *jfe, struct file *filp, struct poll_table_struct *wait) { @@ -159,10 +246,81 @@ static __poll_t uburma_jfce_poll(struct file *filp, struct poll_table_struct *wa return uburma_jfe_poll(&jfce->jfe, filp, wait); } +static int uburma_jfce_wait(struct uburma_jfce_uobj *jfce, struct file *filp, unsigned long arg) +{ + struct uburma_cmd_jfce_wait we; + struct list_head event_list; + struct uburma_jfe_event *event; + uint32_t max_event_cnt; + uint32_t i = 0; + struct list_head *p, *next; + int ret; + + if (arg == 0) + return -EINVAL; + + if (copy_from_user(&we, (const void __user *)(uintptr_t)arg, + sizeof(struct uburma_cmd_jfce_wait)) != 0) + return -EFAULT; + + /* urma lib ensures that max_event_cnt > 0 */ + max_event_cnt = (we.in.max_event_cnt < MAX_JFCE_EVENT_CNT ? we.in.max_event_cnt : + MAX_JFCE_EVENT_CNT); + INIT_LIST_HEAD(&event_list); + if (we.in.time_out <= 0) { + ret = uburma_wait_event(&jfce->jfe, + (filp->f_flags & O_NONBLOCK) | (we.in.time_out == 0), + max_event_cnt, &we.out.event_cnt, &event_list); + } else { + ret = uburma_wait_event_timeout(&jfce->jfe, msecs_to_jiffies(we.in.time_out), + max_event_cnt, &we.out.event_cnt, &event_list); + } + + if (ret < 0) { + uburma_log_err("Failed to wait jfce event"); + return ret; + } + + list_for_each_safe(p, next, &event_list) { + event = list_entry(p, struct uburma_jfe_event, node); + we.out.event_data[i++] = event->event_data; + list_del(p); + kfree(event); + } + + if (we.out.event_cnt > 0 && copy_to_user((void *)arg, &we, sizeof(we))) + return -EFAULT; + + return 0; +} + +static long uburma_jfce_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + unsigned int nr; + int ret; + struct uburma_uobj *uobj = filp->private_data; + struct uburma_jfce_uobj *jfce = container_of(uobj, struct uburma_jfce_uobj, uobj); + + if (_IOC_TYPE(cmd) != UBURMA_EVENT_CMD_MAGIC) + return -EINVAL; + + nr = (unsigned int)_IOC_NR(cmd); + switch (nr) { + case JFCE_CMD_WAIT_EVENT: + ret = uburma_jfce_wait(jfce, filp, arg); + break; + default: + ret = -ENOIOCTLCMD; + break; + } + return (long)ret; +} + const struct file_operations uburma_jfce_fops = { .owner = THIS_MODULE, .poll = uburma_jfce_poll, .release = uburma_delete_jfce, + .unlocked_ioctl = uburma_jfce_ioctl, }; void uburma_init_jfe(struct uburma_jfe *jfe) -- Gitee From e71ce20f9c6970c9476cdbef4aa02c025d346a48 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Sat, 16 Sep 2023 11:05:40 +0800 Subject: [PATCH 40/89] ub: uburma add ioctl file ops impls for jfae event. driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Uburma add ioctl file ops impls for jfae event. Currently ioctl ops will only handle cmd get async event. get async event: get the specific num of async events polled by jfae poll ops. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/uburma/uburma_event.c | 58 +++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/drivers/ub/urma/uburma/uburma_event.c b/drivers/ub/urma/uburma/uburma_event.c index 9741a61d1d48..b8ef510968e8 100644 --- a/drivers/ub/urma/uburma/uburma_event.c +++ b/drivers/ub/urma/uburma/uburma_event.c @@ -352,10 +352,68 @@ static __poll_t uburma_jfae_poll(struct file *filp, struct poll_table_struct *wa return uburma_jfe_poll(&jfae->jfe, filp, wait); } +static inline void uburma_set_async_event(struct uburma_cmd_async_event *async_event, + const struct uburma_jfe_event *event) +{ + async_event->event_data = event->event_data; + async_event->event_type = event->event_type; +} + +static int uburma_get_async_event(struct uburma_jfae_uobj *jfae, struct file *filp, + unsigned long arg) +{ + struct uburma_cmd_async_event async_event = { 0 }; + struct list_head event_list; + struct uburma_jfe_event *event; + uint32_t event_cnt; + int ret; + + if (arg == 0) + return -EINVAL; + + INIT_LIST_HEAD(&event_list); + ret = uburma_wait_event(&jfae->jfe, filp->f_flags & O_NONBLOCK, 1, &event_cnt, &event_list); + if (ret < 0) + return ret; + + event = list_first_entry(&event_list, struct uburma_jfe_event, node); + uburma_set_async_event(&async_event, event); + list_del(&event->node); + kfree(event); + + if (event_cnt > 0 && copy_to_user((void *)arg, &async_event, sizeof(async_event))) + return -EFAULT; + + return 0; +} + +static long uburma_jfae_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + struct uburma_uobj *uobj = filp->private_data; + struct uburma_jfae_uobj *jfae = container_of(uobj, struct uburma_jfae_uobj, uobj); + unsigned int nr; + int ret; + + if (_IOC_TYPE(cmd) != UBURMA_EVENT_CMD_MAGIC) + return -EINVAL; + + nr = (unsigned int)_IOC_NR(cmd); + switch (nr) { + case JFAE_CMD_GET_ASYNC_EVENT: + ret = uburma_get_async_event(jfae, filp, arg); + break; + default: + ret = -ENOIOCTLCMD; + break; + } + return (long)ret; +} + const struct file_operations uburma_jfae_fops = { .owner = THIS_MODULE, .poll = uburma_jfae_poll, .release = uburma_delete_jfae, + .unlocked_ioctl = uburma_jfae_ioctl, }; static void uburma_async_event_callback(struct ubcore_event *event, -- Gitee From 2391b79a68d0cf7ed418339fb5eae7a162f3506d Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Sat, 16 Sep 2023 14:09:13 +0800 Subject: [PATCH 41/89] ub: uburma add cmd create/delete/ctx implementation. driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Uburma add implementations of handling create/delete context cmd from user layer. This will make kernel possible to handle urma_create_ctx/urma_delete_ctx api in user-layer urma. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/uburma/uburma_cmd.c | 78 +++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/drivers/ub/urma/uburma/uburma_cmd.c b/drivers/ub/urma/uburma/uburma_cmd.c index 6958bf63db25..c24f3cdd710d 100644 --- a/drivers/ub/urma/uburma/uburma_cmd.c +++ b/drivers/ub/urma/uburma/uburma_cmd.c @@ -46,11 +46,89 @@ void uburma_cmd_flush(struct uburma_device *ubu_dev) wait_for_completion(&ubu_dev->cmddone); } +static inline void fill_udata(struct ubcore_udata *out, struct ubcore_ucontext *ctx, + struct uburma_cmd_udrv_priv *udata) +{ + out->uctx = ctx; + out->udrv_data = (struct ubcore_udrv_priv *)(void *)udata; +} + +static int uburma_cmd_create_ctx(struct ubcore_device *ubc_dev, struct uburma_file *file, + struct uburma_cmd_hdr *hdr) +{ + struct ubcore_ucontext *ucontext; + struct uburma_cmd_create_ctx arg; + struct uburma_uobj *uobj; + struct uburma_jfae_uobj *jfae; + int ret; + + ret = uburma_copy_from_user(&arg, (void __user *)(uintptr_t)hdr->args_addr, + sizeof(struct uburma_cmd_create_ctx)); + if (ret != 0) + return ret; + + mutex_lock(&file->mutex); + + ucontext = ubcore_alloc_ucontext(ubc_dev, arg.in.uasid, + (struct ubcore_udrv_priv *)(void *)&arg.udata); + if (IS_ERR_OR_NULL(ucontext)) { + mutex_unlock(&file->mutex); + return -EPERM; + } + + uobj = uobj_alloc(UOBJ_CLASS_JFAE, file); + if (IS_ERR(uobj)) { + ret = PTR_ERR(uobj); + goto free_ctx; + } + + jfae = container_of(uobj, struct uburma_jfae_uobj, uobj); + uburma_init_jfae(jfae, ubc_dev); + ucontext->jfae = uobj; + arg.out.async_fd = uobj->id; + file->ucontext = ucontext; + + ret = uburma_copy_to_user((void __user *)(uintptr_t)hdr->args_addr, &arg, + sizeof(struct uburma_cmd_create_ctx)); + if (ret != 0) + goto free_jfae; + + uobj_alloc_commit(uobj); + mutex_unlock(&file->mutex); + uburma_log_info("uburma create context success.\n"); + return ret; + +free_jfae: + uobj_alloc_abort(uobj); +free_ctx: + ubcore_free_ucontext(ubc_dev, ucontext); + mutex_unlock(&file->mutex); + return ret; +} + +static int uburma_cmd_destroy_ctx(struct ubcore_device *ubc_dev, struct uburma_file *file, + struct uburma_cmd_hdr *hdr) +{ + mutex_lock(&file->mutex); + if (file->ucontext == NULL) { + mutex_unlock(&file->mutex); + return -EINVAL; + } + uburma_cleanup_uobjs(file, UBURMA_REMOVE_CLOSE); + ubcore_free_ucontext(ubc_dev, file->ucontext); + file->ucontext = NULL; + uburma_log_info("uburma destroy context success.\n"); + mutex_unlock(&file->mutex); + return 0; +} + typedef int (*uburma_cmd_handler)(struct ubcore_device *ubc_dev, struct uburma_file *file, struct uburma_cmd_hdr *hdr); static uburma_cmd_handler g_uburma_cmd_handlers[] = { [0] = NULL, + [UBURMA_CMD_CREATE_CTX] = uburma_cmd_create_ctx, + [UBURMA_CMD_DESTROY_CTX] = uburma_cmd_destroy_ctx, }; static int uburma_cmd_parse(struct ubcore_device *ubc_dev, struct uburma_file *file, -- Gitee From dd9641804ad19402838975c28003465d0b42042a Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Sat, 16 Sep 2023 14:55:23 +0800 Subject: [PATCH 42/89] ub: uburma add cmd create/delete jfs implementation. driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Uburma add implementations of handling create/delete jfs cmd from user layer. This will make kernel possible to handle urma_create_jfs/urma_delete_jfs api in user-layer urma. Create jfs will finally call ubcore_create_jfs. The created jfs will be related to a uobj. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/uburma/uburma_cmd.c | 155 ++++++++++++++++++++++++++++ drivers/ub/urma/uburma/uburma_cmd.h | 38 +++++++ 2 files changed, 193 insertions(+) diff --git a/drivers/ub/urma/uburma/uburma_cmd.c b/drivers/ub/urma/uburma/uburma_cmd.c index c24f3cdd710d..1f94c9a4b290 100644 --- a/drivers/ub/urma/uburma/uburma_cmd.c +++ b/drivers/ub/urma/uburma/uburma_cmd.c @@ -25,6 +25,9 @@ #include #include "uburma_log.h" #include "uburma_types.h" +#include "uburma_event.h" +#include "uburma_file_ops.h" +#include "uburma_uobj.h" #include "uburma_cmd.h" #define UBURMA_INVALID_TPN UINT_MAX @@ -122,6 +125,156 @@ static int uburma_cmd_destroy_ctx(struct ubcore_device *ubc_dev, struct uburma_f return 0; } +static void uburma_write_async_event(struct ubcore_ucontext *ctx, uint64_t event_data, + uint32_t event_type, struct list_head *obj_event_list, + uint32_t *counter) +{ + struct uburma_jfae_uobj *jfae; + + rcu_read_lock(); + jfae = rcu_dereference(ctx->jfae); + if (jfae == NULL) { + rcu_read_unlock(); + return; + } + uburma_write_event(&jfae->jfe, event_data, event_type, obj_event_list, counter); + rcu_read_unlock(); +} + +void uburma_jfs_event_cb(struct ubcore_event *event, struct ubcore_ucontext *ctx) +{ + struct uburma_jfs_uobj *jfs_uobj; + + if (event->element.jfs == NULL) + return; + + jfs_uobj = (struct uburma_jfs_uobj *)event->element.jfs->jfs_cfg.jfs_context; + uburma_write_async_event(ctx, event->element.jfs->urma_jfs, event->event_type, + &jfs_uobj->async_event_list, &jfs_uobj->async_events_reported); +} + +static int uburma_cmd_create_jfs(struct ubcore_device *ubc_dev, struct uburma_file *file, + struct uburma_cmd_hdr *hdr) +{ + struct uburma_cmd_create_jfs arg; + struct ubcore_jfs_cfg cfg = { 0 }; + struct ubcore_udata udata; + struct uburma_jfs_uobj *jfs_uobj; + struct uburma_uobj *jfc_uobj; + struct ubcore_jfs *jfs; + int ret; + + ret = uburma_copy_from_user(&arg, (void __user *)(uintptr_t)hdr->args_addr, + sizeof(struct uburma_cmd_create_jfs)); + if (ret != 0) + return ret; + + cfg.depth = arg.in.depth; + cfg.flag.value = arg.in.flag; + cfg.trans_mode = arg.in.trans_mode; + cfg.max_sge = arg.in.max_sge; + cfg.max_rsge = arg.in.max_rsge; + cfg.max_inline_data = arg.in.max_inline_data; + cfg.retry_cnt = arg.in.retry_cnt; + cfg.rnr_retry = arg.in.rnr_retry; + cfg.err_timeout = arg.in.err_timeout; + cfg.priority = arg.in.priority; + + jfs_uobj = (struct uburma_jfs_uobj *)uobj_alloc(UOBJ_CLASS_JFS, file); + if (IS_ERR(jfs_uobj)) { + uburma_log_err("UOBJ_CLASS_JFS alloc fail!\n"); + return -ENOMEM; + } + jfs_uobj->async_events_reported = 0; + INIT_LIST_HEAD(&jfs_uobj->async_event_list); + cfg.jfs_context = jfs_uobj; + + jfc_uobj = uobj_get_read(UOBJ_CLASS_JFC, arg.in.jfc_handle, file); + if (IS_ERR(jfc_uobj)) { + uburma_log_err("failed to find jfc, jfc_handle:%llu.\n", arg.in.jfc_handle); + ret = -EINVAL; + goto err_alloc_abort; + } + cfg.jfc = jfc_uobj->object; + fill_udata(&udata, file->ucontext, &arg.udata); + + jfs = ubcore_create_jfs(ubc_dev, &cfg, uburma_jfs_event_cb, &udata); + if (IS_ERR_OR_NULL(jfs)) { + uburma_log_err("create jfs or get jfs_id failed.\n"); + ret = -EPERM; + goto err_put_jfc; + } + jfs_uobj->uobj.object = jfs; + jfs->urma_jfs = arg.in.urma_jfs; + + /* Do not release jfae fd until jfs is destroyed */ + ret = uburma_get_jfae(file); + if (ret != 0) + goto err_delete_jfs; + + arg.out.id = jfs->id; + arg.out.depth = jfs->jfs_cfg.depth; + arg.out.max_sge = jfs->jfs_cfg.max_sge; + arg.out.max_rsge = jfs->jfs_cfg.max_rsge; + arg.out.max_inline_data = jfs->jfs_cfg.max_inline_data; + arg.out.handle = jfs_uobj->uobj.id; + + ret = uburma_copy_to_user((void __user *)(uintptr_t)hdr->args_addr, &arg, + sizeof(struct uburma_cmd_create_jfs)); + if (ret != 0) + goto err_put_jfae; + + uobj_put_read(jfc_uobj); + uobj_alloc_commit(&jfs_uobj->uobj); + return 0; + +err_put_jfae: + uburma_put_jfae(file); +err_delete_jfs: + ubcore_delete_jfs(jfs); +err_put_jfc: + uobj_put_read(jfc_uobj); +err_alloc_abort: + uobj_alloc_abort(&jfs_uobj->uobj); + return ret; +} + +static int uburma_cmd_delete_jfs(struct ubcore_device *ubc_dev, struct uburma_file *file, + struct uburma_cmd_hdr *hdr) +{ + struct uburma_cmd_delete_jfs arg; + struct uburma_jfs_uobj *jfs_uobj; + struct uburma_uobj *uobj; + int ret; + + ret = uburma_copy_from_user(&arg, (void __user *)(uintptr_t)hdr->args_addr, + sizeof(struct uburma_cmd_delete_jfs)); + if (ret != 0) + return ret; + + uobj = uobj_get_del(UOBJ_CLASS_JFS, arg.in.handle, file); + if (IS_ERR(uobj)) { + uburma_log_err("failed to find jfs"); + return -EINVAL; + } + + /* To get async_events_reported after obj removed. */ + uobj_get(uobj); + jfs_uobj = container_of(uobj, struct uburma_jfs_uobj, uobj); + + ret = uobj_remove_commit(uobj); + if (ret != 0) { + uburma_log_err("delete jfs failed, ret:%d.\n", ret); + uobj_put(uobj); + return ret; + } + + arg.out.async_events_reported = jfs_uobj->async_events_reported; + uobj_put(uobj); + return uburma_copy_to_user((void __user *)(uintptr_t)hdr->args_addr, &arg, + sizeof(struct uburma_cmd_delete_jfs)); +} + typedef int (*uburma_cmd_handler)(struct ubcore_device *ubc_dev, struct uburma_file *file, struct uburma_cmd_hdr *hdr); @@ -129,6 +282,8 @@ static uburma_cmd_handler g_uburma_cmd_handlers[] = { [0] = NULL, [UBURMA_CMD_CREATE_CTX] = uburma_cmd_create_ctx, [UBURMA_CMD_DESTROY_CTX] = uburma_cmd_destroy_ctx, + [UBURMA_CMD_CREATE_JFS] = uburma_cmd_create_jfs, + [UBURMA_CMD_DELETE_JFS] = uburma_cmd_delete_jfs, }; static int uburma_cmd_parse(struct ubcore_device *ubc_dev, struct uburma_file *file, diff --git a/drivers/ub/urma/uburma/uburma_cmd.h b/drivers/ub/urma/uburma/uburma_cmd.h index 3811aa93d219..da944ed8355c 100644 --- a/drivers/ub/urma/uburma/uburma_cmd.h +++ b/drivers/ub/urma/uburma/uburma_cmd.h @@ -40,6 +40,8 @@ struct uburma_cmd_hdr { enum uburma_cmd { UBURMA_CMD_CREATE_CTX = 1, UBURMA_CMD_DESTROY_CTX, + UBURMA_CMD_CREATE_JFS, + UBURMA_CMD_DELETE_JFS, UBURMA_CMD_USER_CTL }; @@ -50,6 +52,42 @@ struct uburma_cmd_udrv_priv { uint32_t out_len; }; +struct uburma_cmd_create_jfs { + struct { + uint32_t depth; /* in terms of WQEBB */ + uint32_t flag; + uint32_t trans_mode; + uint8_t priority; + uint8_t max_sge; + uint8_t max_rsge; + uint32_t max_inline_data; + uint8_t retry_cnt; + uint8_t rnr_retry; + uint8_t err_timeout; + uint32_t jfc_id; + uint64_t jfc_handle; + uint64_t urma_jfs; /* urma jfs pointer */ + } in; + struct { + uint32_t id; + uint32_t depth; + uint8_t max_sge; + uint8_t max_rsge; + uint32_t max_inline_data; + uint64_t handle; /* handle of the allocated jfs obj in kernel */ + } out; + struct uburma_cmd_udrv_priv udata; +}; + +struct uburma_cmd_delete_jfs { + struct { + uint64_t handle; /* handle of jfs, used to find jfs obj in kernel */ + } in; + struct { + uint32_t async_events_reported; + } out; +}; + struct uburma_cmd_create_ctx { struct { uint32_t uasid; -- Gitee From 79b60243a9ff771b76add8e16cfe55cc4f5edef2 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Sat, 16 Sep 2023 15:05:50 +0800 Subject: [PATCH 43/89] ub: uburma add cmd create jfr implementation. driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Uburma add implementations of handling create jfr cmd from user layer. This will make kernel possible to handle urma_create_jfr api in user-layer urma. Create jfr will finally call ubcore_create_jfr. The created jfr will be related to a uobj. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/uburma/uburma_cmd.c | 94 +++++++++++++++++++++++++++++ drivers/ub/urma/uburma/uburma_cmd.h | 43 ++++++++++--- 2 files changed, 127 insertions(+), 10 deletions(-) diff --git a/drivers/ub/urma/uburma/uburma_cmd.c b/drivers/ub/urma/uburma/uburma_cmd.c index 1f94c9a4b290..9f636d93a68b 100644 --- a/drivers/ub/urma/uburma/uburma_cmd.c +++ b/drivers/ub/urma/uburma/uburma_cmd.c @@ -153,6 +153,18 @@ void uburma_jfs_event_cb(struct ubcore_event *event, struct ubcore_ucontext *ctx &jfs_uobj->async_event_list, &jfs_uobj->async_events_reported); } +void uburma_jfr_event_cb(struct ubcore_event *event, struct ubcore_ucontext *ctx) +{ + struct uburma_jfr_uobj *jfr_uobj; + + if (event->element.jfr == NULL) + return; + + jfr_uobj = (struct uburma_jfr_uobj *)event->element.jfr->jfr_cfg.jfr_context; + uburma_write_async_event(ctx, event->element.jfr->urma_jfr, event->event_type, + &jfr_uobj->async_event_list, &jfr_uobj->async_events_reported); +} + static int uburma_cmd_create_jfs(struct ubcore_device *ubc_dev, struct uburma_file *file, struct uburma_cmd_hdr *hdr) { @@ -275,6 +287,87 @@ static int uburma_cmd_delete_jfs(struct ubcore_device *ubc_dev, struct uburma_fi sizeof(struct uburma_cmd_delete_jfs)); } +static int uburma_cmd_create_jfr(struct ubcore_device *ubc_dev, struct uburma_file *file, + struct uburma_cmd_hdr *hdr) +{ + struct uburma_cmd_create_jfr arg; + struct uburma_uobj *jfc_uobj; + struct uburma_jfr_uobj *jfr_uobj; + struct ubcore_jfr_cfg cfg = { 0 }; + struct ubcore_udata udata; + struct ubcore_jfr *jfr; + int ret; + + ret = uburma_copy_from_user(&arg, (void __user *)(uintptr_t)hdr->args_addr, + sizeof(struct uburma_cmd_create_jfr)); + if (ret != 0) + return ret; + + cfg.id = arg.in.id; + cfg.flag.value = arg.in.flag; + cfg.trans_mode = arg.in.trans_mode; + cfg.depth = arg.in.depth; + cfg.max_sge = arg.in.max_sge; + cfg.min_rnr_timer = arg.in.min_rnr_timer; + cfg.ukey.key = arg.in.key; + fill_udata(&udata, file->ucontext, &arg.udata); + + jfr_uobj = (struct uburma_jfr_uobj *)uobj_alloc(UOBJ_CLASS_JFR, file); + if (IS_ERR(jfr_uobj)) { + uburma_log_err("UOBJ_CLASS_JFR alloc fail!\n"); + return -ENOMEM; + } + jfr_uobj->async_events_reported = 0; + INIT_LIST_HEAD(&jfr_uobj->async_event_list); + cfg.jfr_context = jfr_uobj; + + jfc_uobj = uobj_get_read(UOBJ_CLASS_JFC, arg.in.jfc_handle, file); + if (IS_ERR(jfc_uobj)) { + uburma_log_err("failed to find jfc, jfc_handle:%llu.\n", arg.in.jfc_handle); + ret = -EINVAL; + goto err_alloc_abort; + } + cfg.jfc = jfc_uobj->object; + + jfr = ubcore_create_jfr(ubc_dev, &cfg, uburma_jfr_event_cb, &udata); + if (IS_ERR_OR_NULL(jfr)) { + uburma_log_err("create jfr or get jfr_id failed.\n"); + ret = -EPERM; + goto err_put_jfc; + } + jfr_uobj->uobj.object = jfr; + jfr->urma_jfr = arg.in.urma_jfr; + + /* Do not release jfae fd until jfr is destroyed */ + ret = uburma_get_jfae(file); + if (ret != 0) + goto err_delete_jfr; + + arg.out.id = jfr->id; + arg.out.depth = jfr->jfr_cfg.depth; + arg.out.max_sge = jfr->jfr_cfg.max_sge; + arg.out.handle = jfr_uobj->uobj.id; + + ret = uburma_copy_to_user((void __user *)(uintptr_t)hdr->args_addr, &arg, + sizeof(struct uburma_cmd_create_jfr)); + if (ret != 0) + goto err_put_jfae; + + uobj_put_read(jfc_uobj); + uobj_alloc_commit(&jfr_uobj->uobj); + return ret; + +err_put_jfae: + uburma_put_jfae(file); +err_delete_jfr: + (void)ubcore_delete_jfr(jfr); +err_put_jfc: + uobj_put_read(jfc_uobj); +err_alloc_abort: + uobj_alloc_abort(&jfr_uobj->uobj); + return ret; +} + typedef int (*uburma_cmd_handler)(struct ubcore_device *ubc_dev, struct uburma_file *file, struct uburma_cmd_hdr *hdr); @@ -284,6 +377,7 @@ static uburma_cmd_handler g_uburma_cmd_handlers[] = { [UBURMA_CMD_DESTROY_CTX] = uburma_cmd_destroy_ctx, [UBURMA_CMD_CREATE_JFS] = uburma_cmd_create_jfs, [UBURMA_CMD_DELETE_JFS] = uburma_cmd_delete_jfs, + [UBURMA_CMD_CREATE_JFR] = uburma_cmd_create_jfr, }; static int uburma_cmd_parse(struct ubcore_device *ubc_dev, struct uburma_file *file, diff --git a/drivers/ub/urma/uburma/uburma_cmd.h b/drivers/ub/urma/uburma/uburma_cmd.h index da944ed8355c..4e11123b1343 100644 --- a/drivers/ub/urma/uburma/uburma_cmd.h +++ b/drivers/ub/urma/uburma/uburma_cmd.h @@ -42,6 +42,7 @@ enum uburma_cmd { UBURMA_CMD_DESTROY_CTX, UBURMA_CMD_CREATE_JFS, UBURMA_CMD_DELETE_JFS, + UBURMA_CMD_CREATE_JFR, UBURMA_CMD_USER_CTL }; @@ -52,6 +53,38 @@ struct uburma_cmd_udrv_priv { uint32_t out_len; }; +struct uburma_cmd_create_ctx { + struct { + uint32_t uasid; + } in; + struct { + int async_fd; + } out; + struct uburma_cmd_udrv_priv udata; +}; + +struct uburma_cmd_create_jfr { + struct { + uint32_t depth; /* in terms of WQEBB */ + uint32_t flag; + uint32_t trans_mode; + uint8_t max_sge; + uint8_t min_rnr_timer; + uint32_t jfc_id; + uint64_t jfc_handle; + uint32_t key; + uint32_t id; + uint64_t urma_jfr; /* urma jfr pointer */ + } in; + struct { + uint32_t id; + uint32_t depth; + uint8_t max_sge; + uint64_t handle; /* handle of the allocated jfr obj in kernel */ + } out; + struct uburma_cmd_udrv_priv udata; +}; + struct uburma_cmd_create_jfs { struct { uint32_t depth; /* in terms of WQEBB */ @@ -88,16 +121,6 @@ struct uburma_cmd_delete_jfs { } out; }; -struct uburma_cmd_create_ctx { - struct { - uint32_t uasid; - } in; - struct { - int async_fd; - } out; - struct uburma_cmd_udrv_priv udata; -}; - /* only for event ioctl */ #define MAX_JFCE_EVENT_CNT 16 #define UBURMA_EVENT_CMD_MAGIC 'E' -- Gitee From d3dea8c3efaf5366b2d16f3e38dbd6905b8c44f1 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Sat, 16 Sep 2023 15:14:00 +0800 Subject: [PATCH 44/89] ub: uburma add cmd modify/delete jfr implementation. driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Uburma add implementations of handling modify/delete jfr cmd from user layer. This will make kernel possible to handle urma_modify_jfr/urma_delete_jfy api in user-layer urma. Modify_jfr will finally call ubcore_modify_jfr. Delete_jfr will delete the jfr-related uobj. In uobj destroy function, it will call ubcore_delete_jfr. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/uburma/uburma_cmd.c | 77 +++++++++++++++++++++++++++++ drivers/ub/urma/uburma/uburma_cmd.h | 20 ++++++++ 2 files changed, 97 insertions(+) diff --git a/drivers/ub/urma/uburma/uburma_cmd.c b/drivers/ub/urma/uburma/uburma_cmd.c index 9f636d93a68b..c225b7a4308e 100644 --- a/drivers/ub/urma/uburma/uburma_cmd.c +++ b/drivers/ub/urma/uburma/uburma_cmd.c @@ -368,6 +368,81 @@ static int uburma_cmd_create_jfr(struct ubcore_device *ubc_dev, struct uburma_fi return ret; } +static int uburma_cmd_modify_jfr(struct ubcore_device *ubc_dev, struct uburma_file *file, + struct uburma_cmd_hdr *hdr) +{ + struct uburma_cmd_modify_jfr arg; + struct uburma_uobj *uobj; + struct ubcore_jfr_attr attr = { 0 }; + struct ubcore_udata udata; + struct ubcore_jfr *jfr; + int ret; + + ret = uburma_copy_from_user(&arg, (void __user *)(uintptr_t)hdr->args_addr, + sizeof(struct uburma_cmd_modify_jfr)); + if (ret != 0) + return ret; + + attr.mask = arg.in.mask; + attr.rx_threshold = arg.in.rx_threshold; + fill_udata(&udata, file->ucontext, &arg.udata); + + uobj = uobj_get_write(UOBJ_CLASS_JFR, arg.in.handle, file); + if (IS_ERR(uobj)) { + uburma_log_err("failed to find jfr.\n"); + return -EINVAL; + } + + jfr = (struct ubcore_jfr *)uobj->object; + ret = ubcore_modify_jfr(jfr, &attr, &udata); + if (ret != 0) { + uobj_put_write(uobj); + uburma_log_err("modify jfr failed, ret:%d.\n", ret); + return ret; + } + + ret = uburma_copy_to_user((void __user *)(uintptr_t)hdr->args_addr, &arg, + sizeof(struct uburma_cmd_modify_jfr)); + uobj_put_write(uobj); + return ret; +} + +static int uburma_cmd_delete_jfr(struct ubcore_device *ubc_dev, struct uburma_file *file, + struct uburma_cmd_hdr *hdr) +{ + struct uburma_cmd_delete_jfr arg; + struct uburma_jfr_uobj *jfr_uobj; + struct uburma_uobj *uobj; + int ret; + + ret = uburma_copy_from_user(&arg, (void __user *)(uintptr_t)hdr->args_addr, + sizeof(struct uburma_cmd_delete_jfr)); + if (ret != 0) + return ret; + + uobj = uobj_get_del(UOBJ_CLASS_JFR, arg.in.handle, file); + if (IS_ERR(uobj)) { + uburma_log_err("failed to find jfr"); + return -EINVAL; + } + + /* To get async_events_reported after obj removed. */ + uobj_get(uobj); + jfr_uobj = container_of(uobj, struct uburma_jfr_uobj, uobj); + + ret = uobj_remove_commit(uobj); + if (ret != 0) { + uburma_log_err("delete jfr failed, ret:%d.\n", ret); + uobj_put(uobj); + return ret; + } + + arg.out.async_events_reported = jfr_uobj->async_events_reported; + uobj_put(uobj); + return uburma_copy_to_user((void __user *)(uintptr_t)hdr->args_addr, &arg, + sizeof(struct uburma_cmd_delete_jfr)); +} + typedef int (*uburma_cmd_handler)(struct ubcore_device *ubc_dev, struct uburma_file *file, struct uburma_cmd_hdr *hdr); @@ -378,6 +453,8 @@ static uburma_cmd_handler g_uburma_cmd_handlers[] = { [UBURMA_CMD_CREATE_JFS] = uburma_cmd_create_jfs, [UBURMA_CMD_DELETE_JFS] = uburma_cmd_delete_jfs, [UBURMA_CMD_CREATE_JFR] = uburma_cmd_create_jfr, + [UBURMA_CMD_MODIFY_JFR] = uburma_cmd_modify_jfr, + [UBURMA_CMD_DELETE_JFR] = uburma_cmd_delete_jfr, }; static int uburma_cmd_parse(struct ubcore_device *ubc_dev, struct uburma_file *file, diff --git a/drivers/ub/urma/uburma/uburma_cmd.h b/drivers/ub/urma/uburma/uburma_cmd.h index 4e11123b1343..9f1cc8997a26 100644 --- a/drivers/ub/urma/uburma/uburma_cmd.h +++ b/drivers/ub/urma/uburma/uburma_cmd.h @@ -43,6 +43,8 @@ enum uburma_cmd { UBURMA_CMD_CREATE_JFS, UBURMA_CMD_DELETE_JFS, UBURMA_CMD_CREATE_JFR, + UBURMA_CMD_MODIFY_JFR, + UBURMA_CMD_DELETE_JFR, UBURMA_CMD_USER_CTL }; @@ -85,6 +87,24 @@ struct uburma_cmd_create_jfr { struct uburma_cmd_udrv_priv udata; }; +struct uburma_cmd_modify_jfr { + struct { + uint64_t handle; /* handle of jfr, used to find jfr obj in kernel */ + uint32_t mask; /* see urma_jfr_attr_mask_t */ + uint32_t rx_threshold; + } in; + struct uburma_cmd_udrv_priv udata; +}; + +struct uburma_cmd_delete_jfr { + struct { + uint64_t handle; /* handle of jfr, used to find jfr obj in kernel */ + } in; + struct { + uint32_t async_events_reported; + } out; +}; + struct uburma_cmd_create_jfs { struct { uint32_t depth; /* in terms of WQEBB */ -- Gitee From c4cd0655c0c898569c0a70162f36258fd5c50eeb Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Sat, 16 Sep 2023 15:25:40 +0800 Subject: [PATCH 45/89] ub: uburma add cmd create jfc implementation. driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Uburma add implementations of handling create jfc cmd from user layer. This will make kernel possible to handle urma_create_jfc api in user-layer urma. Create jfc will finally call ubcore_create_jfc. The created jfc will be related to a uobj. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/uburma/uburma_cmd.c | 92 +++++++++++++++++++++++++++++ drivers/ub/urma/uburma/uburma_cmd.h | 16 +++++ 2 files changed, 108 insertions(+) diff --git a/drivers/ub/urma/uburma/uburma_cmd.c b/drivers/ub/urma/uburma/uburma_cmd.c index c225b7a4308e..7e0b43f124c1 100644 --- a/drivers/ub/urma/uburma/uburma_cmd.c +++ b/drivers/ub/urma/uburma/uburma_cmd.c @@ -141,6 +141,18 @@ static void uburma_write_async_event(struct ubcore_ucontext *ctx, uint64_t event rcu_read_unlock(); } +void uburma_jfc_event_cb(struct ubcore_event *event, struct ubcore_ucontext *ctx) +{ + struct uburma_jfc_uobj *jfc_uobj; + + if (event->element.jfc == NULL) + return; + + jfc_uobj = (struct uburma_jfc_uobj *)event->element.jfc->jfc_cfg.jfc_context; + uburma_write_async_event(ctx, event->element.jfc->urma_jfc, event->event_type, + &jfc_uobj->async_event_list, &jfc_uobj->async_events_reported); +} + void uburma_jfs_event_cb(struct ubcore_event *event, struct ubcore_ucontext *ctx) { struct uburma_jfs_uobj *jfs_uobj; @@ -443,6 +455,85 @@ static int uburma_cmd_delete_jfr(struct ubcore_device *ubc_dev, struct uburma_fi sizeof(struct uburma_cmd_delete_jfr)); } +static int uburma_cmd_create_jfc(struct ubcore_device *ubc_dev, struct uburma_file *file, + struct uburma_cmd_hdr *hdr) +{ + struct uburma_cmd_create_jfc arg; + struct uburma_jfc_uobj *jfc_uobj; + struct uburma_jfce_uobj *jfce; + struct ubcore_jfc_cfg cfg = { 0 }; + struct ubcore_udata udata; + struct ubcore_jfc *jfc; + int ret; + + ret = uburma_copy_from_user(&arg, (void __user *)(uintptr_t)hdr->args_addr, + sizeof(struct uburma_cmd_create_jfc)); + if (ret != 0) + return ret; + + cfg.depth = arg.in.depth; + cfg.flag.value = arg.in.flag; + + /* jfce may be ERR_PTR */ + jfce = uburma_get_jfce_uobj(arg.in.jfce_fd, file); + if (arg.in.jfce_fd >= 0 && IS_ERR(jfce)) { + uburma_log_err("Failed to get jfce.\n"); + return -EINVAL; + } + + fill_udata(&udata, file->ucontext, &arg.udata); + + jfc_uobj = (struct uburma_jfc_uobj *)uobj_alloc(UOBJ_CLASS_JFC, file); + if (IS_ERR(jfc_uobj)) { + uburma_log_err("UOBJ_CLASS_JFC alloc fail!\n"); + ret = -1; + goto err_put_jfce; + } + jfc_uobj->comp_events_reported = 0; + jfc_uobj->async_events_reported = 0; + INIT_LIST_HEAD(&jfc_uobj->comp_event_list); + INIT_LIST_HEAD(&jfc_uobj->async_event_list); + cfg.jfc_context = jfc_uobj; + + jfc = ubcore_create_jfc(ubc_dev, &cfg, uburma_jfce_handler, uburma_jfc_event_cb, &udata); + if (IS_ERR_OR_NULL(jfc)) { + uburma_log_err("create jfc or get jfc_id failed.\n"); + ret = -EPERM; + goto err_alloc_abort; + } + + jfc_uobj->jfce = (struct uburma_uobj *)jfce; + jfc_uobj->uobj.object = jfc; + jfc->urma_jfc = arg.in.urma_jfc; + + /* Do not release jfae fd until jfc is destroyed */ + ret = uburma_get_jfae(file); + if (ret != 0) + goto err_delete_jfc; + + arg.out.id = jfc->id; + arg.out.depth = jfc->jfc_cfg.depth; + arg.out.handle = jfc_uobj->uobj.id; + ret = uburma_copy_to_user((void __user *)(uintptr_t)hdr->args_addr, &arg, + sizeof(struct uburma_cmd_create_jfc)); + if (ret != 0) + goto err_put_jfae; + + uobj_alloc_commit(&jfc_uobj->uobj); + return 0; + +err_put_jfae: + uburma_put_jfae(file); +err_delete_jfc: + (void)ubcore_delete_jfc(jfc); +err_alloc_abort: + uobj_alloc_abort(&jfc_uobj->uobj); +err_put_jfce: + if (!IS_ERR(jfce)) + uobj_put(&jfce->uobj); + return ret; +} + typedef int (*uburma_cmd_handler)(struct ubcore_device *ubc_dev, struct uburma_file *file, struct uburma_cmd_hdr *hdr); @@ -455,6 +546,7 @@ static uburma_cmd_handler g_uburma_cmd_handlers[] = { [UBURMA_CMD_CREATE_JFR] = uburma_cmd_create_jfr, [UBURMA_CMD_MODIFY_JFR] = uburma_cmd_modify_jfr, [UBURMA_CMD_DELETE_JFR] = uburma_cmd_delete_jfr, + [UBURMA_CMD_CREATE_JFC] = uburma_cmd_create_jfc, }; static int uburma_cmd_parse(struct ubcore_device *ubc_dev, struct uburma_file *file, diff --git a/drivers/ub/urma/uburma/uburma_cmd.h b/drivers/ub/urma/uburma/uburma_cmd.h index 9f1cc8997a26..e7742683e95b 100644 --- a/drivers/ub/urma/uburma/uburma_cmd.h +++ b/drivers/ub/urma/uburma/uburma_cmd.h @@ -45,6 +45,7 @@ enum uburma_cmd { UBURMA_CMD_CREATE_JFR, UBURMA_CMD_MODIFY_JFR, UBURMA_CMD_DELETE_JFR, + UBURMA_CMD_CREATE_JFC, UBURMA_CMD_USER_CTL }; @@ -141,6 +142,21 @@ struct uburma_cmd_delete_jfs { } out; }; +struct uburma_cmd_create_jfc { + struct { + uint32_t depth; /* in terms of CQEBB */ + uint32_t flag; + int jfce_fd; + uint64_t urma_jfc; /* urma jfc pointer */ + } in; + struct { + uint32_t id; + uint32_t depth; + uint64_t handle; /* handle of the allocated jfc obj in kernel */ + } out; + struct uburma_cmd_udrv_priv udata; +}; + /* only for event ioctl */ #define MAX_JFCE_EVENT_CNT 16 #define UBURMA_EVENT_CMD_MAGIC 'E' -- Gitee From c6ec826bb610113e803b56facd47f8099a1869e2 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Sat, 16 Sep 2023 15:32:27 +0800 Subject: [PATCH 46/89] ub: uburma add cmd modify/delete jfc implementation. driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Uburma add implementations of handling modify/delete jfc cmd from user layer. This will make kernel possible to handle urma_modify_jfc/urma_delete_jfy api in user-layer urma. Modify_jfc will finally call ubcore_modify_jfc. Delete_jfc will delete the jfc-related uobj. In uobj destroy function, it will call ubcore_delete_jfc. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/uburma/uburma_cmd.c | 79 +++++++++++++++++++++++++++++ drivers/ub/urma/uburma/uburma_cmd.h | 22 ++++++++ 2 files changed, 101 insertions(+) diff --git a/drivers/ub/urma/uburma/uburma_cmd.c b/drivers/ub/urma/uburma/uburma_cmd.c index 7e0b43f124c1..b474fe04accb 100644 --- a/drivers/ub/urma/uburma/uburma_cmd.c +++ b/drivers/ub/urma/uburma/uburma_cmd.c @@ -534,6 +534,83 @@ static int uburma_cmd_create_jfc(struct ubcore_device *ubc_dev, struct uburma_fi return ret; } +static int uburma_cmd_modify_jfc(struct ubcore_device *ubc_dev, struct uburma_file *file, + struct uburma_cmd_hdr *hdr) +{ + struct uburma_cmd_modify_jfc arg; + struct uburma_uobj *uobj; + struct ubcore_jfc_attr attr = { 0 }; + struct ubcore_udata udata; + struct ubcore_jfc *jfc; + int ret; + + ret = uburma_copy_from_user(&arg, (void __user *)(uintptr_t)hdr->args_addr, + sizeof(struct uburma_cmd_modify_jfc)); + if (ret != 0) + return ret; + + attr.mask = arg.in.mask; + attr.moderate_count = arg.in.moderate_count; + attr.moderate_period = arg.in.moderate_period; + fill_udata(&udata, file->ucontext, &arg.udata); + + uobj = uobj_get_write(UOBJ_CLASS_JFC, arg.in.handle, file); + if (IS_ERR(uobj)) { + uburma_log_err("failed to find jfc.\n"); + return -EINVAL; + } + + jfc = (struct ubcore_jfc *)uobj->object; + ret = ubcore_modify_jfc(jfc, &attr, &udata); + if (ret != 0) { + uobj_put_write(uobj); + uburma_log_err("modify jfc failed, ret:%d.\n", ret); + return ret; + } + + ret = uburma_copy_to_user((void __user *)(uintptr_t)hdr->args_addr, &arg, + sizeof(struct uburma_cmd_modify_jfc)); + uobj_put_write(uobj); + return ret; +} + +static int uburma_cmd_delete_jfc(struct ubcore_device *ubc_dev, struct uburma_file *file, + struct uburma_cmd_hdr *hdr) +{ + struct uburma_cmd_delete_jfc arg; + struct uburma_uobj *uobj; + struct uburma_jfc_uobj *jfc_uobj; + int ret; + + ret = uburma_copy_from_user(&arg, (void __user *)(uintptr_t)hdr->args_addr, + sizeof(struct uburma_cmd_delete_jfc)); + if (ret != 0) + return ret; + + uobj = uobj_get_del(UOBJ_CLASS_JFC, arg.in.handle, file); + if (IS_ERR(uobj)) { + uburma_log_err("failed to find jfc.\n"); + return -EINVAL; + } + + /* To get events_reported after obj removed. */ + uobj_get(uobj); + jfc_uobj = container_of(uobj, struct uburma_jfc_uobj, uobj); + + ret = uobj_remove_commit(uobj); + if (ret != 0) { + uburma_log_err("delete jfc failed, ret:%d.\n", ret); + uobj_put(uobj); + return ret; + } + + arg.out.comp_events_reported = jfc_uobj->comp_events_reported; + arg.out.async_events_reported = jfc_uobj->async_events_reported; + uobj_put(uobj); + return uburma_copy_to_user((void __user *)(uintptr_t)hdr->args_addr, &arg, + sizeof(struct uburma_cmd_delete_jfc)); +} + typedef int (*uburma_cmd_handler)(struct ubcore_device *ubc_dev, struct uburma_file *file, struct uburma_cmd_hdr *hdr); @@ -547,6 +624,8 @@ static uburma_cmd_handler g_uburma_cmd_handlers[] = { [UBURMA_CMD_MODIFY_JFR] = uburma_cmd_modify_jfr, [UBURMA_CMD_DELETE_JFR] = uburma_cmd_delete_jfr, [UBURMA_CMD_CREATE_JFC] = uburma_cmd_create_jfc, + [UBURMA_CMD_MODIFY_JFC] = uburma_cmd_modify_jfc, + [UBURMA_CMD_DELETE_JFC] = uburma_cmd_delete_jfc, }; static int uburma_cmd_parse(struct ubcore_device *ubc_dev, struct uburma_file *file, diff --git a/drivers/ub/urma/uburma/uburma_cmd.h b/drivers/ub/urma/uburma/uburma_cmd.h index e7742683e95b..6a7c5cf74717 100644 --- a/drivers/ub/urma/uburma/uburma_cmd.h +++ b/drivers/ub/urma/uburma/uburma_cmd.h @@ -46,6 +46,8 @@ enum uburma_cmd { UBURMA_CMD_MODIFY_JFR, UBURMA_CMD_DELETE_JFR, UBURMA_CMD_CREATE_JFC, + UBURMA_CMD_MODIFY_JFC, + UBURMA_CMD_DELETE_JFC, UBURMA_CMD_USER_CTL }; @@ -157,6 +159,26 @@ struct uburma_cmd_create_jfc { struct uburma_cmd_udrv_priv udata; }; +struct uburma_cmd_modify_jfc { + struct { + uint64_t handle; /* handle of jfc, used to find jfc obj in kernel */ + uint32_t mask; /* see urma_jfc_attr_mask_t */ + uint16_t moderate_count; + uint16_t moderate_period; /* in micro seconds */ + } in; + struct uburma_cmd_udrv_priv udata; +}; + +struct uburma_cmd_delete_jfc { + struct { + uint64_t handle; /* handle of jfc, used to find jfc obj in kernel */ + } in; + struct { + uint32_t comp_events_reported; + uint32_t async_events_reported; + } out; +}; + /* only for event ioctl */ #define MAX_JFCE_EVENT_CNT 16 #define UBURMA_EVENT_CMD_MAGIC 'E' -- Gitee From a54ec835049648222bc04cc3a363970015ba0a62 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Sat, 16 Sep 2023 15:44:01 +0800 Subject: [PATCH 47/89] ub: uburma add cmd import/unimport jfr implementation. driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Uburma add implementations of handling import/unimport jfc cmd from user layer. This will make kernel possible to handle urma_import_jfr/urma_unimport_jfr api in user-layer urma. Import_jfr will finally call ubcore_import_jfr. The created target jfr (tjfr) will be related to a uobj. Unimport_jfr will delete the tjfr-related uobj. In uobj destroy function, it will call ubcore_unimport_jfr. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/uburma/uburma_cmd.c | 80 +++++++++++++++++++++++++++++ drivers/ub/urma/uburma/uburma_cmd.h | 26 ++++++++++ 2 files changed, 106 insertions(+) diff --git a/drivers/ub/urma/uburma/uburma_cmd.c b/drivers/ub/urma/uburma/uburma_cmd.c index b474fe04accb..e6cb998aef45 100644 --- a/drivers/ub/urma/uburma/uburma_cmd.c +++ b/drivers/ub/urma/uburma/uburma_cmd.c @@ -611,6 +611,84 @@ static int uburma_cmd_delete_jfc(struct ubcore_device *ubc_dev, struct uburma_fi sizeof(struct uburma_cmd_delete_jfc)); } +static int uburma_cmd_import_jfr(struct ubcore_device *ubc_dev, struct uburma_file *file, + struct uburma_cmd_hdr *hdr) +{ + struct uburma_cmd_import_jfr arg; + struct ubcore_tjetty_cfg cfg = { 0 }; + struct ubcore_udata udata; + struct ubcore_tjetty *tjfr; + struct uburma_uobj *uobj; + int ret; + + ret = uburma_copy_from_user(&arg, (void __user *)(uintptr_t)hdr->args_addr, + sizeof(struct uburma_cmd_import_jfr)); + if (ret != 0) + return ret; + + uobj = uobj_alloc(UOBJ_CLASS_TARGET_JFR, file); + if (IS_ERR(uobj)) { + uburma_log_err("UOBJ_CLASS_TARGET_JFR alloc fail!\n"); + return -ENOMEM; + } + + (void)memcpy(cfg.id.eid.raw, arg.in.eid, UBCORE_EID_SIZE); + cfg.id.uasid = arg.in.uasid; + cfg.id.id = arg.in.id; + cfg.ukey.key = arg.in.key; + cfg.trans_mode = arg.in.trans_mode; + fill_udata(&udata, file->ucontext, &arg.udata); + + tjfr = ubcore_import_jfr(ubc_dev, &cfg, &udata); + if (IS_ERR_OR_NULL(tjfr)) { + uburma_log_err("ubcore_import_jfr failed.\n"); + uobj_alloc_abort(uobj); + return -EPERM; + } + + uobj->object = tjfr; + arg.out.handle = uobj->id; + if (tjfr->tp != NULL) { + arg.out.tp_type = 1; + arg.out.tpn = tjfr->tp->tpn; + } else { + arg.out.tpn = UBURMA_INVALID_TPN; + } + + ret = uburma_copy_to_user((void __user *)(uintptr_t)hdr->args_addr, &arg, + sizeof(struct uburma_cmd_import_jfr)); + if (ret != 0) { + ubcore_unimport_jfr(tjfr); + uobj_alloc_abort(uobj); + return ret; + } + uobj_alloc_commit(uobj); + return 0; +} + +static int uburma_cmd_unimport_jfr(struct ubcore_device *ubc_dev, struct uburma_file *file, + struct uburma_cmd_hdr *hdr) +{ + struct uburma_cmd_unimport_jfr arg; + struct uburma_uobj *uobj; + int ret; + + ret = uburma_copy_from_user(&arg, (void __user *)(uintptr_t)hdr->args_addr, + sizeof(struct uburma_cmd_unimport_jfr)); + if (ret != 0) + return ret; + + uobj = uobj_get_del(UOBJ_CLASS_TARGET_JFR, arg.in.handle, file); + if (IS_ERR(uobj)) { + uburma_log_err("failed to find tjfr"); + return -EINVAL; + } + ret = uobj_remove_commit(uobj); + if (ret != 0) + uburma_log_err("ubcore_unimport_jfr failed.\n"); + return ret; +} + typedef int (*uburma_cmd_handler)(struct ubcore_device *ubc_dev, struct uburma_file *file, struct uburma_cmd_hdr *hdr); @@ -626,6 +704,8 @@ static uburma_cmd_handler g_uburma_cmd_handlers[] = { [UBURMA_CMD_CREATE_JFC] = uburma_cmd_create_jfc, [UBURMA_CMD_MODIFY_JFC] = uburma_cmd_modify_jfc, [UBURMA_CMD_DELETE_JFC] = uburma_cmd_delete_jfc, + [UBURMA_CMD_IMPORT_JFR] = uburma_cmd_import_jfr, + [UBURMA_CMD_UNIMPORT_JFR] = uburma_cmd_unimport_jfr, }; static int uburma_cmd_parse(struct ubcore_device *ubc_dev, struct uburma_file *file, diff --git a/drivers/ub/urma/uburma/uburma_cmd.h b/drivers/ub/urma/uburma/uburma_cmd.h index 6a7c5cf74717..afcfd462eb7f 100644 --- a/drivers/ub/urma/uburma/uburma_cmd.h +++ b/drivers/ub/urma/uburma/uburma_cmd.h @@ -48,6 +48,8 @@ enum uburma_cmd { UBURMA_CMD_CREATE_JFC, UBURMA_CMD_MODIFY_JFC, UBURMA_CMD_DELETE_JFC, + UBURMA_CMD_IMPORT_JFR, + UBURMA_CMD_UNIMPORT_JFR, UBURMA_CMD_USER_CTL }; @@ -179,6 +181,30 @@ struct uburma_cmd_delete_jfc { } out; }; +struct uburma_cmd_import_jfr { + struct { + /* correspond to urma_jfr_id */ + uint8_t eid[UBCORE_EID_SIZE]; + uint32_t uasid; + uint32_t id; + /* correspond to urma_key_t */ + uint32_t key; + uint32_t trans_mode; + } in; + struct { + uint8_t tp_type; /* TP or TPG */ + uint32_t tpn; + uint64_t handle; /* handle of the allocated tjfr obj in kernel */ + } out; + struct uburma_cmd_udrv_priv udata; +}; + +struct uburma_cmd_unimport_jfr { + struct { + uint64_t handle; /* handle of tjfr, used to find tjfr obj in kernel */ + } in; +}; + /* only for event ioctl */ #define MAX_JFCE_EVENT_CNT 16 #define UBURMA_EVENT_CMD_MAGIC 'E' -- Gitee From c3af5be3e72710b357d9f23a5bdcafe8f96d6dfd Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Sat, 16 Sep 2023 15:59:24 +0800 Subject: [PATCH 48/89] ub: uburma add cmd create jetty implementation. driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Uburma add implementations of handling create jetty cmd from user layer. This will make kernel possible to handle urma_create_jetty api in user-layer urma. Create jetty will finally call ubcore_create_jetty. The created jetty will be related to a uobj. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/uburma/uburma_cmd.c | 138 ++++++++++++++++++++++++++++ drivers/ub/urma/uburma/uburma_cmd.h | 39 ++++++++ 2 files changed, 177 insertions(+) diff --git a/drivers/ub/urma/uburma/uburma_cmd.c b/drivers/ub/urma/uburma/uburma_cmd.c index e6cb998aef45..114abe9687a5 100644 --- a/drivers/ub/urma/uburma/uburma_cmd.c +++ b/drivers/ub/urma/uburma/uburma_cmd.c @@ -177,6 +177,18 @@ void uburma_jfr_event_cb(struct ubcore_event *event, struct ubcore_ucontext *ctx &jfr_uobj->async_event_list, &jfr_uobj->async_events_reported); } +void uburma_jetty_event_cb(struct ubcore_event *event, struct ubcore_ucontext *ctx) +{ + struct uburma_jetty_uobj *jetty_uobj; + + if (event->element.jetty == NULL) + return; + + jetty_uobj = (struct uburma_jetty_uobj *)event->element.jetty->jetty_cfg.jetty_context; + uburma_write_async_event(ctx, event->element.jetty->urma_jetty, event->event_type, + &jetty_uobj->async_event_list, &jetty_uobj->async_events_reported); +} + static int uburma_cmd_create_jfs(struct ubcore_device *ubc_dev, struct uburma_file *file, struct uburma_cmd_hdr *hdr) { @@ -611,6 +623,131 @@ static int uburma_cmd_delete_jfc(struct ubcore_device *ubc_dev, struct uburma_fi sizeof(struct uburma_cmd_delete_jfc)); } +static void fill_create_jetty_attr(struct ubcore_jetty_cfg *cfg, + const struct uburma_cmd_create_jetty *arg) +{ + cfg->id = arg->in.id; + cfg->jfs_depth = arg->in.jfs_depth; + cfg->jfr_depth = arg->in.jfr_depth; + cfg->flag.value = arg->in.flag; + cfg->trans_mode = arg->in.trans_mode; + cfg->max_send_sge = arg->in.max_send_sge; + cfg->max_send_rsge = arg->in.max_send_rsge; + cfg->max_recv_sge = arg->in.max_recv_sge; + cfg->max_inline_data = arg->in.max_inline_data; + cfg->priority = arg->in.priority; + cfg->retry_cnt = arg->in.retry_cnt; + cfg->rnr_retry = arg->in.rnr_retry; + cfg->err_timeout = arg->in.err_timeout; + cfg->min_rnr_timer = arg->in.min_rnr_timer; +} + +static void fill_create_jetty_out(struct uburma_cmd_create_jetty *arg, + const struct ubcore_jetty *jetty) +{ + arg->out.id = jetty->id; + arg->out.jfs_depth = jetty->jetty_cfg.jfs_depth; + arg->out.jfr_depth = jetty->jetty_cfg.jfr_depth; + arg->out.max_send_sge = jetty->jetty_cfg.max_send_sge; + arg->out.max_send_rsge = jetty->jetty_cfg.max_send_rsge; + arg->out.max_recv_sge = jetty->jetty_cfg.max_recv_sge; + arg->out.max_inline_data = jetty->jetty_cfg.max_inline_data; +} + +static int uburma_cmd_create_jetty(struct ubcore_device *ubc_dev, struct uburma_file *file, + struct uburma_cmd_hdr *hdr) +{ + struct uburma_cmd_create_jetty arg; + struct uburma_uobj *send_jfc_uobj = ERR_PTR(-ENOENT); + struct uburma_uobj *recv_jfc_uobj = ERR_PTR(-ENOENT); + struct uburma_uobj *jfr_uobj = ERR_PTR(-ENOENT); + struct ubcore_jetty_cfg cfg = { 0 }; + struct uburma_jetty_uobj *jetty_uobj; + struct ubcore_udata udata; + struct ubcore_jetty *jetty; + int ret = 0; + + ret = uburma_copy_from_user(&arg, (void __user *)(uintptr_t)hdr->args_addr, + sizeof(struct uburma_cmd_create_jetty)); + if (ret != 0) + return ret; + + jetty_uobj = (struct uburma_jetty_uobj *)uobj_alloc(UOBJ_CLASS_JETTY, file); + if (IS_ERR(jetty_uobj)) { + uburma_log_err("UOBJ_CLASS_JETTY alloc fail!\n"); + return -ENOMEM; + } + jetty_uobj->async_events_reported = 0; + INIT_LIST_HEAD(&jetty_uobj->async_event_list); + cfg.jetty_context = jetty_uobj; + + fill_create_jetty_attr(&cfg, &arg); + send_jfc_uobj = uobj_get_read(UOBJ_CLASS_JFC, arg.in.send_jfc_handle, file); + recv_jfc_uobj = uobj_get_read(UOBJ_CLASS_JFC, arg.in.recv_jfc_handle, file); + if (IS_ERR(send_jfc_uobj) || IS_ERR(recv_jfc_uobj)) { + uburma_log_err("failed to find send %llu or recv jfc %llu.\n", + arg.in.send_jfc_handle, arg.in.recv_jfc_handle); + ret = -EINVAL; + goto err_put; + } + cfg.send_jfc = send_jfc_uobj->object; + cfg.recv_jfc = recv_jfc_uobj->object; + if (cfg.flag.bs.share_jfr != 0) { + jfr_uobj = uobj_get_read(UOBJ_CLASS_JFR, arg.in.jfr_handle, file); + if (IS_ERR(jfr_uobj)) { + uburma_log_err("failed to find jfr, jfr_handle:%llu.\n", arg.in.jfr_handle); + ret = -EINVAL; + goto err_put; + } + cfg.jfr = jfr_uobj->object; + } + cfg.ukey.key = arg.in.key; + fill_udata(&udata, file->ucontext, &arg.udata); + + jetty = ubcore_create_jetty(ubc_dev, &cfg, uburma_jetty_event_cb, &udata); + if (IS_ERR_OR_NULL(jetty)) { + uburma_log_err("create jetty or get jetty_id failed.\n"); + ret = -EPERM; + goto err_put; + } + + jetty_uobj->uobj.object = jetty; + jetty->urma_jetty = arg.in.urma_jetty; + /* Do not release jfae fd until jetty is destroyed */ + ret = uburma_get_jfae(file); + if (ret != 0) + goto err_delete_jetty; + + fill_create_jetty_out(&arg, jetty); + arg.out.handle = jetty_uobj->uobj.id; + + ret = uburma_copy_to_user((void __user *)(uintptr_t)hdr->args_addr, &arg, + sizeof(struct uburma_cmd_create_jetty)); + if (ret != 0) + goto err_put_jfae; + + if (cfg.jfr) + uobj_put_read(jfr_uobj); + uobj_put_read(send_jfc_uobj); + uobj_put_read(recv_jfc_uobj); + uobj_alloc_commit(&jetty_uobj->uobj); + return 0; + +err_put_jfae: + uburma_put_jfae(file); +err_delete_jetty: + (void)ubcore_delete_jetty(jetty); +err_put: + if (!IS_ERR(jfr_uobj)) + uobj_put_read(jfr_uobj); + if (!IS_ERR(recv_jfc_uobj)) + uobj_put_read(recv_jfc_uobj); + if (!IS_ERR(send_jfc_uobj)) + uobj_put_read(send_jfc_uobj); + uobj_alloc_abort(&jetty_uobj->uobj); + return ret; +} + static int uburma_cmd_import_jfr(struct ubcore_device *ubc_dev, struct uburma_file *file, struct uburma_cmd_hdr *hdr) { @@ -706,6 +843,7 @@ static uburma_cmd_handler g_uburma_cmd_handlers[] = { [UBURMA_CMD_DELETE_JFC] = uburma_cmd_delete_jfc, [UBURMA_CMD_IMPORT_JFR] = uburma_cmd_import_jfr, [UBURMA_CMD_UNIMPORT_JFR] = uburma_cmd_unimport_jfr, + [UBURMA_CMD_CREATE_JETTY] = uburma_cmd_create_jetty, }; static int uburma_cmd_parse(struct ubcore_device *ubc_dev, struct uburma_file *file, diff --git a/drivers/ub/urma/uburma/uburma_cmd.h b/drivers/ub/urma/uburma/uburma_cmd.h index afcfd462eb7f..9cfd8bba88b4 100644 --- a/drivers/ub/urma/uburma/uburma_cmd.h +++ b/drivers/ub/urma/uburma/uburma_cmd.h @@ -50,6 +50,7 @@ enum uburma_cmd { UBURMA_CMD_DELETE_JFC, UBURMA_CMD_IMPORT_JFR, UBURMA_CMD_UNIMPORT_JFR, + UBURMA_CMD_CREATE_JETTY, UBURMA_CMD_USER_CTL }; @@ -205,6 +206,44 @@ struct uburma_cmd_unimport_jfr { } in; }; +struct uburma_cmd_create_jetty { + struct { + uint32_t id; /* user may assign id */ + uint32_t jfs_depth; + uint32_t jfr_depth; + uint32_t flag; + uint32_t trans_mode; + uint32_t send_jfc_id; + uint32_t recv_jfc_id; + uint32_t jfr_id; /* shared jfr */ + uint8_t max_send_sge; + uint8_t max_send_rsge; + uint8_t max_recv_sge; + uint32_t max_inline_data; + uint8_t priority; + uint8_t retry_cnt; + uint8_t rnr_retry; + uint8_t err_timeout; + uint8_t min_rnr_timer; + uint32_t key; + uint64_t send_jfc_handle; /* handle of the related send jfc */ + uint64_t recv_jfc_handle; /* handle of the related recv jfc */ + uint64_t jfr_handle; /* handle of the shared jfr */ + uint64_t urma_jetty; /* urma jetty pointer */ + } in; + struct { + uint32_t id; /* jetty id allocated by ubcore */ + uint64_t handle; /* handle of the allocated jetty obj in kernel */ + uint32_t jfs_depth; + uint32_t jfr_depth; + uint8_t max_send_sge; + uint8_t max_send_rsge; + uint8_t max_recv_sge; + uint32_t max_inline_data; + } out; + struct uburma_cmd_udrv_priv udata; +}; + /* only for event ioctl */ #define MAX_JFCE_EVENT_CNT 16 #define UBURMA_EVENT_CMD_MAGIC 'E' -- Gitee From b43e7ce22bf7b5129b7be7ff75db53dedb30b11a Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Sat, 16 Sep 2023 16:04:42 +0800 Subject: [PATCH 49/89] ub: uburma add cmd modify/delete jetty implementation. driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Uburma add implementations of handling modify/delete jetty cmd from user layer. This will make kernel possible to handle urma_modify_jetty/urma_delete_jfy api in user-layer urma. Modify_jetty will finally call ubcore_modify_jetty. Delete_jetty will delete the jetty-related uobj. In uobj destroy function, it will call ubcore_delete_jetty. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/uburma/uburma_cmd.c | 77 +++++++++++++++++++++++++++++ drivers/ub/urma/uburma/uburma_cmd.h | 20 ++++++++ 2 files changed, 97 insertions(+) diff --git a/drivers/ub/urma/uburma/uburma_cmd.c b/drivers/ub/urma/uburma/uburma_cmd.c index 114abe9687a5..32e4930b9e3e 100644 --- a/drivers/ub/urma/uburma/uburma_cmd.c +++ b/drivers/ub/urma/uburma/uburma_cmd.c @@ -748,6 +748,81 @@ static int uburma_cmd_create_jetty(struct ubcore_device *ubc_dev, struct uburma_ return ret; } +static int uburma_cmd_modify_jetty(struct ubcore_device *ubc_dev, struct uburma_file *file, + struct uburma_cmd_hdr *hdr) +{ + struct uburma_cmd_modify_jetty arg; + struct uburma_uobj *uobj; + struct ubcore_jetty_attr attr = { 0 }; + struct ubcore_jetty *jetty; + struct ubcore_udata udata; + int ret; + + ret = uburma_copy_from_user(&arg, (void __user *)(uintptr_t)hdr->args_addr, + sizeof(struct uburma_cmd_modify_jetty)); + if (ret != 0) + return ret; + + attr.mask = arg.in.mask; + attr.rx_threshold = arg.in.rx_threshold; + fill_udata(&udata, file->ucontext, &arg.udata); + + uobj = uobj_get_write(UOBJ_CLASS_JETTY, arg.in.handle, file); + if (IS_ERR(uobj)) { + uburma_log_err("failed to find jetty.\n"); + return -EINVAL; + } + + jetty = (struct ubcore_jetty *)uobj->object; + ret = ubcore_modify_jetty(jetty, &attr, &udata); + if (ret != 0) { + uobj_put_write(uobj); + uburma_log_err("modify jetty failed, ret:%d.\n", ret); + return ret; + } + + ret = uburma_copy_to_user((void __user *)(uintptr_t)hdr->args_addr, &arg, + sizeof(struct uburma_cmd_modify_jetty)); + uobj_put_write(uobj); + return ret; +} + +static int uburma_cmd_delete_jetty(struct ubcore_device *ubc_dev, struct uburma_file *file, + struct uburma_cmd_hdr *hdr) +{ + struct uburma_cmd_delete_jetty arg; + struct uburma_jetty_uobj *jetty_uobj; + struct uburma_uobj *uobj; + int ret; + + ret = uburma_copy_from_user(&arg, (void __user *)(uintptr_t)hdr->args_addr, + sizeof(struct uburma_cmd_delete_jetty)); + if (ret != 0) + return ret; + + uobj = uobj_get_del(UOBJ_CLASS_JETTY, arg.in.handle, file); + if (IS_ERR(uobj)) { + uburma_log_err("failed to find jetty"); + return -EINVAL; + } + + /* To get async_events_reported after obj removed. */ + uobj_get(uobj); + jetty_uobj = container_of(uobj, struct uburma_jetty_uobj, uobj); + + ret = uobj_remove_commit(uobj); + if (ret != 0) { + uburma_log_err("delete jetty failed, ret:%d.\n", ret); + uobj_put(uobj); + return ret; + } + + arg.out.async_events_reported = jetty_uobj->async_events_reported; + uobj_put(uobj); + return uburma_copy_to_user((void __user *)(uintptr_t)hdr->args_addr, &arg, + sizeof(struct uburma_cmd_delete_jetty)); +} + static int uburma_cmd_import_jfr(struct ubcore_device *ubc_dev, struct uburma_file *file, struct uburma_cmd_hdr *hdr) { @@ -844,6 +919,8 @@ static uburma_cmd_handler g_uburma_cmd_handlers[] = { [UBURMA_CMD_IMPORT_JFR] = uburma_cmd_import_jfr, [UBURMA_CMD_UNIMPORT_JFR] = uburma_cmd_unimport_jfr, [UBURMA_CMD_CREATE_JETTY] = uburma_cmd_create_jetty, + [UBURMA_CMD_MODIFY_JETTY] = uburma_cmd_modify_jetty, + [UBURMA_CMD_DELETE_JETTY] = uburma_cmd_delete_jetty, }; static int uburma_cmd_parse(struct ubcore_device *ubc_dev, struct uburma_file *file, diff --git a/drivers/ub/urma/uburma/uburma_cmd.h b/drivers/ub/urma/uburma/uburma_cmd.h index 9cfd8bba88b4..49ee66c894d6 100644 --- a/drivers/ub/urma/uburma/uburma_cmd.h +++ b/drivers/ub/urma/uburma/uburma_cmd.h @@ -51,6 +51,8 @@ enum uburma_cmd { UBURMA_CMD_IMPORT_JFR, UBURMA_CMD_UNIMPORT_JFR, UBURMA_CMD_CREATE_JETTY, + UBURMA_CMD_MODIFY_JETTY, + UBURMA_CMD_DELETE_JETTY, UBURMA_CMD_USER_CTL }; @@ -244,6 +246,24 @@ struct uburma_cmd_create_jetty { struct uburma_cmd_udrv_priv udata; }; +struct uburma_cmd_modify_jetty { + struct { + uint64_t handle; /* handle of jetty, used to find jetty obj in kernel */ + uint32_t mask; /* see urma_jetty_attr_mask_t */ + uint32_t rx_threshold; + } in; + struct uburma_cmd_udrv_priv udata; +}; + +struct uburma_cmd_delete_jetty { + struct { + uint64_t handle; /* handle of jetty, used to find jetty obj in kernel */ + } in; + struct { + uint32_t async_events_reported; + } out; +}; + /* only for event ioctl */ #define MAX_JFCE_EVENT_CNT 16 #define UBURMA_EVENT_CMD_MAGIC 'E' -- Gitee From eca25b0c89e9c0e052e02d4a523e4c4e77ad6320 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Sat, 16 Sep 2023 16:12:12 +0800 Subject: [PATCH 50/89] ub: uburma add cmd import/unimport jetty implementation. driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Uburma add implementations of handling import/unimport jetty cmd from user layer. This will make kernel possible to handle urma_import_jetty and urma_unimport_jetty api in user-layer urma. Import_jetty will finally call ubcore_import_jetty. The created target jetty (tjetty) will be related to a uobj. Unimport_jetty will delete the tjetty-related uobj. In uobj destroy function, it will call ubcore_unimport_jetty. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/uburma/uburma_cmd.c | 84 ++++++++++++++++++++++++++++- drivers/ub/urma/uburma/uburma_cmd.h | 27 ++++++++++ 2 files changed, 109 insertions(+), 2 deletions(-) diff --git a/drivers/ub/urma/uburma/uburma_cmd.c b/drivers/ub/urma/uburma/uburma_cmd.c index 32e4930b9e3e..ca93576cbced 100644 --- a/drivers/ub/urma/uburma/uburma_cmd.c +++ b/drivers/ub/urma/uburma/uburma_cmd.c @@ -901,6 +901,84 @@ static int uburma_cmd_unimport_jfr(struct ubcore_device *ubc_dev, struct uburma_ return ret; } +static int uburma_cmd_import_jetty(struct ubcore_device *ubc_dev, struct uburma_file *file, + struct uburma_cmd_hdr *hdr) +{ + struct uburma_cmd_import_jetty arg; + struct ubcore_tjetty_cfg cfg = { 0 }; + struct ubcore_tjetty *tjetty; + struct ubcore_udata udata; + struct uburma_uobj *uobj; + int ret; + + ret = uburma_copy_from_user(&arg, (void __user *)(uintptr_t)hdr->args_addr, + sizeof(struct uburma_cmd_import_jetty)); + if (ret != 0) + return ret; + + uobj = uobj_alloc(UOBJ_CLASS_TARGET_JETTY, file); + if (IS_ERR(uobj)) { + uburma_log_err("UOBJ_CLASS_TARGET_JETTY alloc fail!\n"); + return -ENOMEM; + } + + (void)memcpy(cfg.id.eid.raw, arg.in.eid, UBCORE_EID_SIZE); + cfg.id.uasid = arg.in.uasid; + cfg.id.id = arg.in.id; + cfg.ukey.key = arg.in.key; + cfg.trans_mode = (enum ubcore_transport_mode)arg.in.trans_mode; + fill_udata(&udata, file->ucontext, &arg.udata); + + tjetty = ubcore_import_jetty(ubc_dev, &cfg, &udata); + if (IS_ERR_OR_NULL(tjetty)) { + uburma_log_err("ubcore_import_jetty failed.\n"); + uobj_alloc_abort(uobj); + return -EPERM; + } + + uobj->object = tjetty; + arg.out.handle = uobj->id; + if (tjetty->tp != NULL) { + arg.out.tp_type = 1; + arg.out.tpn = tjetty->tp->tpn; + } else { + arg.out.tpn = UBURMA_INVALID_TPN; + } + + ret = uburma_copy_to_user((void __user *)(uintptr_t)hdr->args_addr, &arg, + sizeof(struct uburma_cmd_import_jetty)); + if (ret != 0) { + (void)ubcore_unimport_jetty(tjetty); + uobj_alloc_abort(uobj); + return ret; + } + uobj_alloc_commit(uobj); + return 0; +} + +static int uburma_cmd_unimport_jetty(struct ubcore_device *ubc_dev, struct uburma_file *file, + struct uburma_cmd_hdr *hdr) +{ + struct uburma_cmd_unimport_jetty arg; + struct uburma_uobj *uobj; + int ret; + + ret = uburma_copy_from_user(&arg, (void __user *)(uintptr_t)hdr->args_addr, + sizeof(struct uburma_cmd_unimport_jetty)); + if (ret != 0) + return ret; + + uobj = uobj_get_del(UOBJ_CLASS_TARGET_JETTY, arg.in.handle, file); + if (IS_ERR(uobj)) { + uburma_log_err("failed to find tjetty"); + return -EINVAL; + } + ret = uobj_remove_commit(uobj); + if (ret != 0) + uburma_log_err("ubcore_unimport_jetty failed.\n"); + return ret; +} + typedef int (*uburma_cmd_handler)(struct ubcore_device *ubc_dev, struct uburma_file *file, struct uburma_cmd_hdr *hdr); @@ -908,11 +986,11 @@ static uburma_cmd_handler g_uburma_cmd_handlers[] = { [0] = NULL, [UBURMA_CMD_CREATE_CTX] = uburma_cmd_create_ctx, [UBURMA_CMD_DESTROY_CTX] = uburma_cmd_destroy_ctx, - [UBURMA_CMD_CREATE_JFS] = uburma_cmd_create_jfs, - [UBURMA_CMD_DELETE_JFS] = uburma_cmd_delete_jfs, [UBURMA_CMD_CREATE_JFR] = uburma_cmd_create_jfr, [UBURMA_CMD_MODIFY_JFR] = uburma_cmd_modify_jfr, [UBURMA_CMD_DELETE_JFR] = uburma_cmd_delete_jfr, + [UBURMA_CMD_CREATE_JFS] = uburma_cmd_create_jfs, + [UBURMA_CMD_DELETE_JFS] = uburma_cmd_delete_jfs, [UBURMA_CMD_CREATE_JFC] = uburma_cmd_create_jfc, [UBURMA_CMD_MODIFY_JFC] = uburma_cmd_modify_jfc, [UBURMA_CMD_DELETE_JFC] = uburma_cmd_delete_jfc, @@ -921,6 +999,8 @@ static uburma_cmd_handler g_uburma_cmd_handlers[] = { [UBURMA_CMD_CREATE_JETTY] = uburma_cmd_create_jetty, [UBURMA_CMD_MODIFY_JETTY] = uburma_cmd_modify_jetty, [UBURMA_CMD_DELETE_JETTY] = uburma_cmd_delete_jetty, + [UBURMA_CMD_IMPORT_JETTY] = uburma_cmd_import_jetty, + [UBURMA_CMD_UNIMPORT_JETTY] = uburma_cmd_unimport_jetty, }; static int uburma_cmd_parse(struct ubcore_device *ubc_dev, struct uburma_file *file, diff --git a/drivers/ub/urma/uburma/uburma_cmd.h b/drivers/ub/urma/uburma/uburma_cmd.h index 49ee66c894d6..1fd417a84494 100644 --- a/drivers/ub/urma/uburma/uburma_cmd.h +++ b/drivers/ub/urma/uburma/uburma_cmd.h @@ -53,6 +53,8 @@ enum uburma_cmd { UBURMA_CMD_CREATE_JETTY, UBURMA_CMD_MODIFY_JETTY, UBURMA_CMD_DELETE_JETTY, + UBURMA_CMD_IMPORT_JETTY, + UBURMA_CMD_UNIMPORT_JETTY, UBURMA_CMD_USER_CTL }; @@ -264,6 +266,31 @@ struct uburma_cmd_delete_jetty { } out; }; +struct uburma_cmd_import_jetty { + struct { + /* correspond to urma_jetty_id */ + uint8_t eid[UBCORE_EID_SIZE]; + uint32_t uasid; + uint32_t id; + uint32_t flag; + /* correspond to urma_key_t */ + uint32_t key; + uint32_t trans_mode; + } in; + struct { + uint8_t tp_type; /* TP or TPG */ + uint32_t tpn; + uint64_t handle; /* handle of the allocated tjetty obj in kernel */ + } out; + struct uburma_cmd_udrv_priv udata; +}; + +struct uburma_cmd_unimport_jetty { + struct { + uint64_t handle; /* handle of tjetty, used to find tjetty obj in kernel */ + } in; +}; + /* only for event ioctl */ #define MAX_JFCE_EVENT_CNT 16 #define UBURMA_EVENT_CMD_MAGIC 'E' -- Gitee From bbf7bf456368310f71efd6b26e8bd364e37729d7 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Sat, 16 Sep 2023 16:20:40 +0800 Subject: [PATCH 51/89] ub: uburma add cmd create jfce implementation. driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Uburma add implementations of handling create jfce cmd from user layer. This will make kernel possible to handle urma_create_jfce api in user-layer urma. Create jfce will finally call ubcore_create_jfce. The created jfce will be related to a uobj. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/uburma/uburma_cmd.c | 33 +++++++++++++++++++++++++++++ drivers/ub/urma/uburma/uburma_cmd.h | 7 ++++++ 2 files changed, 40 insertions(+) diff --git a/drivers/ub/urma/uburma/uburma_cmd.c b/drivers/ub/urma/uburma/uburma_cmd.c index ca93576cbced..7ecea2c9e33d 100644 --- a/drivers/ub/urma/uburma/uburma_cmd.c +++ b/drivers/ub/urma/uburma/uburma_cmd.c @@ -823,6 +823,38 @@ static int uburma_cmd_delete_jetty(struct ubcore_device *ubc_dev, struct uburma_ sizeof(struct uburma_cmd_delete_jetty)); } +static int uburma_cmd_create_jfce(struct ubcore_device *ubc_dev, struct uburma_file *file, + struct uburma_cmd_hdr *hdr) +{ + struct uburma_cmd_create_jfce arg; + struct uburma_jfce_uobj *jfce; + struct uburma_uobj *uobj; + int ret; + + ret = uburma_copy_from_user(&arg, (void __user *)(uintptr_t)hdr->args_addr, + sizeof(struct uburma_cmd_create_jfce)); + if (ret != 0) + return ret; + + uobj = uobj_alloc(UOBJ_CLASS_JFCE, file); + if (IS_ERR(uobj)) + return PTR_ERR(uobj); + + jfce = container_of(uobj, struct uburma_jfce_uobj, uobj); + uburma_init_jfe(&jfce->jfe); + + arg.out.fd = uobj->id; /* should get fd before commit uobj */ + ret = uburma_copy_to_user((void __user *)(uintptr_t)hdr->args_addr, &arg, + sizeof(struct uburma_cmd_create_jfce)); + if (ret != 0) { + uobj_alloc_abort(uobj); + return ret; + } + + uobj_alloc_commit(uobj); + return ret; +} + static int uburma_cmd_import_jfr(struct ubcore_device *ubc_dev, struct uburma_file *file, struct uburma_cmd_hdr *hdr) { @@ -994,6 +1026,7 @@ static uburma_cmd_handler g_uburma_cmd_handlers[] = { [UBURMA_CMD_CREATE_JFC] = uburma_cmd_create_jfc, [UBURMA_CMD_MODIFY_JFC] = uburma_cmd_modify_jfc, [UBURMA_CMD_DELETE_JFC] = uburma_cmd_delete_jfc, + [UBURMA_CMD_CREATE_JFCE] = uburma_cmd_create_jfce, [UBURMA_CMD_IMPORT_JFR] = uburma_cmd_import_jfr, [UBURMA_CMD_UNIMPORT_JFR] = uburma_cmd_unimport_jfr, [UBURMA_CMD_CREATE_JETTY] = uburma_cmd_create_jetty, diff --git a/drivers/ub/urma/uburma/uburma_cmd.h b/drivers/ub/urma/uburma/uburma_cmd.h index 1fd417a84494..6e49461428f4 100644 --- a/drivers/ub/urma/uburma/uburma_cmd.h +++ b/drivers/ub/urma/uburma/uburma_cmd.h @@ -48,6 +48,7 @@ enum uburma_cmd { UBURMA_CMD_CREATE_JFC, UBURMA_CMD_MODIFY_JFC, UBURMA_CMD_DELETE_JFC, + UBURMA_CMD_CREATE_JFCE, UBURMA_CMD_IMPORT_JFR, UBURMA_CMD_UNIMPORT_JFR, UBURMA_CMD_CREATE_JETTY, @@ -186,6 +187,12 @@ struct uburma_cmd_delete_jfc { } out; }; +struct uburma_cmd_create_jfce { + struct { + int fd; + } out; +}; + struct uburma_cmd_import_jfr { struct { /* correspond to urma_jfr_id */ -- Gitee From 832e9fe8cf1ed02211ff43bd4f3f16ddc2d69969 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Sat, 16 Sep 2023 17:25:24 +0800 Subject: [PATCH 52/89] ub: ubcore add create/delete tp table api driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Ubcore add create/delete tp table api, including: - ubcore_create_tptable: it will use ubcore_hash_table as the hash table. - ubcore_destroy_tptable: destroy the tp hash table. - ubcore_remove_tp_node: remove tp node in tp hash table. - ubcore_destroy_tp: destroy the tp by calling the destroy_tp method registered by driver. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/ubcore/Makefile | 3 +- drivers/ub/urma/ubcore/ubcore_device.c | 5 ++ drivers/ub/urma/ubcore/ubcore_tp.c | 20 +++++- drivers/ub/urma/ubcore/ubcore_tp.h | 3 + drivers/ub/urma/ubcore/ubcore_tp_table.c | 91 ++++++++++++++++++++++++ drivers/ub/urma/ubcore/ubcore_tp_table.h | 53 ++++++++++++++ 6 files changed, 173 insertions(+), 2 deletions(-) create mode 100644 drivers/ub/urma/ubcore/ubcore_tp_table.c create mode 100644 drivers/ub/urma/ubcore/ubcore_tp_table.h diff --git a/drivers/ub/urma/ubcore/Makefile b/drivers/ub/urma/ubcore/Makefile index add2d10d23d6..f211ad6dee8a 100644 --- a/drivers/ub/urma/ubcore/Makefile +++ b/drivers/ub/urma/ubcore/Makefile @@ -7,8 +7,9 @@ ubcore-objs := ubcore_main.o \ ubcore_device.o \ ubcore_jetty.o \ ubcore_umem.o \ - ubcore_tp.o \ ubcore_hash_table.o \ + ubcore_tp.o \ + ubcore_tp_table.o \ ubcore_netlink.o \ ubcore_dp.o diff --git a/drivers/ub/urma/ubcore/ubcore_device.c b/drivers/ub/urma/ubcore/ubcore_device.c index ee62b9010932..ec8441ab2080 100644 --- a/drivers/ub/urma/ubcore/ubcore_device.c +++ b/drivers/ub/urma/ubcore/ubcore_device.c @@ -33,6 +33,8 @@ #include #include "ubcore_priv.h" #include "ubcore_hash_table.h" +#include "ubcore_tp.h" +#include "ubcore_tp_table.h" static LIST_HEAD(g_client_list); static LIST_HEAD(g_device_list); @@ -322,6 +324,9 @@ static struct ubcore_ht_param g_ht_params[] = { [UBCORE_HT_JETTY] = { UBCORE_HASH_TABLE_SIZE, offsetof(struct ubcore_jetty, hnode), offsetof(struct ubcore_jetty, id), sizeof(uint32_t), NULL, NULL }, + [UBCORE_HT_TP] = { UBCORE_HASH_TABLE_SIZE, offsetof(struct ubcore_tp_node, hnode), + offsetof(struct ubcore_tp_node, key), sizeof(struct ubcore_tp_key), NULL, + NULL }, }; static int ubcore_alloc_hash_tables(struct ubcore_device *dev) diff --git a/drivers/ub/urma/ubcore/ubcore_tp.c b/drivers/ub/urma/ubcore/ubcore_tp.c index ca665a16a07f..9c94333856de 100644 --- a/drivers/ub/urma/ubcore/ubcore_tp.c +++ b/drivers/ub/urma/ubcore/ubcore_tp.c @@ -22,8 +22,12 @@ #include #include #include -#include +#include "ubcore_log.h" +#include "ubcore_netlink.h" +#include "ubcore_priv.h" #include +#include "ubcore_tp_table.h" +#include "ubcore_tp.h" #define UB_PROTOCOL_HEAD_BYTES 313 #define UB_MTU_BITS_BASE_SHIFT 7 @@ -54,6 +58,20 @@ enum ubcore_mtu ubcore_get_mtu(int mtu) } EXPORT_SYMBOL(ubcore_get_mtu); +int ubcore_destroy_tp(struct ubcore_tp *tp) +{ + if (!ubcore_have_tp_ops(tp->ub_dev)) { + ubcore_log_err("TP ops is NULL"); + return -1; + } + + if (tp->peer_ext.len > 0 && tp->peer_ext.addr != 0) + kfree((void *)tp->peer_ext.addr); + + return tp->ub_dev->ops->destroy_tp(tp); +} +EXPORT_SYMBOL(ubcore_destroy_tp); + struct ubcore_tp *ubcore_create_vtp(struct ubcore_device *dev, const union ubcore_eid *remote_eid, enum ubcore_transport_mode trans_mode, struct ubcore_udata *udata) diff --git a/drivers/ub/urma/ubcore/ubcore_tp.h b/drivers/ub/urma/ubcore/ubcore_tp.h index 5931220caf61..b29c9f220dae 100644 --- a/drivers/ub/urma/ubcore/ubcore_tp.h +++ b/drivers/ub/urma/ubcore/ubcore_tp.h @@ -29,4 +29,7 @@ static inline bool ubcore_have_tp_ops(const struct ubcore_device *dev) return (dev != NULL && dev->ops->create_tp != NULL && dev->ops->modify_tp != NULL && dev->ops->destroy_tp != NULL); } + +/* Called when clear tp table */ +int ubcore_destroy_tp(struct ubcore_tp *tp); #endif diff --git a/drivers/ub/urma/ubcore/ubcore_tp_table.c b/drivers/ub/urma/ubcore/ubcore_tp_table.c new file mode 100644 index 000000000000..3463be68e52f --- /dev/null +++ b/drivers/ub/urma/ubcore/ubcore_tp_table.c @@ -0,0 +1,91 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + * + * Description: ubcore tp table implementation + * Author: Yan Fangfang + * Create: 2023-02-09 + * Note: + * History: 2023-02-09: Create file + */ + +#include +#include "ubcore_log.h" +#include "ubcore_priv.h" +#include "ubcore_tp.h" +#include "ubcore_tp_table.h" + +void ubcore_init_tp_key_jetty_id(struct ubcore_tp_key *key, const struct ubcore_jetty_id *jetty_id) +{ + memset(key, 0, sizeof(struct ubcore_tp_key)); + key->key_type = UBCORE_TP_KEY_JETTY_ID; + key->jetty_id = *jetty_id; +} + +void ubcore_remove_tp_node(struct ubcore_hash_table *ht, struct ubcore_tp_node *tp_node) +{ + if (tp_node == NULL) + return; + + ubcore_hash_table_remove(ht, &tp_node->hnode); + kfree(tp_node); +} + +struct ubcore_hash_table *ubcore_create_tptable(void) +{ + struct ubcore_ht_param p = { .size = UBCORE_HASH_TABLE_SIZE, + .node_offset = offsetof(struct ubcore_tp_node, hnode), + .key_offset = offsetof(struct ubcore_tp_node, key), + .key_size = sizeof(struct ubcore_tp_key), + .cmp_f = NULL, + .free_f = NULL }; + struct ubcore_hash_table *ht; + + ht = kcalloc(1, sizeof(struct ubcore_hash_table), GFP_KERNEL); + if (ht == NULL) + return NULL; + + if (ubcore_hash_table_alloc(ht, &p) != 0) { + kfree(ht); + ubcore_log_err("Failed to calloc jfs tp hash table"); + return NULL; + } + return ht; +} + +static void ubcore_free_tp_node(void *obj) +{ + struct ubcore_tp_node *tp_node = (struct ubcore_tp_node *)obj; + (void)ubcore_destroy_tp(tp_node->tp); + kfree(tp_node); +} + +static void ubcore_tptable_release(struct kref *kref) +{ + struct ubcore_hash_table *ht = container_of(kref, struct ubcore_hash_table, kref); + + kfree(ht); +} + +void ubcore_destroy_tptable(struct ubcore_hash_table **pp_ht) +{ + struct ubcore_hash_table *ht; + + if (pp_ht == NULL || *pp_ht == NULL) + return; + + ht = *pp_ht; + *pp_ht = NULL; + ubcore_hash_table_free_with_cb(ht, ubcore_free_tp_node); + /* pair with kref_init */ + (void)kref_put(&ht->kref, ubcore_tptable_release); +} diff --git a/drivers/ub/urma/ubcore/ubcore_tp_table.h b/drivers/ub/urma/ubcore/ubcore_tp_table.h new file mode 100644 index 000000000000..c5faaccfa362 --- /dev/null +++ b/drivers/ub/urma/ubcore/ubcore_tp_table.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + * + * Description: ubcore tp table header + * Author: Yan Fangfang + * Create: 2023-02-09 + * Note: + * History: 2023-02-09: Create file + */ + +#ifndef UBCORE_TP_TABLE_H +#define UBCORE_TP_TABLE_H + +#include "ubcore_hash_table.h" +#include "ubcore_netlink.h" + +enum ubcore_tp_key_type { UBCORE_TP_KEY_JETTY_ID, UBCORE_TP_KEY_TPN }; + +struct ubcore_tp_key { + enum ubcore_tp_key_type key_type; + union { + struct ubcore_jetty_id jetty_id; /* for initiator tp towards target jfr or jetty */ + uint32_t tpn; /* for target tp */ + }; +} __packed; + +struct ubcore_tp_node { + struct ubcore_tp_key key; + struct ubcore_tp *tp; + struct ubcore_ta ta; + struct hlist_node hnode; + struct mutex lock; +}; + +void ubcore_init_tp_key_jetty_id(struct ubcore_tp_key *key, const struct ubcore_jetty_id *jetty_id); + +void ubcore_remove_tp_node(struct ubcore_hash_table *ht, struct ubcore_tp_node *tp_node); + +/* TP table ops for devices that do not natively support RM */ +struct ubcore_hash_table *ubcore_create_tptable(void); +void ubcore_destroy_tptable(struct ubcore_hash_table **pp_ht); + +#endif -- Gitee From 878c2d6091357ed1564afbe07dcb00e324a25402 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Sat, 16 Sep 2023 17:34:12 +0800 Subject: [PATCH 53/89] ub: ubcore add tp table ops api driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Ubcore add tp table ops api, including: - ubcore_add_tp_node: Add tp as a node in tp hash table. Return old tp node if key already exists. - ubcore_find_remove_tp: Find and remove the tp from table only if it is unreferenced. - ubcore_get_tptable: Get tp hash table. - ubcore_put_tptable: Release the tp hash table. - ubcore_add_tp_with_tpn: Create tp node with specific tp. - ubcore_remove_tp_with_tpn: Destroy tp node with specific tp. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/ubcore/ubcore_tp_table.c | 116 +++++++++++++++++++++++ drivers/ub/urma/ubcore/ubcore_tp_table.h | 12 +++ 2 files changed, 128 insertions(+) diff --git a/drivers/ub/urma/ubcore/ubcore_tp_table.c b/drivers/ub/urma/ubcore/ubcore_tp_table.c index 3463be68e52f..2b2a26acb4d5 100644 --- a/drivers/ub/urma/ubcore/ubcore_tp_table.c +++ b/drivers/ub/urma/ubcore/ubcore_tp_table.c @@ -40,6 +40,33 @@ void ubcore_remove_tp_node(struct ubcore_hash_table *ht, struct ubcore_tp_node * kfree(tp_node); } +/* Find and remove the tp from table only if it is unreferenced */ +struct ubcore_tp *ubcore_find_remove_tp(struct ubcore_hash_table *ht, uint32_t hash, + const struct ubcore_tp_key *key) +{ + struct ubcore_tp_node *tp_node; + struct ubcore_tp *tp = NULL; + + spin_lock(&ht->lock); + if (ht->head == NULL) { + spin_unlock(&ht->lock); + return NULL; + } + tp_node = ubcore_hash_table_lookup_nolock(ht, hash, key); + if (tp_node == NULL) { + spin_unlock(&ht->lock); + return NULL; + } + + if (atomic_dec_return(&tp_node->tp->use_cnt) == 0) { + tp = tp_node->tp; + hlist_del(&tp_node->hnode); + kfree(tp_node); + } + spin_unlock(&ht->lock); + return tp; +} + struct ubcore_hash_table *ubcore_create_tptable(void) { struct ubcore_ht_param p = { .size = UBCORE_HASH_TABLE_SIZE, @@ -89,3 +116,92 @@ void ubcore_destroy_tptable(struct ubcore_hash_table **pp_ht) /* pair with kref_init */ (void)kref_put(&ht->kref, ubcore_tptable_release); } + +struct ubcore_hash_table *ubcore_get_tptable(struct ubcore_hash_table *ht) +{ + if (ht == NULL) + return NULL; + + kref_get(&ht->kref); + return ht; +} + +void ubcore_put_tptable(struct ubcore_hash_table *ht) +{ + if (ht == NULL) + return; + + (void)kref_put(&ht->kref, ubcore_tptable_release); +} + +struct ubcore_tp_node *ubcore_add_tp_node(struct ubcore_hash_table *ht, uint32_t hash, + const struct ubcore_tp_key *key, struct ubcore_tp *tp, + struct ubcore_ta *ta) +{ + struct ubcore_tp_node *new_tp_node; + struct ubcore_tp_node *tp_node; + + new_tp_node = kzalloc(sizeof(struct ubcore_tp_node), GFP_KERNEL); + if (new_tp_node == NULL) + return NULL; + + + new_tp_node->key = *key; + new_tp_node->tp = tp; + new_tp_node->ta = *ta; + mutex_init(&new_tp_node->lock); + + spin_lock(&ht->lock); + if (ht->head == NULL) { + spin_unlock(&ht->lock); + kfree(new_tp_node); + return NULL; + } + tp_node = ubcore_hash_table_lookup_nolock(ht, hash, key); + if (tp_node != NULL) { + spin_unlock(&ht->lock); + kfree(new_tp_node); + return tp_node; + } + + ubcore_hash_table_add_nolock(ht, &new_tp_node->hnode, hash); + /* set private data for tp restore */ + tp->priv = new_tp_node; + spin_unlock(&ht->lock); + return new_tp_node; +} + +struct ubcore_tp_node *ubcore_add_tp_with_tpn(struct ubcore_device *dev, struct ubcore_tp *tp) +{ + struct ubcore_tp_node *tp_node; + int ret; + + tp_node = kzalloc(sizeof(struct ubcore_tp_node), GFP_KERNEL); + if (tp_node == NULL) + return NULL; + + tp_node->key.key_type = UBCORE_TP_KEY_TPN; + tp_node->key.tpn = tp->tpn; + tp_node->tp = tp; + mutex_init(&tp_node->lock); + + ret = ubcore_hash_table_find_add(&dev->ht[UBCORE_HT_TP], &tp_node->hnode, tp->tpn); + if (ret != 0) { + ubcore_log_err("Failed to add tp with tpn %u to tp table", tp->tpn); + kfree(tp_node); + return NULL; + } + /* set private data to find tp node fast */ + tp->priv = tp_node; + return tp_node; +} + +struct ubcore_tp *ubcore_remove_tp_with_tpn(struct ubcore_device *dev, uint32_t tpn) +{ + struct ubcore_tp_key key; + + memset(&key, 0, sizeof(struct ubcore_tp_key)); + key.key_type = UBCORE_TP_KEY_TPN; + key.tpn = tpn; + return ubcore_find_remove_tp(&dev->ht[UBCORE_HT_TP], tpn, &key); +} diff --git a/drivers/ub/urma/ubcore/ubcore_tp_table.h b/drivers/ub/urma/ubcore/ubcore_tp_table.h index c5faaccfa362..5aa0f70ab9dd 100644 --- a/drivers/ub/urma/ubcore/ubcore_tp_table.h +++ b/drivers/ub/urma/ubcore/ubcore_tp_table.h @@ -44,10 +44,22 @@ struct ubcore_tp_node { void ubcore_init_tp_key_jetty_id(struct ubcore_tp_key *key, const struct ubcore_jetty_id *jetty_id); +/* Return old tp node if key already exists */ +struct ubcore_tp_node *ubcore_add_tp_node(struct ubcore_hash_table *ht, uint32_t hash, + const struct ubcore_tp_key *key, struct ubcore_tp *tp, + struct ubcore_ta *ta); void ubcore_remove_tp_node(struct ubcore_hash_table *ht, struct ubcore_tp_node *tp_node); +/* Find and remove the tp from table only if it is unreferenced */ +struct ubcore_tp *ubcore_find_remove_tp(struct ubcore_hash_table *ht, uint32_t hash, + const struct ubcore_tp_key *key); /* TP table ops for devices that do not natively support RM */ struct ubcore_hash_table *ubcore_create_tptable(void); void ubcore_destroy_tptable(struct ubcore_hash_table **pp_ht); +struct ubcore_hash_table *ubcore_get_tptable(struct ubcore_hash_table *ht); +void ubcore_put_tptable(struct ubcore_hash_table *ht); + +struct ubcore_tp_node *ubcore_add_tp_with_tpn(struct ubcore_device *dev, struct ubcore_tp *tp); +struct ubcore_tp *ubcore_remove_tp_with_tpn(struct ubcore_device *dev, uint32_t tpn); #endif -- Gitee From cd6313d54c7a6c913fa32a1b7617b0cfdb43b457 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Sun, 17 Sep 2023 15:22:55 +0800 Subject: [PATCH 54/89] ub: ubcore add advise tp api process driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Ubcore add advise tp api process. Advise tp: create connection between 2 node. Advise tp process: - find if tp existed already. - fill the config - create tp. Driver gurantee to return the same tp if we have created it as a target - add tp into tp hash table - send request to connection agent and set peer cfg and peer ext from response Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/ubcore/ubcore_netlink.h | 20 +++ drivers/ub/urma/ubcore/ubcore_tp.c | 203 ++++++++++++++++++++++++ drivers/ub/urma/ubcore/ubcore_tp.h | 16 ++ 3 files changed, 239 insertions(+) diff --git a/drivers/ub/urma/ubcore/ubcore_netlink.h b/drivers/ub/urma/ubcore/ubcore_netlink.h index b07ba64a67f0..1c3c57da16ef 100644 --- a/drivers/ub/urma/ubcore/ubcore_netlink.h +++ b/drivers/ub/urma/ubcore/ubcore_netlink.h @@ -48,6 +48,26 @@ struct ubcore_nlmsg { uint8_t payload[0]; } __packed; +struct ubcore_multipath_tp_cfg { + union ubcore_tp_flag flag; + uint16_t data_rctp_start; + uint16_t ack_rctp_start; + uint16_t data_rmtp_start; + uint16_t ack_rmtp_start; + uint8_t tp_range; + uint16_t congestion_alg; +}; + +struct ubcore_nl_query_tp_resp { + enum ubcore_nl_resp_status ret; + bool tp_exist; + uint32_t tpn; /* must set if tp exist is true */ + union ubcore_eid dst_eid; /* underlay */ + struct ubcore_net_addr src_addr; /* underlay */ + struct ubcore_net_addr dst_addr; /* underlay */ + struct ubcore_multipath_tp_cfg cfg; +}; + struct ubcore_nl_session { struct ubcore_nlmsg *req; struct ubcore_nlmsg *resp; diff --git a/drivers/ub/urma/ubcore/ubcore_tp.c b/drivers/ub/urma/ubcore/ubcore_tp.c index 9c94333856de..9ef3b4d96127 100644 --- a/drivers/ub/urma/ubcore/ubcore_tp.c +++ b/drivers/ub/urma/ubcore/ubcore_tp.c @@ -32,6 +32,13 @@ #define UB_PROTOCOL_HEAD_BYTES 313 #define UB_MTU_BITS_BASE_SHIFT 7 +static inline void ubcore_set_net_addr_with_eid(struct ubcore_net_addr *net_addr, + const union ubcore_eid *eid) +{ + memset(net_addr, 0, sizeof(struct ubcore_net_addr)); + (void)memcpy(net_addr, eid, UBCORE_EID_SIZE); +} + static inline int ubcore_mtu_enum_to_int(enum ubcore_mtu mtu) { return 1 << ((int)mtu + UB_MTU_BITS_BASE_SHIFT); @@ -58,6 +65,36 @@ enum ubcore_mtu ubcore_get_mtu(int mtu) } EXPORT_SYMBOL(ubcore_get_mtu); +static int ubcore_get_active_mtu(const struct ubcore_device *dev, uint8_t port_num, + enum ubcore_mtu *mtu) +{ + struct ubcore_device_status st = { 0 }; + + if (port_num >= dev->attr.port_cnt || dev->ops->query_device_status == NULL) { + ubcore_log_err("Invalid parameter"); + return -1; + } + if (dev->ops->query_device_status(dev, &st) != 0) { + ubcore_log_err("Failed to query query_device_status for port %d", port_num); + return -1; + } + if (st.port_status[port_num].state != UBCORE_PORT_ACTIVE) { + ubcore_log_err("Port %d is not active", port_num); + return -1; + } + *mtu = st.port_status[port_num].active_mtu; + return 0; +} + +static int ubcore_query_tp(struct ubcore_device *dev, const union ubcore_eid *remote_eid, + enum ubcore_transport_mode trans_mode, + struct ubcore_nl_query_tp_resp *query_tp_resp) +{ + int ret = 0; + + return ret; +} + int ubcore_destroy_tp(struct ubcore_tp *tp) { if (!ubcore_have_tp_ops(tp->ub_dev)) { @@ -72,6 +109,111 @@ int ubcore_destroy_tp(struct ubcore_tp *tp) } EXPORT_SYMBOL(ubcore_destroy_tp); +static struct ubcore_tp *ubcore_create_tp(struct ubcore_device *dev, + const struct ubcore_tp_cfg *cfg, + struct ubcore_udata *udata) +{ + struct ubcore_tp *tp = NULL; + + return tp; +} + +static void ubcore_abort_tp(struct ubcore_tp *tp, struct ubcore_tp_meta *meta) +{ + struct ubcore_tp *target; + + if (tp == NULL) + return; + + target = ubcore_find_remove_tp(meta->ht, meta->hash, &meta->key); + if (target == NULL || target != tp) { + ubcore_log_warn("TP is not found, already removed or under use\n"); + return; + } + + (void)ubcore_destroy_tp(tp); +} + +static void ubcore_set_multipath_tp_cfg(struct ubcore_tp_cfg *cfg, + enum ubcore_transport_mode trans_mode, + struct ubcore_nl_query_tp_resp *query_tp_resp) +{ + cfg->flag.bs.sr_en = query_tp_resp->cfg.flag.bs.sr_en; + cfg->flag.bs.spray_en = query_tp_resp->cfg.flag.bs.spray_en; + cfg->flag.bs.oor_en = query_tp_resp->cfg.flag.bs.oor_en; + cfg->flag.bs.cc_en = query_tp_resp->cfg.flag.bs.cc_en; + cfg->udp_range = query_tp_resp->cfg.tp_range; + if (trans_mode == UBCORE_TP_RC) { + cfg->data_udp_start = query_tp_resp->cfg.data_rctp_start; + cfg->ack_udp_start = query_tp_resp->cfg.ack_rctp_start; + } else if (trans_mode == UBCORE_TP_RM) { + cfg->data_udp_start = query_tp_resp->cfg.data_rmtp_start; + cfg->ack_udp_start = query_tp_resp->cfg.ack_rmtp_start; + } +} + +static int ubcore_set_initiator_tp_cfg(struct ubcore_tp_cfg *cfg, struct ubcore_device *dev, + enum ubcore_transport_mode trans_mode, + const union ubcore_eid *remote_eid, + struct ubcore_nl_query_tp_resp *query_tp_resp) +{ + cfg->flag.value = 0; + cfg->flag.bs.target = 0; + cfg->trans_mode = trans_mode; + cfg->local_eid = dev->attr.eid; + + if (dev->attr.virtualization) { + cfg->peer_eid = *remote_eid; + ubcore_set_net_addr_with_eid(&cfg->local_net_addr, &dev->attr.eid); + ubcore_set_net_addr_with_eid(&cfg->peer_net_addr, remote_eid); + } else { + if (dev->netdev == NULL) + ubcore_log_warn("Could not find netdev.\n"); + + cfg->peer_eid = query_tp_resp->dst_eid; /* set eid to be the remote underlay eid */ + cfg->local_net_addr = query_tp_resp->src_addr; + if (dev->netdev != NULL && dev->netdev->dev_addr != NULL) + (void)memcpy(cfg->local_net_addr.mac, dev->netdev->dev_addr, + dev->netdev->addr_len); + if (dev->netdev != NULL) + cfg->local_net_addr.vlan = (uint64_t)dev->netdev->vlan_features; + cfg->peer_net_addr = query_tp_resp->dst_addr; + ubcore_set_multipath_tp_cfg(cfg, trans_mode, query_tp_resp); + } + + /* set mtu to active mtu temperately */ + if (ubcore_get_active_mtu(dev, 0, &cfg->mtu) != 0) { + ubcore_log_err("Failed to get active mtu"); + return -1; + } + /* set psn to 0 temperately */ + cfg->rx_psn = 0; + return 0; +} + +static int ubcore_query_initiator_tp_cfg(struct ubcore_tp_cfg *cfg, struct ubcore_device *dev, + const union ubcore_eid *remote_eid, + enum ubcore_transport_mode trans_mode) +{ + struct ubcore_nl_query_tp_resp query_tp_resp; + + /* Do not query tp as TPS is not running on VM */ + if (dev->attr.virtualization) + return ubcore_set_initiator_tp_cfg(cfg, dev, trans_mode, remote_eid, NULL); + + if (ubcore_query_tp(dev, remote_eid, trans_mode, &query_tp_resp) != 0) { + ubcore_log_err("Failed to query tp"); + return -1; + } + return ubcore_set_initiator_tp_cfg(cfg, dev, trans_mode, NULL, &query_tp_resp); +} + +static int ubcore_enable_tp(const struct ubcore_device *dev, struct ubcore_tp_node *tp_node, + struct ubcore_ta *ta, struct ubcore_udata *udata) +{ + return 0; +} + struct ubcore_tp *ubcore_create_vtp(struct ubcore_device *dev, const union ubcore_eid *remote_eid, enum ubcore_transport_mode trans_mode, struct ubcore_udata *udata) @@ -85,3 +227,64 @@ int ubcore_destroy_vtp(struct ubcore_tp *vtp) return -1; } EXPORT_SYMBOL(ubcore_destroy_vtp); + +static inline void ubcore_set_ta_for_tp_cfg(struct ubcore_device *dev, struct ubcore_ta *ta, + struct ubcore_tp_cfg *cfg) +{ + if (dev->transport_type == UBCORE_TRANSPORT_IB) + cfg->ta = ta; + else + cfg->ta = NULL; +} + +int ubcore_advise_tp(struct ubcore_device *dev, const union ubcore_eid *remote_eid, + struct ubcore_tp_advice *advice, struct ubcore_udata *udata) +{ + struct ubcore_tp_node *tp_node; + struct ubcore_tp_cfg cfg = { 0 }; + struct ubcore_tp *new_tp; + + /* Must call driver->create_tp with udata if we are advising jetty */ + tp_node = ubcore_hash_table_lookup(advice->meta.ht, advice->meta.hash, &advice->meta.key); + if (tp_node != NULL && !tp_node->tp->flag.bs.target) { + atomic_inc(&tp_node->tp->use_cnt); + return 0; + } + + if (ubcore_query_initiator_tp_cfg(&cfg, dev, remote_eid, UBCORE_TP_RM) != 0) { + ubcore_log_err("Failed to init tp cfg"); + return -1; + } + + ubcore_set_ta_for_tp_cfg(dev, &advice->ta, &cfg); + + /* driver gurantee to return the same tp if we have created it as a target */ + new_tp = ubcore_create_tp(dev, &cfg, udata); + if (new_tp == NULL) { + ubcore_log_err("Failed to create tp"); + return -1; + } + + tp_node = ubcore_add_tp_node(advice->meta.ht, advice->meta.hash, &advice->meta.key, new_tp, + &advice->ta); + if (tp_node == NULL) { + (void)ubcore_destroy_tp(new_tp); + ubcore_log_err("Failed to find and add tp\n"); + return -1; + } else if (tp_node != NULL && tp_node->tp != new_tp) { + (void)ubcore_destroy_tp(new_tp); + new_tp = NULL; + } + + if (ubcore_enable_tp(dev, tp_node, &advice->ta, udata) != 0) { + ubcore_abort_tp(new_tp, &advice->meta); + ubcore_log_err("Failed to enable tp"); + return -1; + } + + if (new_tp == NULL) + atomic_inc(&tp_node->tp->use_cnt); + + return 0; +} +EXPORT_SYMBOL(ubcore_advise_tp); diff --git a/drivers/ub/urma/ubcore/ubcore_tp.h b/drivers/ub/urma/ubcore/ubcore_tp.h index b29c9f220dae..e248bcf6241c 100644 --- a/drivers/ub/urma/ubcore/ubcore_tp.h +++ b/drivers/ub/urma/ubcore/ubcore_tp.h @@ -23,6 +23,18 @@ #include #include "ubcore_netlink.h" +#include "ubcore_tp_table.h" + +struct ubcore_tp_meta { + struct ubcore_hash_table *ht; + uint32_t hash; + struct ubcore_tp_key key; +}; + +struct ubcore_tp_advice { + struct ubcore_ta ta; + struct ubcore_tp_meta meta; +}; static inline bool ubcore_have_tp_ops(const struct ubcore_device *dev) { @@ -30,6 +42,10 @@ static inline bool ubcore_have_tp_ops(const struct ubcore_device *dev) dev->ops->destroy_tp != NULL); } +/* alpha */ +int ubcore_advise_tp(struct ubcore_device *dev, const union ubcore_eid *remote_eid, + struct ubcore_tp_advice *advice, struct ubcore_udata *udata); + /* Called when clear tp table */ int ubcore_destroy_tp(struct ubcore_tp *tp); #endif -- Gitee From 9cbe06ef65bb8be9aa50a8ca886d038c35a1d665 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Sun, 17 Sep 2023 15:45:34 +0800 Subject: [PATCH 55/89] ub: ubcore add nl_send_wait api driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Ubcore add ubcore_nl_send_wait() api. It will use netlink to send msg and wait it complete. It will return response msg pointer, caller must release it. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/ubcore/ubcore_netlink.c | 106 ++++++++++++++++++++++++ drivers/ub/urma/ubcore/ubcore_netlink.h | 8 ++ 2 files changed, 114 insertions(+) diff --git a/drivers/ub/urma/ubcore/ubcore_netlink.c b/drivers/ub/urma/ubcore/ubcore_netlink.c index 15cdff268966..3b2b70d44086 100644 --- a/drivers/ub/urma/ubcore/ubcore_netlink.c +++ b/drivers/ub/urma/ubcore/ubcore_netlink.c @@ -30,8 +30,52 @@ #define UBCORE_NL_INVALID_PORT 0 struct sock *nl_sock; +static LIST_HEAD(g_nl_session_list); +static DEFINE_SPINLOCK(g_nl_session_lock); +atomic_t g_nlmsg_seq; static uint32_t g_agent_port = UBCORE_NL_INVALID_PORT; /* get agent pid */ +static int ubcore_nl_send(struct ubcore_nlmsg *pbuf, uint16_t len); + +static uint32_t ubcore_get_nlmsg_seq(void) +{ + return atomic_inc_return(&g_nlmsg_seq); +} + +static struct ubcore_nl_session *ubcore_create_nl_session(struct ubcore_nlmsg *req) +{ + struct ubcore_nl_session *s; + unsigned long flags; + + s = kzalloc(sizeof(struct ubcore_nl_session), GFP_KERNEL); + if (s == NULL) + return NULL; + + s->req = req; + spin_lock_irqsave(&g_nl_session_lock, flags); + list_add_tail(&s->node, &g_nl_session_list); + spin_unlock_irqrestore(&g_nl_session_lock, flags); + kref_init(&s->kref); + init_completion(&s->comp); + return s; +} + +static void ubcore_free_nl_session(struct kref *kref) +{ + struct ubcore_nl_session *s = container_of(kref, struct ubcore_nl_session, kref); + unsigned long flags; + + spin_lock_irqsave(&g_nl_session_lock, flags); + list_del(&s->node); + spin_unlock_irqrestore(&g_nl_session_lock, flags); + kfree(s); +} + +static inline void ubcore_destroy_nl_session(struct ubcore_nl_session *s) +{ + kref_put(&s->kref, ubcore_free_nl_session); +} + static void ubcore_nl_cb_func(struct sk_buff *skb) { struct nlmsghdr *nlh; @@ -52,6 +96,68 @@ static void ubcore_nl_cb_func(struct sk_buff *skb) } } +static int ubcore_nl_send(struct ubcore_nlmsg *pbuf, uint16_t len) +{ + struct sk_buff *nl_skb; + struct nlmsghdr *nlh; + int ret; + + if (pbuf == NULL || g_agent_port == UBCORE_NL_INVALID_PORT) { + ubcore_log_err("There are illegal parameters.\n"); + return -1; + } + + /* create sk_buff */ + nl_skb = nlmsg_new(len, GFP_ATOMIC); + if (nl_skb == NULL) { + ubcore_log_err("failed to alloc.\n"); + return -1; + } + /* set netlink head */ + nlh = nlmsg_put(nl_skb, 0, pbuf->nlmsg_seq, pbuf->msg_type, len, 0); + if (nlh == NULL) { + ubcore_log_err("Failed to nlmsg put.\n"); + nlmsg_free(nl_skb); + return -1; + } + /* copy msg */ + (void)memcpy(nlmsg_data(nlh), pbuf, len); + ret = netlink_unicast(nl_sock, nl_skb, g_agent_port, 0); + return ret < 0 ? ret : 0; +} + +struct ubcore_nlmsg *ubcore_nl_send_wait(struct ubcore_nlmsg *req) +{ + unsigned long leavetime; + struct ubcore_nl_session *s; + struct ubcore_nlmsg *resp; + int ret; + + req->nlmsg_seq = ubcore_get_nlmsg_seq(); + s = ubcore_create_nl_session(req); + if (s == NULL) { + ubcore_log_err("Failed to create nl session"); + return NULL; + } + + ret = ubcore_nl_send(req, ubcore_nlmsg_len(req)); + if (ret != 0) { + ubcore_log_err("Failed to send nl msg %d", ret); + ubcore_destroy_nl_session(s); + return NULL; + } + + leavetime = wait_for_completion_timeout(&s->comp, msecs_to_jiffies(UBCORE_NL_TIMEOUT)); + if (leavetime == 0) { + ubcore_log_err("Failed to wait reply, ret: %d, leavetime: %lu\n", ret, leavetime); + ubcore_destroy_nl_session(s); + return NULL; + } + resp = s->resp; + ubcore_destroy_nl_session(s); + return resp; +} + int ubcore_netlink_init(void) { /* create netlink socket */ diff --git a/drivers/ub/urma/ubcore/ubcore_netlink.h b/drivers/ub/urma/ubcore/ubcore_netlink.h index 1c3c57da16ef..279df7134903 100644 --- a/drivers/ub/urma/ubcore/ubcore_netlink.h +++ b/drivers/ub/urma/ubcore/ubcore_netlink.h @@ -48,6 +48,12 @@ struct ubcore_nlmsg { uint8_t payload[0]; } __packed; +struct ubcore_ta_data { + enum ubcore_ta_type type; + struct ubcore_jetty_id jetty_id; /* local jetty id */ + struct ubcore_jetty_id tjetty_id; /* peer jetty id */ +}; + struct ubcore_multipath_tp_cfg { union ubcore_tp_flag flag; uint16_t data_rctp_start; @@ -84,4 +90,6 @@ static inline uint32_t ubcore_nlmsg_len(struct ubcore_nlmsg *msg) int ubcore_netlink_init(void); void ubcore_netlink_exit(void); +/* return response msg pointer, caller must release it */ +struct ubcore_nlmsg *ubcore_nl_send_wait(struct ubcore_nlmsg *req); #endif -- Gitee From 647f10104641b51e5b75e75946018bb1f467aa02 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Sun, 17 Sep 2023 16:00:18 +0800 Subject: [PATCH 56/89] ub: ubcore add create and query tp implements. driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Ubcore add create and query tp impls. These will be used in advise tp. Create tp will finally call driver's registered method. Query tp will finally call netlink to send msg to query. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/ubcore/ubcore_netlink.h | 4 + drivers/ub/urma/ubcore/ubcore_tp.c | 103 ++++++++++++++++++++++++ 2 files changed, 107 insertions(+) diff --git a/drivers/ub/urma/ubcore/ubcore_netlink.h b/drivers/ub/urma/ubcore/ubcore_netlink.h index 279df7134903..dd1e2d15a868 100644 --- a/drivers/ub/urma/ubcore/ubcore_netlink.h +++ b/drivers/ub/urma/ubcore/ubcore_netlink.h @@ -64,6 +64,10 @@ struct ubcore_multipath_tp_cfg { uint16_t congestion_alg; }; +struct ubcore_nl_query_tp_req { + enum ubcore_transport_mode trans_mode; +}; + struct ubcore_nl_query_tp_resp { enum ubcore_nl_resp_status ret; bool tp_exist; diff --git a/drivers/ub/urma/ubcore/ubcore_tp.c b/drivers/ub/urma/ubcore/ubcore_tp.c index 9ef3b4d96127..6b7c98c5ff06 100644 --- a/drivers/ub/urma/ubcore/ubcore_tp.c +++ b/drivers/ub/urma/ubcore/ubcore_tp.c @@ -86,12 +86,71 @@ static int ubcore_get_active_mtu(const struct ubcore_device *dev, uint8_t port_n return 0; } +static struct ubcore_nlmsg *ubcore_alloc_nlmsg(size_t payload_len, const union ubcore_eid *src_eid, + const union ubcore_eid *dst_eid) +{ + struct ubcore_nlmsg *msg = kzalloc(sizeof(struct ubcore_nlmsg) + payload_len, GFP_KERNEL); + + if (msg == NULL) + return NULL; + + msg->src_eid = *src_eid; + msg->dst_eid = *dst_eid; + msg->payload_len = payload_len; + return msg; +} + +static struct ubcore_nlmsg *ubcore_get_query_tp_req(struct ubcore_device *dev, + const union ubcore_eid *remote_eid, + enum ubcore_transport_mode trans_mode) +{ + uint32_t payload_len = sizeof(struct ubcore_nl_query_tp_req); + struct ubcore_nl_query_tp_req *query; + struct ubcore_nlmsg *req; + + req = ubcore_alloc_nlmsg(payload_len, &dev->attr.eid, remote_eid); + if (req == NULL) + return NULL; + + req->transport_type = dev->transport_type; + req->msg_type = UBCORE_NL_QUERY_TP_REQ; + query = (struct ubcore_nl_query_tp_req *)req->payload; + query->trans_mode = trans_mode; + return req; +} + static int ubcore_query_tp(struct ubcore_device *dev, const union ubcore_eid *remote_eid, enum ubcore_transport_mode trans_mode, struct ubcore_nl_query_tp_resp *query_tp_resp) { + struct ubcore_nlmsg *req_msg, *resp_msg; + struct ubcore_nl_query_tp_resp *resp; int ret = 0; + req_msg = ubcore_get_query_tp_req(dev, remote_eid, trans_mode); + if (req_msg == NULL) { + ubcore_log_err("Failed to get query tp req"); + return -1; + } + + resp_msg = ubcore_nl_send_wait(req_msg); + if (resp_msg == NULL) { + ubcore_log_err("Failed to wait query response"); + kfree(req_msg); + return -1; + } + + resp = (struct ubcore_nl_query_tp_resp *)(void *)resp_msg->payload; + if (resp_msg->msg_type != UBCORE_NL_QUERY_TP_RESP || resp == NULL || + resp->ret != UBCORE_NL_RESP_SUCCESS) { + ret = -1; + ubcore_log_err("Query tp request is rejected with type %d ret %d", + resp_msg->msg_type, (resp == NULL ? 1 : resp->ret)); + } else { + (void)memcpy(query_tp_resp, resp, sizeof(struct ubcore_nl_query_tp_resp)); + } + kfree(resp_msg); + kfree(req_msg); return ret; } @@ -109,12 +168,56 @@ int ubcore_destroy_tp(struct ubcore_tp *tp) } EXPORT_SYMBOL(ubcore_destroy_tp); +static void ubcore_set_tp_flag(union ubcore_tp_flag *flag, const struct ubcore_tp_cfg *cfg, + const struct ubcore_device *dev) +{ + flag->bs.target = cfg->flag.bs.target; + flag->bs.sr_en = cfg->flag.bs.sr_en; + flag->bs.spray_en = cfg->flag.bs.spray_en; + flag->bs.oor_en = cfg->flag.bs.oor_en; + flag->bs.cc_en = cfg->flag.bs.cc_en; +} + +static void ubcore_set_tp_init_cfg(struct ubcore_tp *tp, const struct ubcore_tp_cfg *cfg) +{ + ubcore_set_tp_flag(&tp->flag, cfg, tp->ub_dev); + tp->local_net_addr = cfg->local_net_addr; + tp->peer_net_addr = cfg->peer_net_addr; + tp->local_eid = cfg->local_eid; + tp->peer_eid = cfg->peer_eid; + tp->trans_mode = cfg->trans_mode; + tp->rx_psn = cfg->rx_psn; + tp->tx_psn = 0; + tp->mtu = cfg->mtu; + tp->data_udp_start = cfg->data_udp_start; + tp->ack_udp_start = cfg->ack_udp_start; + tp->udp_range = cfg->udp_range; + tp->retry_num = cfg->retry_num; + tp->ack_timeout = cfg->ack_timeout; + tp->tc = cfg->tc; +} + static struct ubcore_tp *ubcore_create_tp(struct ubcore_device *dev, const struct ubcore_tp_cfg *cfg, struct ubcore_udata *udata) { struct ubcore_tp *tp = NULL; + if (!ubcore_have_tp_ops(dev)) { + ubcore_log_err("Invalid parameter"); + return NULL; + } + + tp = dev->ops->create_tp(dev, cfg, udata); + if (tp == NULL) { + ubcore_log_err("Failed to create tp towards remote eid %pI6c", &cfg->peer_eid); + return NULL; + } + tp->ub_dev = dev; + ubcore_set_tp_init_cfg(tp, cfg); + tp->state = UBCORE_TP_STATE_RESET; + tp->priv = NULL; + atomic_set(&tp->use_cnt, 1); return tp; } -- Gitee From 6f705b38505f76e40d25548a7bb6dd1ebdd13061 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Sun, 17 Sep 2023 16:35:45 +0800 Subject: [PATCH 57/89] ub: ubcore add handle create tp req driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Ubcore add handle create tp req, which allows ubcore to handle request of tp creation. The TP link establishment process varies according to the transport mode and transaction type. Transport mode: - RC Reliable Connection: A one-to-one binding relationship is established. Messages can be sent only to the bound Jetty and segments in the target process can be accessed. - RM Reliable Message: Multiple connections are established between Jetty/jfs and jfr. Messages can be sent to jetty/jfr of different target processes on multiple nodes, and segments of different processes on multiple nodes can be accessed. - UM Unreliable Message: There is no connection relationship between Jetty/jfs and jfr. Messages can be sent to jetty/jfr of different target processes on multiple nodes. Unilateral semantics are not supported. Transaction type: there are 2 different types, jfs/jfr and jetty. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/ubcore/ubcore_netlink.h | 24 +++ drivers/ub/urma/ubcore/ubcore_priv.h | 5 + drivers/ub/urma/ubcore/ubcore_tp.c | 265 ++++++++++++++++++++++++ drivers/ub/urma/ubcore/ubcore_tp.h | 1 + 4 files changed, 295 insertions(+) diff --git a/drivers/ub/urma/ubcore/ubcore_netlink.h b/drivers/ub/urma/ubcore/ubcore_netlink.h index dd1e2d15a868..34ee02a2f3d5 100644 --- a/drivers/ub/urma/ubcore/ubcore_netlink.h +++ b/drivers/ub/urma/ubcore/ubcore_netlink.h @@ -64,6 +64,30 @@ struct ubcore_multipath_tp_cfg { uint16_t congestion_alg; }; +struct ubcore_nl_create_tp_req { + uint32_t tpn; + struct ubcore_net_addr local_net_addr; + struct ubcore_net_addr peer_net_addr; + enum ubcore_transport_mode trans_mode; + struct ubcore_multipath_tp_cfg cfg; + uint32_t rx_psn; + enum ubcore_mtu mtu; + struct ubcore_ta_data ta; + uint32_t ext_len; + uint32_t udrv_in_len; + uint8_t ext_udrv[0]; /* struct ubcore_tp_ext->len + struct ubcore_udrv_priv->in_len */ +}; + +struct ubcore_nl_create_tp_resp { + enum ubcore_nl_resp_status ret; + union ubcore_tp_flag flag; + uint32_t peer_tpn; + uint32_t peer_rx_psn; + enum ubcore_mtu peer_mtu; + uint32_t peer_ext_len; + uint8_t peer_ext[0]; /* struct ubcore_tp_ext->len */ +}; + struct ubcore_nl_query_tp_req { enum ubcore_transport_mode trans_mode; }; diff --git a/drivers/ub/urma/ubcore/ubcore_priv.h b/drivers/ub/urma/ubcore/ubcore_priv.h index 6c507e9602c5..d8782d9fac46 100644 --- a/drivers/ub/urma/ubcore/ubcore_priv.h +++ b/drivers/ub/urma/ubcore/ubcore_priv.h @@ -44,4 +44,9 @@ struct ubcore_device **ubcore_get_devices_from_netdev(struct net_device *netdev, void ubcore_put_devices(struct ubcore_device **devices, uint32_t cnt); void ubcore_set_default_eid(struct ubcore_device *dev); +static inline uint32_t ubcore_get_jetty_hash(const struct ubcore_jetty_id *jetty_id) +{ + return jhash(jetty_id, sizeof(struct ubcore_jetty_id), 0); +} + #endif diff --git a/drivers/ub/urma/ubcore/ubcore_tp.c b/drivers/ub/urma/ubcore/ubcore_tp.c index 6b7c98c5ff06..a322956bcfb1 100644 --- a/drivers/ub/urma/ubcore/ubcore_tp.c +++ b/drivers/ub/urma/ubcore/ubcore_tp.c @@ -317,6 +317,271 @@ static int ubcore_enable_tp(const struct ubcore_device *dev, struct ubcore_tp_no return 0; } +static struct ubcore_nlmsg *ubcore_get_create_tp_response(struct ubcore_tp *tp, + struct ubcore_nlmsg *req) +{ + uint32_t payload_len = + sizeof(struct ubcore_nl_create_tp_resp) + (tp == NULL ? 0 : tp->tp_ext.len); + struct ubcore_nl_create_tp_resp *create_resp; + struct ubcore_nlmsg *resp = NULL; + + resp = ubcore_alloc_nlmsg(payload_len, &req->dst_eid, &req->src_eid); + if (resp == NULL) { + ubcore_log_err("Failed to alloc create tp response"); + return NULL; + } + + resp->msg_type = req->msg_type + 1; + resp->nlmsg_seq = req->nlmsg_seq; + resp->transport_type = req->transport_type; + create_resp = (struct ubcore_nl_create_tp_resp *)resp->payload; + if (tp == NULL) { + create_resp->ret = UBCORE_NL_RESP_FAIL; + return resp; + } + + create_resp->ret = UBCORE_NL_RESP_SUCCESS; + create_resp->flag = tp->flag; + create_resp->peer_tpn = tp->tpn; + create_resp->peer_mtu = tp->mtu; + create_resp->peer_rx_psn = tp->rx_psn; + create_resp->peer_ext_len = tp->tp_ext.len; + if (tp->tp_ext.len > 0) + (void)memcpy(create_resp->peer_ext, (void *)tp->tp_ext.addr, tp->tp_ext.len); + + return resp; +} + +static void ubcore_set_multipath_target_tp_cfg(struct ubcore_tp_cfg *cfg, + enum ubcore_transport_mode trans_mode, + const struct ubcore_multipath_tp_cfg *tp_cfg) +{ + cfg->flag.bs.sr_en = tp_cfg->flag.bs.sr_en; + cfg->flag.bs.oor_en = tp_cfg->flag.bs.oor_en; + cfg->flag.bs.spray_en = tp_cfg->flag.bs.spray_en; + cfg->flag.bs.cc_en = tp_cfg->flag.bs.cc_en; + cfg->udp_range = tp_cfg->tp_range; + if (trans_mode == UBCORE_TP_RC) { + cfg->data_udp_start = tp_cfg->data_rctp_start; + cfg->ack_udp_start = tp_cfg->ack_rctp_start; + } else if (trans_mode == UBCORE_TP_RM) { + cfg->data_udp_start = tp_cfg->data_rmtp_start; + cfg->ack_udp_start = tp_cfg->ack_rmtp_start; + } +} + +static int ubcore_set_target_tp_cfg(struct ubcore_tp_cfg *cfg, const struct ubcore_device *dev, + struct ubcore_nlmsg *req, struct ubcore_ta *ta) +{ + struct ubcore_nl_create_tp_req *create = + (struct ubcore_nl_create_tp_req *)(void *)req->payload; + + /* set ubcore_ta */ + cfg->ta = ta; + ubcore_set_multipath_target_tp_cfg(cfg, create->trans_mode, &create->cfg); + cfg->flag.bs.target = !create->cfg.flag.bs.target; + cfg->trans_mode = create->trans_mode; + cfg->local_eid = dev->attr.eid; /* or req->dst_eid */ + cfg->peer_eid = req->src_eid; + + if (dev->netdev == NULL) + ubcore_log_warn("Could not find netdev.\n"); + + cfg->local_net_addr = create->peer_net_addr; + if (dev->netdev != NULL && dev->netdev->dev_addr != NULL) + (void)memcpy(cfg->local_net_addr.mac, dev->netdev->dev_addr, dev->netdev->addr_len); + if (dev->netdev != NULL) + cfg->local_net_addr.vlan = (uint64_t)dev->netdev->vlan_features; + cfg->peer_net_addr = create->local_net_addr; + + /* set mtu to active mtu temperately */ + if (ubcore_get_active_mtu(dev, 0, &cfg->mtu) != 0) { + ubcore_log_err("Failed to get active mtu"); + return -1; + } + cfg->mtu = min(cfg->mtu, create->mtu); + /* set psn to 0 temperately */ + cfg->rx_psn = 0; + /* todonext: set cc */ + return 0; +} + +static struct ubcore_tp *ubcore_create_target_tp(struct ubcore_device *dev, + struct ubcore_nlmsg *req, struct ubcore_ta *ta) +{ + struct ubcore_nl_create_tp_req *create = + (struct ubcore_nl_create_tp_req *)(void *)req->payload; + /* create tp parameters */ + struct ubcore_udrv_priv udrv_data = { .in_addr = (uint64_t)(create->ext_udrv + + create->ext_len), + .in_len = create->udrv_in_len, + .out_addr = 0, + .out_len = 0 }; + struct ubcore_udata udata = { .uctx = NULL, .udrv_data = &udrv_data }; + struct ubcore_tp_cfg cfg = { 0 }; + struct ubcore_tp *tp = NULL; + + if (ubcore_set_target_tp_cfg(&cfg, dev, req, ta) != 0) { + ubcore_log_err("Failed to init tp cfg in create target tp.\n"); + return NULL; + } + + tp = ubcore_create_tp(dev, &cfg, &udata); + if (tp == NULL) { + ubcore_log_err("Failed to create tp in create target tp.\n"); + return NULL; + } + + return tp; +} + +static struct ubcore_tp *ubcore_accept_target_tp(struct ubcore_device *dev, + struct ubcore_nlmsg *req, + struct ubcore_tp_advice *advice) +{ + struct ubcore_tp_meta *meta = &advice->meta; + struct ubcore_tp *new_tp = NULL; /* new created target tp */ + struct ubcore_tp_node *tp_node; + + tp_node = ubcore_hash_table_lookup(meta->ht, meta->hash, &meta->key); + if (tp_node == NULL) { + new_tp = ubcore_create_target_tp(dev, req, &advice->ta); + if (new_tp == NULL) { + ubcore_log_err("Failed to create target tp towards remote eid %pI6c", + &req->src_eid); + return NULL; + } + tp_node = ubcore_add_tp_node(meta->ht, meta->hash, &meta->key, new_tp, &advice->ta); + if (tp_node == NULL) { + (void)ubcore_destroy_tp(new_tp); + ubcore_log_err( + "Failed to add target tp towards remote eid %pI6c to the tp table", + &req->src_eid); + return NULL; + } + if (tp_node->tp != new_tp) { + (void)ubcore_destroy_tp(new_tp); + new_tp = NULL; + } + } + + return tp_node->tp; +} + +static int ubcore_parse_ta(struct ubcore_device *dev, struct ubcore_ta_data *ta_data, + struct ubcore_tp_advice *advice) +{ + struct ubcore_tp_meta *meta; + struct ubcore_jetty *jetty; + struct ubcore_jfr *jfr; + + (void)memset(advice, 0, sizeof(struct ubcore_tp_advice)); + meta = &advice->meta; + advice->ta.type = ta_data->type; + + switch (ta_data->type) { + case UBCORE_TA_JFS_TJFR: + jfr = ubcore_find_jfr(dev, ta_data->tjetty_id.id); + if (jfr != NULL) { + meta->ht = ubcore_get_tptable(jfr->tptable); + advice->ta.jfr = jfr; + advice->ta.tjetty_id = ta_data->jetty_id; + } + break; + case UBCORE_TA_JETTY_TJETTY: + /* todonext: add kref to jetty, as it may be destroyed any time */ + jetty = ubcore_find_jetty(dev, ta_data->tjetty_id.id); + if (jetty != NULL) { + if (jetty->jetty_cfg.trans_mode == UBCORE_TP_RC && + jetty->remote_jetty != NULL && + memcmp(&jetty->remote_jetty->cfg.id, &ta_data->jetty_id, + sizeof(struct ubcore_jetty_id))) { + ubcore_log_err( + "the same jetty is binded with another remote jetty.\n"); + return -1; + } + meta->ht = ubcore_get_tptable(jetty->tptable); + advice->ta.jetty = jetty; + advice->ta.tjetty_id = ta_data->jetty_id; + } + break; + case UBCORE_TA_NONE: + case UBCORE_TA_VIRT: + default: + return -1; + } + ubcore_init_tp_key_jetty_id(&meta->key, &ta_data->jetty_id); + + /* jetty and jfs should be indexed consecutively */ + meta->hash = ubcore_get_jetty_hash(&ta_data->jetty_id); + return 0; +} + +static struct ubcore_tp *ubcore_advise_target_tp(struct ubcore_device *dev, + struct ubcore_nlmsg *req) +{ + struct ubcore_nl_create_tp_req *create = + (struct ubcore_nl_create_tp_req *)(void *)req->payload; + struct ubcore_tp_advice advice; + struct ubcore_tp_meta *meta; + struct ubcore_tp *tp; + + meta = &advice.meta; + if (ubcore_parse_ta(dev, &create->ta, &advice) != 0) { + ubcore_log_err("Failed to parse ta with type %u", create->ta.type); + return NULL; + } else if (meta->ht == NULL) { + ubcore_log_err("tp table is already released"); + return NULL; + } + + tp = ubcore_accept_target_tp(dev, req, &advice); + /* pair with get_tptable in parse_ta */ + ubcore_put_tptable(meta->ht); + return tp; +} + +static struct ubcore_tp *ubcore_bind_target_tp(struct ubcore_device *dev, struct ubcore_nlmsg *req) +{ + return ubcore_advise_target_tp(dev, req); +} + +struct ubcore_nlmsg *ubcore_handle_create_tp_req(struct ubcore_nlmsg *req) +{ + struct ubcore_nl_create_tp_req *create = + (struct ubcore_nl_create_tp_req *)(void *)req->payload; + struct ubcore_tp *tp = NULL; + struct ubcore_device *dev; + + if (req->payload_len < sizeof(struct ubcore_nl_create_tp_req)) { + ubcore_log_err("Invalid create req"); + return NULL; + } + + dev = ubcore_find_device(&req->dst_eid, req->transport_type); + if (dev == NULL || !ubcore_have_tp_ops(dev)) { + if (dev != NULL) + ubcore_put_device(dev); + ubcore_log_err("Failed to find device or device ops invalid"); + return ubcore_get_create_tp_response(NULL, req); + } + + if (create->trans_mode == UBCORE_TP_RC) { + tp = ubcore_bind_target_tp(dev, req); + } else if (create->trans_mode == UBCORE_TP_RM && + dev->transport_type == UBCORE_TRANSPORT_IB) { + tp = ubcore_advise_target_tp(dev, req); + } + + if (tp == NULL) + ubcore_log_err("Failed to create target tp towards remote eid %pI6c", + &req->src_eid); + + ubcore_put_device(dev); + return ubcore_get_create_tp_response(tp, req); +} +EXPORT_SYMBOL(ubcore_handle_create_tp_req); + struct ubcore_tp *ubcore_create_vtp(struct ubcore_device *dev, const union ubcore_eid *remote_eid, enum ubcore_transport_mode trans_mode, struct ubcore_udata *udata) diff --git a/drivers/ub/urma/ubcore/ubcore_tp.h b/drivers/ub/urma/ubcore/ubcore_tp.h index e248bcf6241c..2f1bd7807a76 100644 --- a/drivers/ub/urma/ubcore/ubcore_tp.h +++ b/drivers/ub/urma/ubcore/ubcore_tp.h @@ -46,6 +46,7 @@ static inline bool ubcore_have_tp_ops(const struct ubcore_device *dev) int ubcore_advise_tp(struct ubcore_device *dev, const union ubcore_eid *remote_eid, struct ubcore_tp_advice *advice, struct ubcore_udata *udata); +struct ubcore_nlmsg *ubcore_handle_create_tp_req(struct ubcore_nlmsg *req); /* Called when clear tp table */ int ubcore_destroy_tp(struct ubcore_tp *tp); #endif -- Gitee From 92c149b6cc969ad1b4059919ed1322870ec9726b Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Sun, 17 Sep 2023 16:48:47 +0800 Subject: [PATCH 58/89] ub: ubcore add modify target tp in advise tp process driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Ubcore add modify target tp in advise tp process. Modify tp will finally call driver's registered modify tp method. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/ubcore/ubcore_tp.c | 170 +++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) diff --git a/drivers/ub/urma/ubcore/ubcore_tp.c b/drivers/ub/urma/ubcore/ubcore_tp.c index a322956bcfb1..da745cab8d15 100644 --- a/drivers/ub/urma/ubcore/ubcore_tp.c +++ b/drivers/ub/urma/ubcore/ubcore_tp.c @@ -119,6 +119,45 @@ static struct ubcore_nlmsg *ubcore_get_query_tp_req(struct ubcore_device *dev, return req; } +static int ubcore_set_tp_peer_ext(struct ubcore_tp_attr *attr, const uint8_t *ext_addr, + const uint32_t ext_len) +{ + void *peer_ext = NULL; + + if (ext_len == 0 || ext_addr == NULL) + return 0; + + /* copy resp ext from req or response */ + peer_ext = kzalloc(ext_len, GFP_KERNEL); + if (peer_ext == NULL) + return -ENOMEM; + + (void)memcpy(peer_ext, ext_addr, ext_len); + + attr->peer_ext.addr = (uint64_t)peer_ext; + attr->peer_ext.len = ext_len; + return 0; +} + +static inline void ubcore_unset_tp_peer_ext(struct ubcore_tp_attr *attr) +{ + if (attr->peer_ext.addr != 0) + kfree((void *)attr->peer_ext.addr); +} + +static int ubcore_negotiate_optimal_cc_alg(uint16_t local_congestion_alg, + uint16_t peer_local_congestion_alg) +{ + int i; + + /* TODO Configure congestion control priority based on UVS */ + for (i = 0; i <= UBCORE_TP_CC_DIP; i++) { + if ((0x1 << (uint32_t)i) & local_congestion_alg & peer_local_congestion_alg) + return i; + } + return -1; +} + static int ubcore_query_tp(struct ubcore_device *dev, const union ubcore_eid *remote_eid, enum ubcore_transport_mode trans_mode, struct ubcore_nl_query_tp_resp *query_tp_resp) @@ -311,12 +350,85 @@ static int ubcore_query_initiator_tp_cfg(struct ubcore_tp_cfg *cfg, struct ubcor return ubcore_set_initiator_tp_cfg(cfg, dev, trans_mode, NULL, &query_tp_resp); } +static int ubcore_modify_tp_to_rts(const struct ubcore_device *dev, struct ubcore_tp *tp) +{ + union ubcore_tp_attr_mask mask; + struct ubcore_tp_attr attr; + + mask.value = 0; + mask.bs.state = 1; + attr.state = UBCORE_TP_STATE_RTS; + + if (dev->ops->modify_tp(tp, &attr, mask) != 0) { + /* tp->peer_ext.addr will be freed when called ubcore_destroy_tp */ + ubcore_log_err("Failed to modify tp"); + return -1; + } + tp->state = UBCORE_TP_STATE_RTS; + return 0; +} + +#define ubcore_mod_tp_attr_with_mask(tp, attr, field, mask) \ + (tp->field = mask.bs.field ? attr->field : tp->field) + +static void ubcore_modify_tp_attr(struct ubcore_tp *tp, const struct ubcore_tp_attr *attr, + union ubcore_tp_attr_mask mask) +{ + /* flag and mod flag must have the same layout */ + if (mask.bs.flag) + tp->flag.value = tp->flag.bs.target | (attr->flag.value << 1); + + ubcore_mod_tp_attr_with_mask(tp, attr, peer_tpn, mask); + ubcore_mod_tp_attr_with_mask(tp, attr, state, mask); + ubcore_mod_tp_attr_with_mask(tp, attr, tx_psn, mask); + ubcore_mod_tp_attr_with_mask(tp, attr, rx_psn, mask); + ubcore_mod_tp_attr_with_mask(tp, attr, mtu, mask); + ubcore_mod_tp_attr_with_mask(tp, attr, cc_pattern_idx, mask); + ubcore_mod_tp_attr_with_mask(tp, attr, peer_ext, mask); +} + static int ubcore_enable_tp(const struct ubcore_device *dev, struct ubcore_tp_node *tp_node, struct ubcore_ta *ta, struct ubcore_udata *udata) { return 0; } +static int ubcore_set_target_peer(const struct ubcore_tp *tp, struct ubcore_tp_attr *attr, + union ubcore_tp_attr_mask *mask, + const struct ubcore_nl_create_tp_req *create) +{ + int ret; + + mask->value = 0; + mask->bs.peer_tpn = 1; + mask->bs.mtu = 1; + mask->bs.tx_psn = 1; + mask->bs.state = 1; + mask->bs.flag = 1; + + memset(attr, 0, sizeof(*attr)); + attr->peer_tpn = create->tpn; + attr->mtu = min(tp->mtu, create->mtu); + attr->tx_psn = create->rx_psn; + attr->state = UBCORE_TP_STATE_RTR; + + /* Negotiate local and remote optimal algorithms */ + ret = ubcore_negotiate_optimal_cc_alg(tp->ub_dev->attr.dev_cap.congestion_ctrl_alg, + create->cfg.congestion_alg); + if (ret == -1) { + ubcore_log_err("No congestion control algorithm available"); + return -1; + } + attr->flag.value = tp->flag.value >> 1; + attr->flag.bs.cc_alg = (enum ubcore_tp_cc_alg)ret; + + if (tp->peer_ext.addr != 0) + return 0; + + mask->bs.peer_ext = 1; + return ubcore_set_tp_peer_ext(attr, create->ext_udrv, create->ext_len); +} + static struct ubcore_nlmsg *ubcore_get_create_tp_response(struct ubcore_tp *tp, struct ubcore_nlmsg *req) { @@ -435,10 +547,63 @@ static struct ubcore_tp *ubcore_create_target_tp(struct ubcore_device *dev, return tp; } +static int ubcore_modify_target_tp(const struct ubcore_device *dev, struct ubcore_tp_node *tp_node, + const struct ubcore_nl_create_tp_req *create) +{ + struct ubcore_tp *tp = tp_node->tp; + union ubcore_tp_attr_mask mask; + struct ubcore_tp_attr attr; + int ret = 0; + + mutex_lock(&tp_node->lock); + + switch (tp->state) { + case UBCORE_TP_STATE_RTS: + ubcore_log_info("Reuse existing tp with tpn %u", tp->tpn); + break; + case UBCORE_TP_STATE_RESET: + /* Modify target tp to RTR */ + if (ubcore_set_target_peer(tp, &attr, &mask, create) != 0) { + ubcore_log_err("Failed to set target peer"); + ret = -1; + break; + } + if (dev->ops->modify_tp(tp, &attr, mask) != 0) { + ubcore_unset_tp_peer_ext(&attr); + ubcore_log_err("Failed to modify tp"); + ret = -1; + break; + } + ubcore_modify_tp_attr(tp, &attr, mask); + fallthrough; + case UBCORE_TP_STATE_RTR: + /* For RC target TP: modify to RTR only, to RTS when call bind_jetty; + * For IB RM target TP: modify to RTR only, to RTS when call advise_jetty + */ + if (tp->trans_mode == UBCORE_TP_RC || (dev->transport_type == UBCORE_TRANSPORT_IB)) + break; + + /* TRANSPORT_UB: modify target tp to RTS when receive ACK from intiator, + * currently, modify target tp to RTS immediately after target tp is modified to RTR + */ + ret = ubcore_modify_tp_to_rts(dev, tp); + break; + case UBCORE_TP_STATE_ERROR: + default: + ret = -1; + break; + } + + mutex_unlock(&tp_node->lock); + return ret; +} + static struct ubcore_tp *ubcore_accept_target_tp(struct ubcore_device *dev, struct ubcore_nlmsg *req, struct ubcore_tp_advice *advice) { + struct ubcore_nl_create_tp_req *create = + (struct ubcore_nl_create_tp_req *)(void *)req->payload; struct ubcore_tp_meta *meta = &advice->meta; struct ubcore_tp *new_tp = NULL; /* new created target tp */ struct ubcore_tp_node *tp_node; @@ -465,6 +630,11 @@ static struct ubcore_tp *ubcore_accept_target_tp(struct ubcore_device *dev, } } + if (ubcore_modify_target_tp(dev, tp_node, create) != 0) { + ubcore_abort_tp(new_tp, meta); + ubcore_log_err("Failed to modify tp"); + return NULL; + } return tp_node->tp; } -- Gitee From ee7e814e06516735260a86762c36147116e7f2f1 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Sun, 17 Sep 2023 17:02:27 +0800 Subject: [PATCH 59/89] ub: ubcore add handle delete tp req driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Ubcore add handle delete tp req, which allows ubcore to handle request of tp deletion. The TP link deletion process varies according to the transport mode and transaction type. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/ubcore/ubcore_netlink.h | 11 ++ drivers/ub/urma/ubcore/ubcore_tp.c | 142 ++++++++++++++++++++---- drivers/ub/urma/ubcore/ubcore_tp.h | 1 + 3 files changed, 135 insertions(+), 19 deletions(-) diff --git a/drivers/ub/urma/ubcore/ubcore_netlink.h b/drivers/ub/urma/ubcore/ubcore_netlink.h index 34ee02a2f3d5..1c4662b2e775 100644 --- a/drivers/ub/urma/ubcore/ubcore_netlink.h +++ b/drivers/ub/urma/ubcore/ubcore_netlink.h @@ -88,6 +88,17 @@ struct ubcore_nl_create_tp_resp { uint8_t peer_ext[0]; /* struct ubcore_tp_ext->len */ }; +struct ubcore_nl_destroy_tp_req { + uint32_t tpn; + uint32_t peer_tpn; + enum ubcore_transport_mode trans_mode; + struct ubcore_ta_data ta; +}; + +struct ubcore_nl_destroy_tp_resp { + enum ubcore_nl_resp_status ret; +}; + struct ubcore_nl_query_tp_req { enum ubcore_transport_mode trans_mode; }; diff --git a/drivers/ub/urma/ubcore/ubcore_tp.c b/drivers/ub/urma/ubcore/ubcore_tp.c index da745cab8d15..9661bf7c2384 100644 --- a/drivers/ub/urma/ubcore/ubcore_tp.c +++ b/drivers/ub/urma/ubcore/ubcore_tp.c @@ -100,25 +100,6 @@ static struct ubcore_nlmsg *ubcore_alloc_nlmsg(size_t payload_len, const union u return msg; } -static struct ubcore_nlmsg *ubcore_get_query_tp_req(struct ubcore_device *dev, - const union ubcore_eid *remote_eid, - enum ubcore_transport_mode trans_mode) -{ - uint32_t payload_len = sizeof(struct ubcore_nl_query_tp_req); - struct ubcore_nl_query_tp_req *query; - struct ubcore_nlmsg *req; - - req = ubcore_alloc_nlmsg(payload_len, &dev->attr.eid, remote_eid); - if (req == NULL) - return NULL; - - req->transport_type = dev->transport_type; - req->msg_type = UBCORE_NL_QUERY_TP_REQ; - query = (struct ubcore_nl_query_tp_req *)req->payload; - query->trans_mode = trans_mode; - return req; -} - static int ubcore_set_tp_peer_ext(struct ubcore_tp_attr *attr, const uint8_t *ext_addr, const uint32_t ext_len) { @@ -158,6 +139,25 @@ static int ubcore_negotiate_optimal_cc_alg(uint16_t local_congestion_alg, return -1; } +static struct ubcore_nlmsg *ubcore_get_query_tp_req(struct ubcore_device *dev, + const union ubcore_eid *remote_eid, + enum ubcore_transport_mode trans_mode) +{ + uint32_t payload_len = sizeof(struct ubcore_nl_query_tp_req); + struct ubcore_nl_query_tp_req *query; + struct ubcore_nlmsg *req; + + req = ubcore_alloc_nlmsg(payload_len, &dev->attr.eid, remote_eid); + if (req == NULL) + return NULL; + + req->transport_type = dev->transport_type; + req->msg_type = UBCORE_NL_QUERY_TP_REQ; + query = (struct ubcore_nl_query_tp_req *)req->payload; + query->trans_mode = trans_mode; + return req; +} + static int ubcore_query_tp(struct ubcore_device *dev, const union ubcore_eid *remote_eid, enum ubcore_transport_mode trans_mode, struct ubcore_nl_query_tp_resp *query_tp_resp) @@ -429,6 +429,28 @@ static int ubcore_set_target_peer(const struct ubcore_tp *tp, struct ubcore_tp_a return ubcore_set_tp_peer_ext(attr, create->ext_udrv, create->ext_len); } +static struct ubcore_nlmsg *ubcore_get_destroy_tp_response(enum ubcore_nl_resp_status ret, + struct ubcore_nlmsg *req) +{ + struct ubcore_nl_destroy_tp_resp *destroy_resp; + struct ubcore_nlmsg *resp = NULL; + + resp = ubcore_alloc_nlmsg(sizeof(struct ubcore_nl_destroy_tp_resp), &req->dst_eid, + &req->src_eid); + if (resp == NULL) { + ubcore_log_err("Failed to alloc destroy tp response"); + return NULL; + } + + resp->msg_type = UBCORE_NL_DESTROY_TP_RESP; + resp->nlmsg_seq = req->nlmsg_seq; + resp->transport_type = req->transport_type; + destroy_resp = (struct ubcore_nl_destroy_tp_resp *)resp->payload; + destroy_resp->ret = ret; + + return resp; +} + static struct ubcore_nlmsg *ubcore_get_create_tp_response(struct ubcore_tp *tp, struct ubcore_nlmsg *req) { @@ -752,6 +774,88 @@ struct ubcore_nlmsg *ubcore_handle_create_tp_req(struct ubcore_nlmsg *req) } EXPORT_SYMBOL(ubcore_handle_create_tp_req); +/* destroy target vtp created by ubcore_accept_target_vtp */ +static int ubcore_unaccept_target_vtp(struct ubcore_device *dev, + struct ubcore_nl_destroy_tp_req *destroy) +{ + struct ubcore_tp *tp = ubcore_remove_tp_with_tpn(dev, destroy->peer_tpn); + + if (tp == NULL) { + ubcore_log_warn("tp is not found or already destroyed %u", destroy->peer_tpn); + return 0; + } + return ubcore_destroy_tp(tp); +} + +/* destroy target RM tp created by ubcore_advise_target_tp */ +static int ubcore_unadvise_target_tp(struct ubcore_device *dev, + struct ubcore_nl_destroy_tp_req *destroy) +{ + struct ubcore_tp_advice advice; + struct ubcore_tp_meta *meta; + struct ubcore_tp *tp = NULL; + + meta = &advice.meta; + if (ubcore_parse_ta(dev, &destroy->ta, &advice) != 0) { + ubcore_log_err("Failed to parse ta with type %u", destroy->ta.type); + return -1; + } else if (meta->ht == NULL) { + ubcore_log_warn("tp table is already released"); + return 0; + } + + tp = ubcore_find_remove_tp(meta->ht, meta->hash, &meta->key); + /* pair with get_tptable in parse_ta */ + ubcore_put_tptable(meta->ht); + if (tp == NULL) { + ubcore_log_warn("tp is not found, already destroyed or under use %u", + destroy->peer_tpn); + return 0; + } + + return ubcore_destroy_tp(tp); +} + +/* destroy target RC tp created by ubcore_bind_target_tp */ +static int ubcore_unbind_target_tp(struct ubcore_device *dev, + struct ubcore_nl_destroy_tp_req *destroy) +{ + return ubcore_unadvise_target_tp(dev, destroy); +} + +struct ubcore_nlmsg *ubcore_handle_destroy_tp_req(struct ubcore_nlmsg *req) +{ + struct ubcore_nl_destroy_tp_req *destroy = + (struct ubcore_nl_destroy_tp_req *)(void *)req->payload; + struct ubcore_device *dev; + int ret = -1; + + if (req->payload_len != sizeof(struct ubcore_nl_destroy_tp_req)) { + ubcore_log_err("Invalid destroy req"); + return NULL; + } + + dev = ubcore_find_device(&req->dst_eid, req->transport_type); + if (dev == NULL || !ubcore_have_tp_ops(dev)) { + if (dev != NULL) + ubcore_put_device(dev); + ubcore_log_err("Failed to find device or device ops invalid"); + return ubcore_get_destroy_tp_response(UBCORE_NL_RESP_FAIL, req); + } + + if (destroy->ta.type == UBCORE_TA_VIRT) { + ret = ubcore_unaccept_target_vtp(dev, destroy); + } else if (destroy->trans_mode == UBCORE_TP_RC) { + ret = ubcore_unbind_target_tp(dev, destroy); + } else if (destroy->trans_mode == UBCORE_TP_RM && + dev->transport_type == UBCORE_TRANSPORT_IB) { + ret = ubcore_unadvise_target_tp(dev, destroy); + } + ubcore_put_device(dev); + return ubcore_get_destroy_tp_response((enum ubcore_nl_resp_status)ret, req); +} +EXPORT_SYMBOL(ubcore_handle_destroy_tp_req); + struct ubcore_tp *ubcore_create_vtp(struct ubcore_device *dev, const union ubcore_eid *remote_eid, enum ubcore_transport_mode trans_mode, struct ubcore_udata *udata) diff --git a/drivers/ub/urma/ubcore/ubcore_tp.h b/drivers/ub/urma/ubcore/ubcore_tp.h index 2f1bd7807a76..c0ba3dc18eb7 100644 --- a/drivers/ub/urma/ubcore/ubcore_tp.h +++ b/drivers/ub/urma/ubcore/ubcore_tp.h @@ -47,6 +47,7 @@ int ubcore_advise_tp(struct ubcore_device *dev, const union ubcore_eid *remote_e struct ubcore_tp_advice *advice, struct ubcore_udata *udata); struct ubcore_nlmsg *ubcore_handle_create_tp_req(struct ubcore_nlmsg *req); +struct ubcore_nlmsg *ubcore_handle_destroy_tp_req(struct ubcore_nlmsg *req); /* Called when clear tp table */ int ubcore_destroy_tp(struct ubcore_tp *tp); #endif -- Gitee From fd5b407053bb651f2fc437c56ccb1a2709af825b Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Sun, 17 Sep 2023 17:06:31 +0800 Subject: [PATCH 60/89] ub: ubcore add handle restore tp req driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Ubcore add handle restore tp req, which allows ubcore to handle request of tp restore. The TP link restore process varies according to the transport mode and transaction type. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/ubcore/ubcore_netlink.h | 13 +++ drivers/ub/urma/ubcore/ubcore_tp.c | 138 ++++++++++++++++++++++++ drivers/ub/urma/ubcore/ubcore_tp.h | 2 + 3 files changed, 153 insertions(+) diff --git a/drivers/ub/urma/ubcore/ubcore_netlink.h b/drivers/ub/urma/ubcore/ubcore_netlink.h index 1c4662b2e775..1bdda997f96a 100644 --- a/drivers/ub/urma/ubcore/ubcore_netlink.h +++ b/drivers/ub/urma/ubcore/ubcore_netlink.h @@ -113,6 +113,19 @@ struct ubcore_nl_query_tp_resp { struct ubcore_multipath_tp_cfg cfg; }; +struct ubcore_nl_restore_tp_req { + enum ubcore_transport_mode trans_mode; + uint32_t tpn; + uint32_t peer_tpn; + uint32_t rx_psn; + struct ubcore_ta_data ta; +}; + +struct ubcore_nl_restore_tp_resp { + enum ubcore_nl_resp_status ret; + uint32_t peer_rx_psn; +}; + struct ubcore_nl_session { struct ubcore_nlmsg *req; struct ubcore_nlmsg *resp; diff --git a/drivers/ub/urma/ubcore/ubcore_tp.c b/drivers/ub/urma/ubcore/ubcore_tp.c index 9661bf7c2384..26e2a46df1d9 100644 --- a/drivers/ub/urma/ubcore/ubcore_tp.c +++ b/drivers/ub/urma/ubcore/ubcore_tp.c @@ -930,3 +930,141 @@ int ubcore_advise_tp(struct ubcore_device *dev, const union ubcore_eid *remote_e return 0; } EXPORT_SYMBOL(ubcore_advise_tp); + +static struct ubcore_nlmsg *ubcore_get_restore_tp_response(struct ubcore_nlmsg *req, + struct ubcore_tp *tp) +{ + struct ubcore_nl_restore_tp_resp *restore_resp; + struct ubcore_nlmsg *resp = NULL; + + resp = ubcore_alloc_nlmsg(sizeof(struct ubcore_nl_restore_tp_resp), &req->dst_eid, + &req->src_eid); + if (resp == NULL) { + ubcore_log_err("Failed to alloc restore tp response"); + return NULL; + } + + resp->msg_type = UBCORE_NL_RESTORE_TP_RESP; + resp->nlmsg_seq = req->nlmsg_seq; + resp->transport_type = req->transport_type; + restore_resp = (struct ubcore_nl_restore_tp_resp *)resp->payload; + + if (tp == NULL) { + restore_resp->ret = UBCORE_NL_RESP_FAIL; + return resp; + } + + restore_resp->peer_rx_psn = tp->rx_psn; + return resp; +} + +static int ubcore_restore_tp_to_rts(const struct ubcore_device *dev, struct ubcore_tp *tp, + uint32_t rx_psn, uint32_t tx_psn) +{ + union ubcore_tp_attr_mask mask; + struct ubcore_tp_attr attr; + + mask.value = 0; + mask.bs.state = 1; + mask.bs.rx_psn = 1; + mask.bs.tx_psn = 1; + + attr.state = UBCORE_TP_STATE_RTS; + attr.rx_psn = rx_psn; + attr.tx_psn = tx_psn; + + if (dev->ops->modify_tp(tp, &attr, mask) != 0) { + /* tp->peer_ext.addr will be freed when called ubcore_destroy_tp */ + ubcore_log_err("Failed to modify tp"); + return -1; + } + + tp->state = UBCORE_TP_STATE_RTS; + tp->rx_psn = rx_psn; + tp->tx_psn = tx_psn; + + return 0; +} + +/* restore target RM tp created by ubcore_advise_target_tp */ +static struct ubcore_tp *ubcore_restore_advised_target_tp(struct ubcore_device *dev, + struct ubcore_nl_restore_tp_req *restore) +{ + struct ubcore_tp_advice advice; + struct ubcore_tp_node *tp_node; + struct ubcore_tp_meta *meta; + struct ubcore_tp *tp; + + meta = &advice.meta; + if (ubcore_parse_ta(dev, &restore->ta, &advice) != 0) { + ubcore_log_err("Failed to parse ta with type %u", restore->ta.type); + return NULL; + } else if (meta->ht == NULL) { + ubcore_log_err("tp table is already released"); + return NULL; + } + + tp_node = ubcore_hash_table_lookup(meta->ht, meta->hash, &meta->key); + /* pair with get_tptable in parse_ta */ + ubcore_put_tptable(meta->ht); + if (tp_node == NULL) { + ubcore_log_err("tp is not found%u", restore->peer_tpn); + return NULL; + } + + tp = tp_node->tp; + if (ubcore_restore_tp_to_rts(dev, tp, get_random_u32(), restore->rx_psn) != 0) { + ubcore_log_err("Failed to modify tp to rts %u", restore->rx_psn); + return NULL; + } + return tp; +} + +static struct ubcore_tp *ubcore_restore_bound_target_tp(struct ubcore_device *dev, + struct ubcore_nl_restore_tp_req *restore) +{ + return ubcore_restore_advised_target_tp(dev, restore); +} + +static struct ubcore_tp *ubcore_handle_restore_tp(struct ubcore_device *dev, + struct ubcore_nl_restore_tp_req *restore) +{ + if (dev->transport_type != UBCORE_TRANSPORT_IB || restore->trans_mode == UBCORE_TP_UM || + restore->ta.type == UBCORE_TA_NONE || restore->ta.type >= UBCORE_TA_VIRT) + return NULL; + + if (restore->trans_mode == UBCORE_TP_RM) + return ubcore_restore_advised_target_tp(dev, restore); + else + return ubcore_restore_bound_target_tp(dev, restore); +} + +struct ubcore_nlmsg *ubcore_handle_restore_tp_req(struct ubcore_nlmsg *req) +{ + struct ubcore_nl_restore_tp_req *restore = + (struct ubcore_nl_restore_tp_req *)(void *)req->payload; + struct ubcore_device *dev; + struct ubcore_tp *tp; + + if (req->payload_len != sizeof(struct ubcore_nl_restore_tp_req)) { + ubcore_log_err("Invalid restore req"); + return NULL; + } + + dev = ubcore_find_device(&req->dst_eid, req->transport_type); + if (dev == NULL || !ubcore_have_tp_ops(dev)) { + if (dev != NULL) + ubcore_put_device(dev); + ubcore_log_err("Failed to find device or device ops invalid"); + return ubcore_get_restore_tp_response(req, NULL); + } + + tp = ubcore_handle_restore_tp(dev, restore); + if (tp == NULL) + ubcore_log_err("Failed to restore target tp towards remote eid %pI6c", + &req->src_eid); + + ubcore_put_device(dev); + return ubcore_get_restore_tp_response(req, tp); +} +EXPORT_SYMBOL(ubcore_handle_restore_tp_req); diff --git a/drivers/ub/urma/ubcore/ubcore_tp.h b/drivers/ub/urma/ubcore/ubcore_tp.h index c0ba3dc18eb7..228701dba740 100644 --- a/drivers/ub/urma/ubcore/ubcore_tp.h +++ b/drivers/ub/urma/ubcore/ubcore_tp.h @@ -48,6 +48,8 @@ int ubcore_advise_tp(struct ubcore_device *dev, const union ubcore_eid *remote_e struct ubcore_nlmsg *ubcore_handle_create_tp_req(struct ubcore_nlmsg *req); struct ubcore_nlmsg *ubcore_handle_destroy_tp_req(struct ubcore_nlmsg *req); +struct ubcore_nlmsg *ubcore_handle_restore_tp_req(struct ubcore_nlmsg *req); + /* Called when clear tp table */ int ubcore_destroy_tp(struct ubcore_tp *tp); #endif -- Gitee From 9a8083d15660cf72cc0883edf3e5ed00f1128e0b Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Sun, 17 Sep 2023 17:17:11 +0800 Subject: [PATCH 61/89] ub: ubcore add tp request and response handle in netlink driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Ubcore add tp request and response handle in netlink. It's possible to handle tp creation/deletion/restore request from user layer. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/ubcore/ubcore_netlink.c | 92 +++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/drivers/ub/urma/ubcore/ubcore_netlink.c b/drivers/ub/urma/ubcore/ubcore_netlink.c index 3b2b70d44086..985424f8bba6 100644 --- a/drivers/ub/urma/ubcore/ubcore_netlink.c +++ b/drivers/ub/urma/ubcore/ubcore_netlink.c @@ -23,6 +23,7 @@ #include #include #include "ubcore_log.h" +#include "ubcore_tp.h" #include "ubcore_netlink.h" #define UBCORE_NL_TYPE 24 /* same with agent netlink type */ @@ -76,6 +77,85 @@ static inline void ubcore_destroy_nl_session(struct ubcore_nl_session *s) kref_put(&s->kref, ubcore_free_nl_session); } +static struct ubcore_nl_session *ubcore_find_nl_session(uint32_t nlmsg_seq) +{ + struct ubcore_nl_session *tmp, *target = NULL; + unsigned long flags; + + spin_lock_irqsave(&g_nl_session_lock, flags); + list_for_each_entry(tmp, &g_nl_session_list, node) { + if (tmp->req->nlmsg_seq == nlmsg_seq) { + target = tmp; + kref_get(&target->kref); + break; + } + } + spin_unlock_irqrestore(&g_nl_session_lock, flags); + return target; +} + +static struct ubcore_nlmsg *ubcore_get_nlmsg_data(struct nlmsghdr *nlh) +{ + struct ubcore_nlmsg *msg; + + msg = kzalloc(nlmsg_len(nlh), GFP_KERNEL); + if (msg == NULL) + return NULL; + + (void)memcpy(msg, nlmsg_data(nlh), nlmsg_len(nlh)); + return msg; +} + +static void ubcore_nl_handle_tp_resp(struct nlmsghdr *nlh) +{ + struct ubcore_nl_session *s; + struct ubcore_nlmsg *resp; + + resp = ubcore_get_nlmsg_data(nlh); + if (resp == NULL) { + ubcore_log_err("Failed to calloc and copy response"); + return; + } + s = ubcore_find_nl_session(resp->nlmsg_seq); + if (s == NULL) { + ubcore_log_err("Failed to find nl session with seq %u", resp->nlmsg_seq); + kfree(resp); + return; + } + s->resp = resp; + kref_put(&s->kref, ubcore_free_nl_session); + complete(&s->comp); +} + +static void ubcore_nl_handle_tp_req(struct nlmsghdr *nlh) +{ + struct ubcore_nlmsg *resp = NULL; + struct ubcore_nlmsg *req; + + req = ubcore_get_nlmsg_data(nlh); + if (req == NULL) { + ubcore_log_err("Failed to calloc and copy req"); + return; + } + if (nlh->nlmsg_type == UBCORE_NL_CREATE_TP_REQ) + resp = ubcore_handle_create_tp_req(req); + else if (nlh->nlmsg_type == UBCORE_NL_DESTROY_TP_REQ) + resp = ubcore_handle_destroy_tp_req(req); + else if (nlh->nlmsg_type == UBCORE_NL_RESTORE_TP_REQ) + resp = ubcore_handle_restore_tp_req(req); + + if (resp == NULL) { + ubcore_log_err("Failed to handle tp req"); + kfree(req); + return; + } + if (ubcore_nl_send(resp, ubcore_nlmsg_len(resp)) != 0) + ubcore_log_err("Failed to send response"); + + kfree(req); + kfree(resp); +} + static void ubcore_nl_cb_func(struct sk_buff *skb) { struct nlmsghdr *nlh; @@ -87,9 +167,21 @@ static void ubcore_nl_cb_func(struct sk_buff *skb) } switch (nlh->nlmsg_type) { + case UBCORE_NL_CREATE_TP_REQ: + case UBCORE_NL_DESTROY_TP_REQ: + case UBCORE_NL_RESTORE_TP_REQ: + ubcore_nl_handle_tp_req(nlh); + break; + case UBCORE_NL_CREATE_TP_RESP: + case UBCORE_NL_DESTROY_TP_RESP: + case UBCORE_NL_QUERY_TP_RESP: + case UBCORE_NL_RESTORE_TP_RESP: + ubcore_nl_handle_tp_resp(nlh); + break; case UBCORE_NL_SET_AGENT_PID: g_agent_port = nlh->nlmsg_pid; break; + case UBCORE_NL_QUERY_TP_REQ: default: ubcore_log_err("Unexpected nl msg type: %d received\n", nlh->nlmsg_type); break; -- Gitee From b73b87f60ce48b53102b9712d74751821cc07045 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Sun, 17 Sep 2023 17:31:24 +0800 Subject: [PATCH 62/89] ub: ubcore add enable tp impls driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Ubcore add enable tp impls. These will be used in advise tp. Enable tp will exchange tp, which will use netlink to exchange infos. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/ubcore/ubcore_tp.c | 296 +++++++++++++++++++++++++++++ 1 file changed, 296 insertions(+) diff --git a/drivers/ub/urma/ubcore/ubcore_tp.c b/drivers/ub/urma/ubcore/ubcore_tp.c index 26e2a46df1d9..8ebcc034d79a 100644 --- a/drivers/ub/urma/ubcore/ubcore_tp.c +++ b/drivers/ub/urma/ubcore/ubcore_tp.c @@ -32,6 +32,27 @@ #define UB_PROTOCOL_HEAD_BYTES 313 #define UB_MTU_BITS_BASE_SHIFT 7 +static inline uint32_t get_udrv_in_len(const struct ubcore_udata *udata) +{ + return ((udata == NULL || udata->udrv_data == NULL) ? 0 : udata->udrv_data->in_len); +} + +static inline int get_udrv_in_data(uint8_t *dst, uint32_t dst_len, struct ubcore_udata *udata) +{ + if (udata == NULL || udata->udrv_data == NULL || udata->udrv_data->in_len == 0) + return 0; + + if (udata->uctx != NULL) { + if (dst_len < udata->udrv_data->in_len) + return -1; + return (int)copy_from_user(dst, (void __user *)(uintptr_t)udata->udrv_data->in_addr, + udata->udrv_data->in_len); + } else { + (void)memcpy(dst, (void *)udata->udrv_data->in_addr, udata->udrv_data->in_len); + return 0; + } +} + static inline void ubcore_set_net_addr_with_eid(struct ubcore_net_addr *net_addr, const union ubcore_eid *eid) { @@ -100,6 +121,85 @@ static struct ubcore_nlmsg *ubcore_alloc_nlmsg(size_t payload_len, const union u return msg; } +static struct ubcore_nlmsg *ubcore_get_destroy_tp_req(struct ubcore_tp *tp, + const struct ubcore_ta_data *ta) +{ + struct ubcore_nl_destroy_tp_req *destroy; + struct ubcore_nlmsg *req; + + req = ubcore_alloc_nlmsg(sizeof(struct ubcore_nl_destroy_tp_req), &tp->local_eid, + &tp->peer_eid); + if (req == NULL) + return NULL; + + req->msg_type = UBCORE_NL_DESTROY_TP_REQ; + req->transport_type = tp->ub_dev->transport_type; + destroy = (struct ubcore_nl_destroy_tp_req *)req->payload; + destroy->trans_mode = tp->trans_mode; + destroy->tpn = tp->tpn; + destroy->peer_tpn = tp->peer_tpn; + if (ta != NULL) + destroy->ta = *ta; + else + destroy->ta.type = UBCORE_TA_NONE; + + return req; +} + +static int ubcore_init_create_tp_req(struct ubcore_nl_create_tp_req *create, struct ubcore_tp *tp, + const struct ubcore_ta_data *ta, struct ubcore_udata *udata) +{ + create->tpn = tp->tpn; + create->local_net_addr = tp->local_net_addr; + create->peer_net_addr = tp->peer_net_addr; + create->trans_mode = tp->trans_mode; + create->mtu = tp->mtu; + create->rx_psn = tp->rx_psn; + create->cfg.flag = tp->flag; + create->cfg.congestion_alg = tp->ub_dev->attr.dev_cap.congestion_ctrl_alg; + + if (ta != NULL) + create->ta = *ta; + else + create->ta.type = UBCORE_TA_NONE; + + create->ext_len = tp->tp_ext.len; + create->udrv_in_len = get_udrv_in_len(udata); + if (tp->tp_ext.len > 0) + (void)memcpy(create->ext_udrv, (void *)tp->tp_ext.addr, tp->tp_ext.len); + + if (get_udrv_in_data(create->ext_udrv + tp->tp_ext.len, create->udrv_in_len, udata) != 0) { + ubcore_log_err("Failed to get udrv data"); + return -1; + } + + return 0; +} + +static struct ubcore_nlmsg *ubcore_get_create_tp_req(struct ubcore_tp *tp, + struct ubcore_ta_data *ta, + struct ubcore_udata *udata) +{ + uint32_t payload_len = + sizeof(struct ubcore_nl_create_tp_req) + tp->tp_ext.len + get_udrv_in_len(udata); + struct ubcore_nlmsg *req; + + req = ubcore_alloc_nlmsg(payload_len, &tp->local_eid, &tp->peer_eid); + if (req == NULL) + return NULL; + + req->transport_type = tp->ub_dev->transport_type; + req->msg_type = UBCORE_NL_CREATE_TP_REQ; + + if (ubcore_init_create_tp_req((struct ubcore_nl_create_tp_req *)req->payload, tp, ta, + udata) != 0) { + kfree(req); + ubcore_log_err("Failed to init create tp req"); + return NULL; + } + return req; +} + static int ubcore_set_tp_peer_ext(struct ubcore_tp_attr *attr, const uint8_t *ext_addr, const uint32_t ext_len) { @@ -139,6 +239,35 @@ static int ubcore_negotiate_optimal_cc_alg(uint16_t local_congestion_alg, return -1; } +static int ubcore_set_initiator_peer(const struct ubcore_tp *tp, struct ubcore_tp_attr *attr, + union ubcore_tp_attr_mask *mask, + const struct ubcore_nl_create_tp_resp *resp) +{ + mask->value = 0; + mask->bs.flag = 1; + mask->bs.peer_tpn = 1; + mask->bs.mtu = 1; + mask->bs.tx_psn = 1; + mask->bs.state = 1; + + memset(attr, 0, sizeof(*attr)); + attr->flag.bs.oor_en = tp->flag.bs.oor_en & resp->flag.bs.oor_en; + attr->flag.bs.sr_en = tp->flag.bs.sr_en & resp->flag.bs.sr_en; + attr->flag.bs.spray_en = tp->flag.bs.spray_en & resp->flag.bs.spray_en; + attr->flag.bs.cc_en = tp->flag.bs.cc_en & resp->flag.bs.cc_en; + attr->flag.bs.cc_alg = resp->flag.bs.cc_alg; /* negotiated with the remote */ + attr->peer_tpn = resp->peer_tpn; + attr->mtu = min(tp->mtu, resp->peer_mtu); + attr->tx_psn = resp->peer_rx_psn; + attr->state = UBCORE_TP_STATE_RTS; + + if (tp->peer_ext.addr != 0) + return 0; + + mask->bs.peer_ext = 1; + return ubcore_set_tp_peer_ext(attr, resp->peer_ext, resp->peer_ext_len); +} + static struct ubcore_nlmsg *ubcore_get_query_tp_req(struct ubcore_device *dev, const union ubcore_eid *remote_eid, enum ubcore_transport_mode trans_mode) @@ -193,6 +322,73 @@ static int ubcore_query_tp(struct ubcore_device *dev, const union ubcore_eid *re return ret; } +static void ubcore_get_ta_data_from_ta(const struct ubcore_ta *ta, struct ubcore_ta_data *ta_data) +{ + struct ubcore_jetty *jetty; + struct ubcore_jfs *jfs; + + ta_data->type = ta->type; + switch (ta->type) { + case UBCORE_TA_JFS_TJFR: + jfs = ta->jfs; + ta_data->jetty_id.eid = jfs->ub_dev->attr.eid; + if (jfs->uctx != NULL) + ta_data->jetty_id.uasid = jfs->uctx->uasid; + ta_data->jetty_id.id = jfs->id; + ta_data->tjetty_id = ta->tjetty_id; + break; + case UBCORE_TA_JETTY_TJETTY: + jetty = ta->jetty; + ta_data->jetty_id.eid = jetty->ub_dev->attr.eid; + if (jetty->uctx != NULL) + ta_data->jetty_id.uasid = jetty->uctx->uasid; + ta_data->jetty_id.id = jetty->id; + ta_data->tjetty_id = ta->tjetty_id; + break; + case UBCORE_TA_NONE: + case UBCORE_TA_VIRT: + default: + return; + } +} + +static struct ubcore_nlmsg *ubcore_exchange_tp(struct ubcore_tp *tp, struct ubcore_ta *ta, + struct ubcore_udata *udata) +{ + struct ubcore_nlmsg *req_msg, *resp_msg; + + struct ubcore_nl_create_tp_resp *resp; + struct ubcore_ta_data ta_data = { 0 }; + + if (ta != NULL) + ubcore_get_ta_data_from_ta(ta, &ta_data); + + req_msg = ubcore_get_create_tp_req(tp, &ta_data, udata); + if (req_msg == NULL) { + ubcore_log_err("Failed to get create tp req"); + return NULL; + } + + resp_msg = ubcore_nl_send_wait(req_msg); + if (resp_msg == NULL) { + ubcore_log_err("Failed to wait create_tp response %pI6c", &tp->peer_eid); + kfree(req_msg); + return NULL; + } + + resp = (struct ubcore_nl_create_tp_resp *)(void *)resp_msg->payload; + if (resp_msg->msg_type != req_msg->msg_type + 1 || resp == NULL || + resp->ret != UBCORE_NL_RESP_SUCCESS) { + ubcore_log_err("Create tp request is rejected with type %d ret %d", + resp_msg->msg_type, (resp == NULL ? 1 : resp->ret)); + kfree(resp_msg); + resp_msg = NULL; + } + + kfree(req_msg); + return resp_msg; +} + int ubcore_destroy_tp(struct ubcore_tp *tp) { if (!ubcore_have_tp_ops(tp->ub_dev)) { @@ -260,6 +456,48 @@ static struct ubcore_tp *ubcore_create_tp(struct ubcore_device *dev, return tp; } +/* send request to destroy remote peer tp */ +static int ubcore_destroy_peer_tp(struct ubcore_tp *tp, struct ubcore_ta *ta) +{ + struct ubcore_nlmsg *req_msg, *resp_msg; + struct ubcore_nl_destroy_tp_resp *resp; + struct ubcore_ta_data ta_data = { 0 }; + int ret = 0; + + if (tp == NULL) { + ubcore_log_err("Invalid parameter"); + return -1; + } + + if (ta != NULL) + ubcore_get_ta_data_from_ta(ta, &ta_data); + + req_msg = ubcore_get_destroy_tp_req(tp, &ta_data); + if (req_msg == NULL) { + ubcore_log_err("Failed to get destroy tp req"); + return -1; + } + + resp_msg = ubcore_nl_send_wait(req_msg); + if (resp_msg == NULL) { + ubcore_log_err("Failed to get destroy tp response"); + kfree(req_msg); + return -1; + } + + resp = (struct ubcore_nl_destroy_tp_resp *)(void *)resp_msg->payload; + if (resp_msg->msg_type != UBCORE_NL_DESTROY_TP_RESP || resp == NULL || + resp->ret != UBCORE_NL_RESP_SUCCESS) { + ubcore_log_err("Destroy tp request is rejected with type %d ret %d", + resp_msg->msg_type, (resp == NULL ? 1 : resp->ret)); + ret = -1; + } + + kfree(resp_msg); + kfree(req_msg); + return ret; +} + static void ubcore_abort_tp(struct ubcore_tp *tp, struct ubcore_tp_meta *meta) { struct ubcore_tp *target; @@ -390,6 +628,64 @@ static void ubcore_modify_tp_attr(struct ubcore_tp *tp, const struct ubcore_tp_a static int ubcore_enable_tp(const struct ubcore_device *dev, struct ubcore_tp_node *tp_node, struct ubcore_ta *ta, struct ubcore_udata *udata) { + struct ubcore_tp *tp = tp_node->tp; + struct ubcore_nlmsg *resp_msg; + union ubcore_tp_attr_mask mask; + struct ubcore_tp_attr attr; + int ret; + + /* Do not exchange tp with remote in the VM */ + if (dev->attr.virtualization) + return 0; + + mutex_lock(&tp_node->lock); + if (tp->state == UBCORE_TP_STATE_RTR) { + ret = ubcore_modify_tp_to_rts(dev, tp); + mutex_unlock(&tp_node->lock); + return ret; + } + mutex_unlock(&tp_node->lock); + + /* send request to connection agent and set peer cfg and peer ext from response */ + resp_msg = ubcore_exchange_tp(tp, ta, udata); + if (resp_msg == NULL) { + ubcore_log_err("Failed to exchange tp info"); + return -1; + } + + mutex_lock(&tp_node->lock); + if (tp->state == UBCORE_TP_STATE_RTS) { + mutex_unlock(&tp_node->lock); + kfree(resp_msg); + ubcore_log_info("TP %u is already at RTS", tp->tpn); + return 0; + } + + ret = ubcore_set_initiator_peer( + tp, &attr, &mask, + (const struct ubcore_nl_create_tp_resp *)(void *)resp_msg->payload); + + /* Here we can free resp msg after use */ + kfree(resp_msg); + + if (ret != 0) { + mutex_unlock(&tp_node->lock); + (void)ubcore_destroy_peer_tp(tp, ta); + ubcore_unset_tp_peer_ext(&attr); + ubcore_log_err("Failed to set initiator peer"); + return -1; + } + + ret = dev->ops->modify_tp(tp, &attr, mask); + if (ret != 0) { + mutex_unlock(&tp_node->lock); + (void)ubcore_destroy_peer_tp(tp, ta); + ubcore_unset_tp_peer_ext(&attr); + ubcore_log_err("Failed to modify tp"); + return -1; + } + ubcore_modify_tp_attr(tp, &attr, mask); + mutex_unlock(&tp_node->lock); return 0; } -- Gitee From 4cc6a2cf2ea7d3ec2a56440ee875b05bc33dea60 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Sun, 17 Sep 2023 17:37:12 +0800 Subject: [PATCH 63/89] ub: ubcore add restore tp api driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Ubcore add restore tp api. Restore tp will restore tp from error state. This will use netlink to send request and wait for response. If success, it will restore tp to ready-to-send state (rts). Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/ubcore/ubcore_tp.c | 91 ++++++++++++++++++++++++++++++ drivers/ub/urma/ubcore/ubcore_tp.h | 3 + 2 files changed, 94 insertions(+) diff --git a/drivers/ub/urma/ubcore/ubcore_tp.c b/drivers/ub/urma/ubcore/ubcore_tp.c index 8ebcc034d79a..a5ebf0063e52 100644 --- a/drivers/ub/urma/ubcore/ubcore_tp.c +++ b/drivers/ub/urma/ubcore/ubcore_tp.c @@ -1227,6 +1227,49 @@ int ubcore_advise_tp(struct ubcore_device *dev, const union ubcore_eid *remote_e } EXPORT_SYMBOL(ubcore_advise_tp); +static void ubcore_get_ta_from_tp(struct ubcore_ta *ta, struct ubcore_tp *tp) +{ + struct ubcore_tp_node *tp_node = (struct ubcore_tp_node *)tp->priv; + + ta->type = UBCORE_TA_NONE; + switch (tp->trans_mode) { + case UBCORE_TP_RC: + case UBCORE_TP_RM: + /* ta is none for UB native device */ + if (tp_node != NULL) + *ta = tp_node->ta; + break; + case UBCORE_TP_UM: + default: + break; + } +} + +static struct ubcore_nlmsg *ubcore_get_restore_tp_req(struct ubcore_tp *tp) +{ + uint32_t payload_len = sizeof(struct ubcore_nl_restore_tp_req); + struct ubcore_nl_restore_tp_req *restore; + struct ubcore_ta ta; + struct ubcore_nlmsg *req; + + req = ubcore_alloc_nlmsg(payload_len, &tp->local_eid, &tp->peer_eid); + if (req == NULL) + return NULL; + + req->transport_type = tp->ub_dev->transport_type; + req->msg_type = UBCORE_NL_RESTORE_TP_REQ; + restore = (struct ubcore_nl_restore_tp_req *)(void *)req->payload; + restore->trans_mode = tp->trans_mode; + restore->tpn = tp->tpn; + restore->peer_tpn = tp->peer_tpn; + restore->rx_psn = get_random_u32(); + + ubcore_get_ta_from_tp(&ta, tp); + ubcore_get_ta_data_from_ta(&ta, &restore->ta); + + return req; +} + static struct ubcore_nlmsg *ubcore_get_restore_tp_response(struct ubcore_nlmsg *req, struct ubcore_tp *tp) { @@ -1282,6 +1325,54 @@ static int ubcore_restore_tp_to_rts(const struct ubcore_device *dev, struct ubco return 0; } +void ubcore_restore_tp(struct ubcore_device *dev, struct ubcore_tp *tp) +{ + struct ubcore_nlmsg *req_msg, *resp_msg; + struct ubcore_nl_restore_tp_resp *resp; + struct ubcore_nl_restore_tp_req *req; + + /* Currently, only try to restore tp in the UBCORE_TRANSPORT_IB device, + * Do not send retore tp req from target to inititor, + * Do not restore UM TP, as it is only visable by the driver + */ + if (dev->transport_type != UBCORE_TRANSPORT_IB || tp->flag.bs.target || tp->priv == NULL || + tp->trans_mode == UBCORE_TP_UM || tp->state != UBCORE_TP_STATE_ERROR || + !ubcore_have_tp_ops(dev)) + return; + + req_msg = ubcore_get_restore_tp_req(tp); + if (req_msg == NULL) { + ubcore_log_err("Failed to get restore tp req"); + return; + } + + resp_msg = ubcore_nl_send_wait(req_msg); + if (resp_msg == NULL) { + ubcore_log_err("Failed to wait restore tp response %pI6c", &tp->peer_eid); + kfree(req_msg); + return; + } + + req = (struct ubcore_nl_restore_tp_req *)(void *)req_msg->payload; + resp = (struct ubcore_nl_restore_tp_resp *)(void *)resp_msg->payload; + if (resp_msg->msg_type != req_msg->msg_type + 1 || resp == NULL || + resp->ret != UBCORE_NL_RESP_SUCCESS) { + ubcore_log_err("Restore tp request is rejected with type %d ret %d", + resp_msg->msg_type, (resp == NULL ? 1 : resp->ret)); + kfree(resp_msg); + kfree(req_msg); + return; + } + + if (ubcore_restore_tp_to_rts(dev, tp, req->rx_psn, resp->peer_rx_psn) != 0) + ubcore_log_err("Failed to restore tp with tpn %u", tp->tpn); + + kfree(req_msg); + kfree(resp_msg); + ubcore_log_info("Restored tp with tpn %u", tp->tpn); +} +EXPORT_SYMBOL(ubcore_restore_tp); + /* restore target RM tp created by ubcore_advise_target_tp */ static struct ubcore_tp *ubcore_restore_advised_target_tp(struct ubcore_device *dev, struct ubcore_nl_restore_tp_req *restore) diff --git a/drivers/ub/urma/ubcore/ubcore_tp.h b/drivers/ub/urma/ubcore/ubcore_tp.h index 228701dba740..5cdacee31ce9 100644 --- a/drivers/ub/urma/ubcore/ubcore_tp.h +++ b/drivers/ub/urma/ubcore/ubcore_tp.h @@ -52,4 +52,7 @@ struct ubcore_nlmsg *ubcore_handle_restore_tp_req(struct ubcore_nlmsg *req); /* Called when clear tp table */ int ubcore_destroy_tp(struct ubcore_tp *tp); + +/* restore tp from error state */ +void ubcore_restore_tp(struct ubcore_device *dev, struct ubcore_tp *tp); #endif -- Gitee From 0dec85bce1caec378c5627447b48f944518ef51d Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Mon, 18 Sep 2023 11:27:54 +0800 Subject: [PATCH 64/89] ub: ubcore add unadivse tp api driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Ubcore add unadvise tp api. Unadvise tp will finally destroy tp, which will call driver's registered method destroy_tp. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/ubcore/ubcore_tp.c | 30 ++++++++++++++++++++++++++++++ drivers/ub/urma/ubcore/ubcore_tp.h | 1 + 2 files changed, 31 insertions(+) diff --git a/drivers/ub/urma/ubcore/ubcore_tp.c b/drivers/ub/urma/ubcore/ubcore_tp.c index a5ebf0063e52..eb381fe566a3 100644 --- a/drivers/ub/urma/ubcore/ubcore_tp.c +++ b/drivers/ub/urma/ubcore/ubcore_tp.c @@ -498,6 +498,23 @@ static int ubcore_destroy_peer_tp(struct ubcore_tp *tp, struct ubcore_ta *ta) return ret; } +/* Destroy both local tp and remote peer tp */ +static int ubcore_destroy_local_peer_tp(struct ubcore_tp *tp, struct ubcore_ta *ta) +{ + struct ubcore_device *dev = tp->ub_dev; + int ret; + + /* Do not send destroy request to the remote if we are in the VM */ + if (!dev->attr.virtualization) { + ret = ubcore_destroy_peer_tp(tp, ta); + if (ret != 0) { + ubcore_log_err("Failed to destroy peer tp"); + return ret; + } + } + return ubcore_destroy_tp(tp); +} + static void ubcore_abort_tp(struct ubcore_tp *tp, struct ubcore_tp_meta *meta) { struct ubcore_tp *target; @@ -1227,6 +1244,19 @@ int ubcore_advise_tp(struct ubcore_device *dev, const union ubcore_eid *remote_e } EXPORT_SYMBOL(ubcore_advise_tp); +int ubcore_unadvise_tp(struct ubcore_device *dev, struct ubcore_tp_advice *advice) +{ + struct ubcore_tp *tp = + ubcore_find_remove_tp(advice->meta.ht, advice->meta.hash, &advice->meta.key); + if (tp == NULL) { + ubcore_log_warn("TP is not found, already removed or under use\n"); + return 0; + } + + return ubcore_destroy_local_peer_tp(tp, &advice->ta); +} +EXPORT_SYMBOL(ubcore_unadvise_tp); + static void ubcore_get_ta_from_tp(struct ubcore_ta *ta, struct ubcore_tp *tp) { struct ubcore_tp_node *tp_node = (struct ubcore_tp_node *)tp->priv; diff --git a/drivers/ub/urma/ubcore/ubcore_tp.h b/drivers/ub/urma/ubcore/ubcore_tp.h index 5cdacee31ce9..3cf8a43cd98e 100644 --- a/drivers/ub/urma/ubcore/ubcore_tp.h +++ b/drivers/ub/urma/ubcore/ubcore_tp.h @@ -45,6 +45,7 @@ static inline bool ubcore_have_tp_ops(const struct ubcore_device *dev) /* alpha */ int ubcore_advise_tp(struct ubcore_device *dev, const union ubcore_eid *remote_eid, struct ubcore_tp_advice *advice, struct ubcore_udata *udata); +int ubcore_unadvise_tp(struct ubcore_device *dev, struct ubcore_tp_advice *advice); struct ubcore_nlmsg *ubcore_handle_create_tp_req(struct ubcore_nlmsg *req); struct ubcore_nlmsg *ubcore_handle_destroy_tp_req(struct ubcore_nlmsg *req); -- Gitee From f693d75427979df43d6995fd7ce3fa17cc0767a3 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Mon, 18 Sep 2023 11:33:05 +0800 Subject: [PATCH 65/89] ub: ubcore add bind and unbind tp api driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Ubcore add bind and unbind tp api. Bind/unbind tp will be used in RC (Reliable connection) mode to create connection between 2 nodes. Bind/unbind tp has the similar process as advise/unadvise tp: - find if tp existed already. - fill the config - create tp. Driver gurantee to return the same tp if we have created it as a target - add tp into tp hash table - send request to connection agent and set peer cfg and peer ext from response Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/ubcore/ubcore_tp.c | 76 ++++++++++++++++++++++++++++++ drivers/ub/urma/ubcore/ubcore_tp.h | 6 +++ 2 files changed, 82 insertions(+) diff --git a/drivers/ub/urma/ubcore/ubcore_tp.c b/drivers/ub/urma/ubcore/ubcore_tp.c index eb381fe566a3..2c91d045e9c8 100644 --- a/drivers/ub/urma/ubcore/ubcore_tp.c +++ b/drivers/ub/urma/ubcore/ubcore_tp.c @@ -1192,6 +1192,82 @@ static inline void ubcore_set_ta_for_tp_cfg(struct ubcore_device *dev, struct ub cfg->ta = NULL; } +int ubcore_bind_tp(struct ubcore_jetty *jetty, struct ubcore_tjetty *tjetty, + struct ubcore_tp_advice *advice, struct ubcore_udata *udata) +{ + struct ubcore_device *dev = jetty->ub_dev; + struct ubcore_tp_cfg cfg = { 0 }; + struct ubcore_tp_node *tp_node; + struct ubcore_tp *new_tp = NULL; + + if (ubcore_query_initiator_tp_cfg(&cfg, dev, (union ubcore_eid *)&tjetty->cfg.id.eid, + tjetty->cfg.trans_mode) != 0) { + ubcore_log_err("Failed to init tp cfg.\n"); + return -1; + } + + mutex_lock(&tjetty->lock); + if (tjetty->tp != NULL) { + mutex_unlock(&tjetty->lock); + ubcore_log_err("The same tjetty, different jetty, prevent duplicate bind.\n"); + return -1; + } + + ubcore_set_ta_for_tp_cfg(dev, &advice->ta, &cfg); + + /* driver gurantee to return the same tp if we have created it as a target */ + new_tp = ubcore_create_tp(dev, &cfg, udata); + if (new_tp == NULL) { + ubcore_log_err("Failed to create tp.\n"); + mutex_unlock(&tjetty->lock); + return -1; + } + + tp_node = ubcore_add_tp_node(advice->meta.ht, advice->meta.hash, &advice->meta.key, new_tp, + &advice->ta); + if (tp_node == NULL) { + (void)ubcore_destroy_tp(new_tp); + mutex_unlock(&tjetty->lock); + ubcore_log_err("Failed to find and add tp\n"); + return -1; + } else if (tp_node != NULL && tp_node->tp != new_tp) { + (void)ubcore_destroy_tp(new_tp); + new_tp = NULL; + } + tjetty->tp = tp_node->tp; + mutex_unlock(&tjetty->lock); + + /* send request to connection agent and set peer cfg and peer ext from response */ + if (ubcore_enable_tp(dev, tp_node, &advice->ta, udata) != 0) { + mutex_lock(&tjetty->lock); + tjetty->tp = NULL; + mutex_unlock(&tjetty->lock); + ubcore_abort_tp(new_tp, &advice->meta); + ubcore_log_err("Failed to enable tp.\n"); + return -1; + } + return 0; +} +EXPORT_SYMBOL(ubcore_bind_tp); + +int ubcore_unbind_tp(struct ubcore_jetty *jetty, struct ubcore_tjetty *tjetty, + struct ubcore_tp_advice *advice) +{ + if (tjetty->tp == NULL) { + ubcore_log_warn("TP is not found, already removed or under use\n"); + return 0; + } + if (ubcore_unadvise_tp(jetty->ub_dev, advice) != 0) { + ubcore_log_warn("failed to unbind tp\n"); + return -1; + } + mutex_lock(&tjetty->lock); + tjetty->tp = NULL; + mutex_unlock(&tjetty->lock); + return 0; +} +EXPORT_SYMBOL(ubcore_unbind_tp); + int ubcore_advise_tp(struct ubcore_device *dev, const union ubcore_eid *remote_eid, struct ubcore_tp_advice *advice, struct ubcore_udata *udata) { diff --git a/drivers/ub/urma/ubcore/ubcore_tp.h b/drivers/ub/urma/ubcore/ubcore_tp.h index 3cf8a43cd98e..567f80d05642 100644 --- a/drivers/ub/urma/ubcore/ubcore_tp.h +++ b/drivers/ub/urma/ubcore/ubcore_tp.h @@ -51,6 +51,12 @@ struct ubcore_nlmsg *ubcore_handle_create_tp_req(struct ubcore_nlmsg *req); struct ubcore_nlmsg *ubcore_handle_destroy_tp_req(struct ubcore_nlmsg *req); struct ubcore_nlmsg *ubcore_handle_restore_tp_req(struct ubcore_nlmsg *req); +/* bind tp APIs */ +int ubcore_bind_tp(struct ubcore_jetty *jetty, struct ubcore_tjetty *tjetty, + struct ubcore_tp_advice *advice, struct ubcore_udata *udata); +int ubcore_unbind_tp(struct ubcore_jetty *jetty, struct ubcore_tjetty *tjetty, + struct ubcore_tp_advice *advice); + /* Called when clear tp table */ int ubcore_destroy_tp(struct ubcore_tp *tp); -- Gitee From 3bb10a6083ac9310fa93e07612060181f92b4310 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Mon, 18 Sep 2023 11:49:13 +0800 Subject: [PATCH 66/89] ub: ubcore add implements of create and destroy vtp driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Ubcore add implements of create and destroy vtp. Vtp is tp used in virtualization scenario. Currently vtp is only supported in IB mode. The process of vtp creation is similar as tp advise. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/ubcore/ubcore_tp.c | 135 ++++++++++++++++++++++++++++- 1 file changed, 134 insertions(+), 1 deletion(-) diff --git a/drivers/ub/urma/ubcore/ubcore_tp.c b/drivers/ub/urma/ubcore/ubcore_tp.c index 2c91d045e9c8..c1643b1935e2 100644 --- a/drivers/ub/urma/ubcore/ubcore_tp.c +++ b/drivers/ub/urma/ubcore/ubcore_tp.c @@ -531,6 +531,23 @@ static void ubcore_abort_tp(struct ubcore_tp *tp, struct ubcore_tp_meta *meta) (void)ubcore_destroy_tp(tp); } +/* destroy initiator and peer tp created by ubcore_connect_vtp, called by ubcore_destroy_vtp */ +static int ubcore_disconnect_vtp(struct ubcore_tp *tp) +{ + struct ubcore_tp_node *tp_node = tp->priv; + struct ubcore_device *dev = tp->ub_dev; + + if (atomic_dec_return(&tp->use_cnt) == 0) { + struct ubcore_ta ta; + + ta.type = UBCORE_TA_VIRT; + + ubcore_remove_tp_node(&dev->ht[UBCORE_HT_TP], tp_node); + return ubcore_destroy_local_peer_tp(tp, &ta); + } + return 0; +} + static void ubcore_set_multipath_tp_cfg(struct ubcore_tp_cfg *cfg, enum ubcore_transport_mode trans_mode, struct ubcore_nl_query_tp_resp *query_tp_resp) @@ -706,6 +723,46 @@ static int ubcore_enable_tp(const struct ubcore_device *dev, struct ubcore_tp_no return 0; } +/* create vtp and connect to a remote vtp peer, called by ubcore_create_vtp */ +static struct ubcore_tp *ubcore_connect_vtp(struct ubcore_device *dev, + const union ubcore_eid *remote_eid, + enum ubcore_transport_mode trans_mode, + struct ubcore_udata *udata) +{ + struct ubcore_tp_cfg cfg = { 0 }; + struct ubcore_tp_node *tp_node; + struct ubcore_tp *tp = NULL; + struct ubcore_ta ta; + + if (ubcore_query_initiator_tp_cfg(&cfg, dev, remote_eid, trans_mode) != 0) { + ubcore_log_err("Failed to init tp cfg"); + return NULL; + } + + tp = ubcore_create_tp(dev, &cfg, udata); + if (tp == NULL) { + ubcore_log_err("Failed to create tp"); + return NULL; + } + + tp_node = ubcore_add_tp_with_tpn(dev, tp); + if (tp_node == NULL) { + (void)ubcore_destroy_tp(tp); + ubcore_log_err("Failed to add vtp"); + return NULL; + } + + ta.type = UBCORE_TA_VIRT; + /* send request to connection agent and set peer cfg and peer ext from response */ + if (ubcore_enable_tp(dev, tp_node, &ta, udata) != 0) { + ubcore_remove_tp_node(&dev->ht[UBCORE_HT_TP], tp_node); + (void)ubcore_destroy_tp(tp); + ubcore_log_err("Failed to enable tp"); + return NULL; + } + return tp; +} + static int ubcore_set_target_peer(const struct ubcore_tp *tp, struct ubcore_tp_attr *attr, union ubcore_tp_attr_mask *mask, const struct ubcore_nl_create_tp_req *create) @@ -1046,6 +1103,40 @@ static struct ubcore_tp *ubcore_advise_target_tp(struct ubcore_device *dev, return tp; } +static struct ubcore_tp *ubcore_accept_target_vtp(struct ubcore_device *dev, + struct ubcore_nlmsg *req) +{ + struct ubcore_nl_create_tp_req *create = + (struct ubcore_nl_create_tp_req *)(void *)req->payload; + struct ubcore_tp_node *tp_node; + struct ubcore_tp *tp = NULL; + + tp = ubcore_create_target_tp(dev, req, NULL); + if (tp == NULL) { + ubcore_log_err("Failed to create tp"); + return NULL; + } + + tp_node = ubcore_add_tp_with_tpn(dev, tp); + if (tp_node == NULL) { + ubcore_log_err("Failed to add tp to the tp table in the device"); + goto destroy_tp; + } + + if (ubcore_modify_target_tp(dev, tp_node, create) != 0) { + ubcore_log_err("Failed to modify tp"); + goto remove_tp_node; + } + + return tp; + +remove_tp_node: + ubcore_remove_tp_node(&dev->ht[UBCORE_HT_TP], tp_node); +destroy_tp: + (void)ubcore_destroy_tp(tp); + return NULL; +} + static struct ubcore_tp *ubcore_bind_target_tp(struct ubcore_device *dev, struct ubcore_nlmsg *req) { return ubcore_advise_target_tp(dev, req); @@ -1071,7 +1162,9 @@ struct ubcore_nlmsg *ubcore_handle_create_tp_req(struct ubcore_nlmsg *req) return ubcore_get_create_tp_response(NULL, req); } - if (create->trans_mode == UBCORE_TP_RC) { + if (create->ta.type == UBCORE_TA_VIRT) { + tp = ubcore_accept_target_vtp(dev, req); + } else if (create->trans_mode == UBCORE_TP_RC) { tp = ubcore_bind_target_tp(dev, req); } else if (create->trans_mode == UBCORE_TP_RM && dev->transport_type == UBCORE_TRANSPORT_IB) { @@ -1173,12 +1266,52 @@ struct ubcore_tp *ubcore_create_vtp(struct ubcore_device *dev, const union ubcor enum ubcore_transport_mode trans_mode, struct ubcore_udata *udata) { + if (dev == NULL || dev->attr.virtualization || remote_eid == NULL || + !ubcore_have_tp_ops(dev)) { + ubcore_log_err("Invalid parameter"); + return NULL; + } + + switch (dev->transport_type) { + case UBCORE_TRANSPORT_IB: /* alpha */ + if (trans_mode == UBCORE_TP_RM || trans_mode == UBCORE_TP_RC) + return ubcore_connect_vtp(dev, remote_eid, trans_mode, udata); + break; + case UBCORE_TRANSPORT_UB: /* beta */ + case UBCORE_TRANSPORT_IP: + case UBCORE_TRANSPORT_INVALID: + case UBCORE_TRANSPORT_MAX: + default: + break; + } return NULL; } EXPORT_SYMBOL(ubcore_create_vtp); int ubcore_destroy_vtp(struct ubcore_tp *vtp) { + enum ubcore_transport_mode trans_mode; + struct ubcore_device *dev; + + if (vtp == NULL || vtp->ub_dev == NULL || vtp->priv == NULL || + vtp->ub_dev->attr.virtualization) { + ubcore_log_err("Invalid para"); + return -1; + } + dev = vtp->ub_dev; + trans_mode = vtp->trans_mode; + switch (dev->transport_type) { + case UBCORE_TRANSPORT_IB: /* alpha */ + if (trans_mode == UBCORE_TP_RM || trans_mode == UBCORE_TP_RC) + return ubcore_disconnect_vtp(vtp); + break; + case UBCORE_TRANSPORT_UB: /* beta */ + case UBCORE_TRANSPORT_IP: + case UBCORE_TRANSPORT_INVALID: + case UBCORE_TRANSPORT_MAX: + default: + break; + } return -1; } EXPORT_SYMBOL(ubcore_destroy_vtp); -- Gitee From 99d491f3e0051932b25eaa0ecdc7ff21bbd0ecb7 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Mon, 18 Sep 2023 14:55:52 +0800 Subject: [PATCH 67/89] ub: ubcore add config and show utp api. driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Ubcore add config and show utp api. Config utp will finally use the driver's registered method config_utp. Show utp will finally use the driver's registered method query_res. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/ubcore/ubcore_priv.h | 4 ++ drivers/ub/urma/ubcore/ubcore_tp.c | 79 ++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/drivers/ub/urma/ubcore/ubcore_priv.h b/drivers/ub/urma/ubcore/ubcore_priv.h index d8782d9fac46..bc848bf51bff 100644 --- a/drivers/ub/urma/ubcore/ubcore_priv.h +++ b/drivers/ub/urma/ubcore/ubcore_priv.h @@ -44,6 +44,10 @@ struct ubcore_device **ubcore_get_devices_from_netdev(struct net_device *netdev, void ubcore_put_devices(struct ubcore_device **devices, uint32_t cnt); void ubcore_set_default_eid(struct ubcore_device *dev); +int ubcore_config_utp(struct ubcore_device *dev, const union ubcore_eid *eid, + const struct ubcore_utp_attr *attr, union ubcore_utp_attr_mask mask); +int ubcore_show_utp(struct ubcore_device *dev, const union ubcore_eid *eid); + static inline uint32_t ubcore_get_jetty_hash(const struct ubcore_jetty_id *jetty_id) { return jhash(jetty_id, sizeof(struct ubcore_jetty_id), 0); diff --git a/drivers/ub/urma/ubcore/ubcore_tp.c b/drivers/ub/urma/ubcore/ubcore_tp.c index c1643b1935e2..d284639925fb 100644 --- a/drivers/ub/urma/ubcore/ubcore_tp.c +++ b/drivers/ub/urma/ubcore/ubcore_tp.c @@ -1694,3 +1694,82 @@ struct ubcore_nlmsg *ubcore_handle_restore_tp_req(struct ubcore_nlmsg *req) return ubcore_get_restore_tp_response(req, tp); } EXPORT_SYMBOL(ubcore_handle_restore_tp_req); + +int ubcore_config_utp(struct ubcore_device *dev, const union ubcore_eid *eid, + const struct ubcore_utp_attr *attr, union ubcore_utp_attr_mask mask) +{ + struct ubcore_res_dev_val dev_val = { 0 }; + struct ubcore_res_key key_val; + struct ubcore_res_val val; + uint32_t i; + + if (dev == NULL || eid == NULL || attr == NULL || dev->ops == NULL || + dev->ops->query_res == NULL || dev->ops->config_utp == NULL) { + ubcore_log_err("dev ops has a null pointer.\n"); + return -1; + } + if (dev->transport_type == UBCORE_TRANSPORT_IB) { + ubcore_log_err( + "The configuration modification of this version of utp is not supported.\n"); + return -1; + } + // Query the utp_list under the device + val.addr = (uint64_t)&dev_val; + val.len = sizeof(struct ubcore_res_dev_val); + key_val.type = UBCORE_RES_KEY_URMA_DEV; + key_val.key = eid->in4.addr; + if (dev->ops->query_res(dev, &key_val, &val) != 0) { + ubcore_log_err("failed to query res.\n"); + return -1; + } + for (i = 0; dev_val.utp_list != NULL && i < dev_val.utp_cnt; i++) { + if (dev->ops->config_utp(dev, dev_val.utp_list[i], attr, mask) != 0) { + ubcore_log_err("failed to config utp.\n"); + return -1; + } + } + return 0; +} +EXPORT_SYMBOL(ubcore_config_utp); + +int ubcore_show_utp(struct ubcore_device *dev, const union ubcore_eid *eid) +{ + struct ubcore_res_dev_val dev_val = { 0 }; + struct ubcore_res_utp_val utp_val = { 0 }; + struct ubcore_res_key key_val; + struct ubcore_res_val val; + uint32_t i; + + if (dev == NULL || eid == NULL || dev->ops == NULL || dev->ops->query_res == NULL) { + ubcore_log_err("dev ops has a null pointer.\n"); + return -1; + } + // Query the utp_list under the device + val.addr = (uint64_t)&dev_val; + val.len = sizeof(struct ubcore_res_dev_val); + key_val.type = UBCORE_RES_KEY_URMA_DEV; + key_val.key = eid->in4.addr; + if (dev->ops->query_res(dev, &key_val, &val) != 0) { + ubcore_log_err("failed to query res.\n"); + return -1; + } + for (i = 0; dev_val.utp_list != NULL && i < dev_val.utp_cnt; i++) { + // Query the utp_val under the utp list + val.addr = (uint64_t)&utp_val; + val.len = sizeof(struct ubcore_res_utp_val); + key_val.type = UBCORE_RES_KEY_UTP; + key_val.key = dev_val.utp_list[i]; + if (dev->ops->query_res(dev, &key_val, &val) != 0) { + ubcore_log_err("failed to query res.\n"); + return -1; + } + ubcore_log_info("-----------utp_info---------\n"); + ubcore_log_info("--utp_id: %d\n", (int)utp_val.utp_id); + ubcore_log_info("--spray_en: %d\n", (int)utp_val.spray_en); + ubcore_log_info("--data_udp_start: %d\n", (int)utp_val.data_udp_start); + ubcore_log_info("--udp_range: %d\n", (int)utp_val.udp_range); + ubcore_log_info("----------------------------\n"); + } + return 0; +} +EXPORT_SYMBOL(ubcore_show_utp); -- Gitee From a64ae4ce3e746f799a499e3ad57694577bc3ff6b Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Mon, 18 Sep 2023 15:06:07 +0800 Subject: [PATCH 68/89] ub: ubcore add advise and unadvise jfr api. driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Ubcore add advise and unadvise jfr api. Advise jfr: construct the transport channel for jfs and remote jfr. Unadvise jfr: Tear down the transport channel from jfs to remote jfr. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/ubcore/ubcore_jetty.c | 73 +++++++++++++++++++++++++++ drivers/ub/urma/ubcore/ubcore_priv.h | 7 +++ include/urma/ubcore_uapi.h | 16 ++++++ 3 files changed, 96 insertions(+) diff --git a/drivers/ub/urma/ubcore/ubcore_jetty.c b/drivers/ub/urma/ubcore/ubcore_jetty.c index cb4c37c013c6..e9391308e873 100644 --- a/drivers/ub/urma/ubcore/ubcore_jetty.c +++ b/drivers/ub/urma/ubcore/ubcore_jetty.c @@ -651,6 +651,79 @@ int ubcore_unimport_jetty(struct ubcore_tjetty *tjetty) } EXPORT_SYMBOL(ubcore_unimport_jetty); +static int ubcore_advice_jfs_tjfr(struct ubcore_tp_advice *advice, struct ubcore_jfs *jfs, + struct ubcore_tjetty *tjfr) +{ + (void)memset(advice, 0, sizeof(struct ubcore_tp_advice)); + advice->meta.ht = ubcore_get_tptable(jfs->tptable); + if (advice->meta.ht == NULL) { + ubcore_log_err("tp table has already been destroyed"); + return -1; + } + + advice->ta.type = UBCORE_TA_JFS_TJFR; + advice->ta.jfs = jfs; + advice->ta.tjetty_id = tjfr->cfg.id; + + ubcore_init_tp_key_jetty_id(&advice->meta.key, &tjfr->cfg.id); + advice->meta.hash = ubcore_get_jetty_hash(&tjfr->cfg.id); + return 0; +} + +static inline void ubcore_put_advice(const struct ubcore_tp_advice *advice) +{ + ubcore_put_tptable(advice->meta.ht); +} + +int ubcore_advise_jfr(struct ubcore_jfs *jfs, struct ubcore_tjetty *tjfr, + struct ubcore_udata *udata) +{ + struct ubcore_tp_advice advice; + int ret; + + if (jfs == NULL || tjfr == NULL || !ubcore_have_tp_ops(jfs->ub_dev)) { + ubcore_log_err("invalid parameter.\n"); + return -1; + } + if (!ubcore_jfs_tjfr_need_advise(jfs, tjfr)) { + ubcore_log_err("The transport mode is not rm.\n"); + return -1; + } + + ret = ubcore_advice_jfs_tjfr(&advice, jfs, tjfr); + if (ret != 0) + return ret; + + ret = ubcore_advise_tp(jfs->ub_dev, &tjfr->cfg.id.eid, &advice, udata); + ubcore_put_advice(&advice); + return ret; +} +EXPORT_SYMBOL(ubcore_advise_jfr); + +int ubcore_unadvise_jfr(struct ubcore_jfs *jfs, struct ubcore_tjetty *tjfr) +{ + struct ubcore_tp_advice advice; + int ret; + + if (jfs == NULL || tjfr == NULL || !ubcore_have_tp_ops(jfs->ub_dev)) { + ubcore_log_err("invalid parameter.\n"); + return -1; + } + if (!ubcore_jfs_tjfr_need_advise(jfs, tjfr)) { + ubcore_log_err("The transport mode is not rm.\n"); + return -1; + } + + ret = ubcore_advice_jfs_tjfr(&advice, jfs, tjfr); + if (ret != 0) + return ret; + + ret = ubcore_unadvise_tp(jfs->ub_dev, &advice); + ubcore_put_advice(&advice); + return ret; +} +EXPORT_SYMBOL(ubcore_unadvise_jfr); + struct ubcore_jetty *ubcore_find_jetty(struct ubcore_device *dev, uint32_t jetty_id) { return ubcore_hash_table_lookup(&dev->ht[UBCORE_HT_JETTY], jetty_id, &jetty_id); diff --git a/drivers/ub/urma/ubcore/ubcore_priv.h b/drivers/ub/urma/ubcore/ubcore_priv.h index bc848bf51bff..9814966dfbb5 100644 --- a/drivers/ub/urma/ubcore/ubcore_priv.h +++ b/drivers/ub/urma/ubcore/ubcore_priv.h @@ -53,4 +53,11 @@ static inline uint32_t ubcore_get_jetty_hash(const struct ubcore_jetty_id *jetty return jhash(jetty_id, sizeof(struct ubcore_jetty_id), 0); } +static inline bool ubcore_jfs_tjfr_need_advise(const struct ubcore_jfs *jfs, + const struct ubcore_tjetty *tjfr) +{ + return jfs->ub_dev->transport_type == UBCORE_TRANSPORT_IB && + jfs->jfs_cfg.trans_mode == UBCORE_TP_RM && tjfr->cfg.trans_mode == UBCORE_TP_RM; +} + #endif diff --git a/include/urma/ubcore_uapi.h b/include/urma/ubcore_uapi.h index 35abea2880e9..a90a833bf84d 100644 --- a/include/urma/ubcore_uapi.h +++ b/include/urma/ubcore_uapi.h @@ -327,6 +327,22 @@ struct ubcore_tjetty *ubcore_import_jetty(struct ubcore_device *dev, * @return: 0 on success, other value on error */ int ubcore_unimport_jetty(struct ubcore_tjetty *tjetty); +/** + * Advise jfr: construct the transport channel for jfs and remote jfr. + * @param[in] jfs: jfs to use to construct the transport channel; + * @param[in] tjfr: target jfr to reach; + * @param[in] udata (optional): ucontext and user space driver data + * @return: 0 on success, other value on error + */ +int ubcore_advise_jfr(struct ubcore_jfs *jfs, struct ubcore_tjetty *tjfr, + struct ubcore_udata *udata); +/** + * Unadvise jfr: Tear down the transport channel from jfs to remote jfr. + * @param[in] jfs: jfs to use to destruct the transport channel; + * @param[in] tjfr: target jfr advised before; + * @return: 0 on success, other value on error + */ +int ubcore_unadvise_jfr(struct ubcore_jfs *jfs, struct ubcore_tjetty *tjfr); /** * operation of user ioctl cmd. * @param[in] k_user_ctl: kdrv user control command pointer; -- Gitee From 6c0c23b9b01fff2df6655fbc9af6b31cb821be9a Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Mon, 18 Sep 2023 15:33:37 +0800 Subject: [PATCH 69/89] ub: ubcore add advise and unadvise jetty api. driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Ubcore add advise and unadvise jetty api. Advise jetty: construct the transport channel between local jetty and remote jetty. Unadvise jetty: deconstruct the transport channel between local jetty and remote jetty. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/ubcore/ubcore_jetty.c | 69 +++++++++++++++++++++++++++ drivers/ub/urma/ubcore/ubcore_priv.h | 8 ++++ include/urma/ubcore_uapi.h | 16 +++++++ 3 files changed, 93 insertions(+) diff --git a/drivers/ub/urma/ubcore/ubcore_jetty.c b/drivers/ub/urma/ubcore/ubcore_jetty.c index e9391308e873..99ec2617176c 100644 --- a/drivers/ub/urma/ubcore/ubcore_jetty.c +++ b/drivers/ub/urma/ubcore/ubcore_jetty.c @@ -670,6 +670,25 @@ static int ubcore_advice_jfs_tjfr(struct ubcore_tp_advice *advice, struct ubcore return 0; } +static int ubcore_advice_jetty_tjetty(struct ubcore_tp_advice *advice, struct ubcore_jetty *jetty, + struct ubcore_tjetty *tjetty) +{ + (void)memset(advice, 0, sizeof(struct ubcore_tp_advice)); + advice->meta.ht = ubcore_get_tptable(jetty->tptable); + if (advice->meta.ht == NULL) { + ubcore_log_err("tp table has already been destroyed"); + return -1; + } + + advice->ta.type = UBCORE_TA_JETTY_TJETTY; + advice->ta.jetty = jetty; + advice->ta.tjetty_id = tjetty->cfg.id; + + ubcore_init_tp_key_jetty_id(&advice->meta.key, &tjetty->cfg.id); + advice->meta.hash = ubcore_get_jetty_hash(&tjetty->cfg.id); + return 0; +} + static inline void ubcore_put_advice(const struct ubcore_tp_advice *advice) { ubcore_put_tptable(advice->meta.ht); @@ -724,6 +743,56 @@ int ubcore_unadvise_jfr(struct ubcore_jfs *jfs, struct ubcore_tjetty *tjfr) } EXPORT_SYMBOL(ubcore_unadvise_jfr); +int ubcore_advise_jetty(struct ubcore_jetty *jetty, struct ubcore_tjetty *tjetty, + struct ubcore_udata *udata) +{ + struct ubcore_tp_advice advice; + int ret; + + if (jetty == NULL || tjetty == NULL || !ubcore_have_tp_ops(jetty->ub_dev)) { + ubcore_log_err("invalid parameter.\n"); + return -1; + } + if (!ubcore_jetty_tjetty_need_advise(jetty, tjetty)) { + ubcore_log_err("The transport mode is not rm.\n"); + return -1; + } + + ret = ubcore_advice_jetty_tjetty(&advice, jetty, tjetty); + if (ret != 0) + return ret; + + /* alpha version, IB transport type and RM tp mode */ + ret = ubcore_advise_tp(jetty->ub_dev, &tjetty->cfg.id.eid, &advice, udata); + ubcore_put_advice(&advice); + return ret; +} +EXPORT_SYMBOL(ubcore_advise_jetty); + +int ubcore_unadvise_jetty(struct ubcore_jetty *jetty, struct ubcore_tjetty *tjetty) +{ + struct ubcore_tp_advice advice; + int ret; + + if (jetty == NULL || tjetty == NULL || !ubcore_have_tp_ops(jetty->ub_dev)) { + ubcore_log_err("invalid parameter.\n"); + return -1; + } + if (!ubcore_jetty_tjetty_need_advise(jetty, tjetty)) { + ubcore_log_err("The transport mode is not rm.\n"); + return -1; + } + + ret = ubcore_advice_jetty_tjetty(&advice, jetty, tjetty); + if (ret != 0) + return ret; + + ret = ubcore_unadvise_tp(jetty->ub_dev, &advice); + ubcore_put_advice(&advice); + return ret; +} +EXPORT_SYMBOL(ubcore_unadvise_jetty); + struct ubcore_jetty *ubcore_find_jetty(struct ubcore_device *dev, uint32_t jetty_id) { return ubcore_hash_table_lookup(&dev->ht[UBCORE_HT_JETTY], jetty_id, &jetty_id); diff --git a/drivers/ub/urma/ubcore/ubcore_priv.h b/drivers/ub/urma/ubcore/ubcore_priv.h index 9814966dfbb5..ce602d0e1cac 100644 --- a/drivers/ub/urma/ubcore/ubcore_priv.h +++ b/drivers/ub/urma/ubcore/ubcore_priv.h @@ -60,4 +60,12 @@ static inline bool ubcore_jfs_tjfr_need_advise(const struct ubcore_jfs *jfs, jfs->jfs_cfg.trans_mode == UBCORE_TP_RM && tjfr->cfg.trans_mode == UBCORE_TP_RM; } +static inline bool ubcore_jetty_tjetty_need_advise(const struct ubcore_jetty *jetty, + const struct ubcore_tjetty *tjetty) +{ + return jetty->ub_dev->transport_type == UBCORE_TRANSPORT_IB && + jetty->jetty_cfg.trans_mode == UBCORE_TP_RM && + tjetty->cfg.trans_mode == UBCORE_TP_RM; +} + #endif diff --git a/include/urma/ubcore_uapi.h b/include/urma/ubcore_uapi.h index a90a833bf84d..ecb6359b20cc 100644 --- a/include/urma/ubcore_uapi.h +++ b/include/urma/ubcore_uapi.h @@ -343,6 +343,22 @@ int ubcore_advise_jfr(struct ubcore_jfs *jfs, struct ubcore_tjetty *tjfr, * @return: 0 on success, other value on error */ int ubcore_unadvise_jfr(struct ubcore_jfs *jfs, struct ubcore_tjetty *tjfr); +/** + * Advise jetty: construct the transport channel between local jetty and remote jetty. + * @param[in] jetty: local jetty to construct the transport channel; + * @param[in] tjetty: target jetty to reach imported before; + * @param[in] udata (optional): ucontext and user space driver data + * @return: 0 on success, other value on error + */ +int ubcore_advise_jetty(struct ubcore_jetty *jetty, struct ubcore_tjetty *tjetty, + struct ubcore_udata *udata); +/** + * Unadvise jetty: deconstruct the transport channel between local jetty and remote jetty. + * @param[in] jetty: local jetty to destruct the transport channel; + * @param[in] tjetty: target jetty advised before; + * @return: 0 on success, other value on error + */ +int ubcore_unadvise_jetty(struct ubcore_jetty *jetty, struct ubcore_tjetty *tjetty); /** * operation of user ioctl cmd. * @param[in] k_user_ctl: kdrv user control command pointer; -- Gitee From 07d04c76dbb371fa1c773fda42596fc8a26437a8 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Mon, 18 Sep 2023 15:37:27 +0800 Subject: [PATCH 70/89] ub: ubcore add bind and unbind jetty api. driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Ubcore add bind and unbind jetty api. Bind jetty: Bind local jetty with remote jetty, and construct a transport channel between them. Unbind jetty: Unbind local jetty with remote jetty. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/ubcore/ubcore_jetty.c | 65 +++++++++++++++++++++++++++ include/urma/ubcore_uapi.h | 19 ++++++++ 2 files changed, 84 insertions(+) diff --git a/drivers/ub/urma/ubcore/ubcore_jetty.c b/drivers/ub/urma/ubcore/ubcore_jetty.c index 99ec2617176c..a95f2df2c409 100644 --- a/drivers/ub/urma/ubcore/ubcore_jetty.c +++ b/drivers/ub/urma/ubcore/ubcore_jetty.c @@ -793,6 +793,71 @@ int ubcore_unadvise_jetty(struct ubcore_jetty *jetty, struct ubcore_tjetty *tjet } EXPORT_SYMBOL(ubcore_unadvise_jetty); +int ubcore_bind_jetty(struct ubcore_jetty *jetty, struct ubcore_tjetty *tjetty, + struct ubcore_udata *udata) +{ + struct ubcore_tp_advice advice; + int ret; + + if (jetty == NULL || tjetty == NULL || !ubcore_have_tp_ops(jetty->ub_dev)) { + ubcore_log_err("invalid parameter.\n"); + return -1; + } + if ((jetty->jetty_cfg.trans_mode != UBCORE_TP_RC) || + (tjetty->cfg.trans_mode != UBCORE_TP_RC)) { + ubcore_log_err("trans mode is not rc type.\n"); + return -1; + } + if (jetty->remote_jetty != NULL) { + ubcore_log_err("The same jetty, different tjetty, prevent duplicate bind.\n"); + return -1; + } + + ret = ubcore_advice_jetty_tjetty(&advice, jetty, tjetty); + if (ret != 0) + return ret; + + ret = ubcore_bind_tp(jetty, tjetty, &advice, udata); + + ubcore_put_advice(&advice); + if (ret != 0) { + ubcore_log_err("Failed to setup tp connection.\n"); + return ret; + } + jetty->remote_jetty = tjetty; + return 0; +} +EXPORT_SYMBOL(ubcore_bind_jetty); + +int ubcore_unbind_jetty(struct ubcore_jetty *jetty, struct ubcore_tjetty *tjetty) +{ + struct ubcore_tp_advice advice; + int ret; + + if (jetty == NULL || tjetty == NULL) { + ubcore_log_err("invalid parameter.\n"); + return -1; + } + if ((jetty->jetty_cfg.trans_mode != UBCORE_TP_RC) || + (tjetty->cfg.trans_mode != UBCORE_TP_RC)) { + ubcore_log_err("trans mode is not rc type.\n"); + return -1; + } + + ret = ubcore_advice_jetty_tjetty(&advice, jetty, tjetty); + if (ret != 0) + return ret; + + ret = ubcore_unbind_tp(jetty, tjetty, &advice); + ubcore_put_advice(&advice); + if (ret != 0) + ubcore_log_err("Failed to destroy jetty tp.\n"); + + jetty->remote_jetty = NULL; + return ret; +} +EXPORT_SYMBOL(ubcore_unbind_jetty); + struct ubcore_jetty *ubcore_find_jetty(struct ubcore_device *dev, uint32_t jetty_id) { return ubcore_hash_table_lookup(&dev->ht[UBCORE_HT_JETTY], jetty_id, &jetty_id); diff --git a/include/urma/ubcore_uapi.h b/include/urma/ubcore_uapi.h index ecb6359b20cc..0f860c98349f 100644 --- a/include/urma/ubcore_uapi.h +++ b/include/urma/ubcore_uapi.h @@ -359,6 +359,25 @@ int ubcore_advise_jetty(struct ubcore_jetty *jetty, struct ubcore_tjetty *tjetty * @return: 0 on success, other value on error */ int ubcore_unadvise_jetty(struct ubcore_jetty *jetty, struct ubcore_tjetty *tjetty); +/** + * Bind jetty: Bind local jetty with remote jetty, and construct a transport channel between them. + * @param[in] jetty: local jetty to bind; + * @param[in] tjetty: target jetty imported before; + * @param[in] udata (optional): ucontext and user space driver data + * @return: 0 on success, other value on error + * Note: A local jetty can be binded with only one remote jetty. + * Only supported by jetty with URMA_TM_RC. + */ +int ubcore_bind_jetty(struct ubcore_jetty *jetty, struct ubcore_tjetty *tjetty, + struct ubcore_udata *udata); +/** + * Unbind jetty: Unbind local jetty with remote jetty, + * and tear down the transport channel between them. + * @param[in] jetty: local jetty to unbind; + * @param[in] tjetty: target jetty advised before; + * @return: 0 on success, other value on error + */ +int ubcore_unbind_jetty(struct ubcore_jetty *jetty, struct ubcore_tjetty *tjetty); /** * operation of user ioctl cmd. * @param[in] k_user_ctl: kdrv user control command pointer; -- Gitee From 800f865b1fabdb79ae9e3ec3c18c882777fb34ee Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Mon, 18 Sep 2023 15:50:59 +0800 Subject: [PATCH 71/89] ub: uburma add cmd advise/unadvise jfr implementation. driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Uburma add implementations of handling advise and unadvise jfr cmd from user layer. This will make kernel possible to handle urma_advise_jfr and urma_unadvise_jfr api in user-layer urma. Advise jfr will finally call ubcore_advise_jfr. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/uburma/uburma_cmd.c | 87 +++++++++++++++++++++++++++++ drivers/ub/urma/uburma/uburma_cmd.h | 17 ++++++ 2 files changed, 104 insertions(+) diff --git a/drivers/ub/urma/uburma/uburma_cmd.c b/drivers/ub/urma/uburma/uburma_cmd.c index 7ecea2c9e33d..3cb0d669af96 100644 --- a/drivers/ub/urma/uburma/uburma_cmd.c +++ b/drivers/ub/urma/uburma/uburma_cmd.c @@ -1011,6 +1011,91 @@ static int uburma_cmd_unimport_jetty(struct ubcore_device *ubc_dev, struct uburm return ret; } +static inline void uburma_put_jetty_tjetty_objs(struct uburma_uobj *jetty_uobj, + struct uburma_uobj *tjetty_uobj) +{ + uobj_put_read(jetty_uobj); + uobj_put_read(tjetty_uobj); +} + +static int uburma_get_jfs_tjfr_objs(struct uburma_file *file, uint64_t jetty_handle, + uint64_t tjetty_handle, struct uburma_uobj **jetty_uobj, + struct uburma_uobj **tjetty_uobj) +{ + *jetty_uobj = uobj_get_read(UOBJ_CLASS_JFS, jetty_handle, file); + if (IS_ERR(*jetty_uobj)) { + uburma_log_err("failed to find jfs with handle %llu", jetty_handle); + return -EINVAL; + } + + *tjetty_uobj = uobj_get_read(UOBJ_CLASS_TARGET_JFR, tjetty_handle, file); + if (IS_ERR(*tjetty_uobj)) { + uobj_put_read(*jetty_uobj); + uburma_log_err("failed to find target jfr with handle %llu", tjetty_handle); + return -EINVAL; + } + return 0; +} + +static inline void uburma_put_jfs_tjfr_objs(struct uburma_uobj *jetty_uobj, + struct uburma_uobj *tjetty_uobj) +{ + uburma_put_jetty_tjetty_objs(jetty_uobj, tjetty_uobj); +} + +static int uburma_cmd_advise_jfr(struct ubcore_device *ubc_dev, struct uburma_file *file, + struct uburma_cmd_hdr *hdr) +{ + struct uburma_cmd_advise_jetty arg; + struct uburma_uobj *tjfr_uobj; + struct uburma_uobj *jfs_uobj; + struct ubcore_udata udata; + int ret; + + ret = uburma_copy_from_user(&arg, (void __user *)(uintptr_t)hdr->args_addr, + sizeof(struct uburma_cmd_advise_jetty)); + if (ret != 0) + return ret; + + if (uburma_get_jfs_tjfr_objs(file, arg.in.jetty_handle, arg.in.tjetty_handle, &jfs_uobj, + &tjfr_uobj)) + return -EINVAL; + + fill_udata(&udata, file->ucontext, &arg.udata); + + ret = ubcore_advise_jfr(jfs_uobj->object, tjfr_uobj->object, &udata); + if (ret != 0) + uburma_log_err("advise jfr failed.\n"); + + uburma_put_jfs_tjfr_objs(jfs_uobj, tjfr_uobj); + return ret; +} + +static int uburma_cmd_unadvise_jfr(struct ubcore_device *ubc_dev, struct uburma_file *file, + struct uburma_cmd_hdr *hdr) +{ + struct uburma_cmd_unadvise_jetty arg; + struct uburma_uobj *tjfr_uobj; + struct uburma_uobj *jfs_uobj; + int ret; + + ret = uburma_copy_from_user(&arg, (void __user *)(uintptr_t)hdr->args_addr, + sizeof(struct uburma_cmd_unadvise_jetty)); + if (ret != 0) + return ret; + + if (uburma_get_jfs_tjfr_objs(file, arg.in.jetty_handle, arg.in.tjetty_handle, &jfs_uobj, + &tjfr_uobj)) + return -EINVAL; + + ret = ubcore_unadvise_jfr(jfs_uobj->object, tjfr_uobj->object); + if (ret != 0) + uburma_log_err("failed to unadvise jfr.\n"); + + uburma_put_jfs_tjfr_objs(jfs_uobj, tjfr_uobj); + return ret; +} + typedef int (*uburma_cmd_handler)(struct ubcore_device *ubc_dev, struct uburma_file *file, struct uburma_cmd_hdr *hdr); @@ -1034,6 +1119,8 @@ static uburma_cmd_handler g_uburma_cmd_handlers[] = { [UBURMA_CMD_DELETE_JETTY] = uburma_cmd_delete_jetty, [UBURMA_CMD_IMPORT_JETTY] = uburma_cmd_import_jetty, [UBURMA_CMD_UNIMPORT_JETTY] = uburma_cmd_unimport_jetty, + [UBURMA_CMD_ADVISE_JFR] = uburma_cmd_advise_jfr, + [UBURMA_CMD_UNADVISE_JFR] = uburma_cmd_unadvise_jfr, }; static int uburma_cmd_parse(struct ubcore_device *ubc_dev, struct uburma_file *file, diff --git a/drivers/ub/urma/uburma/uburma_cmd.h b/drivers/ub/urma/uburma/uburma_cmd.h index 6e49461428f4..b3cb71ee0b1e 100644 --- a/drivers/ub/urma/uburma/uburma_cmd.h +++ b/drivers/ub/urma/uburma/uburma_cmd.h @@ -56,6 +56,8 @@ enum uburma_cmd { UBURMA_CMD_DELETE_JETTY, UBURMA_CMD_IMPORT_JETTY, UBURMA_CMD_UNIMPORT_JETTY, + UBURMA_CMD_ADVISE_JFR, + UBURMA_CMD_UNADVISE_JFR, UBURMA_CMD_USER_CTL }; @@ -298,6 +300,21 @@ struct uburma_cmd_unimport_jetty { } in; }; +struct uburma_cmd_advise_jetty { + struct { + uint64_t jetty_handle; /* handle of jetty, used to find jetty obj in kernel */ + uint64_t tjetty_handle; /* handle of tjetty, used to find tjetty obj in kernel */ + } in; + struct uburma_cmd_udrv_priv udata; +}; + +struct uburma_cmd_unadvise_jetty { + struct { + uint64_t jetty_handle; /* handle of jetty, used to find jetty obj in kernel */ + uint64_t tjetty_handle; /* handle of tjetty, used to find tjetty obj in kernel */ + } in; +}; + /* only for event ioctl */ #define MAX_JFCE_EVENT_CNT 16 #define UBURMA_EVENT_CMD_MAGIC 'E' -- Gitee From 5dc65381369141dab3705d1137db800d0e083759 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Mon, 18 Sep 2023 15:56:13 +0800 Subject: [PATCH 72/89] ub: uburma add cmd advise/unadvise jetty implementation. driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Uburma add implementations of handling advise and unadvise jetty cmd from user layer. This will make kernel possible to handle urma_advise_jetty and urma_unadvise_jetty api in user-layer urma. Advise jetty will finally call ubcore_advise_jetty. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/uburma/uburma_cmd.c | 74 +++++++++++++++++++++++++++++ drivers/ub/urma/uburma/uburma_cmd.h | 2 + 2 files changed, 76 insertions(+) diff --git a/drivers/ub/urma/uburma/uburma_cmd.c b/drivers/ub/urma/uburma/uburma_cmd.c index 3cb0d669af96..2a4e6c5bccb3 100644 --- a/drivers/ub/urma/uburma/uburma_cmd.c +++ b/drivers/ub/urma/uburma/uburma_cmd.c @@ -1011,6 +1011,25 @@ static int uburma_cmd_unimport_jetty(struct ubcore_device *ubc_dev, struct uburm return ret; } +static int uburma_get_jetty_tjetty_objs(struct uburma_file *file, uint64_t jetty_handle, + uint64_t tjetty_handle, struct uburma_uobj **jetty_uobj, + struct uburma_uobj **tjetty_uobj) +{ + *jetty_uobj = uobj_get_read(UOBJ_CLASS_JETTY, jetty_handle, file); + if (IS_ERR(*jetty_uobj)) { + uburma_log_err("failed to find jetty with handle %llu", jetty_handle); + return -EINVAL; + } + + *tjetty_uobj = uobj_get_read(UOBJ_CLASS_TARGET_JETTY, tjetty_handle, file); + if (IS_ERR(*tjetty_uobj)) { + uobj_put_read(*jetty_uobj); + uburma_log_err("failed to find target jetty with handle %llu", tjetty_handle); + return -EINVAL; + } + return 0; +} + static inline void uburma_put_jetty_tjetty_objs(struct uburma_uobj *jetty_uobj, struct uburma_uobj *tjetty_uobj) { @@ -1096,6 +1115,59 @@ static int uburma_cmd_unadvise_jfr(struct ubcore_device *ubc_dev, struct uburma_ return ret; } +static int uburma_cmd_advise_jetty(struct ubcore_device *ubc_dev, struct uburma_file *file, + struct uburma_cmd_hdr *hdr) +{ + struct uburma_cmd_advise_jetty arg; + struct uburma_uobj *tjetty_uobj; + struct uburma_uobj *jetty_uobj; + struct ubcore_udata udata; + int ret; + + ret = uburma_copy_from_user(&arg, (void __user *)(uintptr_t)hdr->args_addr, + sizeof(struct uburma_cmd_advise_jetty)); + if (ret != 0) + return ret; + + if (uburma_get_jetty_tjetty_objs(file, arg.in.jetty_handle, arg.in.tjetty_handle, + &jetty_uobj, &tjetty_uobj)) + return -EINVAL; + + fill_udata(&udata, file->ucontext, &arg.udata); + + ret = ubcore_advise_jetty(jetty_uobj->object, tjetty_uobj->object, &udata); + if (ret != 0) + uburma_log_err("advise_jetty failed.\n"); + + uburma_put_jetty_tjetty_objs(jetty_uobj, tjetty_uobj); + return ret; +} + +static int uburma_cmd_unadvise_jetty(struct ubcore_device *ubc_dev, struct uburma_file *file, + struct uburma_cmd_hdr *hdr) +{ + struct uburma_cmd_unadvise_jetty arg; + struct uburma_uobj *tjetty_uobj; + struct uburma_uobj *jetty_uobj; + int ret; + + ret = uburma_copy_from_user(&arg, (void __user *)(uintptr_t)hdr->args_addr, + sizeof(struct uburma_cmd_unadvise_jetty)); + if (ret != 0) + return ret; + + if (uburma_get_jetty_tjetty_objs(file, arg.in.jetty_handle, arg.in.tjetty_handle, + &jetty_uobj, &tjetty_uobj)) + return -EINVAL; + + ret = ubcore_unadvise_jetty(jetty_uobj->object, tjetty_uobj->object); + if (ret != 0) + uburma_log_err("failed to unadvise jetty, ret: %d.\n", ret); + + uburma_put_jetty_tjetty_objs(jetty_uobj, tjetty_uobj); + return ret; +} + typedef int (*uburma_cmd_handler)(struct ubcore_device *ubc_dev, struct uburma_file *file, struct uburma_cmd_hdr *hdr); @@ -1121,6 +1193,8 @@ static uburma_cmd_handler g_uburma_cmd_handlers[] = { [UBURMA_CMD_UNIMPORT_JETTY] = uburma_cmd_unimport_jetty, [UBURMA_CMD_ADVISE_JFR] = uburma_cmd_advise_jfr, [UBURMA_CMD_UNADVISE_JFR] = uburma_cmd_unadvise_jfr, + [UBURMA_CMD_ADVISE_JETTY] = uburma_cmd_advise_jetty, + [UBURMA_CMD_UNADVISE_JETTY] = uburma_cmd_unadvise_jetty, }; static int uburma_cmd_parse(struct ubcore_device *ubc_dev, struct uburma_file *file, diff --git a/drivers/ub/urma/uburma/uburma_cmd.h b/drivers/ub/urma/uburma/uburma_cmd.h index b3cb71ee0b1e..09a4a7d51b46 100644 --- a/drivers/ub/urma/uburma/uburma_cmd.h +++ b/drivers/ub/urma/uburma/uburma_cmd.h @@ -58,6 +58,8 @@ enum uburma_cmd { UBURMA_CMD_UNIMPORT_JETTY, UBURMA_CMD_ADVISE_JFR, UBURMA_CMD_UNADVISE_JFR, + UBURMA_CMD_ADVISE_JETTY, + UBURMA_CMD_UNADVISE_JETTY, UBURMA_CMD_USER_CTL }; -- Gitee From 1763ad77e02d30c03d39c97f1a0a5728b7d19324 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Mon, 18 Sep 2023 15:59:20 +0800 Subject: [PATCH 73/89] ub: uburma add cmd bind/unbind jetty implementation. driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Uburma add implementations of handling bind and unbind jetty cmd from user layer. This will make kernel possible to handle urma_bind_jetty and urma_unbind_jetty api in user-layer urma. Bind jetty will finally call ubcore_bind_jetty. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/uburma/uburma_cmd.c | 55 +++++++++++++++++++++++++++++ drivers/ub/urma/uburma/uburma_cmd.h | 2 ++ 2 files changed, 57 insertions(+) diff --git a/drivers/ub/urma/uburma/uburma_cmd.c b/drivers/ub/urma/uburma/uburma_cmd.c index 2a4e6c5bccb3..00f827570119 100644 --- a/drivers/ub/urma/uburma/uburma_cmd.c +++ b/drivers/ub/urma/uburma/uburma_cmd.c @@ -1168,6 +1168,59 @@ static int uburma_cmd_unadvise_jetty(struct ubcore_device *ubc_dev, struct uburm return ret; } +static int uburma_cmd_bind_jetty(struct ubcore_device *ubc_dev, struct uburma_file *file, + struct uburma_cmd_hdr *hdr) +{ + struct uburma_cmd_advise_jetty arg; + struct uburma_uobj *tjetty_uobj; + struct uburma_uobj *jetty_uobj; + struct ubcore_udata udata; + int ret; + + ret = uburma_copy_from_user(&arg, (void __user *)(uintptr_t)hdr->args_addr, + sizeof(struct uburma_cmd_advise_jetty)); + if (ret != 0) + return ret; + + if (uburma_get_jetty_tjetty_objs(file, arg.in.jetty_handle, arg.in.tjetty_handle, + &jetty_uobj, &tjetty_uobj)) + return -EINVAL; + + fill_udata(&udata, file->ucontext, &arg.udata); + + ret = ubcore_bind_jetty(jetty_uobj->object, tjetty_uobj->object, &udata); + if (ret != 0) + uburma_log_err("bind jetty failed.\n"); + + uburma_put_jetty_tjetty_objs(jetty_uobj, tjetty_uobj); + return ret; +} + +static int uburma_cmd_unbind_jetty(struct ubcore_device *ubc_dev, struct uburma_file *file, + struct uburma_cmd_hdr *hdr) +{ + struct uburma_cmd_unadvise_jetty arg; + struct uburma_uobj *tjetty_uobj; + struct uburma_uobj *jetty_uobj; + int ret; + + ret = uburma_copy_from_user(&arg, (void __user *)(uintptr_t)hdr->args_addr, + sizeof(struct uburma_cmd_unadvise_jetty)); + if (ret != 0) + return ret; + + if (uburma_get_jetty_tjetty_objs(file, arg.in.jetty_handle, arg.in.tjetty_handle, + &jetty_uobj, &tjetty_uobj)) + return -EINVAL; + + ret = ubcore_unbind_jetty(jetty_uobj->object, tjetty_uobj->object); + if (ret != 0) + uburma_log_err("failed to unbind jetty, ret: %d.\n", ret); + + uburma_put_jetty_tjetty_objs(jetty_uobj, tjetty_uobj); + return ret; +} + typedef int (*uburma_cmd_handler)(struct ubcore_device *ubc_dev, struct uburma_file *file, struct uburma_cmd_hdr *hdr); @@ -1195,6 +1248,8 @@ static uburma_cmd_handler g_uburma_cmd_handlers[] = { [UBURMA_CMD_UNADVISE_JFR] = uburma_cmd_unadvise_jfr, [UBURMA_CMD_ADVISE_JETTY] = uburma_cmd_advise_jetty, [UBURMA_CMD_UNADVISE_JETTY] = uburma_cmd_unadvise_jetty, + [UBURMA_CMD_BIND_JETTY] = uburma_cmd_bind_jetty, + [UBURMA_CMD_UNBIND_JETTY] = uburma_cmd_unbind_jetty, }; static int uburma_cmd_parse(struct ubcore_device *ubc_dev, struct uburma_file *file, diff --git a/drivers/ub/urma/uburma/uburma_cmd.h b/drivers/ub/urma/uburma/uburma_cmd.h index 09a4a7d51b46..e698a9eba354 100644 --- a/drivers/ub/urma/uburma/uburma_cmd.h +++ b/drivers/ub/urma/uburma/uburma_cmd.h @@ -60,6 +60,8 @@ enum uburma_cmd { UBURMA_CMD_UNADVISE_JFR, UBURMA_CMD_ADVISE_JETTY, UBURMA_CMD_UNADVISE_JETTY, + UBURMA_CMD_BIND_JETTY, + UBURMA_CMD_UNBIND_JETTY, UBURMA_CMD_USER_CTL }; -- Gitee From 7139bde31624548c7da5da2d6642f659c1a36864 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Mon, 18 Sep 2023 16:16:26 +0800 Subject: [PATCH 74/89] ub: ubcore add cmd config and show utp implementation. driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Ubcore add implementations of handling config and show utp cmd from user layer. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/ubcore/ubcore_cmd.h | 19 ++++++ drivers/ub/urma/ubcore/ubcore_device.c | 5 ++ drivers/ub/urma/ubcore/ubcore_main.c | 80 ++++++++++++++++++++++++++ 3 files changed, 104 insertions(+) diff --git a/drivers/ub/urma/ubcore/ubcore_cmd.h b/drivers/ub/urma/ubcore/ubcore_cmd.h index 1e4ab2f71290..7e8e49a09d73 100644 --- a/drivers/ub/urma/ubcore/ubcore_cmd.h +++ b/drivers/ub/urma/ubcore/ubcore_cmd.h @@ -95,6 +95,25 @@ struct ubcore_cmd_query_res { } out; }; +struct ubcore_cmd_set_utp { + struct { + char dev_name[UBCORE_MAX_DEV_NAME]; + uint8_t eid[UBCORE_CMD_EID_SIZE]; + uint32_t transport_type; + bool spray_en; + uint16_t data_udp_start; + uint8_t udp_range; + } in; +}; + +struct ubcore_cmd_show_utp { + struct { + char dev_name[UBCORE_MAX_DEV_NAME]; + uint8_t eid[UBCORE_CMD_EID_SIZE]; + uint32_t transport_type; + } in; +}; + /* copy from user_space addr to kernel args */ static inline int ubcore_copy_from_user(void *args, const void *args_addr, unsigned long args_size) { diff --git a/drivers/ub/urma/ubcore/ubcore_device.c b/drivers/ub/urma/ubcore/ubcore_device.c index ec8441ab2080..dc884d6b4a8b 100644 --- a/drivers/ub/urma/ubcore/ubcore_device.c +++ b/drivers/ub/urma/ubcore/ubcore_device.c @@ -520,6 +520,11 @@ void ubcore_dispatch_async_event(struct ubcore_event *event) return; } + if (event->event_type == UBCORE_EVENT_TP_ERR && event->element.tp != NULL) { + ubcore_restore_tp(event->ub_dev, event->element.tp); + return; + } + dev = event->ub_dev; spin_lock_irqsave(&dev->event_handler_lock, flags); list_for_each_entry(handler, &dev->event_handler_list, node) diff --git a/drivers/ub/urma/ubcore/ubcore_main.c b/drivers/ub/urma/ubcore/ubcore_main.c index 9494a18207d1..bec752ea4e8a 100644 --- a/drivers/ub/urma/ubcore/ubcore_main.c +++ b/drivers/ub/urma/ubcore/ubcore_main.c @@ -153,6 +153,82 @@ static int ubcore_cmd_put_uasid(struct ubcore_cmd_hdr *hdr) return 0; } +static void ubcore_set_utp_cfg(struct ubcore_cmd_set_utp *arg, struct ubcore_utp_attr *attr, + union ubcore_utp_attr_mask *mask) +{ + attr->flag.bs.spray_en = arg->in.spray_en; + attr->data_udp_start = arg->in.data_udp_start; + attr->udp_range = arg->in.udp_range; + mask->bs.flag = 1; + mask->bs.udp_port = 1; + mask->bs.udp_range = 1; +} + +static int ubcore_cmd_set_utp(struct ubcore_cmd_hdr *hdr) +{ + enum ubcore_transport_type trans_type; + union ubcore_utp_attr_mask mask = { 0 }; + struct ubcore_cmd_set_utp arg; + struct ubcore_utp_attr attr; + struct ubcore_device *dev; + union ubcore_eid eid; + int ret; + + ret = ubcore_copy_from_user(&arg, (void __user *)(uintptr_t)hdr->args_addr, + sizeof(struct ubcore_cmd_set_utp)); + if (ret != 0) + return -EPERM; + + (void)memcpy(eid.raw, arg.in.eid, UBCORE_EID_SIZE); + trans_type = arg.in.transport_type; + dev = ubcore_find_device(&eid, trans_type); + if (dev == NULL || ubcore_check_dev_name_invalid(dev, arg.in.dev_name)) { + ubcore_log_err("find dev failed, dev:%s, arg_in: %s.\n", + dev == NULL ? "NULL" : dev->dev_name, arg.in.dev_name); + return -EINVAL; + } + + ubcore_set_utp_cfg(&arg, &attr, &mask); + if (ubcore_config_utp(dev, &eid, &attr, mask) != 0) { + ubcore_log_err("config utp failed.\n"); + ubcore_put_device(dev); + return -EPERM; + } + ubcore_put_device(dev); + return 0; +} + +static int ubcore_cmd_show_utp(struct ubcore_cmd_hdr *hdr) +{ + enum ubcore_transport_type trans_type; + struct ubcore_cmd_show_utp arg; + struct ubcore_device *dev; + union ubcore_eid eid; + int ret; + + ret = ubcore_copy_from_user(&arg, (void __user *)(uintptr_t)hdr->args_addr, + sizeof(struct ubcore_cmd_show_utp)); + if (ret != 0) + return -EPERM; + + (void)memcpy(eid.raw, arg.in.eid, UBCORE_EID_SIZE); + trans_type = arg.in.transport_type; + + dev = ubcore_find_device(&eid, trans_type); + if (dev == NULL || ubcore_check_dev_name_invalid(dev, arg.in.dev_name)) { + ubcore_log_err("find dev failed, dev:%s, arg_in: %s.\n", + dev == NULL ? "NULL" : dev->dev_name, arg.in.dev_name); + return -EINVAL; + } + if (ubcore_show_utp(dev, &eid) != 0) { + ubcore_log_err("show utp failed.\n"); + ubcore_put_device(dev); + return -EPERM; + } + ubcore_put_device(dev); + return 0; +} + static int ubcore_cmd_query_stats(struct ubcore_cmd_hdr *hdr) { enum ubcore_transport_type trans_type; @@ -428,6 +504,10 @@ static int ubcore_cmd_parse(struct ubcore_cmd_hdr *hdr) return ubcore_cmd_set_uasid(hdr); case UBCORE_CMD_PUT_UASID: return ubcore_cmd_put_uasid(hdr); + case UBCORE_CMD_SET_UTP: + return ubcore_cmd_set_utp(hdr); + case UBCORE_CMD_SHOW_UTP: + return ubcore_cmd_show_utp(hdr); case UBCORE_CMD_QUERY_STATS: return ubcore_cmd_query_stats(hdr); case UBCORE_CMD_QUERY_RES: -- Gitee From 7e21c7d3eaecc2d9d5e21d86417399a930ba93e6 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Mon, 18 Sep 2023 16:47:07 +0800 Subject: [PATCH 75/89] ub: ubcore add alloc and free key id api. driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Ubcore add alloc and free key id api, which will finally call hw driver's registered method to alloc/free key id. alloc_key_id: The UB Core invokes the UBN driver to allocate the key ID. Input parameter: dev: specifies the key ID allocated to the UB device. udata: contains the pointer of the URMA context and the address of the private data exchanged between the UBN user-mode driver and kernel-mode driver. Return value: If the value is not NULL, the key ID is successfully allocated. If the value is NULL, the key ID fails to be allocated. free_key_id: The UB Core invokes the UBN driver to release the key ID. Input parameter: key_id: ID of the key to be released specified by the ubcore protocol stack. Return value: The value 0 indicates that the key ID is successfully released. The value other than 0 indicates that the key ID fails to be released. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/ubcore/Makefile | 1 + drivers/ub/urma/ubcore/ubcore_segment.c | 64 +++++++++++++++++++++++++ include/urma/ubcore_uapi.h | 13 +++++ 3 files changed, 78 insertions(+) create mode 100644 drivers/ub/urma/ubcore/ubcore_segment.c diff --git a/drivers/ub/urma/ubcore/Makefile b/drivers/ub/urma/ubcore/Makefile index f211ad6dee8a..21242a76024c 100644 --- a/drivers/ub/urma/ubcore/Makefile +++ b/drivers/ub/urma/ubcore/Makefile @@ -6,6 +6,7 @@ ubcore-objs := ubcore_main.o \ ubcore_device.o \ ubcore_jetty.o \ + ubcore_segment.o \ ubcore_umem.o \ ubcore_hash_table.o \ ubcore_tp.o \ diff --git a/drivers/ub/urma/ubcore/ubcore_segment.c b/drivers/ub/urma/ubcore/ubcore_segment.c new file mode 100644 index 000000000000..321598e996b9 --- /dev/null +++ b/drivers/ub/urma/ubcore/ubcore_segment.c @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + * + * Description: ubcore segment + * Author: Qian Guoxin, Ouyang Changchun + * Create: 2022-07-28 + * Note: + * History: 2022-07-28: Yan Fangfang move segment implementation here + */ + +#include "ubcore_log.h" +#include +#include "ubcore_priv.h" +#include "ubcore_hash_table.h" +#include "ubcore_tp.h" +#include "ubcore_tp_table.h" + +struct ubcore_key_id *ubcore_alloc_key_id(struct ubcore_device *dev, struct ubcore_udata *udata) +{ + struct ubcore_key_id *key; + + if (dev == NULL || dev->ops->alloc_key_id == NULL || dev->ops->free_key_id == NULL) { + ubcore_log_err("invalid parameter.\n"); + return NULL; + } + + key = dev->ops->alloc_key_id(dev, udata); + if (key == NULL) { + ubcore_log_err("failed to alloc key id.\n"); + return NULL; + } + key->ub_dev = dev; + key->uctx = ubcore_get_uctx(udata); + atomic_set(&key->use_cnt, 0); + return key; +} +EXPORT_SYMBOL(ubcore_alloc_key_id); + +int ubcore_free_key_id(struct ubcore_key_id *key) +{ + struct ubcore_device *dev; + + if (key == NULL || key->ub_dev == NULL || key->ub_dev->ops->free_key_id == NULL) { + ubcore_log_err("invalid parameter.\n"); + return -1; + } + dev = key->ub_dev; + + if (WARN_ON_ONCE(atomic_read(&key->use_cnt))) + return -EBUSY; + + return dev->ops->free_key_id(key); +} +EXPORT_SYMBOL(ubcore_free_key_id); diff --git a/include/urma/ubcore_uapi.h b/include/urma/ubcore_uapi.h index 0f860c98349f..b09caf107265 100644 --- a/include/urma/ubcore_uapi.h +++ b/include/urma/ubcore_uapi.h @@ -136,6 +136,19 @@ int ubcore_register_client(struct ubcore_client *new_client); * @param[in] rm_client: ubcore client to be unregistered */ void ubcore_unregister_client(struct ubcore_client *rm_client); +/** + * alloc key to ubcore device + * @param[in] dev: the ubcore device handle; + * @param[in] udata (optional): ucontext and user space driver data + * @return: key id pointer on success, NULL on error + */ +struct ubcore_key_id *ubcore_alloc_key_id(struct ubcore_device *dev, struct ubcore_udata *udata); +/** + * free key id from ubcore device + * @param[in] key: the key id alloced before; + * @return: 0 on success, other value on error + */ +int ubcore_free_key_id(struct ubcore_key_id *key); /** * create jfc with ubcore device. * @param[in] dev: the ubcore device handle; -- Gitee From 25407e00cb0dff7be7c4abb5ca1518e65f4c5706 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Mon, 18 Sep 2023 16:59:52 +0800 Subject: [PATCH 76/89] ub: ubcore add register/unregister seg api. driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Ubcore add register/unregister seg api, which will finally call hw driver's registered method register/unregister seg. register_seg: The UB Core invokes the UBN driver to register the segment and key. Input parameter: dev: UB device that registers the segment. cfg: basic information about the segment to be registered. udata: contains the pointer of the URMA context and the address of the private data exchanged between the UBN user-mode driver and kernel-mode driver. Output parameter: None. Return value: If the registration is successful, the segment structure pointer is returned. The returned information includes the segment key ID. The registration fails and NULL is returned. unregister_seg: The UB Core invokes the UBN driver to deregister the segment and ukey. Input parameter: tseg: pointer to the target segment to be deregistered Return value: The value 0 indicates that the deregistration is successful, and other values indicate that the deregistration fails. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/ubcore/ubcore_segment.c | 60 +++++++++++++++++++++++++ include/urma/ubcore_uapi.h | 16 +++++++ 2 files changed, 76 insertions(+) diff --git a/drivers/ub/urma/ubcore/ubcore_segment.c b/drivers/ub/urma/ubcore/ubcore_segment.c index 321598e996b9..a4dafa8280be 100644 --- a/drivers/ub/urma/ubcore/ubcore_segment.c +++ b/drivers/ub/urma/ubcore/ubcore_segment.c @@ -62,3 +62,63 @@ int ubcore_free_key_id(struct ubcore_key_id *key) return dev->ops->free_key_id(key); } EXPORT_SYMBOL(ubcore_free_key_id); + +struct ubcore_target_seg *ubcore_register_seg(struct ubcore_device *dev, + const struct ubcore_seg_cfg *cfg, + struct ubcore_udata *udata) +{ + struct ubcore_target_seg *tseg; + + if (dev == NULL || cfg == NULL || dev->ops->register_seg == NULL || + dev->ops->unregister_seg == NULL) { + ubcore_log_err("invalid parameter.\n"); + return NULL; + } + + if ((cfg->flag.bs.access & (UBCORE_ACCESS_REMOTE_WRITE | UBCORE_ACCESS_REMOTE_ATOMIC)) && + !(cfg->flag.bs.access & UBCORE_ACCESS_LOCAL_WRITE)) { + ubcore_log_err( + "Local write must be set when either remote write or remote atomic is declared.\n"); + return NULL; + } + + tseg = dev->ops->register_seg(dev, cfg, udata); + if (tseg == NULL) { + ubcore_log_err("UBEP failed to register segment with va:%llu\n", cfg->va); + return NULL; + } + + tseg->ub_dev = dev; + tseg->uctx = ubcore_get_uctx(udata); + tseg->seg.len = cfg->len; + tseg->seg.ubva.va = cfg->va; + tseg->keyid = cfg->keyid; + + (void)memcpy(tseg->seg.ubva.eid.raw, dev->attr.eid.raw, UBCORE_EID_SIZE); + (void)memcpy(&tseg->seg.attr, &cfg->flag, sizeof(union ubcore_reg_seg_flag)); + atomic_set(&tseg->use_cnt, 0); + if (tseg->keyid != NULL) + atomic_inc(&tseg->keyid->use_cnt); + + return tseg; +} +EXPORT_SYMBOL(ubcore_register_seg); + +int ubcore_unregister_seg(struct ubcore_target_seg *tseg) +{ + struct ubcore_device *dev; + int ret; + + if (tseg == NULL || tseg->ub_dev == NULL || tseg->ub_dev->ops->unregister_seg == NULL) { + ubcore_log_err("invalid parameter.\n"); + return -1; + } + dev = tseg->ub_dev; + + if (tseg->keyid != NULL) + atomic_dec(&tseg->keyid->use_cnt); + + ret = dev->ops->unregister_seg(tseg); + return ret; +} +EXPORT_SYMBOL(ubcore_unregister_seg); diff --git a/include/urma/ubcore_uapi.h b/include/urma/ubcore_uapi.h index b09caf107265..7ad0b2dd706b 100644 --- a/include/urma/ubcore_uapi.h +++ b/include/urma/ubcore_uapi.h @@ -149,6 +149,22 @@ struct ubcore_key_id *ubcore_alloc_key_id(struct ubcore_device *dev, struct ubco * @return: 0 on success, other value on error */ int ubcore_free_key_id(struct ubcore_key_id *key); +/** + * register segment to ubcore device + * @param[in] dev: the ubcore device handle; + * @param[in] cfg: segment configurations + * @param[in] udata (optional): ucontext and user space driver data + * @return: target segment pointer on success, NULL on error + */ +struct ubcore_target_seg *ubcore_register_seg(struct ubcore_device *dev, + const struct ubcore_seg_cfg *cfg, + struct ubcore_udata *udata); +/** + * unregister segment from ubcore device + * @param[in] tseg: the segment registered before; + * @return: 0 on success, other value on error + */ +int ubcore_unregister_seg(struct ubcore_target_seg *tseg); /** * create jfc with ubcore device. * @param[in] dev: the ubcore device handle; -- Gitee From a9b4d53a84a5a7531b0aea846aa381f117f8a662 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Mon, 18 Sep 2023 17:20:23 +0800 Subject: [PATCH 77/89] ub: ubcore add import/unimport seg api. driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Ubcore add import/unimport seg api, which will finally call hw driver's registered method import/unimport seg. import_seg: The UB Core invokes the UBN driver to import segments and keys. Input parameter: dev: UB device to which the remote segment is imported. cfg: specifies the basic information about the remote segment to be imported by the ubcore protocol stack. udata: contains the pointer of the URMA context and the address of the private data exchanged between the UBN user-mode driver and kernel-mode driver. Output parameter: None. Return value: If the import is successful, the target segment structure pointer is returned. The returned information includes the segment address and length. The import fails and NULL is returned. unimport_seg: The UB Core invokes the UBN driver to unimport the remote segment and key. Input parameter: tseg: pointer to the target segment Return value: The value 0 indicates that the unimport is successful. Other values indicate that the unimport fails. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/ubcore/ubcore_segment.c | 40 +++++++++++++++++++++++++ include/urma/ubcore_uapi.h | 16 ++++++++++ 2 files changed, 56 insertions(+) diff --git a/drivers/ub/urma/ubcore/ubcore_segment.c b/drivers/ub/urma/ubcore/ubcore_segment.c index a4dafa8280be..be37b2d893d4 100644 --- a/drivers/ub/urma/ubcore/ubcore_segment.c +++ b/drivers/ub/urma/ubcore/ubcore_segment.c @@ -122,3 +122,43 @@ int ubcore_unregister_seg(struct ubcore_target_seg *tseg) return ret; } EXPORT_SYMBOL(ubcore_unregister_seg); + +struct ubcore_target_seg *ubcore_import_seg(struct ubcore_device *dev, + const struct ubcore_target_seg_cfg *cfg, + struct ubcore_udata *udata) +{ + struct ubcore_target_seg *tseg; + + if (dev == NULL || cfg == NULL || dev->ops->import_seg == NULL || + dev->ops->unimport_seg == NULL) { + ubcore_log_err("invalid parameter.\n"); + return NULL; + } + + tseg = dev->ops->import_seg(dev, cfg, udata); + if (tseg == NULL) { + ubcore_log_err("UBEP failed to import segment with va:%llu\n", cfg->seg.ubva.va); + return NULL; + } + tseg->ub_dev = dev; + tseg->uctx = ubcore_get_uctx(udata); + tseg->seg = cfg->seg; + atomic_set(&tseg->use_cnt, 0); + + return tseg; +} +EXPORT_SYMBOL(ubcore_import_seg); + +int ubcore_unimport_seg(struct ubcore_target_seg *tseg) +{ + struct ubcore_device *dev; + + if (tseg == NULL || tseg->ub_dev == NULL || tseg->ub_dev->ops->unimport_seg == NULL) { + ubcore_log_err("invalid parameter.\n"); + return -1; + } + dev = tseg->ub_dev; + + return dev->ops->unimport_seg(tseg); +} +EXPORT_SYMBOL(ubcore_unimport_seg); diff --git a/include/urma/ubcore_uapi.h b/include/urma/ubcore_uapi.h index 7ad0b2dd706b..a357afc4e787 100644 --- a/include/urma/ubcore_uapi.h +++ b/include/urma/ubcore_uapi.h @@ -165,6 +165,22 @@ struct ubcore_target_seg *ubcore_register_seg(struct ubcore_device *dev, * @return: 0 on success, other value on error */ int ubcore_unregister_seg(struct ubcore_target_seg *tseg); +/** + * import a remote segment to ubcore device + * @param[in] dev: the ubcore device handle; + * @param[in] cfg: import configurations + * @param[in] udata (optional): ucontext and user space driver data + * @return: target segment handle on success, NULL on error + */ +struct ubcore_target_seg *ubcore_import_seg(struct ubcore_device *dev, + const struct ubcore_target_seg_cfg *cfg, + struct ubcore_udata *udata); +/** + * unimport seg from ubcore device + * @param[in] tseg: the segment imported before; + * @return: 0 on success, other value on error + */ +int ubcore_unimport_seg(struct ubcore_target_seg *tseg); /** * create jfc with ubcore device. * @param[in] dev: the ubcore device handle; -- Gitee From 33800c2820ab85fe02800e33f6b3287130278bdf Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Mon, 18 Sep 2023 17:36:08 +0800 Subject: [PATCH 78/89] ub: ubcore add data plane ops api. driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Ubcore add data plane ops api, which will finally call hw driver's registered methods. Data plane ops including: - ubcore_post_jfs_wr: The UB Core invokes the UBN driver to perform the POST operation. Input parameter: jfs: JFS pointer to the operation. wr: WR information of the sending operation, including the address, length, flag, and user context. Output parameter: bad_wr: Failed requests are returned. Multiple failed requests can be returned. Return value: The value 0 indicates that the operation is submitted successfully. The value other than 0 indicates that the operation fails to be submitted. - ubcore_post_jfr_wr: Initiate a request for filling the recv buffer in the receive operation. After the receive operation succeeds, the application can poll the JFC to obtain the completion message. You can use the JFC associated with the JFR to store the cqe, or the JFC specified in the wr to store the cqe. Ordering and other flags can be specified. Input parameters: JFR: specifies the JFR for storing commands. wr: specifies the content of a request. Multiple requests can be submitted at a time. Output parameters: bad_wr: Failed requests are returned. Multiple failed requests can be returned. Return Value: The execution result is returned. URMA_SUCCESS indicates that the request is successfully enqueued to the JFR. In other cases, error information is returned. - ubcore_post_jetty_send_wr: Initiate a request for unilateral, bilateral, or atomic operations. After the operation is successful, the application can poll the JFC to obtain the completion message. You can use the JFC associated with the Jetty sending channel to store the CQE or the JFC specified in the wr to store the CQE. Ordering and other flags can be specified. Input parameters: jetty: specifies the Jetty sending channel for storing commands. wr: specifies the content of a request. Multiple requests can be submitted at a time. Output parameters: bad_wr: indicates that a failed request is returned. Multiple failed requests are returned. Return Value: The execution result is returned. URMA_SUCCESS indicates that the request is successfully enqueued to the Jetty sending channel. In other cases, error information is returned. - ubcore_post_jetty_recv_wr: Initiate a request for filling the recv buffer in the receive operation. After the receive operation succeeds, the application can poll the JFC to obtain the completion message. You can use the JFC associated with Jetty to store CQEs or the JFC specified in WR to store CQEs. Ordering and other flags can be specified. Input parameters: jetty: specifies the jetty for storing commands. wr: specifies the content of a request. Multiple requests can be submitted at a time. Output parameters: bad_wr: Failed requests are returned. Multiple failed requests can be returned. Return Value: The execution result is returned. URMA_SUCCESS indicates that the request is successfully enqueued to the Jetty receiving channel. In other cases, error information is returned. - ubcore_poll_jfc: The UB Core invokes the UBN driver to perform the poll JFC operation. Input parameter: jfc: indicates the JFC that performs the operation. cr_cnt: indicates the number of CRs that are expected to be received. Return value: cr: indicates the returned cr. If the value is greater than or equal to 0, it indicates the number of returned crs. If the value is less than 0, the operation fails. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/ubcore/ubcore_dp.c | 79 ++++++++++++++++++++++++++++++ include/urma/ubcore_uapi.h | 47 ++++++++++++++++++ 2 files changed, 126 insertions(+) diff --git a/drivers/ub/urma/ubcore/ubcore_dp.c b/drivers/ub/urma/ubcore/ubcore_dp.c index a70aad3013f2..c2bf3b1e173f 100644 --- a/drivers/ub/urma/ubcore/ubcore_dp.c +++ b/drivers/ub/urma/ubcore/ubcore_dp.c @@ -23,6 +23,85 @@ #include #include +int ubcore_post_jetty_send_wr(struct ubcore_jetty *jetty, const struct ubcore_jfs_wr *wr, + struct ubcore_jfs_wr **bad_wr) +{ + struct ubcore_ops *dev_ops; + + if (jetty == NULL || jetty->ub_dev == NULL || jetty->ub_dev->ops == NULL || + jetty->ub_dev->ops->post_jetty_send_wr == NULL || wr == NULL || bad_wr == NULL) { + ubcore_log_err("Invalid parameter"); + return -EINVAL; + } + + dev_ops = jetty->ub_dev->ops; + return dev_ops->post_jetty_send_wr(jetty, wr, bad_wr); +} +EXPORT_SYMBOL(ubcore_post_jetty_send_wr); + +int ubcore_post_jetty_recv_wr(struct ubcore_jetty *jetty, const struct ubcore_jfr_wr *wr, + struct ubcore_jfr_wr **bad_wr) +{ + struct ubcore_ops *dev_ops; + + if (jetty == NULL || jetty->ub_dev == NULL || jetty->ub_dev->ops == NULL || + jetty->ub_dev->ops->post_jetty_recv_wr == NULL || wr == NULL || bad_wr == NULL) { + ubcore_log_err("Invalid parameter"); + return -EINVAL; + } + + dev_ops = jetty->ub_dev->ops; + return dev_ops->post_jetty_recv_wr(jetty, wr, bad_wr); +} +EXPORT_SYMBOL(ubcore_post_jetty_recv_wr); + +int ubcore_post_jfs_wr(struct ubcore_jfs *jfs, const struct ubcore_jfs_wr *wr, + struct ubcore_jfs_wr **bad_wr) +{ + struct ubcore_ops *dev_ops; + + if (jfs == NULL || jfs->ub_dev == NULL || jfs->ub_dev->ops == NULL || + jfs->ub_dev->ops->post_jfs_wr == NULL || wr == NULL || bad_wr == NULL) { + ubcore_log_err("Invalid parameter"); + return -EINVAL; + } + + dev_ops = jfs->ub_dev->ops; + return dev_ops->post_jfs_wr(jfs, wr, bad_wr); +} +EXPORT_SYMBOL(ubcore_post_jfs_wr); + +int ubcore_post_jfr_wr(struct ubcore_jfr *jfr, const struct ubcore_jfr_wr *wr, + struct ubcore_jfr_wr **bad_wr) +{ + struct ubcore_ops *dev_ops; + + if (jfr == NULL || jfr->ub_dev == NULL || jfr->ub_dev->ops == NULL || + jfr->ub_dev->ops->post_jfr_wr == NULL || wr == NULL || bad_wr == NULL) { + ubcore_log_err("Invalid parameter"); + return -EINVAL; + } + + dev_ops = jfr->ub_dev->ops; + return dev_ops->post_jfr_wr(jfr, wr, bad_wr); +} +EXPORT_SYMBOL(ubcore_post_jfr_wr); + +int ubcore_poll_jfc(struct ubcore_jfc *jfc, int cr_cnt, struct ubcore_cr *cr) +{ + struct ubcore_ops *dev_ops; + + if (jfc == NULL || jfc->ub_dev == NULL || jfc->ub_dev->ops == NULL || + jfc->ub_dev->ops->poll_jfc == NULL || cr == NULL) { + ubcore_log_err("Invalid parameter"); + return -EINVAL; + } + + dev_ops = jfc->ub_dev->ops; + return dev_ops->poll_jfc(jfc, cr_cnt, cr); +} +EXPORT_SYMBOL(ubcore_poll_jfc); + int ubcore_rearm_jfc(struct ubcore_jfc *jfc, bool solicited_only) { struct ubcore_ops *dev_ops; diff --git a/include/urma/ubcore_uapi.h b/include/urma/ubcore_uapi.h index a357afc4e787..1eac46714200 100644 --- a/include/urma/ubcore_uapi.h +++ b/include/urma/ubcore_uapi.h @@ -445,6 +445,53 @@ void ubcore_register_event_handler(struct ubcore_device *dev, struct ubcore_even void ubcore_unregister_event_handler(struct ubcore_device *dev, struct ubcore_event_handler *handler); +/* data path API */ +/** + * post jfs wr. + * @param[in] jfs: the jfs created before; + * @param[in] wr: the wr to be posted; + * @param[out] bad_wr: the first failed wr; + * @return: 0 on success, other value on error + */ +int ubcore_post_jfs_wr(struct ubcore_jfs *jfs, const struct ubcore_jfs_wr *wr, + struct ubcore_jfs_wr **bad_wr); +/** + * post jfr wr. + * @param[in] jfr: the jfr created before; + * @param[in] wr: the wr to be posted; + * @param[out] bad_wr: the first failed wr; + * @return: 0 on success, other value on error + */ +int ubcore_post_jfr_wr(struct ubcore_jfr *jfr, const struct ubcore_jfr_wr *wr, + struct ubcore_jfr_wr **bad_wr); +/** + * post jetty send wr. + * @param[in] jetty: the jetty created before; + * @param[in] wr: the wr to be posted; + * @param[out] bad_wr: the first failed wr; + * @return: 0 on success, other value on error + */ +int ubcore_post_jetty_send_wr(struct ubcore_jetty *jetty, const struct ubcore_jfs_wr *wr, + struct ubcore_jfs_wr **bad_wr); +/** + * post jetty receive wr. + * @param[in] jetty: the jetty created before; + * @param[in] wr: the wr to be posted; + * @param[out] bad_wr: the first failed wr; + * @return: 0 on success, other value on error + */ +int ubcore_post_jetty_recv_wr(struct ubcore_jetty *jetty, const struct ubcore_jfr_wr *wr, + struct ubcore_jfr_wr **bad_wr); +/** + * poll jfc. + * @param[in] jfc: the jfc created before; + * @param[in] cr_cnt: the maximum number of CRs expected to be polled; + * @param[out] cr: the addr of returned CRs; + * @return: the number of completion record returned, 0 means no completion record returned, + * -1 on error + */ +int ubcore_poll_jfc(struct ubcore_jfc *jfc, int cr_cnt, struct ubcore_cr *cr); + /* The APIs below are deprecated, should not be called by driver or ubcore client */ struct ubcore_jfc *ubcore_find_jfc(struct ubcore_device *dev, uint32_t jfc_id); -- Gitee From 4a40c42152417804e7fa50220c1f13f76a66c276 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Mon, 18 Sep 2023 19:34:14 +0800 Subject: [PATCH 79/89] ub: uburma add cmd alloc/free key id implementation. driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Uburma add implementations of handling alloc/free key id cmd from user layer. This will make kernel possible to handle urma_alloc_key_id and urma_free_key_id api in user-layer urma. Alloc_key_id will finally call ubcore_alloc_key_id. The created key id will be related to a uobj. Free_key_id will delete the key-id-related uobj. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/uburma/uburma_cmd.c | 71 ++++++++++++++++++++++++++++ drivers/ub/urma/uburma/uburma_cmd.h | 16 +++++++ drivers/ub/urma/uburma/uburma_uobj.c | 7 +++ drivers/ub/urma/uburma/uburma_uobj.h | 2 + 4 files changed, 96 insertions(+) diff --git a/drivers/ub/urma/uburma/uburma_cmd.c b/drivers/ub/urma/uburma/uburma_cmd.c index 00f827570119..11936d95ca08 100644 --- a/drivers/ub/urma/uburma/uburma_cmd.c +++ b/drivers/ub/urma/uburma/uburma_cmd.c @@ -125,6 +125,75 @@ static int uburma_cmd_destroy_ctx(struct ubcore_device *ubc_dev, struct uburma_f return 0; } +static int uburma_cmd_alloc_key_id(struct ubcore_device *ubc_dev, struct uburma_file *file, + struct uburma_cmd_hdr *hdr) +{ + struct uburma_cmd_alloc_key_id arg; + struct ubcore_udata udata = { 0 }; + struct ubcore_key_id *key; + struct uburma_uobj *uobj; + + int ret; + + ret = uburma_copy_from_user(&arg, (void __user *)(uintptr_t)hdr->args_addr, + sizeof(struct uburma_cmd_alloc_key_id)); + if (ret != 0) + return ret; + + fill_udata(&udata, file->ucontext, &arg.udata); + uobj = uobj_alloc(UOBJ_CLASS_KEY, file); + if (IS_ERR(uobj)) { + uburma_log_err("UOBJ_CLASS_KEY alloc fail!\n"); + return -ENOMEM; + } + + key = ubcore_alloc_key_id(ubc_dev, &udata); + if (IS_ERR_OR_NULL(key)) { + uburma_log_err("ubcore alloc key id failed.\n"); + ret = -EPERM; + goto err_free_uobj; + } + uobj->object = key; + arg.out.key_id = key->key_id; + arg.out.handle = uobj->id; + + ret = uburma_copy_to_user((void __user *)(uintptr_t)hdr->args_addr, &arg, + sizeof(struct uburma_cmd_alloc_key_id)); + if (ret != 0) + goto err_free_key; + + return uobj_alloc_commit(uobj); + +err_free_key: + (void)ubcore_free_key_id(key); +err_free_uobj: + uobj_alloc_abort(uobj); + return ret; +} + +static int uburma_cmd_free_key_id(struct ubcore_device *ubc_dev, struct uburma_file *file, + struct uburma_cmd_hdr *hdr) +{ + struct uburma_cmd_free_key_id arg; + struct uburma_uobj *uobj; + int ret; + + ret = uburma_copy_from_user(&arg, (void __user *)(uintptr_t)hdr->args_addr, + sizeof(struct uburma_cmd_free_key_id)); + if (ret != 0) + return ret; + + uobj = uobj_get_del(UOBJ_CLASS_KEY, (int)arg.in.handle, file); + if (IS_ERR(uobj)) { + uburma_log_err("failed to find key id.\n"); + return -EINVAL; + } + ret = uobj_remove_commit(uobj); + if (ret != 0) + uburma_log_err("ubcore remove commit keyid failed.\n"); + return ret; +} + static void uburma_write_async_event(struct ubcore_ucontext *ctx, uint64_t event_data, uint32_t event_type, struct list_head *obj_event_list, uint32_t *counter) @@ -1228,6 +1297,8 @@ static uburma_cmd_handler g_uburma_cmd_handlers[] = { [0] = NULL, [UBURMA_CMD_CREATE_CTX] = uburma_cmd_create_ctx, [UBURMA_CMD_DESTROY_CTX] = uburma_cmd_destroy_ctx, + [UBURMA_CMD_ALLOC_KEY_ID] = uburma_cmd_alloc_key_id, + [UBURMA_CMD_FREE_KEY_ID] = uburma_cmd_free_key_id, [UBURMA_CMD_CREATE_JFR] = uburma_cmd_create_jfr, [UBURMA_CMD_MODIFY_JFR] = uburma_cmd_modify_jfr, [UBURMA_CMD_DELETE_JFR] = uburma_cmd_delete_jfr, diff --git a/drivers/ub/urma/uburma/uburma_cmd.h b/drivers/ub/urma/uburma/uburma_cmd.h index e698a9eba354..907875fa4cc2 100644 --- a/drivers/ub/urma/uburma/uburma_cmd.h +++ b/drivers/ub/urma/uburma/uburma_cmd.h @@ -40,6 +40,8 @@ struct uburma_cmd_hdr { enum uburma_cmd { UBURMA_CMD_CREATE_CTX = 1, UBURMA_CMD_DESTROY_CTX, + UBURMA_CMD_ALLOC_KEY_ID, + UBURMA_CMD_FREE_KEY_ID, UBURMA_CMD_CREATE_JFS, UBURMA_CMD_DELETE_JFS, UBURMA_CMD_CREATE_JFR, @@ -82,6 +84,20 @@ struct uburma_cmd_create_ctx { struct uburma_cmd_udrv_priv udata; }; +struct uburma_cmd_alloc_key_id { + struct { + uint32_t key_id; + uint64_t handle; /* handle of the allocated key_id obj in kernel */ + } out; + struct uburma_cmd_udrv_priv udata; +}; + +struct uburma_cmd_free_key_id { + struct { + uint64_t handle; /* handle of the allocated key_id obj in kernel */ + } in; +}; + struct uburma_cmd_create_jfr { struct { uint32_t depth; /* in terms of WQEBB */ diff --git a/drivers/ub/urma/uburma/uburma_uobj.c b/drivers/ub/urma/uburma/uburma_uobj.c index 9a379396409b..6da63d9339f2 100644 --- a/drivers/ub/urma/uburma/uburma_uobj.c +++ b/drivers/ub/urma/uburma/uburma_uobj.c @@ -504,6 +504,11 @@ void uburma_cleanup_uobjs(struct uburma_file *ufile, enum uburma_remove_reason w up_write(&ufile->cleanup_rwsem); } +static int uburma_free_key(struct uburma_uobj *uobj, enum uburma_remove_reason why) +{ + return ubcore_free_key_id((struct ubcore_key_id *)uobj->object); +} + static int uburma_free_jfc(struct uburma_uobj *uobj, enum uburma_remove_reason why) { struct uburma_jfc_uobj *jfc_uobj = container_of(uobj, struct uburma_jfc_uobj, uobj); @@ -667,6 +672,8 @@ declare_uobj_class(UOBJ_CLASS_JFAE, declare_uobj_class(UOBJ_CLASS_JFC, &uobj_type_alloc_idr(sizeof(struct uburma_jfc_uobj), 2, uburma_free_jfc)); +declare_uobj_class(UOBJ_CLASS_KEY, + &uobj_type_alloc_idr(sizeof(struct uburma_uobj), 1, uburma_free_key)); declare_uobj_class(UOBJ_CLASS_JFS, &uobj_type_alloc_idr(sizeof(struct uburma_jfs_uobj), 1, uburma_free_jfs)); declare_uobj_class(UOBJ_CLASS_JFR, diff --git a/drivers/ub/urma/uburma/uburma_uobj.h b/drivers/ub/urma/uburma/uburma_uobj.h index 10197a3757be..9554750323da 100644 --- a/drivers/ub/urma/uburma/uburma_uobj.h +++ b/drivers/ub/urma/uburma/uburma_uobj.h @@ -25,6 +25,7 @@ enum UOBJ_CLASS_ID { UOBJ_CLASS_ROOT, /* used by framework */ + UOBJ_CLASS_KEY, UOBJ_CLASS_JFR, UOBJ_CLASS_JFS, UOBJ_CLASS_JFC, @@ -212,6 +213,7 @@ static inline bool uobj_type_is_fd(const struct uburma_uobj *uobj) #define uobj_get_del(class_id, _id, ufile) \ uobj_lookup_get(uobj_get_type(class_id), ufile, _id, UOBJ_ACCESS_NOLOCK) +extern const struct uobj_class_def uobj_class_UOBJ_CLASS_KEY; extern const struct uobj_class_def uobj_class_UOBJ_CLASS_JFCE; extern const struct uobj_class_def uobj_class_UOBJ_CLASS_JFAE; extern const struct uobj_class_def uobj_class_UOBJ_CLASS_JFC; -- Gitee From f69956f72c648c24b008a55c003aef957043be22 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Mon, 18 Sep 2023 19:41:26 +0800 Subject: [PATCH 80/89] ub: uburma add cmd register/unregister segment implementation. driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Uburma add implementations of handling register/unregister segment cmd from user layer. This will make kernel possible to handle urma_register_seg and urma_unregister_seg api in user-layer urma. Register_seg will finally call ubcore_register_seg. The created segment will be related to a uobj. Unregister seg will delete the seg-related uobj. In uobj destroy function, it will call ubcore_unregister_seg. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/uburma/uburma_cmd.c | 94 ++++++++++++++++++++++++++++ drivers/ub/urma/uburma/uburma_cmd.h | 24 +++++++ drivers/ub/urma/uburma/uburma_uobj.c | 7 +++ drivers/ub/urma/uburma/uburma_uobj.h | 2 + 4 files changed, 127 insertions(+) diff --git a/drivers/ub/urma/uburma/uburma_cmd.c b/drivers/ub/urma/uburma/uburma_cmd.c index 11936d95ca08..0e7bcd007493 100644 --- a/drivers/ub/urma/uburma/uburma_cmd.c +++ b/drivers/ub/urma/uburma/uburma_cmd.c @@ -125,6 +125,15 @@ static int uburma_cmd_destroy_ctx(struct ubcore_device *ubc_dev, struct uburma_f return 0; } +static void uburma_fill_attr(struct ubcore_seg_cfg *cfg, struct uburma_cmd_register_seg *arg) +{ + cfg->va = arg->in.va; + cfg->len = arg->in.len; + cfg->flag.value = arg->in.flag; + cfg->ukey.key = arg->in.key; + cfg->iova = arg->in.va; +} + static int uburma_cmd_alloc_key_id(struct ubcore_device *ubc_dev, struct uburma_file *file, struct uburma_cmd_hdr *hdr) { @@ -194,6 +203,89 @@ static int uburma_cmd_free_key_id(struct ubcore_device *ubc_dev, struct uburma_f return ret; } +static int uburma_cmd_register_seg(struct ubcore_device *ubc_dev, struct uburma_file *file, + struct uburma_cmd_hdr *hdr) +{ + struct uburma_cmd_register_seg arg; + struct ubcore_seg_cfg cfg = { 0 }; + struct ubcore_target_seg *seg; + struct ubcore_udata udata = { 0 }; + struct uburma_uobj *uobj; + struct uburma_uobj *keyid_uobj; + int ret; + + ret = uburma_copy_from_user(&arg, (void __user *)(uintptr_t)hdr->args_addr, + sizeof(struct uburma_cmd_register_seg)); + if (ret != 0) + return ret; + + keyid_uobj = uobj_get_read(UOBJ_CLASS_KEY, (int)arg.in.keyid_handle, file); + if (!IS_ERR(keyid_uobj)) + cfg.keyid = (struct ubcore_key_id *)keyid_uobj->object; + + uburma_fill_attr(&cfg, &arg); + fill_udata(&udata, file->ucontext, &arg.udata); + + uobj = uobj_alloc(UOBJ_CLASS_SEG, file); + if (IS_ERR(uobj)) { + uburma_log_err("UOBJ_CLASS_SEG alloc fail!\n"); + ret = -ENOMEM; + goto err_put_keyid; + } + + seg = ubcore_register_seg(ubc_dev, &cfg, &udata); + if (IS_ERR_OR_NULL(seg)) { + uburma_log_err("ubcore_register_seg failed.\n"); + ret = -EPERM; + goto err_free_uobj; + } + uobj->object = seg; + arg.out.key_id = seg->seg.key_id; + arg.out.handle = uobj->id; + + ret = uburma_copy_to_user((void __user *)(uintptr_t)hdr->args_addr, &arg, + sizeof(struct uburma_cmd_register_seg)); + if (ret != 0) + goto err_delete_seg; + + if (!IS_ERR(keyid_uobj)) + uobj_put_read(keyid_uobj); + uobj_alloc_commit(uobj); + return 0; + +err_delete_seg: + ubcore_unregister_seg(seg); +err_free_uobj: + uobj_alloc_abort(uobj); +err_put_keyid: + if (!IS_ERR(keyid_uobj)) + uobj_put_read(keyid_uobj); + return ret; +} + +static int uburma_cmd_unregister_seg(struct ubcore_device *ubc_dev, struct uburma_file *file, + struct uburma_cmd_hdr *hdr) +{ + struct uburma_cmd_unregister_seg arg; + struct uburma_uobj *uobj; + int ret; + + ret = uburma_copy_from_user(&arg, (void __user *)(uintptr_t)hdr->args_addr, + sizeof(struct uburma_cmd_unregister_seg)); + if (ret != 0) + return ret; + + uobj = uobj_get_del(UOBJ_CLASS_SEG, arg.in.handle, file); + if (IS_ERR(uobj)) { + uburma_log_err("failed to find registered seg.\n"); + return -EINVAL; + } + ret = uobj_remove_commit(uobj); + if (ret != 0) + uburma_log_err("ubcore_unregister_seg failed.\n"); + return ret; +} + static void uburma_write_async_event(struct ubcore_ucontext *ctx, uint64_t event_data, uint32_t event_type, struct list_head *obj_event_list, uint32_t *counter) @@ -1299,6 +1391,8 @@ static uburma_cmd_handler g_uburma_cmd_handlers[] = { [UBURMA_CMD_DESTROY_CTX] = uburma_cmd_destroy_ctx, [UBURMA_CMD_ALLOC_KEY_ID] = uburma_cmd_alloc_key_id, [UBURMA_CMD_FREE_KEY_ID] = uburma_cmd_free_key_id, + [UBURMA_CMD_REGISTER_SEG] = uburma_cmd_register_seg, + [UBURMA_CMD_UNREGISTER_SEG] = uburma_cmd_unregister_seg, [UBURMA_CMD_CREATE_JFR] = uburma_cmd_create_jfr, [UBURMA_CMD_MODIFY_JFR] = uburma_cmd_modify_jfr, [UBURMA_CMD_DELETE_JFR] = uburma_cmd_delete_jfr, diff --git a/drivers/ub/urma/uburma/uburma_cmd.h b/drivers/ub/urma/uburma/uburma_cmd.h index 907875fa4cc2..711c1ba44b64 100644 --- a/drivers/ub/urma/uburma/uburma_cmd.h +++ b/drivers/ub/urma/uburma/uburma_cmd.h @@ -42,6 +42,8 @@ enum uburma_cmd { UBURMA_CMD_DESTROY_CTX, UBURMA_CMD_ALLOC_KEY_ID, UBURMA_CMD_FREE_KEY_ID, + UBURMA_CMD_REGISTER_SEG, + UBURMA_CMD_UNREGISTER_SEG, UBURMA_CMD_CREATE_JFS, UBURMA_CMD_DELETE_JFS, UBURMA_CMD_CREATE_JFR, @@ -98,6 +100,28 @@ struct uburma_cmd_free_key_id { } in; }; +struct uburma_cmd_register_seg { + struct { + uint64_t va; + uint64_t len; + uint32_t key_id; + uint64_t keyid_handle; + uint32_t key; + uint32_t flag; + } in; + struct { + uint32_t key_id; + uint64_t handle; /* handle of the allocated seg obj in kernel */ + } out; + struct uburma_cmd_udrv_priv udata; +}; + +struct uburma_cmd_unregister_seg { + struct { + uint64_t handle; /* handle of seg, used to find seg obj in kernel */ + } in; +}; + struct uburma_cmd_create_jfr { struct { uint32_t depth; /* in terms of WQEBB */ diff --git a/drivers/ub/urma/uburma/uburma_uobj.c b/drivers/ub/urma/uburma/uburma_uobj.c index 6da63d9339f2..de076e1864d0 100644 --- a/drivers/ub/urma/uburma/uburma_uobj.c +++ b/drivers/ub/urma/uburma/uburma_uobj.c @@ -509,6 +509,11 @@ static int uburma_free_key(struct uburma_uobj *uobj, enum uburma_remove_reason w return ubcore_free_key_id((struct ubcore_key_id *)uobj->object); } +static int uburma_free_seg(struct uburma_uobj *uobj, enum uburma_remove_reason why) +{ + return ubcore_unregister_seg((struct ubcore_target_seg *)uobj->object); +} + static int uburma_free_jfc(struct uburma_uobj *uobj, enum uburma_remove_reason why) { struct uburma_jfc_uobj *jfc_uobj = container_of(uobj, struct uburma_jfc_uobj, uobj); @@ -674,6 +679,8 @@ declare_uobj_class(UOBJ_CLASS_JFC, &uobj_type_alloc_idr(sizeof(struct uburma_jfc_uobj), 2, uburma_free_jfc)); declare_uobj_class(UOBJ_CLASS_KEY, &uobj_type_alloc_idr(sizeof(struct uburma_uobj), 1, uburma_free_key)); +declare_uobj_class(UOBJ_CLASS_SEG, + &uobj_type_alloc_idr(sizeof(struct uburma_uobj), 1, uburma_free_seg)); declare_uobj_class(UOBJ_CLASS_JFS, &uobj_type_alloc_idr(sizeof(struct uburma_jfs_uobj), 1, uburma_free_jfs)); declare_uobj_class(UOBJ_CLASS_JFR, diff --git a/drivers/ub/urma/uburma/uburma_uobj.h b/drivers/ub/urma/uburma/uburma_uobj.h index 9554750323da..5569c1f094b4 100644 --- a/drivers/ub/urma/uburma/uburma_uobj.h +++ b/drivers/ub/urma/uburma/uburma_uobj.h @@ -26,6 +26,7 @@ enum UOBJ_CLASS_ID { UOBJ_CLASS_ROOT, /* used by framework */ UOBJ_CLASS_KEY, + UOBJ_CLASS_SEG, UOBJ_CLASS_JFR, UOBJ_CLASS_JFS, UOBJ_CLASS_JFC, @@ -214,6 +215,7 @@ static inline bool uobj_type_is_fd(const struct uburma_uobj *uobj) uobj_lookup_get(uobj_get_type(class_id), ufile, _id, UOBJ_ACCESS_NOLOCK) extern const struct uobj_class_def uobj_class_UOBJ_CLASS_KEY; +extern const struct uobj_class_def uobj_class_UOBJ_CLASS_SEG; extern const struct uobj_class_def uobj_class_UOBJ_CLASS_JFCE; extern const struct uobj_class_def uobj_class_UOBJ_CLASS_JFAE; extern const struct uobj_class_def uobj_class_UOBJ_CLASS_JFC; -- Gitee From b9103ff6e501a7e054a5e9485b145ff4ca2528f8 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Mon, 18 Sep 2023 19:47:22 +0800 Subject: [PATCH 81/89] ub: uburma add cmd import/unimport segment implementation. driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Uburma add implementations of handling import/unimport segment cmd from user layer. This will make kernel possible to handle urma_import_seg and urma_unimport_seg api in user-layer urma. Import_seg will finally call ubcore_import_seg. The created target segment will be related to a uobj. Unimport seg will delete the tseg-related uobj. In uobj destroy function, it will call ubcore_unimport_seg. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/uburma/uburma_cmd.c | 76 ++++++++++++++++++++++++++++ drivers/ub/urma/uburma/uburma_cmd.h | 25 +++++++++ drivers/ub/urma/uburma/uburma_uobj.c | 8 ++- drivers/ub/urma/uburma/uburma_uobj.h | 2 + 4 files changed, 110 insertions(+), 1 deletion(-) diff --git a/drivers/ub/urma/uburma/uburma_cmd.c b/drivers/ub/urma/uburma/uburma_cmd.c index 0e7bcd007493..c0b13aabe764 100644 --- a/drivers/ub/urma/uburma/uburma_cmd.c +++ b/drivers/ub/urma/uburma/uburma_cmd.c @@ -472,6 +472,80 @@ static int uburma_cmd_delete_jfs(struct ubcore_device *ubc_dev, struct uburma_fi sizeof(struct uburma_cmd_delete_jfs)); } +static int uburma_cmd_import_seg(struct ubcore_device *ubc_dev, struct uburma_file *file, + struct uburma_cmd_hdr *hdr) +{ + struct uburma_cmd_import_seg arg; + struct ubcore_target_seg_cfg cfg = { 0 }; + struct ubcore_udata udata; + struct ubcore_target_seg *tseg; + struct uburma_uobj *uobj; + int ret; + + ret = uburma_copy_from_user(&arg, (void __user *)(uintptr_t)hdr->args_addr, + sizeof(struct uburma_cmd_import_seg)); + if (ret != 0) + return ret; + + uobj = uobj_alloc(UOBJ_CLASS_TARGET_SEG, file); + if (IS_ERR(uobj)) { + uburma_log_err("UOBJ_CLASS_TARGET_JFR alloc fail!\n"); + return -ENOMEM; + } + + (void)memcpy(cfg.seg.ubva.eid.raw, arg.in.eid, UBCORE_EID_SIZE); + cfg.seg.ubva.uasid = arg.in.uasid; + cfg.seg.ubva.va = arg.in.va; + cfg.seg.len = arg.in.len; + cfg.seg.attr.value = arg.in.flag; + cfg.seg.key_id = arg.in.key_id; + fill_udata(&udata, file->ucontext, &arg.udata); + + tseg = ubcore_import_seg(ubc_dev, &cfg, &udata); + if (IS_ERR_OR_NULL(tseg)) { + uburma_log_err("import seg failed.\n"); + uobj_alloc_abort(uobj); + return -EPERM; + } + + uobj->object = tseg; + arg.out.handle = uobj->id; + + ret = uburma_copy_to_user((void __user *)(uintptr_t)hdr->args_addr, &arg, + sizeof(struct uburma_cmd_import_seg)); + if (ret != 0) { + (void)ubcore_unimport_seg(tseg); + uobj_alloc_abort(uobj); + return ret; + } + uobj_alloc_commit(uobj); + return ret; +} + +static int uburma_cmd_unimport_seg(struct ubcore_device *ubc_dev, struct uburma_file *file, + struct uburma_cmd_hdr *hdr) +{ + struct uburma_cmd_unimport_seg arg; + struct uburma_uobj *uobj; + int ret; + + ret = uburma_copy_from_user(&arg, (void __user *)(uintptr_t)hdr->args_addr, + sizeof(struct uburma_cmd_unimport_seg)); + if (ret != 0) + return ret; + + uobj = uobj_get_del(UOBJ_CLASS_TARGET_SEG, arg.in.handle, file); + if (IS_ERR(uobj)) { + uburma_log_err("failed to find imported target seg.\n"); + return -EINVAL; + } + ret = uobj_remove_commit(uobj); + if (ret != 0) + uburma_log_err("unimport seg failed.\n"); + + return ret; +} + static int uburma_cmd_create_jfr(struct ubcore_device *ubc_dev, struct uburma_file *file, struct uburma_cmd_hdr *hdr) { @@ -1393,6 +1467,8 @@ static uburma_cmd_handler g_uburma_cmd_handlers[] = { [UBURMA_CMD_FREE_KEY_ID] = uburma_cmd_free_key_id, [UBURMA_CMD_REGISTER_SEG] = uburma_cmd_register_seg, [UBURMA_CMD_UNREGISTER_SEG] = uburma_cmd_unregister_seg, + [UBURMA_CMD_IMPORT_SEG] = uburma_cmd_import_seg, + [UBURMA_CMD_UNIMPORT_SEG] = uburma_cmd_unimport_seg, [UBURMA_CMD_CREATE_JFR] = uburma_cmd_create_jfr, [UBURMA_CMD_MODIFY_JFR] = uburma_cmd_modify_jfr, [UBURMA_CMD_DELETE_JFR] = uburma_cmd_delete_jfr, diff --git a/drivers/ub/urma/uburma/uburma_cmd.h b/drivers/ub/urma/uburma/uburma_cmd.h index 711c1ba44b64..13b47d8d5477 100644 --- a/drivers/ub/urma/uburma/uburma_cmd.h +++ b/drivers/ub/urma/uburma/uburma_cmd.h @@ -44,6 +44,8 @@ enum uburma_cmd { UBURMA_CMD_FREE_KEY_ID, UBURMA_CMD_REGISTER_SEG, UBURMA_CMD_UNREGISTER_SEG, + UBURMA_CMD_IMPORT_SEG, + UBURMA_CMD_UNIMPORT_SEG, UBURMA_CMD_CREATE_JFS, UBURMA_CMD_DELETE_JFS, UBURMA_CMD_CREATE_JFR, @@ -122,6 +124,29 @@ struct uburma_cmd_unregister_seg { } in; }; +struct uburma_cmd_import_seg { + struct { + uint8_t eid[UBCORE_EID_SIZE]; + uint32_t uasid; + uint64_t va; + uint64_t len; + uint32_t flag; + uint32_t key; + uint32_t key_id; + uint64_t mva; + } in; + struct { + uint64_t handle; /* handle of the allocated tseg obj in kernel */ + } out; + struct uburma_cmd_udrv_priv udata; +}; + +struct uburma_cmd_unimport_seg { + struct { + uint64_t handle; /* handle of the seg to be unimported */ + } in; +}; + struct uburma_cmd_create_jfr { struct { uint32_t depth; /* in terms of WQEBB */ diff --git a/drivers/ub/urma/uburma/uburma_uobj.c b/drivers/ub/urma/uburma/uburma_uobj.c index de076e1864d0..72bf6ead5d77 100644 --- a/drivers/ub/urma/uburma/uburma_uobj.c +++ b/drivers/ub/urma/uburma/uburma_uobj.c @@ -135,7 +135,6 @@ static void uobj_remove_idr(struct uburma_uobj *uobj) spin_unlock(&uobj->ufile->idr_lock); } - static int uobj_try_lock(struct uburma_uobj *uobj, bool exclusive) { /* @@ -580,6 +579,11 @@ static int uburma_free_tjetty(struct uburma_uobj *uobj, enum uburma_remove_reaso return ubcore_unimport_jetty((struct ubcore_tjetty *)uobj->object); } +static int uburma_free_tseg(struct uburma_uobj *uobj, enum uburma_remove_reason why) +{ + return ubcore_unimport_seg((struct ubcore_target_seg *)uobj->object); +} + void uburma_close_uobj_fd(struct file *f) { struct uburma_uobj *uobj = f->private_data; @@ -691,3 +695,5 @@ declare_uobj_class(UOBJ_CLASS_TARGET_JFR, &uobj_type_alloc_idr(sizeof(struct uburma_uobj), 0, uburma_free_tjfr)); declare_uobj_class(UOBJ_CLASS_TARGET_JETTY, &uobj_type_alloc_idr(sizeof(struct uburma_uobj), 0, uburma_free_tjetty)); +declare_uobj_class(UOBJ_CLASS_TARGET_SEG, + &uobj_type_alloc_idr(sizeof(struct uburma_uobj), 0, uburma_free_tseg)); diff --git a/drivers/ub/urma/uburma/uburma_uobj.h b/drivers/ub/urma/uburma/uburma_uobj.h index 5569c1f094b4..5a92c0025f2c 100644 --- a/drivers/ub/urma/uburma/uburma_uobj.h +++ b/drivers/ub/urma/uburma/uburma_uobj.h @@ -27,6 +27,7 @@ enum UOBJ_CLASS_ID { UOBJ_CLASS_ROOT, /* used by framework */ UOBJ_CLASS_KEY, UOBJ_CLASS_SEG, + UOBJ_CLASS_TARGET_SEG, UOBJ_CLASS_JFR, UOBJ_CLASS_JFS, UOBJ_CLASS_JFC, @@ -223,6 +224,7 @@ extern const struct uobj_class_def uobj_class_UOBJ_CLASS_JFR; extern const struct uobj_class_def uobj_class_UOBJ_CLASS_JFS; extern const struct uobj_class_def uobj_class_UOBJ_CLASS_JETTY; extern const struct uobj_class_def uobj_class_UOBJ_CLASS_TARGET_JFR; +extern const struct uobj_class_def uobj_class_UOBJ_CLASS_TARGET_SEG; extern const struct uobj_class_def uobj_class_UOBJ_CLASS_TARGET_JETTY; extern const struct file_operations uburma_jfce_fops; -- Gitee From 84019dd82c5d7e5ac9e45852891c168cfb5e453d Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Mon, 18 Sep 2023 19:51:05 +0800 Subject: [PATCH 82/89] ub: uburma add cmd user control implementation. driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Uburma add implementations of handling user control cmd from user layer. This will make kernel possible to handle urma_user_ctl in user-layer urma. User_ctl will finally call ubcore_user_control. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/uburma/uburma_cmd.c | 49 +++++++++++++++++++++++++++++ drivers/ub/urma/uburma/uburma_cmd.h | 19 +++++++++++ 2 files changed, 68 insertions(+) diff --git a/drivers/ub/urma/uburma/uburma_cmd.c b/drivers/ub/urma/uburma/uburma_cmd.c index c0b13aabe764..af21dc76fc3f 100644 --- a/drivers/ub/urma/uburma/uburma_cmd.c +++ b/drivers/ub/urma/uburma/uburma_cmd.c @@ -1456,6 +1456,54 @@ static int uburma_cmd_unbind_jetty(struct ubcore_device *ubc_dev, struct uburma_ return ret; } +static int uburma_fill_user_ctl_info(struct ubcore_ucontext *ctx, + struct uburma_cmd_user_ctl *user_ctl, + struct ubcore_user_ctl *k_user_ctl) +{ + if (ctx == NULL) { + uburma_log_err("parameter invalid with ctx nullptr.\n"); + return -EINVAL; + } + + k_user_ctl->uctx = ctx; + k_user_ctl->in.addr = user_ctl->in.addr; + k_user_ctl->in.len = user_ctl->in.len; + k_user_ctl->in.opcode = user_ctl->in.opcode; + + k_user_ctl->out.addr = user_ctl->out.addr; + k_user_ctl->out.len = user_ctl->out.len; + + k_user_ctl->udrv_data.in_addr = user_ctl->udrv.in_addr; + k_user_ctl->udrv_data.in_len = user_ctl->udrv.in_len; + k_user_ctl->udrv_data.out_addr = user_ctl->udrv.out_addr; + k_user_ctl->udrv_data.out_len = user_ctl->udrv.out_len; + + return 0; +} + +static int uburma_cmd_user_ctl(struct ubcore_device *ubc_dev, struct uburma_file *file, + struct uburma_cmd_hdr *hdr) +{ + struct ubcore_user_ctl k_user_ctl = { 0 }; + struct uburma_cmd_user_ctl user_ctl; + int ret; + + ret = uburma_copy_from_user(&user_ctl, (void __user *)(uintptr_t)hdr->args_addr, + sizeof(struct uburma_cmd_user_ctl)); + if (ret != 0) + return ret; + + ret = uburma_fill_user_ctl_info(file->ucontext, &user_ctl, &k_user_ctl); + if (ret != 0) + return ret; + + ret = ubcore_user_control(&k_user_ctl); + if (ret != 0) + return ret; + + return 0; +} + typedef int (*uburma_cmd_handler)(struct ubcore_device *ubc_dev, struct uburma_file *file, struct uburma_cmd_hdr *hdr); @@ -1491,6 +1539,7 @@ static uburma_cmd_handler g_uburma_cmd_handlers[] = { [UBURMA_CMD_UNADVISE_JETTY] = uburma_cmd_unadvise_jetty, [UBURMA_CMD_BIND_JETTY] = uburma_cmd_bind_jetty, [UBURMA_CMD_UNBIND_JETTY] = uburma_cmd_unbind_jetty, + [UBURMA_CMD_USER_CTL] = uburma_cmd_user_ctl }; static int uburma_cmd_parse(struct ubcore_device *ubc_dev, struct uburma_file *file, diff --git a/drivers/ub/urma/uburma/uburma_cmd.h b/drivers/ub/urma/uburma/uburma_cmd.h index 13b47d8d5477..631ba2dd103d 100644 --- a/drivers/ub/urma/uburma/uburma_cmd.h +++ b/drivers/ub/urma/uburma/uburma_cmd.h @@ -384,6 +384,25 @@ struct uburma_cmd_unadvise_jetty { } in; }; +struct uburma_cmd_user_ctl { + struct { + uint64_t addr; + uint32_t len; + uint32_t opcode; + } in; /* struct [in] should be consistent with [urma_user_ctl_in_t] */ + struct { + uint64_t addr; + uint32_t len; + uint32_t rsv; + } out; /* struct [out] should be consistent with [urma_user_ctl_out_t] */ + struct { + uint64_t in_addr; + uint32_t in_len; + uint64_t out_addr; + uint32_t out_len; + } udrv; /* struct [udrv] should be consistent with [urma_udrv_t] */ +}; + /* only for event ioctl */ #define MAX_JFCE_EVENT_CNT 16 #define UBURMA_EVENT_CMD_MAGIC 'E' -- Gitee From 231ee3908a6740b397900a278f47bffe56e9f45b Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Mon, 18 Sep 2023 19:59:46 +0800 Subject: [PATCH 83/89] ub: ubcore add attr queried of query res cmd. driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Ubcore add attr queried of query res cmd. The added attributes queried are: - tp_cnt - tpg_cnt - utp_cnt - seg_cnt These attributes are queried from drivers. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/ubcore/ubcore_main.c | 73 ++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/drivers/ub/urma/ubcore/ubcore_main.c b/drivers/ub/urma/ubcore/ubcore_main.c index bec752ea4e8a..2ee18d243f82 100644 --- a/drivers/ub/urma/ubcore/ubcore_main.c +++ b/drivers/ub/urma/ubcore/ubcore_main.c @@ -274,6 +274,14 @@ static int ubcore_cmd_query_stats(struct ubcore_cmd_hdr *hdr) static uint32_t ubcore_get_query_res_len(uint32_t type) { switch (type) { + case UBCORE_RES_KEY_UPI: + return (uint32_t)sizeof(struct ubcore_res_upi_val); + case UBCORE_RES_KEY_TP: + return (uint32_t)sizeof(struct ubcore_res_tp_val); + case UBCORE_RES_KEY_TPG: + return (uint32_t)sizeof(struct ubcore_res_tpg_val); + case UBCORE_RES_KEY_UTP: + return (uint32_t)sizeof(struct ubcore_res_utp_val); case UBCORE_RES_KEY_JFS: return (uint32_t)sizeof(struct ubcore_res_jfs_val); case UBCORE_RES_KEY_JFR: @@ -284,6 +292,8 @@ static uint32_t ubcore_get_query_res_len(uint32_t type) return (uint32_t)sizeof(struct ubcore_res_jetty_group_val); case UBCORE_RES_KEY_JFC: return (uint32_t)sizeof(struct ubcore_res_jfc_val); + case UBCORE_RES_KEY_SEG: + return (uint32_t)sizeof(struct ubcore_res_seg_val); case UBCORE_RES_KEY_URMA_DEV: return (uint32_t)sizeof(struct ubcore_res_dev_val); default: @@ -294,6 +304,10 @@ static uint32_t ubcore_get_query_res_len(uint32_t type) static void ubcore_dealloc_res_dev(struct ubcore_res_dev_val *ubcore_addr) { + if (ubcore_addr->seg_list != NULL) { + vfree(ubcore_addr->seg_list); + ubcore_addr->seg_list = NULL; + } if (ubcore_addr->jfs_list != NULL) { vfree(ubcore_addr->jfs_list); ubcore_addr->jfs_list = NULL; @@ -314,10 +328,26 @@ static void ubcore_dealloc_res_dev(struct ubcore_res_dev_val *ubcore_addr) vfree(ubcore_addr->jetty_group_list); ubcore_addr->jetty_group_list = NULL; } + if (ubcore_addr->tp_list != NULL) { + vfree(ubcore_addr->tp_list); + ubcore_addr->tp_list = NULL; + } + if (ubcore_addr->tpg_list != NULL) { + vfree(ubcore_addr->tpg_list); + ubcore_addr->tpg_list = NULL; + } + if (ubcore_addr->utp_list != NULL) { + vfree(ubcore_addr->utp_list); + ubcore_addr->utp_list = NULL; + } } static int ubcore_fill_res_addr(struct ubcore_res_dev_val *ubcore_addr) { + ubcore_addr->seg_list = vmalloc(sizeof(struct ubcore_seg_info) * ubcore_addr->seg_cnt); + if (ubcore_addr->seg_list == NULL) + return -ENOMEM; + ubcore_addr->jfs_list = vmalloc(sizeof(uint32_t) * ubcore_addr->jfs_cnt); if (ubcore_addr->jfs_list == NULL) goto free_seg_list; @@ -338,7 +368,25 @@ static int ubcore_fill_res_addr(struct ubcore_res_dev_val *ubcore_addr) if (ubcore_addr->jetty_group_list == NULL) goto free_jetty_list; + ubcore_addr->tp_list = vmalloc(sizeof(uint32_t) * ubcore_addr->tp_cnt); + if (ubcore_addr->tp_list == NULL) + goto free_jetty_group_list; + + ubcore_addr->tpg_list = vmalloc(sizeof(uint32_t) * ubcore_addr->tpg_cnt); + if (ubcore_addr->tpg_list == NULL) + goto free_tp_list; + + ubcore_addr->utp_list = vmalloc(sizeof(uint32_t) * ubcore_addr->utp_cnt); + if (ubcore_addr->utp_list == NULL) + goto free_tpg_list; + return 0; +free_tpg_list: + vfree(ubcore_addr->tpg_list); +free_tp_list: + vfree(ubcore_addr->tp_list); +free_jetty_group_list: + vfree(ubcore_addr->jetty_group_list); free_jetty_list: vfree(ubcore_addr->jetty_list); free_jfc_list: @@ -357,6 +405,13 @@ static int ubcore_fill_user_res_dev(struct ubcore_res_dev_val *dev_val, { int ret; + dev_val->seg_cnt = ubcore_addr->seg_cnt; + ret = ubcore_copy_to_user((void __user *)(uintptr_t)(uint64_t)dev_val->seg_list, + ubcore_addr->seg_list, + dev_val->seg_cnt * sizeof(struct ubcore_seg_info)); + if (ret != 0) + return ret; + dev_val->jfs_cnt = ubcore_addr->jfs_cnt; ret = ubcore_copy_to_user((void __user *)(uintptr_t)(uint64_t)dev_val->jfs_list, ubcore_addr->jfs_list, dev_val->jfs_cnt * sizeof(uint32_t)); @@ -388,6 +443,24 @@ static int ubcore_fill_user_res_dev(struct ubcore_res_dev_val *dev_val, if (ret != 0) return ret; + dev_val->tp_cnt = ubcore_addr->tp_cnt; + ret = ubcore_copy_to_user((void __user *)(uintptr_t)(uint64_t)dev_val->tp_list, + ubcore_addr->tp_list, dev_val->tp_cnt * sizeof(uint32_t)); + if (ret != 0) + return ret; + + dev_val->tpg_cnt = ubcore_addr->tpg_cnt; + ret = ubcore_copy_to_user((void __user *)(uintptr_t)(uint64_t)dev_val->tpg_list, + ubcore_addr->tpg_list, dev_val->tpg_cnt * sizeof(uint32_t)); + if (ret != 0) + return ret; + + dev_val->utp_cnt = ubcore_addr->utp_cnt; + ret = ubcore_copy_to_user((void __user *)(uintptr_t)(uint64_t)dev_val->utp_list, + ubcore_addr->utp_list, dev_val->utp_cnt * sizeof(uint32_t)); + if (ret != 0) + return ret; + return 0; } -- Gitee From 0ede019407ced152fc4f25178d8026bb2dd45914 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Mon, 18 Sep 2023 20:09:43 +0800 Subject: [PATCH 84/89] ub: ubcore add set upi and add/delete ueid api impls driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Ubcore add set upi and add/delete ueid api impls, which will finally call hw driver's registered methods. These apis are related to virtualization of UB. Add ueid: The UB Core invokes the UBN driver to set the EID and UPI values. Input parameter: dev: contains vendor-defined private device data. vf_id: specifies the EID and UPI values of a VF. The value 0xFFFF indicates that the PF is set to the PF instead of to the managed VF. cfg: indicates the ID to be set, including the EID and UPI. Return value: If the value is 0, the setting is successful. If the value is less than 0, the setting fails. Delete ueid: The UB Core invokes the UBN driver to delete the EID and UPI values of the VF or PF. Input parameter: dev: contains vendor-defined private device data. vf_id: specifies the UPI value of a VF. 0xFFFF indicates the PF itself. That is, the EID and UPI of the PF are deleted, not the managed VF. cfg: indicates the EID and UPI values to be deleted. Return value: The value 0 indicates that the deletion is successful. The value other than 0 indicates that the deletion fails. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/ubcore/ubcore_device.c | 55 ++++++++++++++++++++++++++ include/urma/ubcore_uapi.h | 26 +++++++++++- 2 files changed, 80 insertions(+), 1 deletion(-) diff --git a/drivers/ub/urma/ubcore/ubcore_device.c b/drivers/ub/urma/ubcore/ubcore_device.c index dc884d6b4a8b..d2978665ea84 100644 --- a/drivers/ub/urma/ubcore/ubcore_device.c +++ b/drivers/ub/urma/ubcore/ubcore_device.c @@ -324,6 +324,7 @@ static struct ubcore_ht_param g_ht_params[] = { [UBCORE_HT_JETTY] = { UBCORE_HASH_TABLE_SIZE, offsetof(struct ubcore_jetty, hnode), offsetof(struct ubcore_jetty, id), sizeof(uint32_t), NULL, NULL }, + [UBCORE_HT_TP] = { UBCORE_HASH_TABLE_SIZE, offsetof(struct ubcore_tp_node, hnode), offsetof(struct ubcore_tp_node, key), sizeof(struct ubcore_tp_key), NULL, NULL }, @@ -589,6 +590,24 @@ int ubcore_set_eid(struct ubcore_device *dev, union ubcore_eid *eid) } EXPORT_SYMBOL(ubcore_set_eid); +int ubcore_set_upi(const struct ubcore_device *dev, uint16_t vf_id, uint16_t idx, uint32_t upi) +{ + int ret; + + if (dev == NULL || dev->ops == NULL || dev->ops->set_upi == NULL) { + ubcore_log_err("Invalid argument.\n"); + return -EINVAL; + } + + ret = dev->ops->set_upi(dev, vf_id, idx, upi); + if (ret != 0) { + ubcore_log_err("failed to set vf%hu upi%hu, ret: %d.\n", vf_id, idx, ret); + return -EPERM; + } + return 0; +} +EXPORT_SYMBOL(ubcore_set_upi); + int ubcore_add_eid(struct ubcore_device *dev, union ubcore_eid *eid) { int ret; @@ -625,6 +644,42 @@ int ubcore_delete_eid(struct ubcore_device *dev, uint16_t idx) } EXPORT_SYMBOL(ubcore_delete_eid); +int ubcore_add_ueid(struct ubcore_device *dev, uint16_t vf_id, struct ubcore_ueid_cfg *cfg) +{ + int ret; + + if (dev == NULL || cfg == NULL || dev->ops == NULL || dev->ops->add_ueid == NULL) { + ubcore_log_err("Invalid argument.\n"); + return -EINVAL; + } + + ret = dev->ops->add_ueid(dev, vf_id, cfg); + if (ret != 0) { + ubcore_log_err("failed to add ueid, ret: %d.\n", ret); + return -EPERM; + } + return ret; +} +EXPORT_SYMBOL(ubcore_add_ueid); + +int ubcore_delete_ueid(struct ubcore_device *dev, uint16_t vf_id, uint16_t idx) +{ + int ret; + + if (dev == NULL || dev->ops == NULL || dev->ops->delete_ueid_by_idx == NULL) { + ubcore_log_err("Invalid argument.\n"); + return -EINVAL; + } + + ret = dev->ops->delete_ueid_by_idx(dev, vf_id, idx); + if (ret != 0) { + ubcore_log_err("failed to delete eid, ret: %d.\n", ret); + return -EPERM; + } + return ret; +} +EXPORT_SYMBOL(ubcore_delete_ueid); + int ubcore_query_device_attr(struct ubcore_device *dev, struct ubcore_device_attr *attr) { int ret; diff --git a/include/urma/ubcore_uapi.h b/include/urma/ubcore_uapi.h index 1eac46714200..8241775399a6 100644 --- a/include/urma/ubcore_uapi.h +++ b/include/urma/ubcore_uapi.h @@ -24,7 +24,6 @@ #define UBCORE_UAPI_H #include - /** * Application specifies the device to allocate an context. * @param[in] dev: ubcore_device found by add ops in the client. @@ -51,6 +50,15 @@ void ubcore_free_ucontext(const struct ubcore_device *dev, struct ubcore_ucontex * @return: 0 on success, other value on error */ int ubcore_set_eid(struct ubcore_device *dev, union ubcore_eid *eid); +/** + * set upi + * @param[in] dev: the ubcore_device handle; + * @param[in] vf_id: vf_id; + * @param[in] idx: idx of upi in vf; + * @param[in] upi: upi of vf to set + * @return: 0 on success, other value on error + */ +int ubcore_set_upi(const struct ubcore_device *dev, uint16_t vf_id, uint16_t idx, uint32_t upi); /** * add a function entity id (eid) to ub device, the upi of vf to which the eid belongs * can be specified @@ -67,6 +75,22 @@ int ubcore_add_eid(struct ubcore_device *dev, union ubcore_eid *eid); * @return: 0 on success, other value on error */ int ubcore_delete_eid(struct ubcore_device *dev, uint16_t idx); +/** + * add a function entity id (eid) to ub device (for uvs) + * @param[in] dev: the ubcore_device handle; + * @param[in] vf_id: vf_id; + * @param[in] cfg: eid and the upi of vf to which the eid belongs can be specified; + * @return: the index of eid/upi, less than 0 indicating error + */ +int ubcore_add_ueid(struct ubcore_device *dev, uint16_t vf_id, struct ubcore_ueid_cfg *cfg); +/** + * remove a function entity id (eid) specified by idx from ub device (for uvs) + * @param[in] dev: the ubcore_device handle; + * @param[in] vf_id: vf_id; + * @param[in] idx: the idx of function entity id (eid) to be deleted; + * @return: 0 on success, other value on error + */ +int ubcore_delete_ueid(struct ubcore_device *dev, uint16_t vf_id, uint16_t idx); /** * query device attributes * @param[in] dev: the ubcore_device handle; -- Gitee From 49354bde674ddae5bbad9954d46400ccf51a940c Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Mon, 18 Sep 2023 20:34:46 +0800 Subject: [PATCH 85/89] ub: uburma support query vf status and write in cdev driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Uburma support query vf status and write in cdev. Uburma will query vf status when uburma device creates, and write port related attrs under /dev/uburma/dev_name>/vf* Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/ubcore/ubcore_main.c | 1 + drivers/ub/urma/uburma/uburma_cdev_file.c | 63 +++++++++++++++++++++++ drivers/ub/urma/uburma/uburma_cdev_file.h | 14 +++++ drivers/ub/urma/uburma/uburma_main.c | 55 +++++++++++++++++++- drivers/ub/urma/uburma/uburma_types.h | 8 +++ 5 files changed, 140 insertions(+), 1 deletion(-) diff --git a/drivers/ub/urma/ubcore/ubcore_main.c b/drivers/ub/urma/ubcore/ubcore_main.c index 2ee18d243f82..fc584e743b9b 100644 --- a/drivers/ub/urma/ubcore/ubcore_main.c +++ b/drivers/ub/urma/ubcore/ubcore_main.c @@ -32,6 +32,7 @@ #include "ubcore_log.h" #include "ubcore_netlink.h" #include +#include #include #include "ubcore_priv.h" diff --git a/drivers/ub/urma/uburma/uburma_cdev_file.c b/drivers/ub/urma/uburma/uburma_cdev_file.c index 77a4f955b414..af5b709361ac 100644 --- a/drivers/ub/urma/uburma/uburma_cdev_file.c +++ b/drivers/ub/urma/uburma/uburma_cdev_file.c @@ -37,6 +37,10 @@ typedef ssize_t (*uburma_show_attr_cb)(const struct ubcore_device *ubc_dev, char typedef ssize_t (*uburma_store_attr_cb)(struct ubcore_device *ubc_dev, const char *buf, size_t len); typedef ssize_t (*uburma_show_port_attr_cb)(const struct ubcore_device *ubc_dev, char *buf, uint8_t port_num); +typedef ssize_t (*uburma_show_vf_attr_cb)(const struct ubcore_device *ubc_dev, char *buf, + uint16_t vf_num); +typedef ssize_t (*uburma_store_vf_attr_cb)(struct ubcore_device *ubc_dev, const char *buf, + size_t len, uint16_t vf_num); static ssize_t uburma_show_dev_attr(struct device *dev, struct device_attribute *attr, char *buf, uburma_show_attr_cb show_cb) @@ -565,6 +569,48 @@ static struct kobj_type uburma_port_type = { .release = uburma_port_release, .default_attrs = uburma_port_attrs }; +static struct attribute *uburma_vf_attrs[] = { + NULL, +}; + +static ssize_t uburma_vf_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) +{ + struct uburma_vf_attribute *vf_attr = container_of(attr, struct uburma_vf_attribute, attr); + struct uburma_vf *vf = container_of(kobj, struct uburma_vf, kobj); + + if (!vf_attr->show) + return -EIO; + + return vf_attr->show(vf, vf_attr, buf); +} + +static ssize_t uburma_vf_attr_store(struct kobject *kobj, struct attribute *attr, const char *buf, + size_t count) +{ + struct uburma_vf_attribute *vf_attr = container_of(attr, struct uburma_vf_attribute, attr); + struct uburma_vf *vf = container_of(kobj, struct uburma_vf, kobj); + + if (!vf_attr->store) + return -EIO; + return vf_attr->store(vf, vf_attr, buf, count); +} + +static const struct sysfs_ops uburma_vf_sysfs_ops = { .show = uburma_vf_attr_show, + .store = uburma_vf_attr_store }; + +static void uburma_vf_release(struct kobject *kobj) +{ +} + +static const struct attribute_group uburma_vf_groups = { + .attrs = uburma_vf_attrs, +}; + +static struct kobj_type uburma_vf_type = { .release = uburma_vf_release, + .sysfs_ops = &uburma_vf_sysfs_ops, + .default_attrs = uburma_vf_attrs +}; + int uburma_create_port_attr_files(struct uburma_device *ubu_dev, uint8_t port_num) { struct uburma_port *p; @@ -577,6 +623,18 @@ int uburma_create_port_attr_files(struct uburma_device *ubu_dev, uint8_t port_nu port_num); } +int uburma_create_vf_attr_files(struct uburma_device *ubu_dev, uint32_t vf_num) +{ + struct uburma_vf *vf; + + vf = &ubu_dev->vf[vf_num]; + vf->ubu_dev = ubu_dev; + vf->vf_idx = vf_num; + + return kobject_init_and_add(&vf->kobj, &uburma_vf_type, &ubu_dev->dev->kobj, "vf%u", + vf_num); +} + int uburma_create_dev_attr_files(struct uburma_device *ubu_dev) { int ret; @@ -595,6 +653,11 @@ void uburma_remove_port_attr_files(struct uburma_device *ubu_dev, uint8_t port_n kobject_put(&ubu_dev->port[port_num].kobj); } +void uburma_remove_vf_attr_files(struct uburma_device *ubu_dev, uint32_t vf_num) +{ + kobject_put(&ubu_dev->vf[vf_num].kobj); +} + void uburma_remove_dev_attr_files(struct uburma_device *ubu_dev) { sysfs_remove_group(&ubu_dev->dev->kobj, &uburma_dev_attr_group); diff --git a/drivers/ub/urma/uburma/uburma_cdev_file.h b/drivers/ub/urma/uburma/uburma_cdev_file.h index ee9c8c9630ba..c0a4483ce2e7 100644 --- a/drivers/ub/urma/uburma/uburma_cdev_file.h +++ b/drivers/ub/urma/uburma/uburma_cdev_file.h @@ -35,9 +35,23 @@ struct uburma_port_attribute { #define PORT_ATTR_RO(_name) struct uburma_port_attribute port_attr_##_name = __ATTR_RO(_name) +struct uburma_vf_attribute { + struct attribute attr; + ssize_t (*show)(struct uburma_vf *vf, struct uburma_vf_attribute *attr, char *buf); + ssize_t (*store)(struct uburma_vf *vf, struct uburma_vf_attribute *attr, const char *buf, + size_t count); +}; + +#define VF_ATTR(_name, _mode, _show, _store) \ + struct uburma_vf_attribute vf_attr_##_name = __ATTR(_name, _mode, _show, _store) + +#define VF_ATTR_RO(_name) struct uburma_vf_attribute vf_attr_##_name = __ATTR_RO(_name) + int uburma_create_port_attr_files(struct uburma_device *ubu_dev, uint8_t port_num); +int uburma_create_vf_attr_files(struct uburma_device *ubu_dev, uint32_t vf_num); int uburma_create_dev_attr_files(struct uburma_device *ubu_dev); void uburma_remove_port_attr_files(struct uburma_device *ubu_dev, uint8_t port_num); +void uburma_remove_vf_attr_files(struct uburma_device *ubu_dev, uint32_t vf_num); void uburma_remove_dev_attr_files(struct uburma_device *ubu_dev); #endif /* UBURMA_CDEV_FILE_H */ diff --git a/drivers/ub/urma/uburma/uburma_main.c b/drivers/ub/urma/uburma/uburma_main.c index d7d15547ec76..ce013da5e8ab 100644 --- a/drivers/ub/urma/uburma/uburma_main.c +++ b/drivers/ub/urma/uburma/uburma_main.c @@ -36,6 +36,7 @@ #include "uburma_types.h" #include "uburma_file_ops.h" #include "uburma_cdev_file.h" +#include "uburma_uobj.h" #include "uburma_cmd.h" #define UBURMA_MAX_DEVICE 1024 @@ -95,7 +96,7 @@ static int uburma_get_devt(dev_t *devt) static int uburma_device_create(struct uburma_device *ubu_dev, struct ubcore_device *ubc_dev) { - uint8_t i, j; + uint8_t i, j, k; /* create /dev/uburma/dev_name> */ ubu_dev->dev = device_create(g_uburma_class, ubc_dev->dev.parent, ubu_dev->cdev.dev, @@ -116,8 +117,17 @@ static int uburma_device_create(struct uburma_device *ubu_dev, struct ubcore_dev goto err_port_attr; } + /* create /dev/uburma/dev_name>/vf* */ + for (k = 0; k < ubc_dev->attr.vf_cnt; k++) { + if (uburma_create_vf_attr_files(ubu_dev, k) != 0) + goto err_vf_attr; + } + return 0; +err_vf_attr: + for (j = 0; j < k; j++) + uburma_remove_vf_attr_files(ubu_dev, j); err_port_attr: for (j = 0; j < i; j++) uburma_remove_port_attr_files(ubu_dev, j); @@ -131,6 +141,15 @@ static int uburma_device_create(struct uburma_device *ubu_dev, struct ubcore_dev static void uburma_device_destroy(struct uburma_device *ubu_dev, const struct ubcore_device *ubc_dev) { + uint8_t i; + + for (i = 0; i < ubc_dev->attr.vf_cnt; i++) + uburma_remove_vf_attr_files(ubu_dev, i); + + for (i = 0; i < ubc_dev->attr.port_cnt; i++) + uburma_remove_port_attr_files(ubu_dev, i); + + uburma_remove_dev_attr_files(ubu_dev); device_destroy(g_uburma_class, ubu_dev->cdev.dev); } @@ -213,6 +232,38 @@ static int uburma_add_device(struct ubcore_device *ubc_dev) return -EPERM; } +static void uburma_free_ucontext(struct uburma_device *ubu_dev, struct ubcore_device *ubc_dev) +{ + struct uburma_file *file; + + rcu_assign_pointer(ubu_dev->ubc_dev, NULL); + synchronize_srcu(&ubu_dev->ubc_dev_srcu); + + mutex_lock(&ubu_dev->lists_mutex); + while (list_empty(&ubu_dev->uburma_file_list) == false) { + struct ubcore_ucontext *ucontext; + + file = list_first_entry(&ubu_dev->uburma_file_list, struct uburma_file, list); + file->is_closed = true; + list_del(&file->list); + kref_get(&file->ref); + mutex_unlock(&ubu_dev->lists_mutex); + + mutex_lock(&file->mutex); + uburma_cleanup_uobjs(file, UBURMA_REMOVE_DRIVER_REMOVE); + ucontext = file->ucontext; + file->ucontext = NULL; + if (ucontext != NULL) + ubcore_free_ucontext(ubc_dev, ucontext); + + mutex_unlock(&file->mutex); + + mutex_lock(&ubu_dev->lists_mutex); + (void)kref_put(&file->ref, uburma_release_file); + } + mutex_unlock(&ubu_dev->lists_mutex); +} + static void uburma_remove_device(struct ubcore_device *ubc_dev, void *client_ctx) { struct uburma_device *ubu_dev = client_ctx; @@ -224,6 +275,8 @@ static void uburma_remove_device(struct ubcore_device *ubc_dev, void *client_ctx cdev_del(&ubu_dev->cdev); clear_bit(ubu_dev->devnum, g_dev_bitmap); + uburma_free_ucontext(ubu_dev, ubc_dev); + if (atomic_dec_and_test(&ubu_dev->refcnt)) complete(&ubu_dev->comp); diff --git a/drivers/ub/urma/uburma/uburma_types.h b/drivers/ub/urma/uburma/uburma_types.h index 5d453ef8f40c..4cbaa5c16776 100644 --- a/drivers/ub/urma/uburma/uburma_types.h +++ b/drivers/ub/urma/uburma/uburma_types.h @@ -65,6 +65,13 @@ struct uburma_port { uint8_t port_num; }; +struct uburma_vf { + struct kobject kobj; + struct uburma_device *ubu_dev; + uint32_t vf_idx; +}; + + struct uburma_device { atomic_t refcnt; struct completion comp; /* When refcnt becomes 0, it will wake up */ @@ -75,6 +82,7 @@ struct uburma_device { struct cdev cdev; struct device *dev; struct uburma_port port[UBCORE_MAX_PORT_CNT]; + struct uburma_vf vf[UBCORE_MAX_VF_CNT]; struct ubcore_device *__rcu ubc_dev; struct srcu_struct ubc_dev_srcu; /* protect ubc_dev */ struct kobject kobj; /* when equal to 0 , free uburma_device. */ -- Gitee From 5f918eec9259d51cef795116f0d17dd5b1ba96b8 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Mon, 18 Sep 2023 20:41:38 +0800 Subject: [PATCH 86/89] ub: uburma query upi, then store in cdev. driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Uburma query upi attrs, then store in cdev. All these attributes will be obtained by ubcore_query_device_status(). Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/uburma/uburma_cdev_file.c | 187 ++++++++++++++++++++++ 1 file changed, 187 insertions(+) diff --git a/drivers/ub/urma/uburma/uburma_cdev_file.c b/drivers/ub/urma/uburma/uburma_cdev_file.c index af5b709361ac..53f62cab608a 100644 --- a/drivers/ub/urma/uburma/uburma_cdev_file.c +++ b/drivers/ub/urma/uburma/uburma_cdev_file.c @@ -163,6 +163,113 @@ static ssize_t guid_show(struct device *dev, struct device_attribute *attr, char static DEVICE_ATTR_RO(guid); +static ssize_t max_upi_cnt_show_cb(const struct ubcore_device *ubc_dev, char *buf) +{ + return snprintf(buf, UBURMA_MAX_VALUE_LEN, "%u\n", ubc_dev->attr.max_upi_cnt); +} + +static ssize_t max_upi_cnt_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + return uburma_show_dev_attr(dev, attr, buf, max_upi_cnt_show_cb); +} + +static DEVICE_ATTR_RO(max_upi_cnt); + +static ssize_t uburma_query_upi(const struct ubcore_device *ubc_dev, char *buf, uint16_t vf_id) +{ + struct ubcore_res_key key = { 0 }; + struct ubcore_res_val val = { 0 }; + uint32_t upi; + uint32_t i; + ssize_t ret; + + key.type = UBCORE_RES_KEY_UPI; + key.key = (uint32_t)vf_id; + + val.len = sizeof(uint32_t) * UBCORE_MAX_UPI_CNT; + val.addr = (uint64_t)kcalloc(1, val.len, GFP_KERNEL); + if (val.addr == 0) { + uburma_log_err("kcalloc vf%u failed.\n", vf_id); + return -ENOMEM; + } + + if (ubcore_query_resource(ubc_dev, &key, &val) != 0) { + uburma_log_err("query vf%u resource failed.\n", vf_id); + kfree((void *)val.addr); + return -EPERM; + } + +#define UBURMA_UPI_STR_LEN (9) /* 2^20 <= 8bit, add 1 bit space */ + for (i = 0; i < (val.len / sizeof(upi)); i++) { + upi = *((uint32_t *)val.addr + i); + ret = snprintf(buf + (UBURMA_UPI_STR_LEN * i), UBURMA_UPI_STR_LEN + 1, "%8u ", upi); + if (ret <= 0) { + uburma_log_err("snprintf for vf%u upi failed %ld.\n", vf_id, ret); + kfree((void *)val.addr); + return ret; + } + } + + buf[(UBURMA_UPI_STR_LEN * i) - 1] = '\n'; + + kfree((void *)val.addr); + return (ssize_t)(UBURMA_UPI_STR_LEN * i); +} + +static int uburma_parse_upi_str(const char *buf, size_t len, uint16_t *idx, uint32_t *upi) +{ + int ret; + + ret = sscanf(buf, "%hu=%u", idx, upi); + if (ret <= 1) // ret must be equal to 2 + return -1; + + return 0; +} + +static ssize_t uburma_upi_store(struct ubcore_device *ubc_dev, const char *buf, size_t len, + uint16_t vf_id) +{ + ssize_t ret = -ENODEV; + uint16_t idx; + uint32_t upi; + + ret = uburma_parse_upi_str(buf, len, &idx, &upi); + if (ret != 0) { + uburma_log_err("parse vf%u upi str:%s failed %ld.\n", vf_id, buf, ret); + return -EINVAL; + } + + if (ubcore_set_upi(ubc_dev, vf_id, idx, upi) != 0) { + uburma_log_err("set vf%u idx:%u upi:%u failed.\n", vf_id, idx, upi); + return -EPERM; + } + return (ssize_t)len; // len is required for success return. +} + +static ssize_t upi_show_cb(const struct ubcore_device *ubc_dev, char *buf) +{ + return uburma_query_upi(ubc_dev, buf, UBCORE_OWN_VF_ID); +} + +static ssize_t upi_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + return uburma_show_dev_attr(dev, attr, buf, upi_show_cb); +} + +static ssize_t upi_store_cb(struct ubcore_device *ubc_dev, const char *buf, size_t len) +{ + return uburma_upi_store(ubc_dev, buf, len, UBCORE_OWN_VF_ID); +} + +static ssize_t upi_store(struct device *dev, struct device_attribute *attr, const char *buf, + size_t len) +{ + return uburma_store_dev_attr(dev, attr, buf, len, upi_store_cb); +} + +static DEVICE_ATTR_RW(upi); + static ssize_t feature_show_cb(const struct ubcore_device *ubc_dev, char *buf) { return snprintf(buf, UBURMA_MAX_VALUE_LEN, "0x%x\n", ubc_dev->attr.dev_cap.feature.value); @@ -377,6 +484,8 @@ static struct attribute *uburma_dev_attrs[] = { &dev_attr_ubdev.attr, &dev_attr_eid.attr, &dev_attr_guid.attr, + &dev_attr_max_upi_cnt.attr, + &dev_attr_upi.attr, &dev_attr_feature.attr, &dev_attr_max_jfc.attr, &dev_attr_max_jfs.attr, @@ -569,7 +678,85 @@ static struct kobj_type uburma_port_type = { .release = uburma_port_release, .default_attrs = uburma_port_attrs }; +static ssize_t uburma_show_vf_attr(struct uburma_vf *vf, struct uburma_vf_attribute *attr, + char *buf, uburma_show_vf_attr_cb show_cb) +{ + struct uburma_device *ubu_dev = vf->ubu_dev; + struct ubcore_device *ubc_dev; + int srcu_idx; + ssize_t ret; + + if (!ubu_dev) { + uburma_log_err("Invalid argument in show_vf_attr.\n"); + return -EINVAL; + } + + srcu_idx = srcu_read_lock(&ubu_dev->ubc_dev_srcu); + ubc_dev = srcu_dereference(ubu_dev->ubc_dev, &ubu_dev->ubc_dev_srcu); + if (ubc_dev == NULL) { + srcu_read_unlock(&ubu_dev->ubc_dev_srcu, srcu_idx); + return -ENODEV; + } + + ret = show_cb(ubc_dev, buf, vf->vf_idx); + srcu_read_unlock(&ubu_dev->ubc_dev_srcu, srcu_idx); + return ret; +} + +static ssize_t uburma_store_vf_attr(struct uburma_vf *vf, struct uburma_vf_attribute *attr, + const char *buf, size_t len, uburma_store_vf_attr_cb store_cb) +{ + struct uburma_device *ubu_dev = vf->ubu_dev; + struct ubcore_device *ubc_dev; + int srcu_idx; + ssize_t ret; + + if (!ubu_dev) { + uburma_log_err("Invalid argument in store_vf_attr.\n"); + return -EINVAL; + } + + srcu_idx = srcu_read_lock(&ubu_dev->ubc_dev_srcu); + ubc_dev = srcu_dereference(ubu_dev->ubc_dev, &ubu_dev->ubc_dev_srcu); + if (ubc_dev == NULL) { + srcu_read_unlock(&ubu_dev->ubc_dev_srcu, srcu_idx); + return -ENODEV; + } + + ret = store_cb(ubc_dev, buf, len, vf->vf_idx); + srcu_read_unlock(&ubu_dev->ubc_dev_srcu, srcu_idx); + return ret; +} + +static ssize_t vf_upi_show_cb(const struct ubcore_device *ubc_dev, char *buf, uint16_t vf_id) +{ + return uburma_query_upi(ubc_dev, buf, vf_id); +} + +static ssize_t vf_upi_show(struct uburma_vf *vf, struct uburma_vf_attribute *attr, char *buf) +{ + return uburma_show_vf_attr(vf, attr, buf, vf_upi_show_cb); +} + +static ssize_t vf_upi_store_cb(struct ubcore_device *ubc_dev, const char *buf, size_t len, + uint16_t vf_id) +{ + if (ubc_dev == NULL || buf == NULL) + return -EINVAL; + + return uburma_upi_store(ubc_dev, buf, len, vf_id); +} + +static ssize_t vf_upi_store(struct uburma_vf *vf, struct uburma_vf_attribute *attr, const char *buf, + size_t len) +{ + return uburma_store_vf_attr(vf, attr, buf, len, vf_upi_store_cb); +} + +static VF_ATTR(upi, 0644, vf_upi_show, vf_upi_store); + static struct attribute *uburma_vf_attrs[] = { + &vf_attr_upi.attr, NULL, }; -- Gitee From 4f71e46858fb4e977077069486612a00c2da78e2 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Mon, 18 Sep 2023 20:45:15 +0800 Subject: [PATCH 87/89] ub: uburma query vf related attributes, then store in cdev. driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Uburma query vf related attributes, then store in cdev. These attributes includes: - congestion_ctrl_alg - comp_vector_cnt - utp_cnt - port_count - vf_cnt - virtualization All these attributes will be obtained by ubcore_query_device_status(). Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/uburma/uburma_cdev_file.c | 101 ++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/drivers/ub/urma/uburma/uburma_cdev_file.c b/drivers/ub/urma/uburma/uburma_cdev_file.c index 53f62cab608a..93d990edcf08 100644 --- a/drivers/ub/urma/uburma/uburma_cdev_file.c +++ b/drivers/ub/urma/uburma/uburma_cdev_file.c @@ -453,6 +453,101 @@ static ssize_t trans_mode_show(struct device *dev, struct device_attribute *attr static DEVICE_ATTR_RO(trans_mode); +static ssize_t congestion_ctrl_alg_show_cb(const struct ubcore_device *ubc_dev, char *buf) +{ + return snprintf(buf, UBURMA_MAX_VALUE_LEN, "%u\n", + ubc_dev->attr.dev_cap.congestion_ctrl_alg); +} + +static ssize_t congestion_ctrl_alg_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + return uburma_show_dev_attr(dev, attr, buf, congestion_ctrl_alg_show_cb); +} + +static ssize_t congestion_ctrl_alg_store_cb(struct ubcore_device *ubc_dev, const char *buf, + size_t len) +{ + uint16_t value; + int ret; + + ret = kstrtou16(buf, 0, &value); + if (ret != 0) + return -EINVAL; + + ubc_dev->attr.dev_cap.congestion_ctrl_alg = value; + return (ssize_t)len; +} + +static ssize_t congestion_ctrl_alg_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t len) +{ + return uburma_store_dev_attr(dev, attr, buf, len, congestion_ctrl_alg_store_cb); +} + +static DEVICE_ATTR_RW(congestion_ctrl_alg); // 0644 + +static ssize_t comp_vector_cnt_show_cb(const struct ubcore_device *ubc_dev, char *buf) +{ + return snprintf(buf, UBURMA_MAX_VALUE_LEN, "%u\n", ubc_dev->attr.dev_cap.comp_vector_cnt); +} + +static ssize_t comp_vector_cnt_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + return uburma_show_dev_attr(dev, attr, buf, comp_vector_cnt_show_cb); +} + +static DEVICE_ATTR_RO(comp_vector_cnt); + +static ssize_t utp_cnt_show_cb(const struct ubcore_device *ubc_dev, char *buf) +{ + return snprintf(buf, UBURMA_MAX_VALUE_LEN, "%u\n", ubc_dev->attr.dev_cap.utp_cnt); +} + +static ssize_t utp_cnt_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + return uburma_show_dev_attr(dev, attr, buf, utp_cnt_show_cb); +} + +static DEVICE_ATTR_RO(utp_cnt); + +static ssize_t port_count_show_cb(const struct ubcore_device *ubc_dev, char *buf) +{ + return snprintf(buf, UBURMA_MAX_VALUE_LEN, "%u\n", ubc_dev->attr.port_cnt); +} + +static ssize_t port_count_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + return uburma_show_dev_attr(dev, attr, buf, port_count_show_cb); +} + +static DEVICE_ATTR_RO(port_count); + +static ssize_t virtualization_show_cb(const struct ubcore_device *ubc_dev, char *buf) +{ + return snprintf(buf, UBURMA_MAX_VALUE_LEN, "%s\n", + ubc_dev->attr.virtualization ? "true" : "false"); +} + +static ssize_t virtualization_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + return uburma_show_dev_attr(dev, attr, buf, virtualization_show_cb); +} + +static DEVICE_ATTR_RO(virtualization); + +static ssize_t vf_cnt_show_cb(const struct ubcore_device *ubc_dev, char *buf) +{ + return snprintf(buf, UBURMA_MAX_VALUE_LEN, "%u\n", ubc_dev->attr.vf_cnt); +} + +static ssize_t vf_cnt_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + return uburma_show_dev_attr(dev, attr, buf, vf_cnt_show_cb); +} + +static DEVICE_ATTR_RO(vf_cnt); + static ssize_t transport_type_show_cb(const struct ubcore_device *ubc_dev, char *buf) { return snprintf(buf, UBURMA_MAX_VALUE_LEN, "%d\n", (int)ubc_dev->transport_type); @@ -501,6 +596,12 @@ static struct attribute *uburma_dev_attrs[] = { &dev_attr_max_msg_size.attr, &dev_attr_max_rc_outstd_cnt.attr, &dev_attr_trans_mode.attr, + &dev_attr_congestion_ctrl_alg.attr, + &dev_attr_comp_vector_cnt.attr, + &dev_attr_utp_cnt.attr, + &dev_attr_port_count.attr, + &dev_attr_vf_cnt.attr, + &dev_attr_virtualization.attr, &dev_attr_transport_type.attr, &dev_attr_driver_name.attr, NULL, -- Gitee From 155b929cfbdc0a063aa1f49e89f1d7bda61f8ec6 Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Mon, 18 Sep 2023 20:56:31 +0800 Subject: [PATCH 88/89] ub: ubcore add tp-related process in jetty implements driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Ubcore add tp-related process in jetty implements. When creates jfc/jfs/jfr/jetty, it will also create a tptable related to this jetty. When deletes jfc/jfs/jfr/jetty, the related tp table should also deleted. Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/ubcore/ubcore_jetty.c | 45 ++++++++++++++++++++++++++- drivers/ub/urma/ubcore/ubcore_priv.h | 28 +++++++++++++++++ 2 files changed, 72 insertions(+), 1 deletion(-) diff --git a/drivers/ub/urma/ubcore/ubcore_jetty.c b/drivers/ub/urma/ubcore/ubcore_jetty.c index a95f2df2c409..e662189c59f0 100644 --- a/drivers/ub/urma/ubcore/ubcore_jetty.c +++ b/drivers/ub/urma/ubcore/ubcore_jetty.c @@ -30,6 +30,7 @@ #include "ubcore_priv.h" #include "ubcore_hash_table.h" #include "ubcore_tp.h" +#include "ubcore_tp_table.h" struct ubcore_jfc *ubcore_find_jfc(struct ubcore_device *dev, uint32_t jfc_id) { @@ -209,10 +210,18 @@ struct ubcore_jfs *ubcore_create_jfs(struct ubcore_device *dev, const struct ubc jfs->ub_dev = dev; jfs->uctx = ubcore_get_uctx(udata); jfs->jfae_handler = jfae_handler; - + if (ubcore_jfs_need_advise(jfs)) { + jfs->tptable = ubcore_create_tptable(); + if (jfs->tptable == NULL) { + (void)dev->ops->destroy_jfs(jfs); + ubcore_log_err("Failed to create tp table in the jfs.\n"); + return NULL; + } + } atomic_set(&jfs->use_cnt, 0); if (ubcore_hash_table_find_add(&dev->ht[UBCORE_HT_JFS], &jfs->hnode, jfs->id) != 0) { + ubcore_destroy_tptable(&jfs->tptable); (void)dev->ops->destroy_jfs(jfs); ubcore_log_err("Failed to add jfs.\n"); return NULL; @@ -277,6 +286,7 @@ int ubcore_delete_jfs(struct ubcore_jfs *jfs) jfs_id = jfs->id; dev = jfs->ub_dev; ubcore_hash_table_remove(&dev->ht[UBCORE_HT_JFS], &jfs->hnode); + ubcore_destroy_tptable(&jfs->tptable); ret = dev->ops->destroy_jfs(jfs); if (ret < 0) ubcore_log_err("UBEP failed to destroy jfs, jfs_id:%u.\n", jfs_id); @@ -341,8 +351,23 @@ struct ubcore_jfr *ubcore_create_jfr(struct ubcore_device *dev, const struct ubc jfr->ub_dev = dev; jfr->uctx = ubcore_get_uctx(udata); jfr->jfae_handler = jfae_handler; + if (ubcore_jfr_need_advise(jfr)) { + jfr->tptable = ubcore_create_tptable(); + if (jfr->tptable == NULL) { + (void)dev->ops->destroy_jfr(jfr); + ubcore_log_err("Failed to create tp table in the jfr.\n"); + return NULL; + } + } atomic_set(&jfr->use_cnt, 0); + if (ubcore_hash_table_find_add(&dev->ht[UBCORE_HT_JFR], &jfr->hnode, jfr->id) != 0) { + ubcore_destroy_tptable(&jfr->tptable); + (void)dev->ops->destroy_jfr(jfr); + ubcore_log_err("Failed to add jfr.\n"); + return NULL; + } + atomic_inc(&cfg->jfc->use_cnt); return jfr; } @@ -405,6 +430,7 @@ int ubcore_delete_jfr(struct ubcore_jfr *jfr) jfr_id = jfr->id; dev = jfr->ub_dev; ubcore_hash_table_remove(&dev->ht[UBCORE_HT_JFR], &jfr->hnode); + ubcore_destroy_tptable(&jfr->tptable); ret = dev->ops->destroy_jfr(jfr); if (ret < 0) ubcore_log_err("UBEP failed to destroy jfr, jfr_id:%u.\n", jfr_id); @@ -509,8 +535,24 @@ struct ubcore_jetty *ubcore_create_jetty(struct ubcore_device *dev, jetty->ub_dev = dev; jetty->uctx = ubcore_get_uctx(udata); jetty->jfae_handler = jfae_handler; + if (ubcore_jetty_need_advise(jetty) || jetty->jetty_cfg.trans_mode == UBCORE_TP_RC) { + jetty->tptable = ubcore_create_tptable(); + if (jetty->tptable == NULL) { + ubcore_log_err("Failed to create tp table in the jetty.\n"); + (void)dev->ops->destroy_jetty(jetty); + return NULL; + } + } else { + jetty->tptable = NULL; /* To prevent kernel-mode drivers, malloc is not empty */ + } atomic_set(&jetty->use_cnt, 0); + if (ubcore_hash_table_find_add(&dev->ht[UBCORE_HT_JETTY], &jetty->hnode, jetty->id) != 0) { + ubcore_destroy_tptable(&jetty->tptable); + (void)dev->ops->destroy_jetty(jetty); + ubcore_log_err("Failed to add jetty.\n"); + } + atomic_inc(&cfg->send_jfc->use_cnt); atomic_inc(&cfg->recv_jfc->use_cnt); if (cfg->jfr) @@ -579,6 +621,7 @@ int ubcore_delete_jetty(struct ubcore_jetty *jetty) jetty_id = jetty->id; dev = jetty->ub_dev; ubcore_hash_table_remove(&dev->ht[UBCORE_HT_JETTY], &jetty->hnode); + ubcore_destroy_tptable(&jetty->tptable); ret = dev->ops->destroy_jetty(jetty); if (ret < 0) { ubcore_log_err("UBEP failed to destroy jetty, jetty_id:%u.\n", jetty_id); diff --git a/drivers/ub/urma/ubcore/ubcore_priv.h b/drivers/ub/urma/ubcore/ubcore_priv.h index ce602d0e1cac..73a3060e2d78 100644 --- a/drivers/ub/urma/ubcore/ubcore_priv.h +++ b/drivers/ub/urma/ubcore/ubcore_priv.h @@ -53,6 +53,22 @@ static inline uint32_t ubcore_get_jetty_hash(const struct ubcore_jetty_id *jetty return jhash(jetty_id, sizeof(struct ubcore_jetty_id), 0); } +static inline uint32_t ubcore_get_tseg_hash(const struct ubcore_ubva *ubva) +{ + return jhash(ubva, sizeof(struct ubcore_ubva), 0); +} + +static inline uint32_t ubcore_get_eid_hash(const union ubcore_eid *eid) +{ + return jhash(eid, sizeof(union ubcore_eid), 0); +} + +static inline bool ubcore_jfs_need_advise(const struct ubcore_jfs *jfs) +{ + return jfs->ub_dev->transport_type == UBCORE_TRANSPORT_IB && + jfs->jfs_cfg.trans_mode == UBCORE_TP_RM; +} + static inline bool ubcore_jfs_tjfr_need_advise(const struct ubcore_jfs *jfs, const struct ubcore_tjetty *tjfr) { @@ -60,6 +76,12 @@ static inline bool ubcore_jfs_tjfr_need_advise(const struct ubcore_jfs *jfs, jfs->jfs_cfg.trans_mode == UBCORE_TP_RM && tjfr->cfg.trans_mode == UBCORE_TP_RM; } +static inline bool ubcore_jetty_need_advise(const struct ubcore_jetty *jetty) +{ + return jetty->ub_dev->transport_type == UBCORE_TRANSPORT_IB && + jetty->jetty_cfg.trans_mode == UBCORE_TP_RM; +} + static inline bool ubcore_jetty_tjetty_need_advise(const struct ubcore_jetty *jetty, const struct ubcore_tjetty *tjetty) { @@ -68,4 +90,10 @@ static inline bool ubcore_jetty_tjetty_need_advise(const struct ubcore_jetty *je tjetty->cfg.trans_mode == UBCORE_TP_RM; } +static inline bool ubcore_jfr_need_advise(const struct ubcore_jfr *jfr) +{ + return jfr->ub_dev->transport_type == UBCORE_TRANSPORT_IB && + jfr->jfr_cfg.trans_mode == UBCORE_TP_RM; +} + #endif -- Gitee From 3e5fd29d51db3180d4778ff612d841bb33532cfb Mon Sep 17 00:00:00 2001 From: Yizhen Fan Date: Mon, 9 Oct 2023 23:15:42 +0800 Subject: [PATCH 89/89] ub: fix warning happened in compilation driver inclusion category: feature bugzilla: NA CVE: NA -------------------------------- Fix warning happened in compilation. Change the kconfig of urea so that it will not compile on other structure of computer Signed-off-by: Guoxin Qian Signed-off-by: Yizhen Fan --- drivers/ub/urma/ubcore/ubcore_main.c | 24 +++++++++++------------ drivers/ub/urma/ubcore/ubcore_tp.c | 10 +++++----- drivers/ub/urma/uburma/uburma_cdev_file.c | 8 ++++---- drivers/ub/urma/uburma/uburma_dev_ops.c | 2 +- include/urma/ubcore_types.h | 8 ++++---- 5 files changed, 26 insertions(+), 26 deletions(-) diff --git a/drivers/ub/urma/ubcore/ubcore_main.c b/drivers/ub/urma/ubcore/ubcore_main.c index fc584e743b9b..733aff02e61c 100644 --- a/drivers/ub/urma/ubcore/ubcore_main.c +++ b/drivers/ub/urma/ubcore/ubcore_main.c @@ -257,7 +257,7 @@ static int ubcore_cmd_query_stats(struct ubcore_cmd_hdr *hdr) key.type = (uint8_t)arg.in.type; key.key = arg.in.key; - val.addr = (uint64_t)&com_val; + val.addr = (uintptr_t)&com_val; val.len = sizeof(struct ubcore_stats_com_val); ret = ubcore_query_stats(dev, &key, &val); @@ -407,57 +407,57 @@ static int ubcore_fill_user_res_dev(struct ubcore_res_dev_val *dev_val, int ret; dev_val->seg_cnt = ubcore_addr->seg_cnt; - ret = ubcore_copy_to_user((void __user *)(uintptr_t)(uint64_t)dev_val->seg_list, + ret = ubcore_copy_to_user((void __user *)(uintptr_t)dev_val->seg_list, ubcore_addr->seg_list, dev_val->seg_cnt * sizeof(struct ubcore_seg_info)); if (ret != 0) return ret; dev_val->jfs_cnt = ubcore_addr->jfs_cnt; - ret = ubcore_copy_to_user((void __user *)(uintptr_t)(uint64_t)dev_val->jfs_list, + ret = ubcore_copy_to_user((void __user *)(uintptr_t)dev_val->jfs_list, ubcore_addr->jfs_list, dev_val->jfs_cnt * sizeof(uint32_t)); if (ret != 0) return ret; dev_val->jfr_cnt = ubcore_addr->jfr_cnt; - ret = ubcore_copy_to_user((void __user *)(uintptr_t)(uint64_t)dev_val->jfr_list, + ret = ubcore_copy_to_user((void __user *)(uintptr_t)dev_val->jfr_list, ubcore_addr->jfr_list, dev_val->jfr_cnt * sizeof(uint32_t)); if (ret != 0) return ret; dev_val->jfc_cnt = ubcore_addr->jfc_cnt; - ret = ubcore_copy_to_user((void __user *)(uintptr_t)(uint64_t)dev_val->jfc_list, + ret = ubcore_copy_to_user((void __user *)(uintptr_t)dev_val->jfc_list, ubcore_addr->jfc_list, dev_val->jfc_cnt * sizeof(uint32_t)); if (ret != 0) return ret; dev_val->jetty_cnt = ubcore_addr->jetty_cnt; - ret = ubcore_copy_to_user((void __user *)(uintptr_t)(uint64_t)dev_val->jetty_list, + ret = ubcore_copy_to_user((void __user *)(uintptr_t)dev_val->jetty_list, ubcore_addr->jetty_list, dev_val->jetty_cnt * sizeof(uint32_t)); if (ret != 0) return ret; dev_val->jetty_group_cnt = ubcore_addr->jetty_group_cnt; - ret = ubcore_copy_to_user((void __user *)(uintptr_t)(uint64_t)dev_val->jetty_group_list, + ret = ubcore_copy_to_user((void __user *)(uintptr_t)dev_val->jetty_group_list, ubcore_addr->jetty_group_list, dev_val->jetty_group_cnt * sizeof(uint32_t)); if (ret != 0) return ret; dev_val->tp_cnt = ubcore_addr->tp_cnt; - ret = ubcore_copy_to_user((void __user *)(uintptr_t)(uint64_t)dev_val->tp_list, + ret = ubcore_copy_to_user((void __user *)(uintptr_t)dev_val->tp_list, ubcore_addr->tp_list, dev_val->tp_cnt * sizeof(uint32_t)); if (ret != 0) return ret; dev_val->tpg_cnt = ubcore_addr->tpg_cnt; - ret = ubcore_copy_to_user((void __user *)(uintptr_t)(uint64_t)dev_val->tpg_list, + ret = ubcore_copy_to_user((void __user *)(uintptr_t)dev_val->tpg_list, ubcore_addr->tpg_list, dev_val->tpg_cnt * sizeof(uint32_t)); if (ret != 0) return ret; dev_val->utp_cnt = ubcore_addr->utp_cnt; - ret = ubcore_copy_to_user((void __user *)(uintptr_t)(uint64_t)dev_val->utp_list, + ret = ubcore_copy_to_user((void __user *)(uintptr_t)dev_val->utp_list, ubcore_addr->utp_list, dev_val->utp_cnt * sizeof(uint32_t)); if (ret != 0) return ret; @@ -480,7 +480,7 @@ static int ubcore_query_res_dev(const struct ubcore_device *dev, struct ubcore_r return -ENOMEM; } - val.addr = (uint64_t)&ubcore_addr; + val.addr = (uintptr_t)&ubcore_addr; val.len = sizeof(struct ubcore_res_dev_val); ret = ubcore_query_resource(dev, key, &val); @@ -511,7 +511,7 @@ static int ubcore_query_res_arg(const struct ubcore_device *dev, struct ubcore_c key.type = (uint8_t)arg->in.type; key.key = arg->in.key; - val.addr = (uint64_t)addr; + val.addr = (uintptr_t)addr; val.len = res_len; if (arg->in.type == UBCORE_RES_KEY_URMA_DEV) diff --git a/drivers/ub/urma/ubcore/ubcore_tp.c b/drivers/ub/urma/ubcore/ubcore_tp.c index d284639925fb..34104b8f050e 100644 --- a/drivers/ub/urma/ubcore/ubcore_tp.c +++ b/drivers/ub/urma/ubcore/ubcore_tp.c @@ -215,7 +215,7 @@ static int ubcore_set_tp_peer_ext(struct ubcore_tp_attr *attr, const uint8_t *ex (void)memcpy(peer_ext, ext_addr, ext_len); - attr->peer_ext.addr = (uint64_t)peer_ext; + attr->peer_ext.addr = (uintptr_t)peer_ext; attr->peer_ext.len = ext_len; return 0; } @@ -916,7 +916,7 @@ static struct ubcore_tp *ubcore_create_target_tp(struct ubcore_device *dev, struct ubcore_nl_create_tp_req *create = (struct ubcore_nl_create_tp_req *)(void *)req->payload; /* create tp parameters */ - struct ubcore_udrv_priv udrv_data = { .in_addr = (uint64_t)(create->ext_udrv + + struct ubcore_udrv_priv udrv_data = { .in_addr = (uintptr_t)(create->ext_udrv + create->ext_len), .in_len = create->udrv_in_len, .out_addr = 0, @@ -1714,7 +1714,7 @@ int ubcore_config_utp(struct ubcore_device *dev, const union ubcore_eid *eid, return -1; } // Query the utp_list under the device - val.addr = (uint64_t)&dev_val; + val.addr = (uintptr_t)&dev_val; val.len = sizeof(struct ubcore_res_dev_val); key_val.type = UBCORE_RES_KEY_URMA_DEV; key_val.key = eid->in4.addr; @@ -1745,7 +1745,7 @@ int ubcore_show_utp(struct ubcore_device *dev, const union ubcore_eid *eid) return -1; } // Query the utp_list under the device - val.addr = (uint64_t)&dev_val; + val.addr = (uintptr_t)&dev_val; val.len = sizeof(struct ubcore_res_dev_val); key_val.type = UBCORE_RES_KEY_URMA_DEV; key_val.key = eid->in4.addr; @@ -1755,7 +1755,7 @@ int ubcore_show_utp(struct ubcore_device *dev, const union ubcore_eid *eid) } for (i = 0; dev_val.utp_list != NULL && i < dev_val.utp_cnt; i++) { // Query the utp_val under the utp list - val.addr = (uint64_t)&utp_val; + val.addr = (uintptr_t)&utp_val; val.len = sizeof(struct ubcore_res_utp_val); key_val.type = UBCORE_RES_KEY_UTP; key_val.key = dev_val.utp_list[i]; diff --git a/drivers/ub/urma/uburma/uburma_cdev_file.c b/drivers/ub/urma/uburma/uburma_cdev_file.c index 93d990edcf08..700f8cfd1cd8 100644 --- a/drivers/ub/urma/uburma/uburma_cdev_file.c +++ b/drivers/ub/urma/uburma/uburma_cdev_file.c @@ -133,7 +133,7 @@ static ssize_t eid_store_cb(struct ubcore_device *ubc_dev, const char *buf, size ssize_t ret; if (str_to_eid(buf, len, &eid) != 0) { - uburma_log_err("failed to str_to_eid: %s, %lu.\n", buf, len); + uburma_log_err("failed to str_to_eid: %s, %zu.\n", buf, len); return -EINVAL; } @@ -187,7 +187,7 @@ static ssize_t uburma_query_upi(const struct ubcore_device *ubc_dev, char *buf, key.key = (uint32_t)vf_id; val.len = sizeof(uint32_t) * UBCORE_MAX_UPI_CNT; - val.addr = (uint64_t)kcalloc(1, val.len, GFP_KERNEL); + val.addr = (uintptr_t)kcalloc(1, val.len, GFP_KERNEL); if (val.addr == 0) { uburma_log_err("kcalloc vf%u failed.\n", vf_id); return -ENOMEM; @@ -204,7 +204,7 @@ static ssize_t uburma_query_upi(const struct ubcore_device *ubc_dev, char *buf, upi = *((uint32_t *)val.addr + i); ret = snprintf(buf + (UBURMA_UPI_STR_LEN * i), UBURMA_UPI_STR_LEN + 1, "%8u ", upi); if (ret <= 0) { - uburma_log_err("snprintf for vf%u upi failed %ld.\n", vf_id, ret); + uburma_log_err("snprintf for vf%u upi failed %zd.\n", vf_id, ret); kfree((void *)val.addr); return ret; } @@ -236,7 +236,7 @@ static ssize_t uburma_upi_store(struct ubcore_device *ubc_dev, const char *buf, ret = uburma_parse_upi_str(buf, len, &idx, &upi); if (ret != 0) { - uburma_log_err("parse vf%u upi str:%s failed %ld.\n", vf_id, buf, ret); + uburma_log_err("parse vf%u upi str:%s failed %zd.\n", vf_id, buf, ret); return -EINVAL; } diff --git a/drivers/ub/urma/uburma/uburma_dev_ops.c b/drivers/ub/urma/uburma/uburma_dev_ops.c index c2c3c4e0adb0..625193d2a04a 100644 --- a/drivers/ub/urma/uburma/uburma_dev_ops.c +++ b/drivers/ub/urma/uburma/uburma_dev_ops.c @@ -96,7 +96,7 @@ int uburma_open(struct inode *inode, struct file *filp) srcu_idx = srcu_read_lock(&ubu_dev->ubc_dev_srcu); mutex_lock(&ubu_dev->lists_mutex); ubc_dev = srcu_dereference(ubu_dev->ubc_dev, &ubu_dev->ubc_dev_srcu); - if (ubc_dev == NULL || ubc_dev->dev_name == NULL) { + if (ubc_dev == NULL) { uburma_log_err("can not find ubcore device.\n"); ret = EIO; goto err; diff --git a/include/urma/ubcore_types.h b/include/urma/ubcore_types.h index 73bae89574d6..c80a072680bf 100644 --- a/include/urma/ubcore_types.h +++ b/include/urma/ubcore_types.h @@ -217,9 +217,9 @@ union ubcore_reg_seg_flag { }; struct ubcore_udrv_priv { - uint64_t in_addr; + uintptr_t in_addr; uint32_t in_len; - uint64_t out_addr; + uintptr_t out_addr; uint32_t out_len; }; @@ -745,7 +745,7 @@ struct ubcore_tp_cfg { }; struct ubcore_tp_ext { - uint64_t addr; + uintptr_t addr; uint32_t len; }; @@ -923,7 +923,7 @@ struct ubcore_res_key { }; struct ubcore_res_val { - uint64_t addr; /* allocated and free by ubcore */ + uintptr_t addr; /* allocated and free by ubcore */ uint32_t len; /* in&out. As a input parameter, * it indicates the length allocated by the ubcore * As a output parameter, it indicates the actual data length. -- Gitee