From 36896bb5dbc91898909ee379851c73de4a2f1121 Mon Sep 17 00:00:00 2001 From: Tianyu Wang Date: Mon, 29 Apr 2024 19:53:50 +0800 Subject: [PATCH 1/4] fix strlcpy --- library/remoteproc/mica_rsc_table.c | 8 +++----- library/rpmsg_device/rpmsg_service.c | 4 ++-- mica/micad/socket_listener.c | 8 ++++---- scripts/checkpatch.pl | 4 ++-- 4 files changed, 11 insertions(+), 13 deletions(-) diff --git a/library/remoteproc/mica_rsc_table.c b/library/remoteproc/mica_rsc_table.c index d777619..9c7dde0 100644 --- a/library/remoteproc/mica_rsc_table.c +++ b/library/remoteproc/mica_rsc_table.c @@ -17,14 +17,12 @@ int handle_mica_rsc(struct remoteproc *rproc, void *rsc, size_t len) { int i; uint32_t rsc_type; + struct fw_rsc_ept *ept_rsc = rsc; + struct ept_info *ept; rsc_type = ((struct fw_rsc_vendor *)rsc)->type; switch (rsc_type) { case RSC_VENDOR_EPT_TABLE: - { - struct fw_rsc_ept *ept_rsc = rsc; - struct ept_info *ept; - for (i = 0; i < ept_rsc->num_of_epts; i++) { ept = &ept_rsc->endpoints[i]; if (ept->addr != 0) @@ -75,7 +73,7 @@ int rsc_update_ept_table(struct remoteproc *rproc, struct rpmsg_device *rdev) */ ept_rsc->endpoints[i].addr = ept->dest_addr; ept_rsc->endpoints[i].dest_addr = ept->addr; - strlcpy(ept_rsc->endpoints[i].name, ept->name, RPMSG_NAME_SIZE); + strncpy(ept_rsc->endpoints[i].name, ept->name, RPMSG_NAME_SIZE); ept_rsc->num_of_epts++; } diff --git a/library/rpmsg_device/rpmsg_service.c b/library/rpmsg_device/rpmsg_service.c index b0af670..94437e8 100644 --- a/library/rpmsg_device/rpmsg_service.c +++ b/library/rpmsg_device/rpmsg_service.c @@ -151,7 +151,7 @@ void mica_ns_bind_cb(struct rpmsg_device *rdev, const char *name, uint32_t dest) r_ept->addr = dest; r_ept->dest_addr = RPMSG_ADDR_ANY; - strlcpy(r_ept->name, name, RPMSG_NAME_SIZE); + strncpy(r_ept->name, name, RPMSG_NAME_SIZE); metal_list_add_tail(&remote_ept_list, &r_ept->node); } @@ -168,6 +168,6 @@ void register_remote_ept(const char *name, uint32_t addr, uint32_t dest_addr) DEBUG_PRINT("restore endpoint: %s, addr:%d, dest_addr: %d", name, addr, dest_addr); r_ept->addr = addr; r_ept->dest_addr = dest_addr; - strlcpy(r_ept->name, name, RPMSG_NAME_SIZE); + strncpy(r_ept->name, name, RPMSG_NAME_SIZE); metal_list_add_tail(&remote_ept_list, &r_ept->node); } diff --git a/mica/micad/socket_listener.c b/mica/micad/socket_listener.c index d34ccac..db9b897 100644 --- a/mica/micad/socket_listener.c +++ b/mica/micad/socket_listener.c @@ -133,7 +133,7 @@ static int add_listener(const char *name, struct mica_client *client, listener_c unit->client = client; unit->cb = cb; - strlcpy(unit->name, name, MAX_NAME_LEN); + strncpy(unit->name, name, MAX_NAME_LEN); snprintf(unit->socket_path, MAX_PATH_LEN, "%s/%s.socket", MICA_SOCKET_DIRECTORY, unit->name); @@ -146,7 +146,7 @@ static int add_listener(const char *name, struct mica_client *client, listener_c memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; - strlcpy(addr.sun_path, unit->socket_path, sizeof(addr.sun_path) - 1); + strncpy(addr.sun_path, unit->socket_path, sizeof(addr.sun_path) - 1); ret = bind(unit->socket_fd, (struct sockaddr *)&addr, sizeof(addr)); if (ret < 0) { @@ -338,14 +338,14 @@ static int create_mica_client(int epoll_fd, void *data) } client->cpu_id = msg.cpu; - strlcpy(client->path, msg.path, MAX_FIRMWARE_PATH_LEN); + strncpy(client->path, msg.path, MAX_FIRMWARE_PATH_LEN); if (strcmp(msg.ped, "jailhouse") == 0) client->ped = JAILHOUSE; else client->ped = BARE_METAL; - strlcpy(client->ped_cfg, msg.ped_cfg, MAX_FIRMWARE_PATH_LEN); + strncpy(client->ped_cfg, msg.ped_cfg, MAX_FIRMWARE_PATH_LEN); ret = mica_create(client); if (ret < 0) { diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 7d16f86..272fb5a 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -7008,10 +7008,10 @@ sub process { "Prefer strscpy over strcpy - see: https://github.com/KSPP/linux/issues/88\n" . $herecurr); } -# strlcpy uses that should likely be strscpy +# strncpy uses that should likely be strscpy if ($line =~ /\bstrlcpy\s*\(/) { WARN("STRLCPY", - "Prefer strscpy over strlcpy - see: https://github.com/KSPP/linux/issues/89\n" . $herecurr); + "Prefer strscpy over strncpy - see: https://github.com/KSPP/linux/issues/89\n" . $herecurr); } # strncpy uses that should likely be strscpy or strscpy_pad -- Gitee From 0691b71c803cbc9e1e30880afe260bbb769ca6df Mon Sep 17 00:00:00 2001 From: Tianyu Wang Date: Mon, 29 Apr 2024 20:54:52 +0800 Subject: [PATCH 2/4] add rsc phymem table --- library/include/remoteproc/mica_rsc.h | 20 +++++++++++++++ library/remoteproc/mica_rsc_table.c | 37 ++++++++++++++++++++++++--- 2 files changed, 54 insertions(+), 3 deletions(-) diff --git a/library/include/remoteproc/mica_rsc.h b/library/include/remoteproc/mica_rsc.h index 5f7ecce..a0c5a4c 100644 --- a/library/include/remoteproc/mica_rsc.h +++ b/library/include/remoteproc/mica_rsc.h @@ -18,6 +18,7 @@ extern "C" { * * Range: [RSC_VENDOR_START, RSC_VENDOR_END] * @RSC_VENDOR_EPT_TABLE: List of bound endpoints + * @RSC_PHY_MEM: continuous physical memory * * For more details regarding a specific resource type, please see its * dedicated structure below. @@ -30,6 +31,7 @@ extern "C" { */ enum mica_resource_type { RSC_VENDOR_EPT_TABLE = 128, + RSC_PHY_MEM = 129, }; /** @@ -57,6 +59,24 @@ struct fw_rsc_ept { struct ept_info endpoints[MAX_NUM_OF_EPTS]; } METAL_PACKED_END; +/** + * struct fw_rsc_ept - List of bound endpoints + * @pa: physical address of allocated memory + * @len: requested length of memory + + * Client can request physical memory and treated it as share memory, host will record + * the allocated physical address in the rsctable for client to use. + * Client can not specify the physical address of requested memory by @pa. + */ +METAL_PACKED_BEGIN +struct fw_rsc_phymem { + uint32_t type; + uint32_t pa; + uint32_t va; + uint32_t len; + char name[RPMSG_NAME_SIZE]; +} METAL_PACKED_END; + /** * handle_mica_rsc - Process our custom rsctable entries */ diff --git a/library/remoteproc/mica_rsc_table.c b/library/remoteproc/mica_rsc_table.c index 9c7dde0..8f8d53b 100644 --- a/library/remoteproc/mica_rsc_table.c +++ b/library/remoteproc/mica_rsc_table.c @@ -12,6 +12,9 @@ #include #include +#include "memory/shm_pool.h" + +int rsc_update_phymem_table(struct remoteproc *rproc, void *rsc); int handle_mica_rsc(struct remoteproc *rproc, void *rsc, size_t len) { @@ -29,14 +32,42 @@ int handle_mica_rsc(struct remoteproc *rproc, void *rsc, size_t len) register_remote_ept(ept->name, ept->addr, ept->dest_addr); } break; + case RSC_PHY_MEM: + return rsc_update_phymem_table(rproc, rsc); } - default: - break; - } return 0; } +int rsc_update_phymem_table(struct remoteproc *rproc, void *rsc) +{ + void *buf; + metal_phys_addr_t da, pa; + size_t bufsz, phymem_rsc_offset; + struct fw_rsc_phymem *mem_rsc; + if (rproc == NULL || rsc == NULL) { + return EFAULT; + } + mem_rsc = (struct fw_rsc_phymem *)rsc; + pa = mem_rsc->pa; + bufsz = mem_rsc->len; + struct mica_client *client = metal_container_of(rproc, struct mica_client, rproc); + if (bufsz == 0) { + return 0; + } + buf = alloc_shmem_region(client, 0, bufsz); + if (!buf) { + return -ENOMEM; + } + pa = shm_pool_virt_to_phys(client, buf); + da = METAL_BAD_PHYS; + (void *)remoteproc_mmap(rproc, &pa, &da, bufsz, 0, NULL); + DEBUG_PRINT("alloc phymem, paddr: 0x%lx, daddr: 0x%lx, vaddr: %p, size: 0x%lx\n", pa, da, buf, bufsz); + mem_rsc->pa = da; + metal_cache_flush(mem_rsc, sizeof(struct fw_rsc_phymem)); + return 0; +} + int rsc_update_ept_table(struct remoteproc *rproc, struct rpmsg_device *rdev) { void *rsc_table = rproc->rsc_table; -- Gitee From 5851c0c4fd5d06c5326c1fa44fb139b9e5eed31d Mon Sep 17 00:00:00 2001 From: Tianyu Wang Date: Wed, 8 May 2024 18:55:03 +0800 Subject: [PATCH 3/4] temp commit log_worker ko --- library/include/mica/mica_client.h | 2 +- library/memory/shm_pool.c | 4 +- library/remoteproc/baremetal_rproc.c | 4 +- library/remoteproc/jailhouse_rproc.c | 2 +- library/remoteproc/mica_rsc_table.c | 37 +- mcs_km/log_worker/Makefile | 7 + mcs_km/log_worker/build.sh | 9 + mcs_km/log_worker/log_list.c | 81 ++++ mcs_km/log_worker/log_list.h | 25 ++ mcs_km/log_worker/log_main.c | 536 +++++++++++++++++++++++++++ mcs_km/log_worker/log_main.h | 63 ++++ mcs_km/log_worker/module.mk | 6 + mcs_km/log_worker/readme.txt | 1 + 13 files changed, 770 insertions(+), 7 deletions(-) create mode 100644 mcs_km/log_worker/Makefile create mode 100644 mcs_km/log_worker/build.sh create mode 100644 mcs_km/log_worker/log_list.c create mode 100644 mcs_km/log_worker/log_list.h create mode 100644 mcs_km/log_worker/log_main.c create mode 100644 mcs_km/log_worker/log_main.h create mode 100644 mcs_km/log_worker/module.mk create mode 100644 mcs_km/log_worker/readme.txt diff --git a/library/include/mica/mica_client.h b/library/include/mica/mica_client.h index 71b9ef8..c49b6ed 100644 --- a/library/include/mica/mica_client.h +++ b/library/include/mica/mica_client.h @@ -18,7 +18,7 @@ extern "C" { #define MAX_FIRMWARE_PATH_LEN 128 #ifdef DEBUG -#define DEBUG_PRINT(fmt, args...) do{ syslog(LOG_DEBUG, "DEBUG: %s:%d:%s(): " fmt, \ +#define DEBUG_PRINT(fmt, args...) do{ syslog(LOG_ERR, "DEBUG: %s:%d:%s(): " fmt, \ __FILE__, __LINE__, __func__, ##args); } while (0) #else #define DEBUG_PRINT(fmt, ...) do{ } while (0) diff --git a/library/memory/shm_pool.c b/library/memory/shm_pool.c index 20aeb10..4d72482 100644 --- a/library/memory/shm_pool.c +++ b/library/memory/shm_pool.c @@ -46,7 +46,7 @@ int init_shmem_pool(struct mica_client *client, metal_phys_addr_t pa, size_t siz void *alloc_shmem_region(struct mica_client *client, metal_phys_addr_t phys, size_t size) { void *va; - + syslog(LOG_ERR, "alloc enter, pa:0x%lx, size:%lu\n", phys, size); if (phys == 0) { va = client->unused_shmem_start; } else { @@ -70,7 +70,7 @@ void *alloc_shmem_region(struct mica_client *client, metal_phys_addr_t phys, siz (size_t)(client->virt_shmem_end - client->unused_shmem_start), size); return NULL; } - + syslog(LOG_ERR, "alloc leave, va:%p\n", va, size); client->unused_shmem_start = va + size; DEBUG_PRINT("alloc shmem: %p - %p\n", va, va + size); return va; diff --git a/library/remoteproc/baremetal_rproc.c b/library/remoteproc/baremetal_rproc.c index c2c551b..ce10b6d 100644 --- a/library/remoteproc/baremetal_rproc.c +++ b/library/remoteproc/baremetal_rproc.c @@ -48,6 +48,7 @@ static int pipe_fd[2]; /* shared memory pool size: 128 K */ #define SHM_POOL_SIZE 0x20000 +#define LOG_POOL_SIZE 0x1F00000UL static atomic_bool notifier; static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; @@ -273,7 +274,8 @@ static int rproc_config(struct remoteproc *rproc, void *data) } client = metal_container_of(rproc, struct mica_client, rproc); - ret = init_shmem_pool(client, info.phy_addr + (client->cpu_id * SHM_POOL_SIZE), SHM_POOL_SIZE); + ret = init_shmem_pool(client, info.phy_addr, LOG_POOL_SIZE + SHM_POOL_SIZE); + if (ret) { syslog(LOG_ERR, "init shared memory pool failed, err %d\n", ret); return ret; diff --git a/library/remoteproc/jailhouse_rproc.c b/library/remoteproc/jailhouse_rproc.c index 37f7112..aa98df6 100644 --- a/library/remoteproc/jailhouse_rproc.c +++ b/library/remoteproc/jailhouse_rproc.c @@ -304,7 +304,7 @@ static struct remoteproc *rproc_init(struct remoteproc *rproc, } /* After creating cell, we need the name of cell to manage the corresponding cell. */ - strlcpy(pdata->cell_name, cell_desc_hdr.name, sizeof(pdata->cell_name)); + strncpy(pdata->cell_name, cell_desc_hdr.name, sizeof(pdata->cell_name)); rproc->ops = ops; rproc->priv = pdata; diff --git a/library/remoteproc/mica_rsc_table.c b/library/remoteproc/mica_rsc_table.c index 8f8d53b..67c15c9 100644 --- a/library/remoteproc/mica_rsc_table.c +++ b/library/remoteproc/mica_rsc_table.c @@ -5,6 +5,9 @@ */ #include +#include +#include +#include #include #include @@ -39,31 +42,61 @@ int handle_mica_rsc(struct remoteproc *rproc, void *rsc, size_t len) return 0; } +#define LOG_DEVICE_NAME "/dev/logW" + +#define MAGIC_NUMBER 'L' +#define IOC_LOG_START _IOW(MAGIC_NUMBER, 0, int) +#define IOC_LOG_STOP _IOW(MAGIC_NUMBER, 1, int) +#define IOC_MAXNR 1 + int rsc_update_phymem_table(struct remoteproc *rproc, void *rsc) { void *buf; metal_phys_addr_t da, pa; - size_t bufsz, phymem_rsc_offset; + size_t bufsz; struct fw_rsc_phymem *mem_rsc; + int ret; + if (rproc == NULL || rsc == NULL) { - return EFAULT; + return -EFAULT; } mem_rsc = (struct fw_rsc_phymem *)rsc; pa = mem_rsc->pa; bufsz = mem_rsc->len; + syslog(LOG_ERR, "mem rsc pa:0x%lx, size:%lu\n", pa, bufsz); struct mica_client *client = metal_container_of(rproc, struct mica_client, rproc); if (bufsz == 0) { return 0; } buf = alloc_shmem_region(client, 0, bufsz); + syslog(LOG_ERR, "alloc buf:%p, size:0x%lx\n", buf, bufsz); if (!buf) { return -ENOMEM; } + memset(buf, 0, bufsz); pa = shm_pool_virt_to_phys(client, buf); + syslog(LOG_ERR, "alloc pa:0x%lx\n", pa); da = METAL_BAD_PHYS; (void *)remoteproc_mmap(rproc, &pa, &da, bufsz, 0, NULL); DEBUG_PRINT("alloc phymem, paddr: 0x%lx, daddr: 0x%lx, vaddr: %p, size: 0x%lx\n", pa, da, buf, bufsz); + syslog(LOG_ERR, "alloc da:0x%lx\n", da); mem_rsc->pa = da; + + // TODO 修改成非通用的资源表,申请内存的同时启动日志线程 + // 或者修改为Uniproton侧发消息启动,但可能无法获取发消息前的日志 + // 根据申请的名字特殊处理?? + int fd = open(LOG_DEVICE_NAME, O_RDWR | O_SYNC); + if (fd < 0) { + syslog(LOG_ERR, "open %s device failed, err %d\n", LOG_DEVICE_NAME, fd); + return fd; + } + uintptr_t phyAddr = (uintptr_t)da; + ret = ioctl(fd, IOC_LOG_START, &phyAddr); + if (ret < 0) { + syslog(LOG_ERR, "unable to start log worker %d\n", ret); + return ret; + } + metal_cache_flush(mem_rsc, sizeof(struct fw_rsc_phymem)); return 0; } diff --git a/mcs_km/log_worker/Makefile b/mcs_km/log_worker/Makefile new file mode 100644 index 0000000..96cff41 --- /dev/null +++ b/mcs_km/log_worker/Makefile @@ -0,0 +1,7 @@ +ccflags-y += -Wall -Werror -Wtrampolines $(WDATE_TIME) -Wfloat-equal -Wvla -Wundef -funsigned-char -Wformat=2 -Wstack-usage=2048 -Wcast-align +ccflags-y += -Wextra -Wno-unused-parameter -Wno-sign-compare -Wno-missing-field-initializers + +# -DDEBUG + +obj-m := log_worker.o +log_worker-y = log_main.o log_list.o diff --git a/mcs_km/log_worker/build.sh b/mcs_km/log_worker/build.sh new file mode 100644 index 0000000..c372eb0 --- /dev/null +++ b/mcs_km/log_worker/build.sh @@ -0,0 +1,9 @@ + +rm -rf /opt/Ascend310B-source/driver/drivers/usr +mkdir /opt/Ascend310B-source/driver/drivers/usr +cp -r ../log_worker/* /opt/Ascend310B-source/driver/drivers/usr + +cd /opt/Ascend310B-source +bash build.sh driver + +cp /opt/Ascend310B-source/output/driver_modules/log_worker.ko /mnt/d/transfer/ \ No newline at end of file diff --git a/mcs_km/log_worker/log_list.c b/mcs_km/log_worker/log_list.c new file mode 100644 index 0000000..7304fc7 --- /dev/null +++ b/mcs_km/log_worker/log_list.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include +#include +#include +#include "log_list.h" + +struct log_list_elem; + +struct log_list_elem { + struct log_list_elem *next; + struct log_elem_content cont; +}; + +static struct log_list_elem g_log_list_head; +static struct log_list_elem *g_log_list_tail; + +void init_log_list(void) +{ + g_log_list_head.cont.log_mem = NULL; + g_log_list_head.cont.log_num = 0; + g_log_list_head.next = NULL; + g_log_list_tail = &(g_log_list_head); + LOG_DEBUG("[logList] INIT, head==tail:%p\n", g_log_list_tail); +} + +long add_log_elem(struct log_elem_content cont) +{ + struct log_list_elem *elem; + elem = (struct log_list_elem *)vmalloc(sizeof(struct log_list_elem)); + if (elem == NULL) { + printk(KERN_ERR "[logWorker] add log element no meme\n"); + return -ENOMEM; + } + elem->cont = cont; + elem->next = NULL; + LOG_DEBUG("[logList] ADD prev tail:%p new elem:%p\n", g_log_list_tail, elem); + g_log_list_tail->next = elem; + g_log_list_tail = elem; + + return 0; +} + +long peek_log_elem(struct log_elem_content *cont) +{ + struct log_list_elem *elem = g_log_list_head.next; + if (elem == NULL) { + return -1; + } + + if (cont != NULL) { + *cont = elem->cont; + } + return 0; +} + +long pop_log_elem(struct log_elem_content *cont) +{ + struct log_list_elem *elem = g_log_list_head.next; + LOG_DEBUG("[logList] POP head next:%p, tail:%p\n", elem, g_log_list_tail); + if (elem == NULL) { + return -1; + } + if (cont != NULL) { + *cont = g_log_list_head.next->cont; + } + g_log_list_head.next = elem->next; + vfree(elem); + + // 链表空,尾指针重新指向头指针 + if (g_log_list_head.next == NULL) { + LOG_DEBUG("[logList] POP Q empty!\n"); + g_log_list_tail = &(g_log_list_head); + } + return 0; +} + diff --git a/mcs_km/log_worker/log_list.h b/mcs_km/log_worker/log_list.h new file mode 100644 index 0000000..77e6c98 --- /dev/null +++ b/mcs_km/log_worker/log_list.h @@ -0,0 +1,25 @@ +#ifndef _LOG_LIST_H_ +#define _LOG_LIST_H_ + +#include + +#ifdef DEBUG +#define LOG_DEBUG(fmt, ...) printk(KERN_INFO fmt, ##__VA_ARGS__) +#else +#define LOG_DEBUG(fmt, ...) +#endif + +struct log_elem_content { + void *log_mem; + uint32_t log_num; +}; + +extern void init_log_list(void); + +extern long add_log_elem(struct log_elem_content cont); + +extern long peek_log_elem(struct log_elem_content *cont); + +extern long pop_log_elem(struct log_elem_content *cont); + +#endif diff --git a/mcs_km/log_worker/log_main.c b/mcs_km/log_worker/log_main.c new file mode 100644 index 0000000..5793ebe --- /dev/null +++ b/mcs_km/log_worker/log_main.c @@ -0,0 +1,536 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "log_main.h" +#include "log_list.h" + +/* uint32_t [0, 4294967295] 条日志, 按照每秒1w条日志计算, 需要连续运行5天才会翻转 */ +static struct task_struct *g_worker_thread = NULL; +static void *g_ring_buffer = NULL; +static uint8_t g_flag_valid; +static uint8_t g_tmp_valid_flags[BUFFER_BLOCK_NUM]; + +#ifdef DEBUG +static uint64_t g_pintk_count = 0; +#define VPRINTK_DEBUG_FMT "[%llu][Uni][%llu.%09llu][seq:%llu][pid:%u] %s" +#else +#define VPRINTK_FMT "[Uni][%llu.%09llu][seq:%llu][pid:%u] %s" +#endif + +static int vprintk_emit_wrapper(int facility, int level, ...) +{ + va_list args; + int ret; + + va_start(args, level); +#ifdef DEBUG + ret = vprintk_emit(facility, level, NULL, VPRINTK_DEBUG_FMT, args); +#else + ret = vprintk_emit(facility, level, NULL, VPRINTK_FMT, args); +#endif + va_end(args); + return ret; +} + +/* 至少输出 emit_num 条日志,0代表全部输出 */ +static void log_emit(uint32_t emit_num) +{ + int ret, i; + uint32_t total_emit_num; + struct log_elem_content log_elem; + struct log_header *cur_log; + + uint32_t count = 0; + while (pop_log_elem(&log_elem) != -1) { + count++; + for (i = 0; i < log_elem.log_num; i++) { + cur_log = ((struct log_header *)(log_elem.log_mem + i * BUFFER_BLOCK_SIZE)); + cur_log->log_content[cur_log->len] = '\0'; +#ifdef DEBUG + g_pintk_count++; + ret = vprintk_emit_wrapper((int)cur_log->facility, (int)cur_log->level, g_pintk_count, cur_log->sec, + cur_log->nano_sec, cur_log->sequence_num, cur_log->task_pid, cur_log->log_content); +#else + ret = vprintk_emit_wrapper((int)cur_log->facility, (int)cur_log->level, cur_log->sec, cur_log->nano_sec, + cur_log->sequence_num, cur_log->task_pid, cur_log->log_content); +#endif + } + total_emit_num += log_elem.log_num; + if (log_elem.log_mem != NULL) { + vfree(log_elem.log_mem); + } else { + printk(KERN_ERR "[logWorker] log mem is NULL?\n"); + } + + if (emit_num != 0 && total_emit_num > emit_num) { + break; + } + } + /* 后续应考虑, 避免连续输出日志, 每100条等待10ms ? */ + return; +} + +static uint8_t reverse_flag(uint8_t flag) +{ + if (flag == 0) { + return 1; + } + if (flag == 1) { + return 0; + } + printk(KERN_ERR "[logWorker] error: illegal flag\n"); + return flag; +} + +static uint32_t check_valid_num(uint32_t head_index, uint32_t copy_num) +{ + const uint8_t *const valid_ptr = (uint8_t *)g_ring_buffer + VALID_FLAGS_OFFSET; + uint32_t tail_copy_num, head_copy_num, valid_num; + uint8_t valid_flag = g_flag_valid; + uint8_t rev_valid_flag = reverse_flag(valid_flag); + int i; + + if (head_index + copy_num > BUFFER_BLOCK_NUM) { + // 到达结尾后,从头拷贝 + tail_copy_num = BUFFER_BLOCK_NUM - head_index; + head_copy_num = head_index + copy_num - BUFFER_BLOCK_NUM; + } else { + tail_copy_num = copy_num; + head_copy_num = 0; + } + + valid_num = 0; + memcpy_fromio(g_tmp_valid_flags, valid_ptr + head_index, tail_copy_num); + for (i = 0; i < tail_copy_num; i++) { + if (g_tmp_valid_flags[i] == valid_flag) { + valid_num++; + } else { + return valid_num; + } + } + + if (head_copy_num != 0) { + memcpy_fromio(g_tmp_valid_flags, valid_ptr, head_copy_num); + for (i = 0; i < head_copy_num; i++) { + if (g_tmp_valid_flags[i] == rev_valid_flag) { + valid_num++; + } else { + return valid_num; + } + } + } + return valid_num; +} + +static void copy_log_buffer(void *log_buffer, uint32_t head_index, uint32_t copy_num) +{ + uint32_t tail_copy_num, head_copy_num; + if (head_index + copy_num > BUFFER_BLOCK_NUM) { + // 到达结尾,从头拷贝 + tail_copy_num = BUFFER_BLOCK_NUM - head_index; + head_copy_num = head_index + copy_num - BUFFER_BLOCK_NUM; + } else { + tail_copy_num = copy_num; + head_copy_num = 0; + } + + memcpy_fromio(log_buffer, g_ring_buffer + (head_index * BUFFER_BLOCK_SIZE), (tail_copy_num * BUFFER_BLOCK_SIZE)); + if (head_copy_num != 0) { + memcpy_fromio(log_buffer + (tail_copy_num * BUFFER_BLOCK_SIZE), g_ring_buffer, (head_copy_num * BUFFER_BLOCK_SIZE)); + } + return; +} + +/* 不应该返回 NULL, 返回错误码或者内存 */ +static void *log_read(uint32_t *num, bool check_log, uint32_t head_index) +{ + void *vmem = NULL; + uint32_t copy_num; + + if (num == NULL) { + return ERR_PTR(-EFAULT); + } + copy_num = *num; + + if (copy_num == 0 || copy_num > BUFFER_BLOCK_NUM || head_index >= BUFFER_BLOCK_NUM) { + *num = 0; + return ERR_PTR(-EINVAL); + } + + if (check_log == true) { + copy_num = check_valid_num(head_index, copy_num); + } + LOAD_FENCE(); + + if (copy_num == 0) { + *num = 0; + return ERR_PTR(-EAGAIN); + } + + // 后续应考虑, 设置每次拷贝的最大数量 + + vmem = vmalloc(copy_num * BUFFER_BLOCK_SIZE); + if (vmem == NULL) { + *num = 0; + return ERR_PTR(-ENOMEM); + } + + copy_log_buffer(vmem, head_index, copy_num); + *num = copy_num; + return vmem; +} + +/* 返回NULL代表没有尝试读取日志 */ +static void *log_read_or_emit(uint32_t local_head, uint32_t curr_tail, uint32_t *read_num) +{ + void *log_mem = NULL; + uint32_t num = curr_tail - local_head; + uint32_t head_index = local_head % BUFFER_BLOCK_NUM; + + if (curr_tail < local_head || curr_tail > local_head + BUFFER_BLOCK_NUM) { + printk(KERN_ERR "[logWorker] invalid tail/head, tail:%u, head:%u\n", curr_tail, local_head); + return ERR_PTR(-EINVAL); + } + + if (BUFFER_BLOCK_NUM - num < BUFFER_NO_CHECK_COPY_THRESHOLD) { + // tail 即将追上一圈, 读取日志,不检查有效标记位 + // TODO 1k缓冲可能不够 + printk(KERN_ERR "[logWorker] tail is about to be full\n"); + log_mem = log_read(&num, false, head_index); + } else if (num > BUFFER_COPY_THRESHOLD) { + // 有足够多的日志读取 + log_mem = log_read(&num, true, head_index); + } else if (peek_log_elem(NULL) == -1) { + // 链表为空,继续读取日志 + if (num == 0) { + // 没有可处理/读取的日志,休眠一下, TODO休眠暂定10ms + schedule_timeout(HZ/100); + LOAD_FENCE() + return NULL; + } + log_mem = log_read(&num, true, head_index); + } else { + // 处理链表中的日志 + log_emit(LEAST_LOG_EMIT_NUM); + return NULL; + } + + if (IS_ERR(log_mem) && PTR_ERR(log_mem) == -EAGAIN) { + /* 有日志阻塞, 无法读取有效日志, 优先处理链表中的日志 */ + if (peek_log_elem(NULL) == -1) { + // 没有可处理/读取的日志,休眠一下, TODO休眠暂定10ms + schedule_timeout(HZ/100); + } else { + log_emit(LEAST_LOG_EMIT_NUM); + } + return NULL; + } + + *read_num = num; + return log_mem; +} + +static void log_worker_fix_overflow(uint32_t *local_head, uint32_t *local_tail, bool *is_overflow) +{ + uint32_t head = *local_head; + uint32_t tail = *local_tail; + bool overflow = *is_overflow; + if (overflow) { + /* 恢复前一轮翻转特殊处理过的head */ + head -= 2 * BUFFER_BLOCK_NUM; + overflow = false; + } + + if (head > (__UINT32_MAX__ - BUFFER_BLOCK_NUM)) { + /* __UINT32_MAX__ + 1 是 2 * BUFFER_BLOCK_NUM 的整倍数 */ + /* 接近翻转的情况下,让head和tail都向前移动两圈 */ + head += 2 * BUFFER_BLOCK_NUM; + tail += 2 * BUFFER_BLOCK_NUM; + overflow = true; + } + *local_head = head; + *local_tail = tail; + *is_overflow = overflow; + return; +} + +static int log_worker_last_read(uint32_t local_head, uint32_t curr_tail, bool is_overflow) +{ + uint32_t read_num; + int ret = 0; + void *log_mem = NULL; + + log_worker_fix_overflow(&local_head, &curr_tail, &is_overflow); + + /* 如果 curr_tail 和 local_head 不一致,需要读取剩下的所有日志 */ + if (curr_tail == local_head) { + g_worker_thread = NULL; + return 0; + } + + read_num = curr_tail - local_head; + if (curr_tail < local_head || curr_tail > local_head + BUFFER_BLOCK_NUM) { + printk(KERN_ERR "[logWorker] last read, invalid tail/head, tail:%u, head:%u\n", curr_tail, local_head); + return -EINVAL; + } + /* 读取所有日志, 无论是否有效 */ + log_mem = log_read(&read_num, false, local_head % BUFFER_BLOCK_NUM); + ret = add_log_elem((struct log_elem_content){log_mem, read_num}); + return ret; +} + +int log_worker_thd(void *param) +{ + void *log_mem = NULL; + uint32_t curr_tail, read_num; + long ret = 0; + bool is_overflow = 0; + uint32_t local_head = __UINT32_MAX__ - 2 * BUFFER_BLOCK_NUM + 1; + volatile uint32_t *const head_ptr = (uint32_t *)(g_ring_buffer + HEAD_PTR_OFFSET); + volatile uint32_t *const tail_ptr = (uint32_t *)(g_ring_buffer + TAIL_PTR_OFFSET); + (void)param; + + if (g_ring_buffer == NULL) { + printk(KERN_ERR "[logWorker] error: ring buffer null\n"); + return 0; + } + + while (!kthread_should_stop()) { + curr_tail = *tail_ptr; + log_worker_fix_overflow(&local_head, &curr_tail, &is_overflow); + + /* 根据head和tail, 读取日志或处理日志 */ + log_mem = log_read_or_emit(local_head, curr_tail, &read_num); + if (IS_ERR(log_mem)) { + ret = PTR_ERR(log_mem); + goto LOG_EXIT; + } + /* 未进行日志读取 */ + if (log_mem == NULL) { + continue; + } + printk(KERN_INFO "[logWorker] log head:%u, curr_tail:%u, read num:%u\n", local_head, curr_tail, read_num); + /* 更新标记位,head指针 */ + if (local_head % BUFFER_BLOCK_NUM + read_num >= BUFFER_BLOCK_NUM) { + g_flag_valid = reverse_flag(g_flag_valid); + } + local_head += read_num; + if (is_overflow) { + local_head -= 2 * BUFFER_BLOCK_NUM; + is_overflow = false; + } + *head_ptr = local_head; + STORE_FENCE(); + /* 读取到日志,添加进链表中 */ + ret = add_log_elem((struct log_elem_content){log_mem, read_num}); + if (ret != 0) { + vfree(log_mem); + goto LOG_EXIT; + } + } + curr_tail = *tail_ptr; + /* 读取剩余日志 */ + ret = log_worker_last_read(local_head, curr_tail, is_overflow); +LOG_EXIT: + /* 输出剩余日志 */ + log_emit(0); + return ret; +} + +/** + * 读取日志内容,日志有效标记,最好有cache(memcpy应该会有预取),读取日志有效标记后需要加读取屏障。 + * + * 读取tail,最好没有cache,有cache获取更新会不太及时,但是每次读取有效标记后已经会有读屏障了,tail的值足够新。 + * + * 写入head,最好没有cache,有cache更新会不太及时,使用MEMREMAP_WT write through,只要不读取head,写入时就不会写入cache也 + * 不会建立cache,所以不能读取head,并且和读取的内容不能在同一个cacheline里面。 + * + * 初始化写入全0,最好没有cache,速度快慢无所谓,MEMREMAP_WT可以满足。 +*/ +static int log_worker_start(uintptr_t phymem) +{ + volatile uint32_t *head_ptr; + volatile uint32_t *tail_ptr; + printk(KERN_INFO "[logWorker] start enter, %lx, %u\n", phymem, HZ); + + g_ring_buffer = memremap(phymem, SHM_MAP_SIZE, MEMREMAP_WT); + + // TODO 检查内容? 开头结尾魔术字? + + if (g_ring_buffer == NULL) { + printk(KERN_ERR "[logWorker] log worker memremap fail\n"); + return -ENOMEM; + } else { + printk(KERN_INFO "[logWorker] ring_buffer alloc success, %p\n", g_ring_buffer); + printk(KERN_INFO "[logWorker] str1:%s\nstr2:%s\n", + (char *)g_ring_buffer, (char *)g_ring_buffer + SHM_MAP_SIZE - 100); + } + + memset_io(g_ring_buffer, 0, SHM_MAP_SIZE); + head_ptr = (volatile uint32_t *)(g_ring_buffer + HEAD_PTR_OFFSET); + tail_ptr = (volatile uint32_t *)(g_ring_buffer + TAIL_PTR_OFFSET); + *head_ptr = __UINT32_MAX__ - 2 * BUFFER_BLOCK_NUM + 1; + *tail_ptr = __UINT32_MAX__ - 2 * BUFFER_BLOCK_NUM + 1; + printk(KERN_ERR "[logWorker] log worker ring start:%lx, ring end:%lx\n", + (uintptr_t)g_ring_buffer, ((uintptr_t)g_ring_buffer + SHM_MAP_SIZE)); + STORE_FENCE(); + printk(KERN_INFO "[logWorker] head:%u tail:%u\n", *head_ptr, *tail_ptr); + + // 初始化标记位,链表 + g_flag_valid = 1; + init_log_list(); + + // 拉起线程 + g_worker_thread = kthread_run(log_worker_thd, g_ring_buffer, "Uniproton_log_worker"); + if (IS_ERR(g_worker_thread)) { + printk(KERN_ERR "[logWorker] thread run fail, ret: %ld\n", PTR_ERR(g_worker_thread)); + g_worker_thread = NULL; + return 0; + } + printk(KERN_INFO "[logWorker] start finish\n"); + return 0; +} + + +static void log_worker_stop(void) +{ + printk(KERN_INFO "[logWorker] stop enter\n"); + if (g_worker_thread != NULL) { + kthread_stop(g_worker_thread); + g_worker_thread = NULL; + } else { + printk(KERN_INFO "[logWorker] g_worker_thread is NULL\n"); + } + + if (g_ring_buffer != NULL) { + memset_io(g_ring_buffer, 0, SHM_USED_SIZE); + STORE_FENCE(); + memunmap(g_ring_buffer); + g_ring_buffer = NULL; + } else { + printk(KERN_INFO "[logWorker] g_ring_buffer is NULL\n"); + } + printk(KERN_INFO "[logWorker] stop finish\n"); +} + +static long log_ioctl(struct file *f, unsigned int cmd, unsigned long arg) { + int ret; + uintptr_t phymem = 0; + + if (_IOC_TYPE(cmd) != MAGIC_NUMBER) { + return -EINVAL; + } + if (_IOC_NR(cmd) > IOC_MAXNR) { + return -EINVAL; + } + + printk(KERN_INFO "[logWorker] log worker ioctl cmd: %x %lx %lx\n", cmd, IOC_START, IOC_STOP); + if (cmd == IOC_START) { + ret = copy_from_user(&phymem, (uintptr_t __user *)arg, sizeof(uintptr_t)); + printk(KERN_INFO "[logWorker] log worker phymem:0x%lx\n", phymem); + if (ret) { + return -EFAULT; + } + log_worker_stop(); + printk(KERN_INFO "[logWorker] log worker stoped?\n"); + ret = log_worker_start(phymem); + if (ret) { + printk(KERN_ERR "[logWorker] log worker start fail, ret:%d\n", ret); + return -EINVAL; + } + } else if (cmd == IOC_STOP) { + log_worker_stop(); + return 0; + } else { + return -EINVAL; + } + return 0; +} + +static const struct file_operations log_worker_fops = { + .unlocked_ioctl = log_ioctl, + .compat_ioctl = compat_ptr_ioctl, + .llseek = generic_file_llseek, +}; + +#define LOG_DEVICE_NAME "logW" + +static struct class *log_class; +static int log_major; + +static int register_log_dev(void) +{ + int ret; + struct device *log_dev; + + log_major = register_chrdev(0, LOG_DEVICE_NAME, &log_worker_fops); + if (log_major < 0) { + ret = log_major; + printk(KERN_ERR "[logWorker]register_chrdev failed (%d)\n", ret); + goto err; + } + + log_class = class_create(THIS_MODULE, LOG_DEVICE_NAME); + if (IS_ERR(log_class)) { + ret = PTR_ERR(log_class); + printk(KERN_ERR "[logWorker] class_create failed (%d)\n", ret); + goto err_class; + } + + log_dev = device_create(log_class, NULL, MKDEV(log_major, 0), + NULL, LOG_DEVICE_NAME); + if (IS_ERR(log_dev)) { + ret = PTR_ERR(log_dev); + printk(KERN_ERR "[logWorker] device_create failed (%d)\n", ret); + goto err_device; + } + return 0; + +err_device: + class_destroy(log_class); +err_class: + unregister_chrdev(log_major, LOG_DEVICE_NAME); +err: + return ret; +} + +static void unregister_log_dev(void) +{ + device_destroy(log_class, MKDEV(log_major, 0)); + class_destroy(log_class); + unregister_chrdev(log_major, LOG_DEVICE_NAME); +} + +static int __init log_worker_init(void) +{ + return register_log_dev(); +} + +static void __exit log_worker_exit(void) +{ + log_worker_stop(); + unregister_log_dev(); +} + +module_init(log_worker_init); +module_exit(log_worker_exit); + +MODULE_AUTHOR("OpenEuler Embedded"); +MODULE_DESCRIPTION("log worker"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/mcs_km/log_worker/log_main.h b/mcs_km/log_worker/log_main.h new file mode 100644 index 0000000..becf9d3 --- /dev/null +++ b/mcs_km/log_worker/log_main.h @@ -0,0 +1,63 @@ +#ifndef _LOG_WORKER_H_ +#define _LOG_WORKER_H_ + +#define MCS_DEVICE_NAME "/dev/mcs" + +#define BUFFER_BLOCK_NUM 0x4000 +#define BUFFER_BLOCK_SIZE 0x400 /* 1KB */ +// 未读日志数量超过该数值,进行一次读取 +#define BUFFER_COPY_THRESHOLD 0x200 + +// 剩余缓存块低于该数值,读取日志时不检查有效标记位 +#define BUFFER_NO_CHECK_COPY_THRESHOLD 0x400 + +// 空闲时一次性至少输出该数值的日志 +#define LEAST_LOG_EMIT_NUM 0x200 + +/* + TOTAL size = 0x4000 * 0x400 + 0x4000 + 0x100 * 2 = 0x1004200 + +========= + | + | + | ring buffer size: BUFFER_BLOCK_NUM * BUFFER_BLOCK_SIZE = 16MB + | + | + +-------- + | + | valid flag size: BUFFER_BLOCK_NUM * sizeof(U8) = 16 KB + | + +----------- + | head (one cacheline 64 byte) + | tail (one cacheline 64 byte) + +========= +*/ +#define SHM_MAP_SIZE 0x1100000UL +#define SHM_USED_SIZE 0x1004200UL // ~16MB +#define VALID_FLAGS_OFFSET 0x1000000UL +#define VALID_FLAGS_SIZE 0x4000UL +#define HEAD_PTR_OFFSET 0x1004000UL +#define TAIL_PTR_OFFSET 0x1004100UL + +// armv8 memory fence +#define STORE_FENCE() __asm__ __volatile__ ("dmb st" : : : "memory"); +#define M_FENCE() __asm__ __volatile__ ("dmb sy" : : : "memory"); +#define LOAD_FENCE() __asm__ __volatile__ ("dmb ld" : : : "memory"); + +// ioctl cmd +#define MAGIC_NUMBER 'L' +#define IOC_START _IOW(MAGIC_NUMBER, 0, int) +#define IOC_STOP _IOW(MAGIC_NUMBER, 1, int) +#define IOC_MAXNR 1 + +struct log_header { + uint64_t sec; + uint64_t nano_sec; + uint64_t sequence_num; + uint32_t task_pid; + uint16_t len; + uint8_t facility; + uint8_t level; + uint8_t log_content[]; +}; + +#endif /* _LOG_WORKER_H_ */ diff --git a/mcs_km/log_worker/module.mk b/mcs_km/log_worker/module.mk new file mode 100644 index 0000000..c8ebc96 --- /dev/null +++ b/mcs_km/log_worker/module.mk @@ -0,0 +1,6 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) +LOCAL_MODULE := log_worker +LOCAL_KO_SRC_FOLDER := $(LOCAL_PATH) +LOCAL_INSTALLED_KO_FILES := log_worker.ko +include $(BUILD_DEVICE_KO) \ No newline at end of file diff --git a/mcs_km/log_worker/readme.txt b/mcs_km/log_worker/readme.txt new file mode 100644 index 0000000..2d00666 --- /dev/null +++ b/mcs_km/log_worker/readme.txt @@ -0,0 +1 @@ +rsyslog配置指南 -- Gitee From 42e8cbd4426441e028761ab87413b2215c9378e0 Mon Sep 17 00:00:00 2001 From: luoyimei Date: Mon, 13 May 2024 14:47:21 +0800 Subject: [PATCH 4/4] mcs: mica without so description: mica without so Signed-off-by: luoyimei --- CMakeLists.txt | 11 +- mica/micad/CMakeLists.txt | 3 + mica/micad/socket_listener.c | 197 +++++++++++++++++++++++++++++++---- 3 files changed, 190 insertions(+), 21 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 15314d2..284a178 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,9 +8,16 @@ set(CMAKE_C_FLAGS "-fstack-protector-all -O2 -Wall") set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DDEBUG") ## Add dependencies +# set(SHARED_LINK_LIBS +# metal +# open_amp +# ) +set(LIBRARY_PATH /opt/openeuler/oecore-x86_64/sysroots/aarch64-openeuler-linux/usr/lib64) + set(SHARED_LINK_LIBS - metal - open_amp + ${LIBRARY_PATH}/libopen_amp.a + ${LIBRARY_PATH}/libmetal.a + libsysfs.a ) ## Add headers diff --git a/mica/micad/CMakeLists.txt b/mica/micad/CMakeLists.txt index fe8dbab..5725b9c 100644 --- a/mica/micad/CMakeLists.txt +++ b/mica/micad/CMakeLists.txt @@ -7,6 +7,9 @@ target_include_directories(micad PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ) +set_target_properties(micad PROPERTIES LINK_SEARCH_START_STATIC ON) +set_target_properties(micad PROPERTIES LINK_SEARCH_END_STATIC ON) +target_link_options(micad PRIVATE -static-libgcc -static-libstdc++ -static) target_link_libraries(micad ${MICA_LIB} ${SHARED_LINK_LIBS}) install(TARGETS micad diff --git a/mica/micad/socket_listener.c b/mica/micad/socket_listener.c index db9b897..c8f814d 100644 --- a/mica/micad/socket_listener.c +++ b/mica/micad/socket_listener.c @@ -19,6 +19,8 @@ #include #include +#include +int g_changestate = 0; #define MAX_EVENTS 64 #define MAX_NAME_LEN 32 @@ -189,6 +191,85 @@ free_mem: return ret; } +static int client_ctrl_pre(const char *name, struct mica_client *client, listener_cb cb, int epoll_fd) +{ + int ret; + struct sockaddr_un addr; + struct listen_unit *unit; + struct epoll_event ev = { 0 }; + + unit = calloc(1, sizeof(*unit)); + if (!unit) + return -ENOMEM; + + /* bind a mica client */ + if (client != NULL) + unit->client = client; + + unit->cb = cb; + strcpy(unit->name, name); + snprintf(unit->socket_path, MAX_PATH_LEN, "%s/%s.socket", + MICA_SOCKET_DIRECTORY, unit->name); + syslog(LOG_INFO, "strcpy unit name and path success\n"); + + // unit->socket_fd = socket(AF_UNIX, SOCK_STREAM, 0); + // if (unit->socket_fd < 0) { + // syslog(LOG_ERR, "Failed to create socket: %s", strerror(errno)); + // ret = -1; + // goto free_mem; + // } + + // memset(&addr, 0, sizeof(addr)); + // addr.sun_family = AF_UNIX; + // strcpy(addr.sun_path, unit->socket_path); + + // ret = bind(unit->socket_fd, (struct sockaddr *)&addr, sizeof(addr)); + // if (ret < 0) { + // syslog(LOG_ERR, "Failed to bind socket: %s", strerror(errno)); + // goto free_socket; + // } + + /* + * From listen(2): + * If the backlog argument is greater than the value in + * /proc/sys/net/core/somaxconn, then it is silently capped to that value. + * Since Linux 5.4, the default in this file is 4096; in earlier kernels, + * the default value is 128. Before Linux 2.4.25, this limit was a hard + * coded value, SOMAXCONN, with the value 128. + * + * Here we use 128 directly. + */ + // ret = listen(unit->socket_fd, 128); + // if (ret < 0) { + // syslog(LOG_ERR, "Failed to listen socket: %s", strerror(errno)); + // goto free_socket; + // } + + // ev.events = EPOLLIN; + // ev.data.ptr = unit; + // ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, unit->socket_fd, &ev); + // if (ret < 0) { + // syslog(LOG_ERR, "Failed to add epoll handler: %s", strerror(errno)); + // goto free_socket; + // } + + // metal_list_add_tail(&listener_list, &unit->node); + ret = unit->cb(epoll_fd, unit); + if (ret < 0) { + syslog(LOG_ERR, "Failed to client_ctrl_handler: %s", strerror(errno)); + goto free_mem; + } + return 0; + +free_socket: + close(unit->socket_fd); + unlink(unit->socket_path); +free_mem: + free(unit); + return ret; +} + + static int check_create_msg(struct create_msg msg, int msg_fd) { int ret; @@ -235,6 +316,8 @@ static void show_status(int msg_fd, struct listen_unit *unit) unit->name, unit->client->cpu_id, status, buffer); send_log(msg_fd, "%s", response); + syslog(LOG_INFO, "%s\n", response); + send_log(msg_fd, "name: %s, %s", unit->name, response); } static int client_ctrl_handler(int epoll_fd, void *data) @@ -245,16 +328,44 @@ static int client_ctrl_handler(int epoll_fd, void *data) socklen_t addrlen = sizeof(addr); char msg[CTRL_MSG_SIZE] = { 0 }; - msg_fd = accept(unit->socket_fd, (struct sockaddr *)&addr, &addrlen); - if (msg_fd == -1) { - syslog(LOG_ERR, "Failed to accept %s: %s", unit->socket_path, strerror(errno)); - return -1; + // msg_fd = accept(unit->socket_fd, (struct sockaddr *)&addr, &addrlen); + // if (msg_fd == -1) { + // syslog(LOG_ERR, "Failed to accept %s: %s", unit->socket_path, strerror(errno)); + // return -1; + // } + + // ret = recv(msg_fd, msg, CTRL_MSG_SIZE, 0); + // if (ret < 0) { + // syslog(LOG_ERR, "Failed to receive %s: %s", unit->socket_path, strerror(errno)); + // goto err; + // } + + syslog(LOG_ERR, "g_changestate: %d\n", g_changestate); + + if(g_changestate == 0) { + strcpy(msg, "status"); } - ret = recv(msg_fd, msg, CTRL_MSG_SIZE, 0); - if (ret < 0) { - syslog(LOG_ERR, "Failed to receive %s: %s", unit->socket_path, strerror(errno)); - goto err; + if(g_changestate == 1) { + strcpy(msg, "start"); + } + + if(g_changestate == 2) { + strcpy(msg, "status"); + } + + if(g_changestate == 3) { + syslog(LOG_ERR, "123456"); + strcpy(msg, "stop"); + } + + if(g_changestate == 4) { + syslog(LOG_ERR, "123456"); + strcpy(msg, "status"); + } + + if(g_changestate == 5) { + strcpy(msg, "start"); } if (strncmp(msg, "start", CTRL_MSG_SIZE) == 0) { @@ -313,17 +424,21 @@ static int create_mica_client(int epoll_fd, void *data) struct listen_unit *unit = data; socklen_t addrlen = sizeof(addr); - msg_fd = accept(unit->socket_fd, (struct sockaddr *)&addr, &addrlen); - if (msg_fd == -1) { - syslog(LOG_ERR, "Failed to accept %s: %s", unit->socket_path, strerror(errno)); - return -1; - } + // msg_fd = accept(unit->socket_fd, (struct sockaddr *)&addr, &addrlen); + // if (msg_fd == -1) { + // syslog(LOG_ERR, "Failed to accept %s: %s", unit->socket_path, strerror(errno)); + // return -1; + // } - ret = recv(msg_fd, &msg, sizeof(msg), 0); - if (ret < 0) { - syslog(LOG_ERR, "Failed to receive %s: %s", unit->socket_path, strerror(errno)); - goto out; - } + // ret = recv(msg_fd, &msg, sizeof(msg), 0); + // if (ret < 0) { + // syslog(LOG_ERR, "Failed to receive %s: %s", unit->socket_path, strerror(errno)); + // goto out; + // } + + msg.cpu = 2; + strcpy(msg.name, "uniproton-hi3093"); + strcpy(msg.path, "/mcs/hi3093.elf"); ret = check_create_msg(msg, msg_fd); if (ret < 0) @@ -355,10 +470,53 @@ static int create_mica_client(int epoll_fd, void *data) } ret = add_listener(msg.name, client, client_ctrl_handler, epoll_fd); + ret = client_ctrl_pre(msg.name, client, client_ctrl_handler, epoll_fd); + // ret = client_ctrl_handler(epoll_fd, data); if (ret < 0) { syslog(LOG_ERR, "Failed to add listener for %s, ret: %d", msg.name, ret); free(client); } + + g_changestate = 1; + ret = client_ctrl_pre(msg.name, client, client_ctrl_handler, epoll_fd); + if (ret < 0) { + syslog(LOG_ERR, "Failed to add listener for %s, ret: %d", msg.name, ret); + free(client); + } + + /*g_changestate = 2; + int i = 3; + while (i--) + { + ret = client_ctrl_pre(msg.name, client, client_ctrl_handler, epoll_fd); + if (ret < 0) { + syslog(LOG_ERR, "Failed to add listener for %s, ret: %d", msg.name, ret); + free(client); + } + sleep(30); + } + + g_changestate = 3; + ret = client_ctrl_pre(msg.name, client, client_ctrl_handler, epoll_fd); + if (ret < 0) { + syslog(LOG_ERR, "Failed to add listener for %s, ret: %d", msg.name, ret); + free(client); + } + g_changestate = 4; + ret = client_ctrl_pre(msg.name, client, client_ctrl_handler, epoll_fd); + if (ret < 0) { + syslog(LOG_ERR, "Failed to add listener for %s, ret: %d", msg.name, ret); + free(client); + } + + sleep(10); + g_changestate = 5; + ret = client_ctrl_pre(msg.name, client, client_ctrl_handler, epoll_fd); + if (ret < 0) { + syslog(LOG_ERR, "Failed to add listener for %s, ret: %d", msg.name, ret); + free(client); + }*/ + out: if (ret != 0) send_log(msg_fd, "%s", MICA_MSG_FAILED); @@ -380,7 +538,8 @@ static void *wait_create_msg(void *arg) goto out; } - ret = add_listener("mica-create", NULL, create_mica_client, epoll_fd); + // ret = add_listener("mica-create", NULL, create_mica_client, epoll_fd); + ret = client_ctrl_pre("mica-create", NULL, create_mica_client, epoll_fd); if (ret < 0) { close(epoll_fd); goto out; -- Gitee