diff options
author | sharath reddy <bs.reddy@huawei.com> | 2019-06-04 11:53:49 +0530 |
---|---|---|
committer | sharath reddy <bs.reddy@huawei.com> | 2019-06-04 20:38:30 +0530 |
commit | 2a42ad20b9730706ad371ae3787d4597c4e42276 (patch) | |
tree | fa01cd312586ea007468e7233f94c0ce53d75873 /stacks/lwip_stack/src/mem | |
parent | a826fe833d3f2a8fe2673fa05811fe1a22baf045 (diff) |
Feature: 19.04 part-2DMM-2
Change-Id: I0b52a6bb67c25c7955d58e29eb81a3cc9efea9e9
Signed-off-by: sharath reddy <bs.reddy@huawei.com>
Diffstat (limited to 'stacks/lwip_stack/src/mem')
23 files changed, 5235 insertions, 0 deletions
diff --git a/stacks/lwip_stack/src/mem/CMakeLists.txt b/stacks/lwip_stack/src/mem/CMakeLists.txt new file mode 100644 index 0000000..eb4e0b5 --- /dev/null +++ b/stacks/lwip_stack/src/mem/CMakeLists.txt @@ -0,0 +1,36 @@ +######################################################################### +# +# Copyright (c) 2018 Huawei Technologies Co.,Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +######################################################################### + +if(WITH_HAL_LIB) +else() + SET(PAL_H_DIRECTORIES "/usr/include/dpdk/") +endif() + + +FILE(GLOB_RECURSE MEM *.c) +ADD_LIBRARY(nsfw_mem STATIC ${MEM}) +ADD_DEPENDENCIES(nsfw_mem GLOG) +INCLUDE_DIRECTORIES( + ${CMAKE_CURRENT_LIST_DIR}/../include + ${PAL_H_DIRECTORIES} + ${CMAKE_CURRENT_LIST_DIR}/../../../../src/framework/include + ${CMAKE_CURRENT_LIST_DIR}/../../../../src/framework/include/common + ${CMAKE_CURRENT_LIST_DIR}/../../../../src/include + nsfw_shmem/ + include/ + ${CMAKE_CURRENT_LIST_DIR}/../include/ + ${CMAKE_CURRENT_LIST_DIR}/nsfw_nshmem/ +) diff --git a/stacks/lwip_stack/src/mem/include/common_mem_memzone.h b/stacks/lwip_stack/src/mem/include/common_mem_memzone.h new file mode 100644 index 0000000..20e18c2 --- /dev/null +++ b/stacks/lwip_stack/src/mem/include/common_mem_memzone.h @@ -0,0 +1,25 @@ +/* +* +* Copyright (c) 2018 Huawei Technologies Co.,Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef _COMMON_MEM_MEMZONE_H_ +#define _COMMON_MEM_MEMZONE_H_ + +#ifdef HAL_LIB +#else +#include "rte_memzone.h" +#endif + +#endif /* _COMMON_MEM_MEMZONE_H_ */ diff --git a/stacks/lwip_stack/src/mem/include/common_pal_bitwide_adjust.h b/stacks/lwip_stack/src/mem/include/common_pal_bitwide_adjust.h new file mode 100644 index 0000000..086460c --- /dev/null +++ b/stacks/lwip_stack/src/mem/include/common_pal_bitwide_adjust.h @@ -0,0 +1,204 @@ +/* +* +* Copyright (c) 2018 Huawei Technologies Co.,Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef _COMMON_PAL_BITWIDE_ADJUST_H_ +#define _COMMON_PAL_BITWIDE_ADJUST_H_ + +#ifdef HAL_LIB +#include "pal_bitwide_adjust.h" +#else +#define MODULE(name) (1) + +#include "common_mem_common.h" + +#include "common_func.h" + +#define ALIGN_SIZET(size) ((uint64_t)(size)) +#define ALIGN_PTR(PTR) ((uint64_t)(PTR)) + +extern struct common_mem_memseg *g_PMemSegArry; +extern void **g_LMegAddrArry; + +/*get Local Seg addr by segIdx*/ +#define HMEM_SEG_LVADDR(segid) (g_LMegAddrArry[segid]) +/*get SegIDX by PrimSegAddr, just get the array Idx of g_PMemSegArry*/ +#define HMEM_SEGID(segaddr) ((struct common_mem_memseg*)segaddr - &(g_PMemSegArry[0])) + +/***************************************************************** +Parameters : LMegAddrArry[] Local common_mem_memseg addr Array + SegNum common_mem_memseg Num. +Return : +Description : init g_PrimAddr2LocalMap g_LocalAddr2PrimMap while the process start +*****************************************************************/ +void *pal_shddr_to_laddr(uint64_t shaddr); +uint64_t pal_laddr_to_shddr(void *laddr); +int dmm_pal_addr_align(); +void *shmem_shddr_to_laddr(void *addr); +uint64_t shmem_laddr_to_shddr(void *addr); + +extern int g_PrimSameFlg; + +/* if __NSTACK_MAIN__ is defined, no need do addr trans*/ +#ifndef __NSTACK_MAIN__ +/* g_PrimSameFlg check should be done before calling cast functions */ + +/*share memory address to local virtual address*/ +#define ADDR_SHTOL(addr) (g_PrimSameFlg ? ((void*) (addr)) : pal_shddr_to_laddr((uint64_t)(addr))) + +/*local virtual address to share memory address according to memseg*/ +#define ADDR_LTOSH(addr) (g_PrimSameFlg ? ((uint64_t)(addr)) : pal_laddr_to_shddr((void*)(addr))) + +#define PTR_SHTOL(type, addr) ((type)ADDR_SHTOL(addr)) + +/*local virtual address to share memory address; for compatible, not delete ADDR_LTOSH_EXT*/ +#define ADDR_LTOSH_EXT(addr) ADDR_LTOSH(addr) +#else +/*share memory address to local virtual address*/ +#define ADDR_SHTOL(addr) ((void*)(addr)) + +/*local virtual address to share memory address according to memseg*/ +#define ADDR_LTOSH(addr) ((uint64_t)(addr)) + +#define PTR_SHTOL(type, addr) ((type)(addr)) + +/*local virtual address to share memory address; for compatible, not delete ADDR_LTOSH_EXT*/ +#define ADDR_LTOSH_EXT(addr) ADDR_LTOSH(addr) +#endif + +#if MODULE("list") +#define COMMON_LIST_INSERT_HEAD(lhead, lelm, field) do { \ + if (((lelm)->field.le_next_align = (lhead)->lh_first_align) != ((typeof((lhead)->lh_first_align))(long)NULL)) \ + ((typeof((lhead)->lh_first))ADDR_SHTOL((lhead)->lh_first_align))->field.le_prev_align = \ + ADDR_LTOSH(&(lelm)->field.le_next); \ + (lhead)->lh_first_align = ADDR_LTOSH(lelm); \ + (lelm)->field.le_prev_align = ADDR_LTOSH(&(lhead)->lh_first); \ +} while (/*CONSTCOND*/0) + +#define COMMON_LIST_REMOVE(lelm, field) do { \ + if ((lelm)->field.le_next_align != ((typeof((lelm)->field.le_next_align))ALIGN_PTR(NULL))) \ + ((typeof((lelm)->field.le_next))ADDR_SHTOL((lelm)->field.le_next_align))->field.le_prev_align = \ + (lelm)->field.le_prev_align; \ + if (EOK != (MEMCPY_S((typeof((lelm)->field.le_prev))ADDR_SHTOL((lelm)->field.le_prev_align), \ + sizeof((lelm)->field.le_next_align), \ + &((lelm)->field.le_next_align), \ + sizeof((lelm)->field.le_next_align)))) \ + {\ + NSCOMM_LOGERR("MEMCPY_S failed.");\ + return;\ + }\ +} while (/*CONSTCOND*/0) + +#define COMMON_LIST_EMPTY(lhead) ((typeof((lhead)->lh_first))ADDR_SHTOL((lhead)->lh_first_align) == NULL) +#define COMMON_LIST_FIRST(lhead) ((typeof((lhead)->lh_first))ADDR_SHTOL((lhead)->lh_first_align)) +#define COMMON_LIST_NEXT(lelm, field) ((typeof((lelm)->field.le_next))ADDR_SHTOL((lelm)->field.le_next_align)) + +#endif + +#if MODULE("tailq") + +#define COMMON_TAILQ_INSERT_TAIL(lhead, lelm, field) do { \ + (lelm)->field.tqe_next_align = (typeof((lelm)->field.tqe_next_align))NULL; \ + (lelm)->field.tqe_prev_align = (lhead)->tqh_last_align; \ + typeof((lhead)->tqh_last_align) tempelm = ADDR_LTOSH(lelm);\ + if (EOK != (MEMCPY_S(ADDR_SHTOL((lhead)->tqh_last_align), sizeof(tempelm), &tempelm, sizeof(tempelm)))) \ + {\ + NSCOMM_LOGERR("MEMCPY_S failed.");\ + }\ + (lhead)->tqh_last_align = ADDR_LTOSH(&(lelm)->field.tqe_next); \ +} while (/*CONSTCOND*/0) + +#define COMMON_TAILQ_FOREACH(lvar, lhead, field) \ + for ((lvar) = (typeof(lvar))ADDR_SHTOL((lhead)->tqh_first_align); \ + (lvar); \ + (lvar) = (typeof(lvar))ADDR_SHTOL((lvar)->field.tqe_next_align)) + +#define COMMON_TAILQ_REMOVE(lhead, lelm, field) do { \ + if (((lelm)->field.tqe_next_align) != (typeof((lelm)->field.tqe_next_align))NULL) \ + ((typeof((lelm)->field.tqe_next))ADDR_SHTOL((lelm)->field.tqe_next_align))->field.tqe_prev_align = \ + (lelm)->field.tqe_prev_align; \ + else \ + (lhead)->tqh_last_align = (lelm)->field.tqe_prev_align; \ + if (EOK != (MEMCPY_S(ADDR_SHTOL((lelm)->field.tqe_prev_align), \ + sizeof((lelm)->field.tqe_next_align), \ + &((lelm)->field.tqe_next_align), \ + sizeof((lelm)->field.tqe_next_align)))) \ + {\ + NSCOMM_LOGERR("MEMCPY_S failed.");\ + }\ + } while (/*CONSTCOND*/0) + +/* + * Tail queue functions. + */ +#define COMMON_TAILQ_INIT(head) do { \ + (head)->tqh_first_align = (typeof((head)->tqh_first_align))NULL; \ + (head)->tqh_last_align = ADDR_LTOSH(&(head)->tqh_first); \ + } while (/*CONSTCOND*/0) + +/* + * Tail queue access methods. + */ +#define COMMON_TAILQ_EMPTY(head) ((head)->tqh_first_align == (typeof((head)->tqh_first_align))NULL) +#define COMMON_TAILQ_FIRST(head) ((typeof((head)->tqh_first))ADDR_SHTOL((head)->tqh_first_align)) +#define COMMON_TAILQ_NEXT(elm, field) ((typeof((elm)->field.tqe_next))ADDR_SHTOL((elm)->field.tqe_next_align)) + +#endif + +#if MODULE("stailq") +/* +* Singly-linked Tail queue functions. +*/ +#define COMMON_STAILQ_INIT(head) do { \ + (head)->stqh_first_align = ALIGN_PTR(NULL); \ + (head)->stqh_last_align = ADDR_LTOSH(&(head)->stqh_first); \ +} while (/*CONSTCOND*/0) + +#define COMMON_STAILQ_INSERT_TAIL(head, elm, field) do { \ + (elm)->field.stqe_next_align = ALIGN_PTR(NULL); \ + typeof((head)->stqh_last_align) telm = ADDR_LTOSH(elm);\ + if (EOK != (MEMCPY_S(ADDR_SHTOL((head)->stqh_last_align), sizeof(telm), &telm, sizeof(telm))))\ + {\ + NSCOMM_LOGERR("MEMCPY_S failed.");\ + }\ + (head)->stqh_last_align = ADDR_LTOSH(&(elm)->field.stqe_next); \ +} while (/*CONSTCOND*/0) + +#define COMMON_STAILQ_REMOVE_HEAD(head, field) do { \ + if (((head)->stqh_first_align = \ + ((typeof((head)->stqh_first))ADDR_SHTOL((head)->stqh_first_align))->field.stqe_next_align) == \ + (PTR_ALIGN_TYPE)NULL) \ + (head)->stqh_last_align = ADDR_LTOSH(&(head)->stqh_first); \ +} while (/*CONSTCOND*/0) + +#define COMMON_STAILQ_FOREACH(var, head, field) \ + for ((var) = ADDR_SHTOL((head)->stqh_first_align); \ + (var); \ + (var) = ADDR_SHTOL((var)->field.stqe_next_align)) + +/* +* Singly-linked Tail queue access methods. +*/ + +#define COMMON_STAILQ_EMPTY(head) ((head)->stqh_first_align == (PTR_ALIGN_TYPE)NULL) + +#define COMMON_STAILQ_FIRST(head) (ADDR_SHTOL((head)->stqh_first_align)) + +#define COMMON_STAILQ_NEXT(elm, field) (ADDR_SHTOL((elm)->field.stqe_next_align)) +#endif + +#endif + +#endif diff --git a/stacks/lwip_stack/src/mem/include/common_sys_config.h b/stacks/lwip_stack/src/mem/include/common_sys_config.h new file mode 100644 index 0000000..736c47b --- /dev/null +++ b/stacks/lwip_stack/src/mem/include/common_sys_config.h @@ -0,0 +1,46 @@ +/* +* +* Copyright (c) 2018 Huawei Technologies Co.,Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef __COMMON_SYS_CONFIG_H_ +#define __COMMON_SYS_CONFIG_H_ + +/* Below compile macro is used only in UT makefile */ +#if (HAL_LIB) +#else +#undef RTE_CACHE_LINE_SIZE +#define RTE_CACHE_LINE_SIZE 64 /* RTE_CACHE_LINE_SIZE */ +#undef RTE_MAX_LCORE +#define RTE_MAX_LCORE 128 /* RTE_MAX_LCORE */ +#undef RTE_MAX_NUMA_NODES +#define RTE_MAX_NUMA_NODES 8 /* RTE_MAX_NUMA_NODES */ +#undef RTE_MAX_MEMSEG +#define RTE_MAX_MEMSEG 256 /* RTE_MAX_MEMSEG */ +#undef RTE_MAX_MEMZONE +#define RTE_MAX_MEMZONE 2560 /* RTE_MAX_MEMZONE */ +#undef RTE_MAX_TAILQ +#define RTE_MAX_TAILQ 32 /* RTE_MAX_TAILQ */ +#undef RTE_ARCH_X86 +#define RTE_ARCH_X86 1 /* RTE_ARCH_64 */ +#undef RTE_ARCH_64 +#define RTE_ARCH_64 1 /* RTE_ARCH_64 */ +#undef RTE_PKTMBUF_HEADROOM +#define RTE_PKTMBUF_HEADROOM 128 /* RTE_PKTMBUF_HEADROOM */ +#undef RTE_MEMPOOL_CACHE_MAX_SIZE +#define RTE_MEMPOOL_CACHE_MAX_SIZE 512 /* RTE_MEMPOOL_CACHE_MAX_SIZE */ + +#endif + +#endif // __COMMON_SYS_CONFIG_H_ diff --git a/stacks/lwip_stack/src/mem/lib_common_mem/common_api.c b/stacks/lwip_stack/src/mem/lib_common_mem/common_api.c new file mode 100644 index 0000000..453f33f --- /dev/null +++ b/stacks/lwip_stack/src/mem/lib_common_mem/common_api.c @@ -0,0 +1,163 @@ +/* +* +* Copyright (c) 2018 Huawei Technologies Co.,Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include <string.h> +#include "common_mem_api.h" +#include "nstack_log.h" +#include "nstack_securec.h" +#include "common_func.h" +#include "pid_common.h" + +void sys_sem_init_v2(sys_sem_t_v2 sem) +{ + sem->locked = 1; +} + +/** Returns the current time in milliseconds, + * may be the same as sys_jiffies or at least based on it. */ +u32_t sys_now(void) +{ + struct timespec now; + + if (unlikely(0 != clock_gettime(CLOCK_MONOTONIC, &now))) + { + NSRTP_LOGERR("Failed to get time, errno = %d", errno); + } + + return 1000 * now.tv_sec + now.tv_nsec / 1000000; +} + +long sys_jiffies(void) +{ + return sys_now(); +} + +err_t sys_sem_new_v2(sys_sem_t_v2 * sem, u8_t isUnLockd) +{ + int retVal; + if (!sem) + { + return -1; + } + *sem = malloc(sizeof(common_mem_spinlock_t)); + + if (NULL == *sem) + { + return -1; + } + else + { + retVal = + memset_s(*sem, sizeof(common_mem_spinlock_t), 0, + sizeof(common_mem_spinlock_t)); + if (EOK != retVal) + { + NSRTP_LOGERR("MEMSET_S failed]ret=%d", retVal); + free(*sem); + *sem = NULL; + return -1; + } + common_mem_spinlock_init(*sem); + } + + if (!isUnLockd) + { + common_mem_spinlock_lock(*sem); + } + + return 0; +} + +void sys_sem_free_v2(sys_sem_t_v2 * sem) +{ + if ((sem != NULL) && (*sem != NULL)) + { + free(*sem); + *sem = NULL; + } + else + { + } +} + +void sys_sem_signal_v2(sys_sem_t_v2 * sem) +{ + common_mem_spinlock_unlock(*sem); +} + +void sys_sem_signal_s_v2(sys_sem_t_v2 sem) +{ + common_mem_spinlock_unlock(sem); +} + +u32_t sys_arch_sem_trywait_v2(sys_sem_t_v2 * sem) +{ + return (u32_t) common_mem_spinlock_trylock(*sem); +} + +u32_t sys_arch_sem_wait_v2(sys_sem_t_v2 * pstsem) +{ + common_mem_spinlock_lock(*pstsem); + return 0; +} + +u32_t sys_arch_sem_wait_s_v2(sys_sem_t_v2 sem) +{ + common_mem_spinlock_lock(sem); + return 0; +} + +/***************************************************************************** +* Prototype : get_pid_namespace +* Description : Get namespace of pid +* Input : uint32_t pid +* Output : None +* Return Value : uint64_t +* Calls : +* Called By : +*****************************************************************************/ +uint64_t get_pid_namespace(pid_t pid) +{ + char buf[BUF_SIZE_FILEPATH] = { 0 }; + char path[BUF_SIZE_FILEPATH] = { 0 }; + const char *pstart; + int ret = 0; + if (!pid) + { + NSSOC_LOGERR("Pid is zero!"); + return 0; + } + + ret = + snprintf_s(path, sizeof(path), sizeof(path) - 1, "/proc/%d/ns/pid", + pid); + if (-1 == ret) + { + NSSOC_LOGERR("SNPRINTF_S failed]ret=%d", ret); + return 0; + } + + ret = readlink(path, buf, sizeof(buf) - 1); + if (ret <= (int) sizeof(STR_PID)) + { + NSSOC_LOGERR("readlink pid ns file error]ret=%d", ret); + return 0; + } + + buf[ret - 1] = 0; + pstart = &(buf[sizeof(STR_PID)]); + return strtoull(pstart, NULL, 10); +} diff --git a/stacks/lwip_stack/src/mem/lib_common_mem/common_buf.c b/stacks/lwip_stack/src/mem/lib_common_mem/common_buf.c new file mode 100644 index 0000000..98983d5 --- /dev/null +++ b/stacks/lwip_stack/src/mem/lib_common_mem/common_buf.c @@ -0,0 +1,299 @@ +/* +* +* Copyright (c) 2018 Huawei Technologies Co.,Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <stdarg.h> +#include <inttypes.h> +#include <errno.h> +#include <ctype.h> +#include <sys/queue.h> + +#include "common_mem_base_type.h" + +#include "common_mem_common.h" + +#include "common_mem_memzone.h" + +#include "common_mem_mempool.h" +#include "common_mem_buf.h" + +#include "nstack_log.h" +#include "nstack_securec.h" + +#include "common_func.h" +#include "common_pal_bitwide_adjust.h" + +#define LOG_ERR 0 +#define LOG_WARN 1 +#define LOG_INFO 2 +#define LOG_DEBUG 3 +#define LOG_MAX 4 + +#define COMMON_LOG_PRINT(level, fmt, args...) \ + if (level <= log_level) NSRTP_LOGERR("===>[COMMON]"fmt, ##args); \ + +#define COMMON_PANIC(fmt) \ + NSRTP_LOGERR("==>[COMMON_PANIC]"fmt); \ + common_dump_stack(); \ + +#define PARA1_SET(argv, tempargv, Index, para1) do {\ + retVal = strcpy_s(tempargv[Index], PATA_STRLENT, para1);\ + if (retVal != EOK)\ + {\ + NSRTP_LOGERR("STRCPY_S failed]ret=%d", retVal);\ + return DMM_MBUF_RET_ERR;\ + }\ + argv[Index] = tempargv[Index]; \ + Index ++; } while (0) + +#define PARA2_SET(argv, tempargv, Index, para1, para2) do {\ + retVal = strcpy_s(tempargv[Index], PATA_STRLENT, para1); \ + if (retVal != EOK)\ + {\ + NSRTP_LOGERR("STRCPY_S failed]ret=%d", retVal);\ + return DMM_MBUF_RET_ERR;\ + }\ + argv[Index] = tempargv[Index]; \ + Index++; \ + retVal = strcpy_s(tempargv[Index], PATA_STRLENT, para2); \ + if (retVal != EOK)\ + {\ + NSRTP_LOGERR("STRCPY_S failed]ret=%d", retVal);\ + return DMM_MBUF_RET_ERR;\ + }\ + argv[Index] = tempargv[Index]; \ + Index ++; } while (0) + +#define PATA_STRLENT 64 +#define PATA_NUM_MAX 12 + +int log_level = LOG_INFO; + +int +nscomm_pal_module_init(nsfw_mem_para * para, + common_mem_pal_module_info * pinfo, u8 app_mode) +{ + char tempargv[PATA_NUM_MAX][PATA_STRLENT]; + char *argv[PATA_NUM_MAX]; + char tempbuf[PATA_STRLENT]; + unsigned int Index = 0; + int ioffset = 0; + int agindex = 0; + int intmask = 0; + int retVal; + char name[10] = { '\0' }; + + if (para == NULL) + { + NSRTP_LOGERR("para is null"); + return DMM_MBUF_RET_ERR; + } + + retVal = memset_s(tempargv, sizeof(tempargv), '\0', sizeof(tempargv)); + if (EOK != retVal) + { + NSRTP_LOGERR("MEMSET_S failed]ret=%d", retVal); + return DMM_MBUF_RET_ERR; + } + retVal = memset_s(argv, sizeof(argv), 0, sizeof(argv)); + if (EOK != retVal) + { + NSRTP_LOGERR("MEMSET_S failed]ret=%d", retVal); + return DMM_MBUF_RET_ERR; + } + if (NSFW_PROC_MAIN == para->enflag) + { + if (para->iargsnum != 0) + { + if (common_mem_pal_init(para->iargsnum, para->pargs) < 0) + { + COMMON_LOG_PRINT(LOG_ERR, "Cannot init pal\r\n"); + return DMM_MBUF_RET_ERR; + } + else + { + return DMM_MBUF_RET_OK; + } + } + + PARA1_SET(argv, tempargv, agindex, "nStackMain"); + PARA2_SET(argv, tempargv, agindex, "-c", "0x1"); + PARA2_SET(argv, tempargv, agindex, "-n", "4"); + PARA1_SET(argv, tempargv, agindex, "--huge-dir=/mnt/nstackhuge"); + PARA1_SET(argv, tempargv, agindex, "--proc-type=primary"); + + if (app_mode == 1) + { + sprintf(name, "dmm_app_%ld", (long) getpid()); + PARA2_SET(argv, tempargv, agindex, "--file-prefix", name); + PARA1_SET(argv, tempargv, agindex, "--no-pci"); + + // TODO: the size of the memory should not be fixed + PARA2_SET(argv, tempargv, agindex, "-m", "32"); + } + else + { + // TODO: replay the name 'nStackMain' + /* snprintf(name, 10, "dmm_main_%ld", (long) getpid()); */ + PARA2_SET(argv, tempargv, agindex, "--file-prefix", "nStackMain"); + PARA2_SET(argv, tempargv, agindex, "-m", "2048"); + } + + } + else + { + PARA1_SET(argv, tempargv, agindex, "nStackMain"); + PARA2_SET(argv, tempargv, agindex, "--file-prefix", "nStackMain"); + + retVal = sprintf_s(tempbuf, PATA_STRLENT, "0x"); + if (-1 == retVal) + { + NSRTP_LOGERR("SPRINTF_S failed]ret=%d", ioffset); + return DMM_MBUF_RET_ERR; + } + ioffset = retVal; + for (Index = 0; Index < LCORE_MASK_MAX; Index++) + { + if (ioffset >= PATA_STRLENT) + { + NSRTP_LOGERR("SPRINTF_S tempbuf overflow]ioffset=%d", + ioffset); + return DMM_MBUF_RET_ERR; + } + retVal = + sprintf_s(&(tempbuf[ioffset]), PATA_STRLENT - ioffset, "%8u", + pinfo->ilcoremask[Index]); + if (-1 == retVal) + { + NSRTP_LOGERR("SPRINTF_S failed]ret=%d", ioffset); + return DMM_MBUF_RET_ERR; + } + ioffset = ioffset + retVal; + intmask |= pinfo->ilcoremask[Index]; + } + if (0 == intmask) + { + PARA2_SET(argv, tempargv, agindex, "-c", "0x1"); + } + else + { + PARA2_SET(argv, tempargv, agindex, "-c", tempbuf); + } + if (pinfo->ishare_mem_size > 0) + { + retVal = memset_s(tempbuf, PATA_STRLENT, 0, PATA_NUM_MAX); + if (EOK != retVal) + { + NSRTP_LOGERR("MEMSET_S failed]ret=%d", retVal); + return DMM_MBUF_RET_ERR; + } + retVal = + sprintf_s(tempbuf, PATA_STRLENT, "%d", + pinfo->ishare_mem_size); + if (-1 == retVal) + { + NSRTP_LOGERR("SPRINTF_S failed]ret=%d", retVal); + return DMM_MBUF_RET_ERR; + } + PARA2_SET(argv, tempargv, agindex, "-m", tempbuf); + } + + retVal = memset_s(tempbuf, PATA_STRLENT, 0, PATA_NUM_MAX); + if (EOK != retVal) + { + NSRTP_LOGERR("MEMSET_S failed]ret=%d", retVal); + return DMM_MBUF_RET_ERR; + } + + switch (pinfo->ucproctype) + { + case DMM_PROC_T_PRIMARY: + retVal = + sprintf_s(tempbuf, PATA_STRLENT, "--proc-type=primary"); + if (-1 == retVal) + { + NSRTP_LOGERR("SPRINTF_S failed]ret=%d", retVal); + return DMM_MBUF_RET_ERR; + } + break; + case DMM_PROC_T_SECONDARY: + retVal = + sprintf_s(tempbuf, PATA_STRLENT, "--proc-type=secondary"); + if (-1 == retVal) + { + NSRTP_LOGERR("SPRINTF_S failed]ret=%d", retVal); + return DMM_MBUF_RET_ERR; + } + break; + case DMM_PROC_T_AUTO: + default: + retVal = sprintf_s(tempbuf, PATA_STRLENT, "--proc-type=auto"); + if (-1 == retVal) + { + NSRTP_LOGERR("SPRINTF_S failed]ret=%d", retVal); + return DMM_MBUF_RET_ERR; + } + break; + } + PARA1_SET(argv, tempargv, agindex, tempbuf); + + if (DMM_HUGTBL_DISABLE == pinfo->uchugeflag) + { + PARA1_SET(argv, tempargv, agindex, "--no-huge"); + } + } + if (common_mem_pal_init(agindex, argv) < 0) + { + COMMON_LOG_PRINT(LOG_ERR, "Cannot init pal\r\n"); + return DMM_MBUF_RET_ERR; + } + return DMM_MBUF_RET_OK; +} + +void *nscomm_memzone_data_reserve_name(const char *name, size_t len, + int socket_id) +{ + const struct common_mem_memzone *mz = NULL; + /* + rte_memzone_reserve must Call first, cause rte_memzone_reserve has a globe lock. + while proc race happen, who(calls A) got lock first will create memzone success. + others create same memzone proc will got lock after A, and rte_memzone_reserve return NULL; + so while rte_memzone_reserve return NULL we need do rte_memzone_lookup; + */ + mz = common_mem_memzone_reserve(name, len, socket_id, 0); + if (mz == NULL) + { + mz = common_mem_memzone_lookup(name); + } + + return mz ? (void *) ADDR_SHTOL(mz->addr_64) : NULL; +} + +void *nscomm_memzone_data_lookup_name(const char *name) +{ + void *addr = NULL; + const struct common_mem_memzone *mz = NULL; + mz = common_mem_memzone_lookup(name); + if (mz == NULL) + { + return NULL; + } + addr = (void *) ADDR_SHTOL(mz->addr_64); + return addr; +} diff --git a/stacks/lwip_stack/src/mem/lib_common_mem/common_func.c b/stacks/lwip_stack/src/mem/lib_common_mem/common_func.c new file mode 100644 index 0000000..6dd3d13 --- /dev/null +++ b/stacks/lwip_stack/src/mem/lib_common_mem/common_func.c @@ -0,0 +1,211 @@ +/* +* +* Copyright (c) 2018 Huawei Technologies Co.,Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "common_mem_pal_memconfig.h" +#include "common_mem_mbuf.h" +#include "common_mem_common.h" +#include "nstack_log.h" +#include "common_pal_bitwide_adjust.h" + +#include "common_func.h" + +#include "nstack_securec.h" + +#define COMMON_PROCESS_MAPS "/proc/self/maps" + +int g_PrimSameFlg = 1; + +NSTACK_STATIC void **g_PrimAddr2LocalMap = NULL; +NSTACK_STATIC void *g_LocalBaseAddr = NULL; +NSTACK_STATIC void *g_LocalMaxAddr = NULL; +NSTACK_STATIC void *g_LocalCfgAddrBase = NULL; + +NSTACK_STATIC uint64_t *g_LocalAddr2PrimMap = NULL; +NSTACK_STATIC uint64_t g_PrimBaseAddr = 0; +NSTACK_STATIC uint64_t g_PrimMaxAddr = 0; +NSTACK_STATIC uint64_t g_PrimCfgAddrBase = 0; + +NSTACK_STATIC uint64_t g_LBitMask = 0; +NSTACK_STATIC int g_LBitMaskLen = 0; + +uint64_t pal_laddr_to_shddr(void *LAddr) +{ + size_t l2pIdx; + + if (g_PrimSameFlg || LAddr == NULL) + { + return (uint64_t) LAddr; + } + + /*calculate the IDX */ + l2pIdx = (ALIGN_PTR(LAddr) - ALIGN_PTR(g_LocalBaseAddr)) >> g_LBitMaskLen; + + /*check the Hugepage Addr Rang */ + if (LAddr <= g_LocalMaxAddr && LAddr >= g_LocalBaseAddr + && g_LocalAddr2PrimMap[l2pIdx]) + { + return g_LocalAddr2PrimMap[l2pIdx] + (ALIGN_PTR(LAddr) & g_LBitMask); + } + + /*check the Cfg Mapping Addr Rang */ + if (LAddr >= g_LocalCfgAddrBase + && LAddr <= + (void *) ((char *) g_LocalCfgAddrBase + + sizeof(struct common_mem_mem_config))) + { + return g_PrimCfgAddrBase + ((char *) LAddr - + (char *) g_LocalCfgAddrBase); + } + + NSRTP_LOGWAR + ("WARNING!!! Input invalid LAddr]LAddr=%p, g_LocalBaseAddr=%p, g_LocalMaxAddr=%p, g_LocalCfgAddrBase=%p, g_LocalCfgAddrMax=%p.", + LAddr, g_LocalBaseAddr, g_LocalMaxAddr, g_LocalCfgAddrBase, + (char *) g_LocalCfgAddrBase + sizeof(struct common_mem_mem_config)); + + return (uint64_t) LAddr; +} + +void *pal_shddr_to_laddr(uint64_t PAddr) +{ + size_t p2lIdx; + + if (g_PrimSameFlg || PAddr == ALIGN_PTR(NULL)) + { + return (void *) PAddr; + } + + p2lIdx = (PAddr - g_PrimBaseAddr) >> g_LBitMaskLen; + /*check the Hugepage Addr Rang */ + if (PAddr <= g_PrimMaxAddr && PAddr >= g_PrimBaseAddr + && g_PrimAddr2LocalMap[p2lIdx]) + { + return (void *) ((uint64_t) g_PrimAddr2LocalMap[p2lIdx] + + (PAddr & g_LBitMask)); + } + + /*check the Cfg Mapping Addr Rang */ + if (PAddr >= g_PrimCfgAddrBase + && PAddr <= g_PrimCfgAddrBase + sizeof(struct common_mem_mem_config)) + { + return (void *) ((uint64_t) g_LocalCfgAddrBase + PAddr - + g_PrimCfgAddrBase); + } + + NSRTP_LOGWAR + ("WARNING!!! Input invalid PAddr]PAddr=%lx, g_PrimBaseAddr=%lx, g_PrimMaxAddr=%lx, g_PrimCfgAddrBase=%lx, g_PrimCfgAddrMax=%lx.", + PAddr, g_PrimBaseAddr, g_PrimMaxAddr, g_PrimCfgAddrBase, + g_PrimCfgAddrBase + sizeof(struct common_mem_mem_config)); + + return (void *) PAddr; +} + +/*lint +e539 */ + +int dmm_pal_addr_align() +{ + return g_PrimSameFlg; +} + +int32_t +dmm_pktmbuf_pool_iterator(struct common_mem_mempool * mp, uint32_t start, + uint32_t end, dmm_mbuf_item_fun fun, void *argv) +{ + if (NULL == mp || fun == NULL) + { + return 0; + } + + if (start >= mp->size || end <= start) + { + return 0; + } + + int32_t elm_size = mp->elt_size + mp->header_size + mp->trailer_size; + struct common_mem_mbuf *elm_mbuf = (struct common_mem_mbuf *) (STAILQ_FIRST(&mp->mem_list)->addr + start * elm_size + mp->header_size); /*lint !e647 */ + + uint32_t i; + uint32_t mbuf_end = COMMON_MEM_MIN(end, mp->size) - start; + for (i = 0; i < mbuf_end; i++) + { + (void) fun(elm_mbuf, argv); + elm_mbuf = (struct common_mem_mbuf *) ((char *) elm_mbuf + elm_size); + } + + return mbuf_end; +} + +void dmm_addr_print(void) +{ + const struct common_mem_mem_config *mcfg = + common_mem_pal_get_configuration()->mem_config; + int s; + FILE *fd; + char *ptembuf = NULL; + if (!mcfg) + { + NSRTP_LOGERR("mcfg is null"); + return; + } + /*printf base address */ + NSRTP_LOGINF("********master baseaddr begin***************"); + for (s = 0; s < COMMON_MEM_MAX_MEMSEG; ++s) + { + if ((mcfg->memseg[s].len > 0) && (mcfg->memseg[s].addr != 0)) + { + NSRTP_LOGINF("addr:%p, len:%u", mcfg->memseg[s].addr, + mcfg->memseg[s].len); + } + } + NSRTP_LOGINF("********master baseaddr end***************"); + + fd = fopen(COMMON_PROCESS_MAPS, "r"); + if (!fd) + { + NSRTP_LOGERR("/proc/self/maps open fail, erro:%d", errno); + return; + } + + ptembuf = (char *) malloc(BUFSIZ); + if (!ptembuf) + { + NSRTP_LOGERR("malloc buff failed]buff_len=%d", BUFSIZ); + fclose(fd); + return; + } + if (EOK != memset_s(ptembuf, BUFSIZ, 0, BUFSIZ)) + { + NSRTP_LOGERR("MEMSET_S failed] buff=%p", ptembuf); + } + NSRTP_LOGINF("********self process addr space begin***************"); + while (fgets(ptembuf, BUFSIZ, fd) != NULL) + { + NSRTP_LOGERR("%s", ptembuf); + } + NSRTP_LOGINF("********self process addr space end*****************"); + fclose(fd); + free(ptembuf); + return; +} + +void *shmem_shddr_to_laddr(void *addr) +{ + return ADDR_SHTOL(addr); +} + +uint64_t shmem_laddr_to_shddr(void *addr) +{ + return ADDR_LTOSH(addr); +} diff --git a/stacks/lwip_stack/src/mem/lwip_mem_api.c b/stacks/lwip_stack/src/mem/lwip_mem_api.c new file mode 100644 index 0000000..72dd9e5 --- /dev/null +++ b/stacks/lwip_stack/src/mem/lwip_mem_api.c @@ -0,0 +1,86 @@ +/* +* +* Copyright (c) 2018 Huawei Technologies Co.,Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include <sys/types.h> +#include <unistd.h> +#include <dlfcn.h> +#include "nsfw_mem_api.h" +#include "nstack_securec.h" +#include "nsfw_ring_data.h" +#include "nsfw_init_api.h" +#include "nsfw_shmem_mng.h" + +#define NSFW_MEM_MBUF_CHECK_RET_ERR(mhandle, entype, desc) {\ + if ((NULL == mhandle) || (entype >= NSFW_MEM_TYPEMAX)) \ + { \ + NSRTP_LOGERR("input para error]desc=%s,mhandle=%p,mtype=%d", desc, mhandle, entype); \ + return NSFW_MEM_ERR; \ + } \ + } + +#define NSFW_MEM_MBUF_CHECK_RET_NULL(mhandle, entype, desc) {\ + if ((NULL == mhandle) || (entype >= NSFW_MEM_TYPEMAX)) \ + { \ + NSRTP_LOGERR("input para error]desc=%s,mhandle=%p,mtype=%d", desc, mhandle, entype); \ + return NULL; \ + } \ + } + +/***************************************************************************** +* Prototype : nsfw_mem_mbf_alloc +* Description : alloc a mbuf from mbuf pool +* Input : mpool_handle mhandle +* nsfw_mem_type entype +* Output : None +* Return Value : mbuf_handle +* Calls : +* Called By : +*****************************************************************************/ +mbuf_handle nsfw_mem_mbf_alloc(mpool_handle mhandle, nsfw_mem_type entype) +{ + if (entype == NSFW_SHMEM) + { + return nsfw_shmem_mbfalloc(mhandle); + } + + NSPOL_LOGINF(NS_LOG_STACKPOOL_ON, "mbf alloc fail] handle=%p, type=%d", + mhandle, entype); + return NULL; +} + +/***************************************************************************** +* Prototype : nsfw_mem_mbf_free +* Description : put a mbuf backintp mbuf pool +* Input : mbuf_handle mhandle +* nsfw_mem_type entype +* Output : None +* Return Value : i32 +* Calls : +* Called By : +* +*****************************************************************************/ +i32 nsfw_mem_mbf_free(mbuf_handle mhandle, nsfw_mem_type entype) +{ + if (entype == NSFW_SHMEM) + { + return nsfw_shmem_mbffree(mhandle); + } + + NSPOL_LOGINF(NS_LOG_STACKPOOL_ON, "mbf free fail] handle=%p, type=%d", + mhandle, entype); + return NSFW_MEM_ERR; + +} diff --git a/stacks/lwip_stack/src/mem/lwip_mem_desc.c b/stacks/lwip_stack/src/mem/lwip_mem_desc.c new file mode 100644 index 0000000..217649a --- /dev/null +++ b/stacks/lwip_stack/src/mem/lwip_mem_desc.c @@ -0,0 +1,80 @@ +/* +* +* Copyright (c) 2018 Huawei Technologies Co.,Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include <sys/types.h> +#include <unistd.h> +#include "nsfw_mem_api.h" +#include "nsfw_shmem_ring.h" +#include "nsfw_nshmem_ring.h" + +/* *INDENT-OFF* */ +nsfw_ring_ops g_ring_ops_arry_lwip[NSFW_MEM_TYPEMAX][NSFW_MPOOL_TYPEMAX] = { + { + { + (nsfw_mem_ring_enqueue_fun)nsfw_shmem_ring_sp_enqueue, \ + (nsfw_mem_ring_dequeue_fun)nsfw_shmem_ring_sc_dequeue, \ + (nsfw_mem_ring_dequeuev_fun)nsfw_shmem_ring_sc_dequeuev + }, + { + (nsfw_mem_ring_enqueue_fun)nsfw_shmem_ring_mp_enqueue, \ + (nsfw_mem_ring_dequeue_fun)nsfw_shmem_ring_sc_dequeue, \ + (nsfw_mem_ring_dequeuev_fun)nsfw_shmem_ring_sc_dequeuev + }, + { + (nsfw_mem_ring_enqueue_fun)nsfw_shmem_ring_sp_enqueue, \ + (nsfw_mem_ring_dequeue_fun)nsfw_shmem_ring_mc_dequeue, \ + (nsfw_mem_ring_dequeuev_fun)nsfw_shmem_ring_mc_dequeuev + }, + { + (nsfw_mem_ring_enqueue_fun)nsfw_shmem_ring_mp_enqueue, \ + (nsfw_mem_ring_dequeue_fun)nsfw_shmem_ring_mc_dequeue, \ + (nsfw_mem_ring_dequeuev_fun)nsfw_shmem_ring_mc_dequeuev + }, + { + (nsfw_mem_ring_enqueue_fun)nsfw_shmem_ring_singlethread_enqueue, \ + (nsfw_mem_ring_dequeue_fun)nsfw_shmem_ring_singlethread_dequeue, \ + (nsfw_mem_ring_dequeuev_fun)nsfw_shmem_ring_singlethread_dequeuev + } + }, + { + { + (nsfw_mem_ring_enqueue_fun)nsfw_nshmem_ring_sp_enqueue, \ + (nsfw_mem_ring_dequeue_fun)nsfw_nshmem_ring_sc_dequeue, \ + (nsfw_mem_ring_dequeuev_fun)nsfw_nshmem_ring_sc_dequeuev + }, + { + (nsfw_mem_ring_enqueue_fun)nsfw_nshmem_ring_mp_enqueue, \ + (nsfw_mem_ring_dequeue_fun)nsfw_nshmem_ring_sc_dequeue, \ + (nsfw_mem_ring_dequeuev_fun)nsfw_nshmem_ring_sc_dequeuev + }, + { + (nsfw_mem_ring_enqueue_fun)nsfw_nshmem_ring_sp_enqueue, \ + (nsfw_mem_ring_dequeue_fun)nsfw_nshmem_ring_mc_dequeue, \ + (nsfw_mem_ring_dequeuev_fun)nsfw_nshmem_ring_mc_dequeuev + }, + { + (nsfw_mem_ring_enqueue_fun)nsfw_nshmem_ring_mp_enqueue, \ + (nsfw_mem_ring_dequeue_fun)nsfw_nshmem_ring_mc_dequeue, \ + (nsfw_mem_ring_dequeuev_fun)nsfw_nshmem_ring_mc_dequeuev + }, + { + (nsfw_mem_ring_enqueue_fun)nsfw_nshmem_ring_singlethread_enqueue, \ + (nsfw_mem_ring_dequeue_fun)nsfw_nshmem_ring_singlethread_dequeue, \ + (nsfw_mem_ring_dequeuev_fun)nsfw_nshmem_ring_singlethread_dequeuev + } + } +}; +/* *INDENT-ON* */ diff --git a/stacks/lwip_stack/src/mem/nsfw_nshmem/nsfw_nshmem_mdesc.c b/stacks/lwip_stack/src/mem/nsfw_nshmem/nsfw_nshmem_mdesc.c new file mode 100644 index 0000000..1be5f82 --- /dev/null +++ b/stacks/lwip_stack/src/mem/nsfw_nshmem/nsfw_nshmem_mdesc.c @@ -0,0 +1,44 @@ +/* +* +* Copyright (c) 2018 Huawei Technologies Co.,Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "nsfw_mem_api.h" +#include "nsfw_nshmem_mng.h" +#include "nsfw_nshmem_mdesc.h" + +/*no share memory access inferface*/ +nsfw_mem_ops g_nshmem_ops = { + nsfw_nshmem_init, + nsfw_nshmem_destory, + nsfw_nshmem_create, + NULL, + nsfw_nshmem_lookup, + nsfw_nshmem_release, + NULL, + NULL, + NULL, + NULL, + nsfw_nshmem_spcreate, + NULL, + NULL, + nsfw_nshmem_sprelease, + nsfw_nshmem_sp_lookup, + nsfw_nshmem_ringcreate, + NULL, + nsfw_nshmem_ringrelease, + nsfw_nshmem_static, + NULL, /*mem_ops_sp_iterator */ + NULL, /*mem_ops_mbuf_iterator */ +}; diff --git a/stacks/lwip_stack/src/mem/nsfw_nshmem/nsfw_nshmem_mdesc.h b/stacks/lwip_stack/src/mem/nsfw_nshmem/nsfw_nshmem_mdesc.h new file mode 100644 index 0000000..1b63520 --- /dev/null +++ b/stacks/lwip_stack/src/mem/nsfw_nshmem/nsfw_nshmem_mdesc.h @@ -0,0 +1,22 @@ +/* +* +* Copyright (c) 2018 Huawei Technologies Co.,Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef _NSFW_NSHMEM_MDESC_H +#define _NSFW_NSHMEM_MDESC_H + +extern nsfw_mem_ops g_nshmem_ops; + +#endif diff --git a/stacks/lwip_stack/src/mem/nsfw_nshmem/nsfw_nshmem_mng.c b/stacks/lwip_stack/src/mem/nsfw_nshmem/nsfw_nshmem_mng.c new file mode 100644 index 0000000..a3c7f60 --- /dev/null +++ b/stacks/lwip_stack/src/mem/nsfw_nshmem/nsfw_nshmem_mng.c @@ -0,0 +1,529 @@ +/* +* +* Copyright (c) 2018 Huawei Technologies Co.,Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include <stdlib.h> +#include "nstack_log.h" +#include "nstack_securec.h" +#include "nsfw_mem_api.h" +#include "nsfw_ring_fun.h" +#include "nsfw_nshmem_ring.h" +#include "nsfw_nshmem_mng.h" + +#include "common_func.h" + +#define nsfw_get_glb_lock() (&g_nshmem_internal_cfg->mlock) + +#define NSFW_NSHMEM_INIT_CHK_RET_NULL() \ + if ((!g_nshmem_internal_cfg) || (!g_nshmem_localdata)) \ + { \ + NSRTP_LOGDBG("Error] g_nshmem_internal_cfg=%p, g_nshmem_localdata=%p", g_nshmem_internal_cfg, g_nshmem_localdata); \ + return NULL; \ + } + +#define NSFW_NSHMEM_INIT_CHK_RET() \ + if ((!g_nshmem_internal_cfg) || (!g_nshmem_localdata)) \ + { \ + NSRTP_LOGDBG("Error] g_nshmem_internal_cfg=%p, g_nshmem_localdata=%p", g_nshmem_internal_cfg, g_nshmem_localdata); \ + return NSFW_MEM_ERR; \ + } + +nsfw_mem_localdata *g_nshmem_localdata = NULL; +nsfw_nshmem_cfg *g_nshmem_internal_cfg = NULL; + +/*look up a mem zone*/ +NSTACK_STATIC inline nsfw_nshmem_mzone *nsfw_nshmem_get_free_zone(void) +{ + int icnt = 0; + + /*g_nshmem_internal_cfg must not be null if come here */ + for (icnt = 0; icnt < COMMON_MEM_MAX_MEMZONE; icnt++) + { + if (g_nshmem_internal_cfg->amemzone[icnt].addr == NULL) + { + return &g_nshmem_internal_cfg->amemzone[icnt]; + } + } + + return NULL; +} + +NSTACK_STATIC inline void nsfw_nshmem_free_zone(nsfw_nshmem_mzone * pzone) +{ + nsfw_nshmem_mzone *pzonebase = &g_nshmem_internal_cfg->amemzone[0]; + nsfw_nshmem_mzone *pzoneend = + &g_nshmem_internal_cfg->amemzone[NSFW_NSHMEM_ZONE_MAX - 1]; + + if ((((int) ((char *) pzone - (char *) pzonebase) < 0) + || ((int) ((char *) pzone - (char *) pzoneend) > 0)) + && ((unsigned int) ((char *) pzone - (char *) pzonebase) % + sizeof(nsfw_nshmem_mzone) != 0)) + { + NSRTP_LOGERR("nshmem free fail] mem=%p", pzone); + return; + } + if (pzone->addr) + { + free(pzone->addr); + } + pzone->addr = NULL; + + int ret = memset_s((void *) pzone, sizeof(nsfw_nshmem_mzone), 0, + sizeof(nsfw_nshmem_mzone)); + if (EOK != ret) + { + NSRTP_LOGERR("MEMSET_S failed] mem=%p, ret=%d", pzone, ret); + } + return; +} + +/***************************************************************************** +* Prototype : nsfw_nshmem_init +* Description : nsh module init +* Input : nsfw_mem_para* para +* Output : None +* Return Value : i32 +* Calls : +* Called By : +*****************************************************************************/ +i32 nsfw_nshmem_init(nsfw_mem_para * para) +{ + i32 iret = NSFW_MEM_OK; + NSRTP_LOGINF("nsfw nshmem init begin"); + g_nshmem_localdata = + (nsfw_mem_localdata *) malloc(sizeof(nsfw_mem_localdata)); + + if (NULL == g_nshmem_localdata) + { + NSRTP_LOGERR("nshmem init g_nshmem_localdata malloc fail"); + return NSFW_MEM_ERR; + } + + iret = + memset_s(g_nshmem_localdata, sizeof(nsfw_mem_localdata), 0, + sizeof(nsfw_mem_localdata)); + + if (EOK != iret) + { + NSRTP_LOGERR("nshmem init g_nshmem_localdata MEMSET_S fail"); + goto ERROR; + } + + g_nshmem_internal_cfg = + (nsfw_nshmem_cfg *) malloc(sizeof(nsfw_nshmem_cfg)); + + if (NULL == g_nshmem_internal_cfg) + { + NSRTP_LOGERR("nshmem init g_nshmem_internal_cfg malloc fail"); + goto ERROR; + } + + iret = + memset_s(g_nshmem_internal_cfg, sizeof(nsfw_nshmem_cfg), 0, + sizeof(nsfw_nshmem_cfg)); + + if (EOK != iret) + { + NSRTP_LOGERR("nshmem init g_nshmem_internal_cfg MEMSET_S fail"); + goto ERROR; + } + + g_nshmem_localdata->enflag = para->enflag; + NSRTP_LOGINF("nsfw nshmem init end"); + goto OK; + + ERROR: + iret = NSFW_MEM_ERR; + nsfw_nshmem_destory(); + return iret; + OK: + iret = NSFW_MEM_OK; + return iret; +} + +/* + * memory destory + */ +void nsfw_nshmem_destory(void) +{ + if (g_nshmem_localdata) + { + free(g_nshmem_localdata); + g_nshmem_localdata = NULL; + } + + if (g_nshmem_internal_cfg) + { + free(g_nshmem_internal_cfg); + g_nshmem_internal_cfg = NULL; + } + + return; +} + +/***************************************************************************** +* Prototype : nsfw_nshmem_reserv_safe +* Description : malloc a memory and save to memzone +* Input : const char* name +* size_t length +* Output : None +* Return Value : mzone_handle +* Calls : +* Called By : +* +*****************************************************************************/ +mzone_handle nsfw_nshmem_reserv_safe(const char *name, size_t length) +{ + void *addr = NULL; + i32 iret = NSFW_MEM_OK; + nsfw_nshmem_mzone *pmemzone = NULL; + + if (length <= 0) + { + return NULL; + } + + nsfw_write_lock(nsfw_get_glb_lock()); + + addr = malloc(length); + if (!addr) + { + NSRTP_LOGERR("nshmem malloc addr fail] addr=%p", addr); + nsfw_write_unlock(nsfw_get_glb_lock()); + return NULL; + } + + iret = memset_s(addr, length, 0, length); + if (EOK != iret) + { + NSRTP_LOGERR("nshmem malloc addr MEMSET_S fail] addr=%p", addr); + free(addr); + nsfw_write_unlock(nsfw_get_glb_lock()); + return NULL; + } + + pmemzone = nsfw_nshmem_get_free_zone(); + + if (!pmemzone) + { + NSRTP_LOGERR("nshmem get free zone fail"); + free(addr); + nsfw_write_unlock(nsfw_get_glb_lock()); + return NULL; + } + + pmemzone->addr = addr; + pmemzone->length = length; + /*name must be less than NSFW_MEM_APPNAME_LENGTH */ + if (EOK != + strcpy_s((char *) pmemzone->aname, sizeof(pmemzone->aname), name)) + { + NSRTP_LOGERR("STRCPY_S failed]name=%s", name); + free(addr); + nsfw_write_unlock(nsfw_get_glb_lock()); + return NULL; + } + + nsfw_write_unlock(nsfw_get_glb_lock()); + return addr; +} + +/* + * create no shared memory + * nsfw_mem_zone::stname no shared memory name + * nsfw_mem_zone::isize memory size + */ +mzone_handle nsfw_nshmem_create(nsfw_mem_zone * pinfo) +{ + + NSFW_NAME_LENCHECK_RET_NULL(pinfo->stname.aname, "nshmem create"); + NSFW_NSHMEM_INIT_CHK_RET_NULL(); + return nsfw_nshmem_reserv_safe(pinfo->stname.aname, pinfo->lenth); +} + +/***************************************************************************** +* Prototype : nsfw_nshmem_lookup +* Description : find a block memory by name +* Input : nsfw_mem_name* pname +* Output : None +* Return Value : mzone_handle +* Calls : +* Called By : +* +*****************************************************************************/ +mzone_handle nsfw_nshmem_lookup(nsfw_mem_name * pname) +{ + int icnt = 0; + nsfw_nshmem_mzone *mz = NULL; + + NSFW_NAME_LENCHECK_RET_NULL(pname->aname, "nshmem lookup"); + NSFW_NSHMEM_INIT_CHK_RET_NULL(); + nsfw_read_lock(nsfw_get_glb_lock()); + + for (icnt = 0; icnt < NSFW_NSHMEM_ZONE_MAX; icnt++) + { + mz = &g_nshmem_internal_cfg->amemzone[icnt]; + + if (mz->addr != NULL + && !strncmp(pname->aname, mz->aname, NSFW_MEM_NAME_LENTH)) + { + nsfw_read_unlock(nsfw_get_glb_lock()); + return mz->addr; + } + } + + nsfw_read_unlock(nsfw_get_glb_lock()); + return NULL; +} + +/***************************************************************************** +* Prototype : nsfw_nshmem_release +* Description : free a block memory +* Input : nsfw_mem_name* pname +* Output : None +* Return Value : i32 +* Calls : +* Called By : +* +*****************************************************************************/ +i32 nsfw_nshmem_release(nsfw_mem_name * pname) +{ + int icnt = 0; + nsfw_nshmem_mzone *mz = NULL; + + NSFW_NAME_LENCHECK_RET(pname->aname, "nshmem release"); + NSFW_NSHMEM_INIT_CHK_RET(); + nsfw_read_lock(nsfw_get_glb_lock()); + + for (icnt = 0; icnt < NSFW_NSHMEM_ZONE_MAX; icnt++) + { + mz = &g_nshmem_internal_cfg->amemzone[icnt]; + + if (mz->addr != NULL + && !strncmp(pname->aname, mz->aname, NSFW_MEM_NAME_LENTH)) + { + nsfw_nshmem_free_zone(mz); + nsfw_read_unlock(nsfw_get_glb_lock()); + return NSFW_MEM_OK; + } + } + + nsfw_read_unlock(nsfw_get_glb_lock()); + return NSFW_MEM_OK; + +} + +/***************************************************************************** +* Prototype : nsfw_nshmem_spcreate +* Description : create a memory pool by ring +* Input : nsfw_mem_sppool* pmpinfo +* Output : None +* Return Value : mring_handle +* Calls : +* Called By : +*****************************************************************************/ +mring_handle nsfw_nshmem_spcreate(nsfw_mem_sppool * pmpinfo) +{ + size_t len = 0; + unsigned int usnum = common_mem_align32pow2(pmpinfo->usnum + 1); + unsigned int uselt_size = pmpinfo->useltsize; + struct nsfw_mem_ring *pringhead = NULL; + unsigned int uscnt = 0; + char *pmz = NULL; + NSFW_NAME_LENCHECK_RET_NULL(pmpinfo->stname.aname, "nshmem sp create"); + NSFW_NSHMEM_INIT_CHK_RET_NULL(); + + len = + sizeof(struct nsfw_mem_ring) + + (size_t) usnum *sizeof(union RingData_U) + (size_t) usnum *uselt_size; + pringhead = + (struct nsfw_mem_ring *) nsfw_nshmem_reserv_safe(pmpinfo-> + stname.aname, len); + + if (!pringhead) + { + NSRTP_LOGERR("nshmem sp create mzone reserv fail"); + return NULL; + } + + nsfw_mem_ring_init(pringhead, usnum, pringhead, NSFW_NSHMEM, + pmpinfo->enmptype); + pmz = + ((char *) pringhead + sizeof(struct nsfw_mem_ring) + + usnum * sizeof(union RingData_U)); + + for (uscnt = 0; uscnt < usnum; uscnt++) + { + if (0 == + g_ring_ops_arry[pringhead->memtype][pringhead-> + ringflag].ring_ops_enqueue + (pringhead, (void *) pmz)) + { + NSRTP_LOGERR("nsfw_nshmem_ringenqueue enqueue fail] uscnt=%u", + uscnt); + } + + pmz = pmz + uselt_size; + } + + return pringhead; +} + +/***************************************************************************** +* Prototype : nsfw_nshmem_sp_lookup +* Description : look up a sppool memory +* Input : nsfw_mem_name* pname +* Output : None +* Return Value : mring_handle +* Calls : +* Called By : +*****************************************************************************/ +mring_handle nsfw_nshmem_sp_lookup(nsfw_mem_name * pname) +{ + return nsfw_nshmem_lookup(pname); +} + +/***************************************************************************** +* Prototype : nsfw_nshmem_sprelease +* Description : release a sp pool +* Input : nsfw_mem_name* pname +* Output : None +* Return Value : i32 +* Calls : +* Called By : +* +*****************************************************************************/ +i32 nsfw_nshmem_sprelease(nsfw_mem_name * pname) +{ + NSFW_NAME_LENCHECK_RET(pname->aname, "nshmem sp mempool release"); + NSFW_NSHMEM_INIT_CHK_RET(); + return nsfw_nshmem_release(pname); +} + +/***************************************************************************** +* Prototype : nsfw_nshmem_ringcreate +* Description : create a ring +* Input : nsfw_mem_mring* pringinfo +* Output : None +* Return Value : mring_handle +* Calls : +* Called By : +* +*****************************************************************************/ +mring_handle nsfw_nshmem_ringcreate(nsfw_mem_mring * pringinfo) +{ + size_t len = 0; + unsigned int usnum = common_mem_align32pow2(pringinfo->usnum + 1); + struct nsfw_mem_ring *pringhead = NULL; + NSFW_NAME_LENCHECK_RET_NULL(pringinfo->stname.aname, + "nshmem ring create"); + NSFW_NSHMEM_INIT_CHK_RET_NULL(); + + len = sizeof(struct nsfw_mem_ring) + usnum * sizeof(union RingData_U); + pringhead = + (struct nsfw_mem_ring *) nsfw_nshmem_reserv_safe(pringinfo-> + stname.aname, len); + + if (!pringhead) + { + NSRTP_LOGERR("nshmem ring create mzone reserv fail"); + return NULL; + } + + nsfw_mem_ring_init(pringhead, usnum, (void *) pringhead, NSFW_NSHMEM, + pringinfo->enmptype); + return pringhead; + +} + +/***************************************************************************** +* Prototype : nsfw_nshmem_ringrelease +* Description : release a nsh ring memory +* Input : nsfw_mem_name* pname +* Output : None +* Return Value : i32 +* Calls : +* Called By : +* +*****************************************************************************/ +i32 nsfw_nshmem_ringrelease(nsfw_mem_name * pname) +{ + NSFW_NAME_LENCHECK_RET(pname->aname, "nshmem ring mempool release"); + NSFW_NSHMEM_INIT_CHK_RET(); + return nsfw_nshmem_release(pname); +} + +/***************************************************************************** +* Prototype : nsfw_nshmem_sppool_statics +* Description : static the memory size of sppool +* Input : mring_handle sppool +* Output : None +* Return Value : ssize_t +* Calls : +* Called By : +* +*****************************************************************************/ +ssize_t nsfw_nshmem_sppool_statics(mring_handle sppool) +{ + struct nsfw_mem_ring *phead = (struct nsfw_mem_ring *) sppool; + + return sizeof(struct nsfw_mem_ring) + + (ssize_t) phead->size * sizeof(union RingData_U) + + (ssize_t) phead->size * phead->eltsize; +} + +/***************************************************************************** +* Prototype : nsfw_nshmem_ring_statics +* Description : static the memory size of ring +* Input : mring_handle handle +* Output : None +* Return Value : ssize_t +* Calls : +* Called By : +* +*****************************************************************************/ +ssize_t nsfw_nshmem_ring_statics(mring_handle handle) +{ + struct nsfw_mem_ring *ring = (struct nsfw_mem_ring *) handle; + return ring->size * sizeof(union RingData_U) + + sizeof(struct nsfw_mem_ring); +} + +/***************************************************************************** +* Prototype : nsfw_nshmem_static +* Description : static the memory size according to mem type +* Input : void* handle +* nsfw_mem_struct_type type +* Output : None +* Return Value : ssize_t +* Calls : +* Called By : +* +*****************************************************************************/ +ssize_t nsfw_nshmem_static(void *handle, nsfw_mem_struct_type type) +{ + switch (type) + { + case NSFW_MEM_MBUF: + return -1; + case NSFW_MEM_SPOOL: + return nsfw_nshmem_sppool_statics(handle); + case NSFW_MEM_RING: + return nsfw_nshmem_ring_statics(handle); + default: + break; + } + return -1; +} diff --git a/stacks/lwip_stack/src/mem/nsfw_nshmem/nsfw_nshmem_mng.h b/stacks/lwip_stack/src/mem/nsfw_nshmem/nsfw_nshmem_mng.h new file mode 100644 index 0000000..fa5bc6b --- /dev/null +++ b/stacks/lwip_stack/src/mem/nsfw_nshmem/nsfw_nshmem_mng.h @@ -0,0 +1,70 @@ +/* +* +* Copyright (c) 2018 Huawei Technologies Co.,Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef _NSFW_NSHMEM_MNG_H_ +#define _NSFW_NSHMEM_MNG_H_ + +#include "common_mem_rwlock.h" + +#include "common_func.h" + +#define NSFW_NSHMEM_ZONE_MAX 2560 + +typedef struct +{ + i8 aname[NSFW_MEM_NAME_LENTH]; + void *addr; + int length; +} nsfw_nshmem_mzone; + +typedef struct +{ + nsfw_nshmem_mzone amemzone[NSFW_NSHMEM_ZONE_MAX]; + common_mem_rwlock_t mlock; +} nsfw_nshmem_cfg; + +/* + * no share memory module init + */ +i32 nsfw_nshmem_init(nsfw_mem_para * para); + +/* + * no share memory module destory + */ +void nsfw_nshmem_destory(void); + +/* + * create a no shared memory + */ +mzone_handle nsfw_nshmem_create(nsfw_mem_zone * pinfo); + +mzone_handle nsfw_nshmem_lookup(nsfw_mem_name * pname); + +i32 nsfw_nshmem_release(nsfw_mem_name * pname); + +mring_handle nsfw_nshmem_spcreate(nsfw_mem_sppool * pmpinfo); + +i32 nsfw_nshmem_sprelease(nsfw_mem_name * pname); + +mring_handle nsfw_nshmem_sp_lookup(nsfw_mem_name * pname); + +mring_handle nsfw_nshmem_ringcreate(nsfw_mem_mring * pringinfo); + +i32 nsfw_nshmem_ringrelease(nsfw_mem_name * pname); + +ssize_t nsfw_nshmem_static(void *handle, nsfw_mem_struct_type type); + +#endif diff --git a/stacks/lwip_stack/src/mem/nsfw_nshmem/nsfw_nshmem_ring.c b/stacks/lwip_stack/src/mem/nsfw_nshmem/nsfw_nshmem_ring.c new file mode 100644 index 0000000..51f1fa4 --- /dev/null +++ b/stacks/lwip_stack/src/mem/nsfw_nshmem/nsfw_nshmem_ring.c @@ -0,0 +1,434 @@ +/* +* +* Copyright (c) 2018 Huawei Technologies Co.,Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include <string.h> +#include <sched.h> +#include "nstack_securec.h" + +#include "nsfw_mem_api.h" +#include "nsfw_nshmem_ring.h" +#include "nsfw_ring_fun.h" +#include "common_func.h" + +/*copy the data to obj*/ +NSTACK_STATIC inline void +nsfw_nshmem_ring_obj_copy(struct nsfw_mem_ring *r, uint32_t cons_head, + void **obj_table, unsigned n) +{ + uint32_t idx = cons_head & r->mask; + unsigned i = 0; + const uint32_t size = r->size; + + if (likely(idx + n < size)) + { + for (i = 0; i < (n & (~(unsigned) 0x3)); i += 4, idx += 4) + { + obj_table[i] = (void *) r->ring[idx].data_l; + obj_table[i + 1] = (void *) r->ring[idx + 1].data_l; + obj_table[i + 2] = (void *) r->ring[idx + 2].data_l; + obj_table[i + 3] = (void *) r->ring[idx + 3].data_l; + } + switch (n & 0x3) + { + case 3: + obj_table[i++] = (void *) r->ring[idx++].data_l; + + case 2: + obj_table[i++] = (void *) r->ring[idx++].data_l; + + case 1: + obj_table[i++] = (void *) r->ring[idx++].data_l; + } + } + else + { + for (i = 0; idx < size; i++, idx++) + { + obj_table[i] = (void *) r->ring[idx].data_l; + } + + for (idx = 0; i < n; i++, idx++) + { + obj_table[i] = (void *) r->ring[idx].data_l; + } + } +} + +/*fork recover*/ +NSTACK_STATIC inline void +nsfw_nshmem_enqueue_fork_recov(struct nsfw_mem_ring *r) +{ + u32_t pidflag = 0; + u32_t curpid = get_sys_pid(); + int success = 0; + /*if pid is not the same, maybe mult thread fork happen */ + pidflag = r->prodhflag; + + if (unlikely(pidflag != curpid)) + { + success = common_mem_atomic32_cmpset(&r->prodhflag, pidflag, curpid); + + if (unlikely(success != 0)) + { + /*recover it */ + if (r->prod.tail != r->prod.head) + { + r->prod.head = r->prod.tail; + } + + r->prodtflag = curpid; + } + } + + return; +} + +NSTACK_STATIC inline void +nsfw_nshmem_dequeue_fork_recov(struct nsfw_mem_ring *r) +{ + u32_t pidflag = 0; + u32_t curpid = get_sys_pid(); + int success = 0; + /*if pid is not the same, maybe mult thread fork happen */ + pidflag = r->conshflag; + + if (unlikely(pidflag != curpid)) + { + success = common_mem_atomic32_cmpset(&r->conshflag, pidflag, curpid); + + if (unlikely(success != 0)) + { + /*recover it */ + if (r->cons.tail != r->cons.head) + { + r->cons.head = r->cons.tail; + } + + r->constflag = curpid; + } + } + + return; +} + +/* +this is a multi thread/process enqueue function, please pay attention to the bellow point +1. while Enqueue corrupt, we may lose one element; because no one to add the Head +*/ +int +nsfw_nshmem_ring_mp_enqueue(struct nsfw_mem_ring *mem_ring, void *obj_table) +{ + uint32_t producer_head, producer_next; + uint32_t consumer_tail, free_entries; + int success; + unsigned rep = 0; + uint32_t mask = mem_ring->mask; + uint32_t size = mem_ring->size; + uint32_t n = 1; + + /* move prod.head atomically */ + do + { + + producer_head = mem_ring->prod.head; + consumer_tail = mem_ring->cons.tail; + /* The subtraction is done between two unsigned 32bits value + * (the result is always modulo 32 bits even if we have + * producer_head > consumer_tail). So 'free_entries' is always between 0 + * and size(ring)-1. */ + free_entries = (size + consumer_tail - producer_head); + + /* check that we have enough room in ring */ + if (unlikely(n > free_entries)) + { + return 0; + /* Below code is commented currenlty as its a dead code. */ + } + + /*if pid is not the same, maybe mult thread fork happen */ + nsfw_nshmem_enqueue_fork_recov(mem_ring); + + while (unlikely + ((mem_ring->prod.tail != mem_ring->prod.head) + || (mem_ring->prodtflag != mem_ring->prodhflag))) + { + common_mem_pause(); + } + + producer_next = producer_head + n; + success = + common_mem_atomic32_cmpset(&mem_ring->prod.head, producer_head, + producer_next); + } + while (unlikely(success == 0)); + + mem_ring->ring[producer_head & mask].data_l = (u64) obj_table; + + /* + * If there are other enqueues in progress that preceded us, + * we need to wait for them to complete + */ + while (unlikely(mem_ring->prod.tail != producer_head)) + { + common_mem_pause(); + + /* Set COMMON_RING_PAUSE_REP_COUNT to avoid spin too long waiting + * for other thread finish. It gives pre-emptied thread a chance + * to proceed and finish with ring dequeue operation. */ + /* check the queue can be operate */ + if (++rep == 5) + { + rep = 0; + (void) sched_yield(); + } + } + + mem_ring->prod.tail = producer_next; + return (int) n; +} + +/* + this is a single thread/process enqueue function + */ +int nsfw_nshmem_ring_sp_enqueue(struct nsfw_mem_ring *r, void *obj_table) +{ + uint32_t producer_head, consumer_tail; + uint32_t producer_next, free_entries; + uint32_t mask = r->mask; + uint32_t n = 1; + uint32_t size = r->size; + + producer_head = r->prod.head; + consumer_tail = r->cons.tail; + /* The subtraction is done between two unsigned 32bits value + * (the result is always modulo 32 bits even if we have + * producer_head > consumer_tail). So 'free_entries' is always between 0 + * and size(ring)-1. */ + free_entries = size + consumer_tail - producer_head; + + /* check that we have enough room in ring */ + if (unlikely(n > free_entries)) + { + return 0; + } + + nsfw_nshmem_enqueue_fork_recov(r); + + producer_next = producer_head + n; + r->prod.head = producer_next; + + r->ring[producer_head & mask].data_l = (u64) obj_table; + + r->prod.tail = producer_next; + return (int) n; +} + +/* + this is enhanced mc_ring_dequeue, support dequeue multi element one time. +*/ +int +nsfw_nshmem_ring_mc_dequeuev(struct nsfw_mem_ring *r, void **obj_table, + unsigned int n) +{ + uint32_t consumer_head, producer_tail; + uint32_t consumer_next, entries; + int success; + unsigned rep = 0; + uint32_t num = n; + + /* Avoid the unnecessary cmpset operation below, which is also + * potentially harmful when n equals 0. */ + if (unlikely(num == 0)) + { + return 0; + } + + nsfw_nshmem_dequeue_fork_recov(r); + + /* move cons.head atomically */ + do + { + num = n; + consumer_head = r->cons.head; + producer_tail = r->prod.tail; + /* The subtraction is done between two unsigned 32bits value + * (the result is always modulo 32 bits even if we have + * cons_head > prod_tail). So 'entries' is always between 0 + * and size(ring)-1. */ + entries = (producer_tail - consumer_head); + + /* Set the actual entries for dequeue */ + if (unlikely(num > entries)) + { + if (likely(entries > 0)) + { + num = entries; + } + else + { + return 0; + } + } + + /* check the queue can be operate */ + while (unlikely + ((r->cons.tail != r->cons.head) + || (r->conshflag != r->constflag))) + { + common_mem_pause(); + } + + consumer_next = consumer_head + num; + + success = + common_mem_atomic32_cmpset(&r->cons.head, consumer_head, + consumer_next); + } + while (unlikely(success == 0)); + + nsfw_nshmem_ring_obj_copy(r, consumer_head, obj_table, num); + + /* + * If there are other dequeues in progress that preceded us, + * we need to wait for them to complete + */ + while (unlikely(r->cons.tail != consumer_head)) + { + common_mem_pause(); + + /* Set COMMON_RING_PAUSE_REP_COUNT to avoid spin too long waiting + * for other thread finish. It gives pre-emptied thread a chance + * to proceed and finish with ring dequeue operation. */ + /* check the queue can be operate */ + if (++rep == 5) + { + rep = 0; + (void) sched_yield(); + } + } + + r->cons.tail = consumer_next; + + return (int) num; +} + +/*this is a multi thread/process dequeue function, please pay attention to the bellow point +1. while dequeue corrupt, the tail no one added, may multi the try times. +*/ +int nsfw_nshmem_ring_mc_dequeue(struct nsfw_mem_ring *ring, void **box) +{ + return nsfw_nshmem_ring_mc_dequeuev(ring, box, 1); +} + +/* + this is a single thread/process dequeue function +*/ +int +nsfw_nshmem_ring_sc_dequeuev(struct nsfw_mem_ring *r, void **obj_table, + unsigned int n) +{ + uint32_t consumer_head, producer_tail; + uint32_t consumer_next, entries; + uint32_t inum = n; + consumer_head = r->cons.head; + producer_tail = r->prod.tail; + /* The subtraction is done between two unsigned 32bits value + * (the result is always modulo 32 bits even if we have + * cons_head > prod_tail). So 'entries' is always between 0 + * and size(ring)-1. */ + entries = producer_tail - consumer_head; + + if (unlikely(inum > entries)) + { + if (likely(entries > 0)) + { + inum = entries; + } + else + { + return 0; + } + } + + nsfw_nshmem_dequeue_fork_recov(r); + + consumer_next = consumer_head + inum; + r->cons.head = consumer_next; + + nsfw_nshmem_ring_obj_copy(r, consumer_head, obj_table, inum); + + r->cons.tail = consumer_next; + return (int) inum; +} + +/* + this is enhanced mc_ring_dequeue, support dequeue multi element one time. +*/ +int nsfw_nshmem_ring_sc_dequeue(struct nsfw_mem_ring *ring, void **box) +{ + return nsfw_nshmem_ring_sc_dequeuev(ring, box, 1); +} + +/*stack just using one thread, for performance using que not support multi thread*/ +int +nsfw_nshmem_ring_singlethread_enqueue(struct nsfw_mem_ring *ring, void *box) +{ + u32 head = 0; + + /*if queue is full, just return 0 */ + if (unlikely(ring->prod.head >= (ring->size + ring->cons.tail))) + { + return 0; + } + + head = ring->prod.head; + ring->ring[head & ring->mask].data_l = (u64) box; + ring->prod.head++; + return 1; +} + +/*stack just using one thread, for performance using que not support multi thread*/ +int +nsfw_nshmem_ring_singlethread_dequeue(struct nsfw_mem_ring *ring, void **box) +{ + return nsfw_nshmem_ring_singlethread_dequeuev(ring, box, 1); +} + +/*stack just using one thread, for performance using que not support multi thread*/ +int +nsfw_nshmem_ring_singlethread_dequeuev(struct nsfw_mem_ring *ring, + void **box, unsigned int n) +{ + u32 tail = 0; + u32 num = 0; + + while (num < n) + { + tail = ring->cons.tail; + + /* if all entries are dequeued return 0 */ + if (unlikely(ring->prod.head == ring->cons.tail)) + { + return num; + } + + box[num] = (void *) ring->ring[tail & ring->mask].data_l; + ring->cons.tail++; + num++; + } + + return num; +} diff --git a/stacks/lwip_stack/src/mem/nsfw_nshmem/nsfw_nshmem_ring.h b/stacks/lwip_stack/src/mem/nsfw_nshmem/nsfw_nshmem_ring.h new file mode 100644 index 0000000..f7f7732 --- /dev/null +++ b/stacks/lwip_stack/src/mem/nsfw_nshmem/nsfw_nshmem_ring.h @@ -0,0 +1,38 @@ +/* +* +* Copyright (c) 2018 Huawei Technologies Co.,Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef _NSFW_NSHMEM_RING_H_ +#define _NSFW_NSHMEM_RING_H_ + +#include <stdint.h> +#include "nsfw_ring_data.h" + +int nsfw_nshmem_ring_mp_enqueue(struct nsfw_mem_ring *ring, void *box); +int nsfw_nshmem_ring_sp_enqueue(struct nsfw_mem_ring *ring, void *box); +int nsfw_nshmem_ring_mc_dequeue(struct nsfw_mem_ring *ring, void **box); +int nsfw_nshmem_ring_mc_dequeuev(struct nsfw_mem_ring *ring, void **box, + unsigned int n); +int nsfw_nshmem_ring_sc_dequeue(struct nsfw_mem_ring *ring, void **box); +int nsfw_nshmem_ring_sc_dequeuev(struct nsfw_mem_ring *ring, void **box, + unsigned int n); +int nsfw_nshmem_ring_singlethread_enqueue(struct nsfw_mem_ring *ring, + void *box); +int nsfw_nshmem_ring_singlethread_dequeue(struct nsfw_mem_ring *ring, + void **box); +int nsfw_nshmem_ring_singlethread_dequeuev(struct nsfw_mem_ring *ring, + void **box, unsigned int n); + +#endif /*_NSFW_NSHMEM_RING_H_*/ diff --git a/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_rshmem_mng.c b/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_rshmem_mng.c new file mode 100644 index 0000000..9016282 --- /dev/null +++ b/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_rshmem_mng.c @@ -0,0 +1,989 @@ +/* +* +* Copyright (c) 2018 Huawei Technologies Co.,Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include <stdint.h> +#include "nstack_securec.h" +#include "nstack_log.h" +#include "nsfw_ring_fun.h" +#include "nsfw_shmem_ring.h" +#include "nsfw_shmem_mng.h" +#include "common_mem_buf.h" +#include "common_mem_common.h" + +#include "common_func.h" +#include "common_pal_bitwide_adjust.h" + +/*get the base address of msg data */ +#define NSFW_SHMEM_GET_DATA(pmsg, type) (type *)&((pmsg)->aidata[0]) + +/*if input point is nun, just return null*/ +#define NSFW_POINT_CHK_RET_NULL(p, desc) \ + if (NULL == (p)) \ + { \ + NSRTP_LOGERR("point check fail] desc_para=%s", desc); \ + return NULL; \ + } + +/*if input point is nun, just return err num*/ +#define NSFW_POINT_CHK_RET_ERR(p, desc) \ + if (NULL == (p)) \ + { \ + NSRTP_LOGDBG("point check fail] desc_para=%s", desc); \ + return NSFW_MEM_ERR; \ + } + +/*if input point is nun, goto flag*/ +#define NSFW_POINT_CHK_RET_GOTO(p, gotoflag, desc) \ + if (NULL == (p)) \ + { \ + NSRTP_LOGERR("point check fail] desc_para=%s", desc); \ + goto gotoflag; \ + } + +/*init the msg head*/ +#define NSFW_SHMEM_MSG_HEAD_INIT(pmsg, type, length) { \ + (pmsg)->usmsg_type = (type); \ + (pmsg)->uslenth = (length); \ + } + +/*rsp msg head check, and if err goto*/ +#define NSFW_SHMEM_MSGHEAD_CHK_GOTO(pmsg, type, length, gotoflag) { \ + if (((type) != pmsg->usmsg_type) && ((length) != pmsg->uslenth)) \ + { \ + NSRTP_LOGERR("check fail] msgtype=%d, type_para=%d, len=%d", (pmsg->usmsg_type), (type), (length)); \ + goto gotoflag; \ + } \ + } + +/*rsp check the state*/ +#define NSFW_SHMEM_ACKSTATE_CHK_GOTO(expret, ret, expseg, seg, gotoflag) { \ + if (((ret) != (expret)) || ((expseg) != (seg))) \ + { \ + NSRTP_LOGERR("ackstate check fail]msgack exp=%d, real=%d,eseg=%d, rseg=%d", (expret), (ret), (expseg), (seg)); \ + goto gotoflag; \ + } \ + } + +/*mzone msg init*/ +#define NSFW_SHMEM_MZONE_DATA_INIT(pdata, slength, seg, socketid) { \ + (pdata)->isocket_id = (socketid); \ + (pdata)->lenth = (slength); \ + (pdata)->usseq = (seg); \ + (pdata)->ireserv = 0; \ + } + +/*mbuf msg init*/ +#define NSFW_SHMEM_MBUF_DATA_INIT(pdata, seg, num, cashsize, priv_size, data_room, flag, socketid) { \ + (pdata)->usseq = (seg); \ + (pdata)->usnum = (num); \ + (pdata)->uscash_size = (cashsize); \ + (pdata)->uspriv_size = (priv_size); \ + (pdata)->usdata_room = (data_room); \ + (pdata)->enmptype = (flag); \ + (pdata)->isocket_id = (socketid); \ + (pdata)->ireserv = 0; \ + } + +/*mpool msg init*/ +#define NSFW_SHMEM_MPOOL_DATA_INIT(pdata, seg, num, eltsize, flag, socketid) { \ + (pdata)->usseq = (seg); \ + (pdata)->usnum = (num); \ + (pdata)->useltsize = (eltsize); \ + (pdata)->enmptype = (flag); \ + (pdata)->isocket_id = (socketid); \ + (pdata)->ireserv = 0; \ + } + +/*mring msg init*/ +#define NSFW_SHMEM_MRING_DATA_INIT(pdata, seg, num, flag, socketid) { \ + (pdata)->usseq = (seg); \ + (pdata)->usnum = (num); \ + (pdata)->enmptype = (flag); \ + (pdata)->isocket_id = (socketid); \ + (pdata)->ireserv = 0; \ + } + +#define NSFW_SHMEM_MSG_FREE(pmsg, prsp_msg) {\ + if (pmsg) \ + { \ + nsfw_mgr_msg_free(pmsg); \ + } \ + if (prsp_msg) \ + { \ + nsfw_mgr_msg_free(prsp_msg); \ + } \ +} + +/* + * create a block memory by send a msg + * + */ +mzone_handle +nsfw_memzone_remote_reserv(const i8 * name, size_t mlen, i32 socket_id) +{ + /*msg point define */ + nsfw_mgr_msg *pmsg = NULL; + nsfw_mgr_msg *prsp_msg = NULL; + + /*msg head point define */ + nsfw_shmem_msg_head *pdata_head = NULL; + + /*msg data point define */ + nsfw_shmem_reserv_req *pdata = NULL; + nsfw_shmem_msg_head *pack_head = NULL; + + /*ack msg define */ + nsfw_shmem_ack *pack_data = NULL; + + mzone_handle hhandle = NULL; + u8 ucret = TRUE; + i32 iretval = NSFW_MEM_OK; + + //pmsg = nsfw_mgr_msg_alloc(MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MASTER); + pmsg = nsfw_mgr_msg_alloc(MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MAIN); + NSFW_POINT_CHK_RET_NULL(pmsg, "remote reserv pmsg alloc"); + + prsp_msg = nsfw_mgr_null_rspmsg_alloc(); + NSFW_POINT_CHK_RET_GOTO(prsp_msg, release, "remote reserv rspmsg alloc"); + + /*msg head init */ + pdata_head = GET_USER_MSG(nsfw_shmem_msg_head, pmsg); + NSFW_SHMEM_MSG_HEAD_INIT(pdata_head, NSFW_RESERV_REQ_MSG, + sizeof(nsfw_shmem_reserv_req)); + + /*msg data init */ + pdata = NSFW_SHMEM_GET_DATA(pdata_head, nsfw_shmem_reserv_req); + iretval = strcpy_s(pdata->aname, sizeof(pdata->aname), name); + if (EOK != iretval) + { + NSRTP_LOGERR("reserv mem copy name fail] ret=%d", iretval); + goto release; + } + + /*fill msg data */ + NSFW_SHMEM_MZONE_DATA_INIT(pdata, mlen, (u16) 0, socket_id); + + ucret = nsfw_mgr_send_req_wait_rsp(pmsg, prsp_msg); + + if (FALSE == ucret) + { + NSRTP_LOGERR("reserv mem req rsp fail] ret=%u", ucret); + goto release; + } + + /*interrupt msg head */ + pack_head = GET_USER_MSG(nsfw_shmem_msg_head, prsp_msg); + NSFW_SHMEM_MSGHEAD_CHK_GOTO(pack_head, NSFW_RESERV_ACK_MSG, + sizeof(nsfw_shmem_ack), release); + + pack_data = NSFW_SHMEM_GET_DATA(pack_head, nsfw_shmem_ack); + NSFW_SHMEM_ACKSTATE_CHK_GOTO(NSFW_MEM_ALLOC_SUCC, pack_data->cstate, 0, + pack_data->usseq, release); + + hhandle = (mzone_handle) ADDR_SHTOL(pack_data->pbase_addr); + NSRTP_LOGDBG("mem reserve] name=%s, handle=%p, seg=%u", name, hhandle, + pack_data->usseq); + release: + NSFW_SHMEM_MSG_FREE(pmsg, prsp_msg); + return hhandle; +} + +/* + *create some memories by send a msg + */ +i32 +nsfw_memzone_remote_reserv_v(nsfw_mem_zone * pmeminfo, + mzone_handle * paddr_array, i32 inum, pid_t pid) +{ + /*msg point define */ + nsfw_mgr_msg *pmsg = NULL; + nsfw_mgr_msg *prsp_msg = NULL; + nsfw_shmem_msg_head *pdata_head = NULL; + nsfw_shmem_reserv_req *pdata = NULL; + nsfw_shmem_reserv_req *ptempdata = NULL; + nsfw_shmem_msg_head *pack_head = NULL; + + nsfw_shmem_ack *pack_data = NULL; + u8 ucret = TRUE; + i32 iretval = NSFW_MEM_OK; + i32 icount = 0; + i32 itindex = 0; + i32 iindex = 0; + u16 ussegbase = 0; + u16 ustempv = 0; + i32 ieltnum = 0; + i32 ieltnum_max = + (NSFW_MGR_MSG_BODY_LEN - + sizeof(nsfw_shmem_msg_head)) / sizeof(nsfw_shmem_reserv_req); + + //pmsg = nsfw_mgr_msg_alloc(MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MASTER); + pmsg = nsfw_mgr_msg_alloc(MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MAIN); + NSFW_POINT_CHK_RET_GOTO(pmsg, err, "remote reserv_v msg alloc"); + + prsp_msg = nsfw_mgr_null_rspmsg_alloc(); + NSFW_POINT_CHK_RET_GOTO(prsp_msg, err, "remote reserv_v rspmsg alloc"); + + pdata_head = GET_USER_MSG(nsfw_shmem_msg_head, pmsg); + + ptempdata = pdata = + NSFW_SHMEM_GET_DATA(pdata_head, nsfw_shmem_reserv_req); + + do + { + icount++; + ieltnum++; + + if (((icount % ieltnum_max) == 0) || (icount >= inum)) + { + NSFW_SHMEM_MSG_HEAD_INIT(pdata_head, NSFW_RESERV_REQ_MSG, + ieltnum * sizeof(nsfw_shmem_reserv_req)); + + itindex = icount - 1; + int retVal = + sprintf_s(ptempdata->aname, sizeof(ptempdata->aname), "%s_%x", + pmeminfo[itindex].stname.aname, pid); + if (-1 == retVal) + { + NSRTP_LOGERR("SPRINTF_S failed]ret=%d", retVal); + } + NSFW_SHMEM_MZONE_DATA_INIT(ptempdata, pmeminfo[itindex].lenth, + (u16) itindex, + pmeminfo[itindex].isocket_id); + + ucret = nsfw_mgr_send_req_wait_rsp(pmsg, prsp_msg); + + if (FALSE == ucret) + { + NSRTP_LOGERR("reserv v mem req rsp fail] ret=%u", ucret); + goto err; + } + + pack_head = GET_USER_MSG(nsfw_shmem_msg_head, prsp_msg); + NSFW_SHMEM_MSGHEAD_CHK_GOTO(pack_head, NSFW_RESERV_ACK_MSG, + ieltnum * sizeof(nsfw_shmem_ack), + err); + + pack_data = NSFW_SHMEM_GET_DATA(pack_head, nsfw_shmem_ack); + + for (iindex = 0; iindex < ieltnum; iindex++) + { + ustempv = ussegbase + iindex; + + NSFW_SHMEM_ACKSTATE_CHK_GOTO(NSFW_MEM_ALLOC_SUCC, + pack_data->cstate, ustempv, + (u16) pack_data->usseq, err); + + paddr_array[ustempv] = ADDR_SHTOL(pack_data->pbase_addr); + NSRTP_LOGDBG("remote reserve]index=%u, seg=%u, handle=%p", + ustempv, pack_data->usseq, paddr_array[ustempv]); + pack_data++; + } + + ussegbase = icount; + ieltnum = 0; + ptempdata = pdata; + } + else + { + itindex = icount - 1; + int retVal = + sprintf_s(ptempdata->aname, sizeof(ptempdata->aname), "%s_%x", + pmeminfo[itindex].stname.aname, pid); + if (-1 == retVal) + { + NSRTP_LOGERR("SPRINTF_S failed]ret=%d", retVal); + } + NSFW_SHMEM_MZONE_DATA_INIT(ptempdata, pmeminfo[itindex].lenth, + (u16) itindex, + pmeminfo[itindex].isocket_id); + ptempdata++; + } + } + while (icount < inum); + + iretval = NSFW_MEM_OK; + goto free; + + err: + iretval = NSFW_MEM_ERR; + free: + NSFW_SHMEM_MSG_FREE(pmsg, prsp_msg); + return iretval; +} + +/* + *release a block memory with name by send msg + */ +i32 nsfw_remote_free(const i8 * name, nsfw_mem_struct_type entype) +{ + /*msg point define */ + nsfw_mgr_msg *pmsg = NULL; + nsfw_mgr_msg *prsp_msg = NULL; + + nsfw_shmem_msg_head *pdata_head = NULL; + + nsfw_shmem_free_req *pdata = NULL; + + nsfw_shmem_msg_head *pack_head = NULL; + nsfw_shmem_ack *pack_data = NULL; + u8 ucret = TRUE; + i32 iretval = NSFW_MEM_OK; + + pmsg = nsfw_mgr_msg_alloc(MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MAIN); + NSFW_POINT_CHK_RET_ERR(pmsg, "remote free msg alloc"); + + prsp_msg = nsfw_mgr_null_rspmsg_alloc(); + NSFW_POINT_CHK_RET_GOTO(prsp_msg, terr, "remote free rspmsg alloc"); + + pdata_head = GET_USER_MSG(nsfw_shmem_msg_head, pmsg); + NSFW_SHMEM_MSG_HEAD_INIT(pdata_head, NSFW_RELEASE_REQ_MSG, + sizeof(nsfw_shmem_free_req)); + + pdata = NSFW_SHMEM_GET_DATA(pdata_head, nsfw_shmem_free_req); + if (EOK != strcpy_s(pdata->aname, sizeof(pdata->aname), name)) + { + NSRTP_LOGERR("STRCPY_S failed]name=%s", name); + } + pdata->usseq = 0; + pdata->ustype = entype; + pdata->ireserv = 0; + + ucret = nsfw_mgr_send_req_wait_rsp(pmsg, prsp_msg); + + if (FALSE == ucret) + { + NSRTP_LOGERR("free mem req rsp fail] ret=%u", ucret); + goto release; + } + + pack_head = GET_USER_MSG(nsfw_shmem_msg_head, prsp_msg); + NSFW_SHMEM_MSGHEAD_CHK_GOTO(pack_head, NSFW_RELEASE_ACK_MSG, + sizeof(nsfw_shmem_ack), terr); + + pack_data = NSFW_SHMEM_GET_DATA(pack_head, nsfw_shmem_ack); + NSFW_SHMEM_ACKSTATE_CHK_GOTO(NSFW_MEM_ALLOC_SUCC, pack_data->cstate, 0, + pack_data->usseq, terr); + + iretval = NSFW_MEM_OK; + goto release; + terr: + iretval = NSFW_MEM_ERR; + release: + NSFW_SHMEM_MSG_FREE(pmsg, prsp_msg); + return iretval; +} + +/* + *create a mbuf pool by send a msg + */ +mpool_handle +nsfw_remote_shmem_mbf_create(const i8 * name, unsigned n, + unsigned cache_size, unsigned priv_size, + unsigned data_room_size, i32 socket_id, + nsfw_mpool_type entype) +{ + /*msg point define */ + nsfw_mgr_msg *pmsg = NULL; + nsfw_mgr_msg *prsp_msg = NULL; + nsfw_shmem_msg_head *pdata_head = NULL; + nsfw_shmem_mbuf_req *pdata = NULL; + nsfw_shmem_msg_head *tpack_head = NULL; + nsfw_shmem_ack *tpack_data = NULL; + mpool_handle hhandle = NULL; + u8 ucret = TRUE; + i32 iretval = NSFW_MEM_OK; + + pmsg = nsfw_mgr_msg_alloc(MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MAIN); + NSFW_POINT_CHK_RET_NULL(pmsg, "remote mbf create pmsg alloc"); + + prsp_msg = nsfw_mgr_null_rspmsg_alloc(); + NSFW_POINT_CHK_RET_GOTO(prsp_msg, release, "remote mbf create msg alloc"); + + pdata_head = GET_USER_MSG(nsfw_shmem_msg_head, pmsg); + NSFW_SHMEM_MSG_HEAD_INIT(pdata_head, NSFW_MBUF_REQ_MSG, + sizeof(nsfw_shmem_mbuf_req)); + + pdata = NSFW_SHMEM_GET_DATA(pdata_head, nsfw_shmem_mbuf_req); + iretval = strcpy_s(pdata->aname, sizeof(pdata->aname), name); + if (EOK != iretval) + { + NSRTP_LOGERR("mbf create name cpy fail] ret=%d", iretval); + goto release; + } + + NSFW_SHMEM_MBUF_DATA_INIT(pdata, 0, n, cache_size, priv_size, + data_room_size, (u16) entype, socket_id); + + ucret = nsfw_mgr_send_req_wait_rsp(pmsg, prsp_msg); + + if (FALSE == ucret) + { + NSRTP_LOGERR("mbf create mem req rsp fail] ret=%u", ucret); + goto release; + } + + tpack_head = GET_USER_MSG(nsfw_shmem_msg_head, prsp_msg); + NSFW_SHMEM_MSGHEAD_CHK_GOTO(tpack_head, NSFW_MBUF_ACK_MSG, + sizeof(nsfw_shmem_ack), release); + + tpack_data = NSFW_SHMEM_GET_DATA(tpack_head, nsfw_shmem_ack); + NSFW_SHMEM_ACKSTATE_CHK_GOTO(NSFW_MEM_ALLOC_SUCC, tpack_data->cstate, 0, + tpack_data->usseq, release); + + hhandle = ADDR_SHTOL(tpack_data->pbase_addr); + NSRTP_LOGDBG("mbf create] name=%s, handle=%p, seg=%u", name, hhandle, + tpack_data->usseq); + release: + NSFW_SHMEM_MSG_FREE(pmsg, prsp_msg); + return hhandle; +} + +/* + *create some mbuf pools + */ +i32 +nsfw_remote_shmem_mbf_createv(nsfw_mem_mbfpool * pmbfname, + mpool_handle * phandle_array, i32 inum, + pid_t pid) +{ + /*msg point define */ + nsfw_mgr_msg *mbpmsg = NULL; + nsfw_mgr_msg *prsp_msg = NULL; + nsfw_shmem_msg_head *pdata_head = NULL; + + nsfw_shmem_mbuf_req *pdata = NULL; + nsfw_shmem_mbuf_req *ptempdata = NULL; + + nsfw_shmem_msg_head *pack_head = NULL; + + nsfw_shmem_ack *pack_data = NULL; + mpool_handle hhandle = NULL; + u8 ucret = TRUE; + i32 iretval = NSFW_MEM_OK; + i32 icount = 0; + i32 itindex = 0; + i32 iindex = 0; + i32 isegbase = 0; + i32 ieltnum = 0; + i32 ieltnum_max = + (NSFW_MGR_MSG_BODY_LEN - + sizeof(nsfw_shmem_msg_head)) / sizeof(nsfw_shmem_mbuf_req); + + mbpmsg = nsfw_mgr_msg_alloc(MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MAIN); + NSFW_POINT_CHK_RET_GOTO(mbpmsg, lerr, "remote mbf createv msg alloc"); + + prsp_msg = nsfw_mgr_null_rspmsg_alloc(); + NSFW_POINT_CHK_RET_GOTO(prsp_msg, lerr, + "remote mbf createv rspmsg alloc"); + + pdata_head = GET_USER_MSG(nsfw_shmem_msg_head, mbpmsg); + + ptempdata = pdata = NSFW_SHMEM_GET_DATA(pdata_head, nsfw_shmem_mbuf_req); + + do + { + icount++; + ieltnum++; + + if (((icount % ieltnum_max) == 0) || (icount >= inum)) + { + NSFW_SHMEM_MSG_HEAD_INIT(pdata_head, NSFW_MBUF_REQ_MSG, + ieltnum * sizeof(nsfw_shmem_mbuf_req)); + + /*fill msg data */ + itindex = icount - 1; + if (-1 == + sprintf_s(ptempdata->aname, sizeof(ptempdata->aname), "%s_%x", + pmbfname[itindex].stname.aname, pid)) + { + NSRTP_LOGERR("SPRINTF_S failed]"); + goto lerr; + } + NSFW_SHMEM_MBUF_DATA_INIT(ptempdata, (u16) itindex, + pmbfname[itindex].usnum, + pmbfname[itindex].uscash_size, + pmbfname[itindex].uspriv_size, + pmbfname[itindex].usdata_room, + pmbfname[itindex].enmptype, + pmbfname[itindex].isocket_id); + + ucret = nsfw_mgr_send_req_wait_rsp(mbpmsg, prsp_msg); + + if (FALSE == ucret) + { + NSRTP_LOGERR("mbf createv mem req rsp fail] ret=%d", ucret); + goto lerr; + } + + /*interrupt msg head */ + pack_head = GET_USER_MSG(nsfw_shmem_msg_head, prsp_msg); + NSFW_SHMEM_MSGHEAD_CHK_GOTO(pack_head, NSFW_MBUF_ACK_MSG, + ieltnum * sizeof(nsfw_shmem_ack), + lerr); + + pack_data = NSFW_SHMEM_GET_DATA(pack_head, nsfw_shmem_ack); + + for (iindex = 0; iindex < ieltnum; iindex++) + { + NSFW_SHMEM_ACKSTATE_CHK_GOTO(NSFW_MEM_ALLOC_SUCC, + pack_data->cstate, + (isegbase + iindex), + (u16) pack_data->usseq, lerr); + phandle_array[isegbase + iindex] = + ADDR_SHTOL(pack_data->pbase_addr); + NSRTP_LOGDBG("mbf createv] seg=%d, handle=%p", + pack_data->usseq, hhandle); + pack_data++; + } + + isegbase = icount; + ieltnum = 0; + ptempdata = pdata; + } + else + { + itindex = icount - 1; + if (-1 == + sprintf_s(ptempdata->aname, sizeof(ptempdata->aname), "%s_%x", + pmbfname[itindex].stname.aname, pid)) + { + NSRTP_LOGERR("SPRINTF_S failed]"); + goto lerr; + } + NSFW_SHMEM_MBUF_DATA_INIT(ptempdata, (u16) itindex, + pmbfname[itindex].usnum, + pmbfname[itindex].uscash_size, + pmbfname[itindex].uspriv_size, + pmbfname[itindex].usdata_room, + pmbfname[itindex].enmptype, + pmbfname[itindex].isocket_id); + ptempdata++; + } + } + while (icount < inum); + + /*release memory */ + iretval = NSFW_MEM_OK; + goto release; + + lerr: + iretval = NSFW_MEM_ERR; + release: + NSFW_SHMEM_MSG_FREE(mbpmsg, prsp_msg); + return iretval; +} + +/* + *create a simpile pool + */ +mring_handle +nsfw_remote_shmem_mpcreate(const char *name, unsigned int n, + unsigned int elt_size, i32 socket_id, + nsfw_mpool_type entype) +{ + /*msg point define */ + nsfw_mgr_msg *pmsg = NULL; + nsfw_mgr_msg *prsp_msg = NULL; + nsfw_shmem_msg_head *pdata_head = NULL; + nsfw_shmem_sppool_req *pdata = NULL; + nsfw_shmem_msg_head *mppack_head = NULL; + nsfw_shmem_ack *mppack_data = NULL; + mring_handle hhandle = NULL; + u8 ucret = TRUE; + i32 iretval = NSFW_MEM_OK; + + pmsg = nsfw_mgr_msg_alloc(MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MAIN); + NSFW_POINT_CHK_RET_NULL(pmsg, "remote mbf mpcreate pmsg alloc"); + + prsp_msg = nsfw_mgr_null_rspmsg_alloc(); + NSFW_POINT_CHK_RET_GOTO(prsp_msg, release, + "remote mpcreate rspmsg alloc"); + + /*init msg head */ + pdata_head = GET_USER_MSG(nsfw_shmem_msg_head, pmsg); + NSFW_SHMEM_MSG_HEAD_INIT(pdata_head, NSFW_SPPOOL_REQ_MSG, + sizeof(nsfw_shmem_sppool_req)); + + /*fill msg data */ + pdata = NSFW_SHMEM_GET_DATA(pdata_head, nsfw_shmem_sppool_req); + iretval = strcpy_s(pdata->aname, sizeof(pdata->aname), name); + if (EOK != iretval) + { + NSRTP_LOGERR("mp create copy name fail] ret=%d", iretval); + goto release; + } + + /*fill msg data */ + NSFW_SHMEM_MPOOL_DATA_INIT(pdata, 0, n, elt_size, entype, socket_id); + + ucret = nsfw_mgr_send_req_wait_rsp(pmsg, prsp_msg); + + if (FALSE == ucret) + { + NSRTP_LOGERR("mp create rsp fail] ret=%d", ucret); + goto release; + } + + /*get msg head */ + mppack_head = GET_USER_MSG(nsfw_shmem_msg_head, prsp_msg); + NSFW_SHMEM_MSGHEAD_CHK_GOTO(mppack_head, NSFW_SPPOOL_ACK_MSG, + sizeof(nsfw_shmem_ack), release); + + mppack_data = NSFW_SHMEM_GET_DATA(mppack_head, nsfw_shmem_ack); + NSFW_SHMEM_ACKSTATE_CHK_GOTO(NSFW_MEM_ALLOC_SUCC, mppack_data->cstate, 0, + mppack_data->usseq, release); + + hhandle = ADDR_SHTOL(mppack_data->pbase_addr); + NSRTP_LOGDBG("mpcreate] name=%s, handle=%p, seg=%d", name, hhandle, + mppack_data->usseq); + release: + NSFW_SHMEM_MSG_FREE(pmsg, prsp_msg); + return hhandle; +} + +/* + *create some simpile pools by send a msg + */ +i32 +nsfw_remote_shmem_mpcreatev(nsfw_mem_sppool * pmpinfo, + mring_handle * pringhandle_array, i32 inum, + pid_t pid) +{ + /*msg point define */ + nsfw_mgr_msg *pmsg = NULL; + nsfw_mgr_msg *prsp_msg = NULL; + + /*msg head define */ + nsfw_shmem_msg_head *pdata_head = NULL; + + /*msg data define */ + nsfw_shmem_sppool_req *pdata = NULL; + nsfw_shmem_sppool_req *ptempdata = NULL; + + /*ack msg define */ + nsfw_shmem_msg_head *pack_head = NULL; + + nsfw_shmem_ack *pack_data = NULL; + mring_handle hhandle = NULL; + u8 ucret = TRUE; + i32 iretval = NSFW_MEM_OK; + i32 icount = 0; + i32 itindex = 0; + i32 iindex = 0; + i32 isegbase = 0; + i32 ieltnum = 0; + /*the max members that a msg can take */ + i32 ieltnum_max = + (NSFW_MGR_MSG_BODY_LEN - + sizeof(nsfw_shmem_msg_head)) / sizeof(nsfw_shmem_sppool_req); + + /*alloc a msg */ + //pmsg = nsfw_mgr_msg_alloc(MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MASTER); + pmsg = nsfw_mgr_msg_alloc(MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MAIN); + NSFW_POINT_CHK_RET_GOTO(pmsg, mperr, "remote mpcreatev pmsg alloc"); + + /*alloc rsp msg */ + prsp_msg = nsfw_mgr_null_rspmsg_alloc(); + NSFW_POINT_CHK_RET_GOTO(prsp_msg, mperr, "remote mpcreatev rspmsg alloc"); + + pdata_head = GET_USER_MSG(nsfw_shmem_msg_head, pmsg); + + ptempdata = pdata = + NSFW_SHMEM_GET_DATA(pdata_head, nsfw_shmem_sppool_req); + + do + { + icount++; + ieltnum++; + + /*if the element num reach the bigest, or already send all, just deal */ + if (((icount % ieltnum_max) == 0) || (icount >= inum)) + { + /*init msg header */ + NSFW_SHMEM_MSG_HEAD_INIT(pdata_head, NSFW_SPPOOL_REQ_MSG, + ieltnum * sizeof(nsfw_shmem_sppool_req)); + + /*fill the msg data */ + itindex = icount - 1; + + int retVal = + sprintf_s(ptempdata->aname, sizeof(ptempdata->aname), "%s_%x", + pmpinfo[itindex].stname.aname, pid); + if (-1 == retVal) + { + NSRTP_LOGERR("SPRINTF_S fail]ret=%d", retVal); + goto mperr; + } + NSFW_SHMEM_MPOOL_DATA_INIT(ptempdata, itindex, + pmpinfo[itindex].usnum, + pmpinfo[itindex].useltsize, + pmpinfo[itindex].enmptype, + pmpinfo[itindex].isocket_id); + + ucret = nsfw_mgr_send_req_wait_rsp(pmsg, prsp_msg); + + if (FALSE == ucret) + { + NSRTP_LOGERR("mpcreatev create fail] ret=%u", ucret); + goto mperr; + } + + /*interrupt mgs head */ + pack_head = GET_USER_MSG(nsfw_shmem_msg_head, prsp_msg); + NSFW_SHMEM_MSGHEAD_CHK_GOTO(pack_head, NSFW_SPPOOL_ACK_MSG, + ieltnum * sizeof(nsfw_shmem_ack), + mperr); + + pack_data = NSFW_SHMEM_GET_DATA(pack_head, nsfw_shmem_ack); + + for (iindex = 0; iindex < ieltnum; iindex++) + { + NSFW_SHMEM_ACKSTATE_CHK_GOTO(NSFW_MEM_ALLOC_SUCC, + pack_data->cstate, + (isegbase + iindex), + (u16) pack_data->usseq, mperr); + pringhandle_array[isegbase + iindex] = + ADDR_SHTOL(pack_data->pbase_addr); + NSRTP_LOGDBG("mpcreatev] seg=%u, handle=%p", pack_data->usseq, + hhandle); + pack_data++; + } + + isegbase = icount; + ieltnum = 0; + ptempdata = pdata; + } + else + { + itindex = icount - 1; + int retVal = + sprintf_s(ptempdata->aname, sizeof(ptempdata->aname), "%s_%x", + pmpinfo[itindex].stname.aname, pid); + if (-1 == retVal) + { + NSRTP_LOGERR("SPRINTF_S fail]ret=%d", retVal); + goto mperr; + } + NSFW_SHMEM_MPOOL_DATA_INIT(ptempdata, itindex, + pmpinfo[itindex].usnum, + pmpinfo[itindex].useltsize, + pmpinfo[itindex].enmptype, + pmpinfo[itindex].isocket_id); + + ptempdata++; + } + } + while (icount < inum); + + /*release the memory */ + iretval = NSFW_MEM_OK; + goto release; + + mperr: + iretval = NSFW_MEM_ERR; + release: + NSFW_SHMEM_MSG_FREE(pmsg, prsp_msg); + return iretval; +} + +/* + *create a ring + */ +mring_handle +nsfw_remote_shmem_ringcreate(const char *name, unsigned int n, i32 socket_id, + nsfw_mpool_type entype) +{ + /*msg point define */ + nsfw_mgr_msg *pmsg = NULL; + nsfw_mgr_msg *prsp_msg = NULL; + + /*msg head define */ + nsfw_shmem_msg_head *pdata_head = NULL; + + /*msg data define */ + nsfw_shmem_ring_req *pdata = NULL; + /*ack msg define */ + nsfw_shmem_msg_head *pack_head = NULL; + nsfw_shmem_ack *ppack_data = NULL; + mring_handle hhandle = NULL; + u8 ucret = TRUE; + i32 iretval = NSFW_MEM_OK; + + //pmsg = nsfw_mgr_msg_alloc(MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MASTER); + pmsg = nsfw_mgr_msg_alloc(MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MAIN); + NSFW_POINT_CHK_RET_NULL(pmsg, "remote ringcreate pmsg alloc"); + + prsp_msg = nsfw_mgr_null_rspmsg_alloc(); + NSFW_POINT_CHK_RET_GOTO(prsp_msg, release, + "remote ringcreate rspmsg alloc"); + + /*fill msg head */ + pdata_head = GET_USER_MSG(nsfw_shmem_msg_head, pmsg); + NSFW_SHMEM_MSG_HEAD_INIT(pdata_head, NSFW_RING_REQ_MSG, + sizeof(nsfw_shmem_ring_req)); + + /*fill msg data */ + pdata = NSFW_SHMEM_GET_DATA(pdata_head, nsfw_shmem_ring_req); + iretval = strcpy_s(pdata->aname, sizeof(pdata->aname), name); + if (EOK != iretval) + { + NSRTP_LOGERR("ring create cpy name fail] ret=%d", iretval); + goto release; + } + + /*fill msg data */ + NSFW_SHMEM_MRING_DATA_INIT(pdata, 0, n, entype, socket_id); + + ucret = nsfw_mgr_send_req_wait_rsp(pmsg, prsp_msg); + + if (FALSE == ucret) + { + NSRTP_LOGERR("ring create rsp fail] ret=%d", ucret); + goto release; + } + + /*interrupt mgs head */ + pack_head = GET_USER_MSG(nsfw_shmem_msg_head, prsp_msg); + NSFW_SHMEM_MSGHEAD_CHK_GOTO(pack_head, NSFW_RING_ACK_MSG, + sizeof(nsfw_shmem_ack), release); + + ppack_data = NSFW_SHMEM_GET_DATA(pack_head, nsfw_shmem_ack); + NSFW_SHMEM_ACKSTATE_CHK_GOTO(NSFW_MEM_ALLOC_SUCC, ppack_data->cstate, 0, + ppack_data->usseq, release); + + hhandle = ADDR_SHTOL(ppack_data->pbase_addr); + NSRTP_LOGDBG("ring create] name=%s, handle=%p, seg=%u", name, hhandle, + ppack_data->usseq); + release: + NSFW_SHMEM_MSG_FREE(pmsg, prsp_msg); + return hhandle; +} + +/* + *create a mem pool that the members are rings by send a msg + *ieltnum:the num of ring member + *iringnum:the num of ring in simple mem pool + *entype:the default the of ring + */ +i32 +nsfw_remote_shmem_ringcreatev(const char *name, i32 ieltnum, + mring_handle * pringhandle_array, i32 iringnum, + i32 socket_id, nsfw_mpool_type entype) +{ + unsigned int useltsize = 0; + mring_handle nhandle = NULL; + i32 icount = 0; + i32 n = 0; + uint64_t baseaddr = 0; + uint64_t endaddr = 0; + /*the num of ring member must be power of 2 */ + unsigned int usnum = common_mem_align32pow2(ieltnum + 1); + + useltsize = + sizeof(struct nsfw_mem_ring) + usnum * sizeof(union RingData_U); + nhandle = + nsfw_remote_shmem_mpcreate(name, iringnum, useltsize, socket_id, + NSFW_MRING_SPSC); + NSFW_POINT_CHK_RET_ERR(nhandle, "remote ringcreatev msg alloc"); + + n = nsfw_shmem_ring_sc_dequeuev(nhandle, (void **) pringhandle_array, + iringnum); + + if (n != iringnum) + { + NSRTP_LOGERR("ring dequeue fail] ringnum=%d, retnum=%d", iringnum, n); + return NSFW_MEM_ERR; + } + + nsfw_shmem_ring_baseaddr_query(&baseaddr, &endaddr); + + for (icount = 0; icount < iringnum; icount++) + { + nsfw_mem_ring_init(pringhandle_array[icount], usnum, + (void *) baseaddr, NSFW_SHMEM, entype); + } + + return NSFW_MEM_OK; +} + +/* + *look up a msg by send a msg + */ +void *nsfw_remote_shmem_lookup(const i8 * name, nsfw_mem_struct_type entype) +{ + /*msg point define */ + nsfw_mgr_msg *pmsg = NULL; + nsfw_mgr_msg *prsp_msg = NULL; + void *addr = NULL; + /*msg head data define */ + nsfw_shmem_msg_head *pdata_head = NULL; + + /*msg data define */ + nsfw_shmem_lookup_req *pdata = NULL; + + /*ack msg define */ + nsfw_shmem_msg_head *pack_head = NULL; + nsfw_shmem_ack *lpack_data = NULL; + u8 ucret = TRUE; + + pmsg = nsfw_mgr_msg_alloc(MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MAIN); + NSFW_POINT_CHK_RET_NULL(pmsg, "remote lookup pmsg alloc"); + + prsp_msg = nsfw_mgr_null_rspmsg_alloc(); + NSFW_POINT_CHK_RET_GOTO(prsp_msg, perr, "remote lookup rspmsg alloc"); + + /*msg head init */ + pdata_head = GET_USER_MSG(nsfw_shmem_msg_head, pmsg); + NSFW_SHMEM_MSG_HEAD_INIT(pdata_head, NSFW_MEM_LOOKUP_REQ_MSG, + sizeof(nsfw_shmem_lookup_req)); + + pdata = NSFW_SHMEM_GET_DATA(pdata_head, nsfw_shmem_lookup_req); + if (EOK != strcpy_s(pdata->aname, sizeof(pdata->aname), name)) + { + NSRTP_LOGERR("STRCPY_S failed]name=%s", name); + } + pdata->usseq = 0; + pdata->ustype = entype; + pdata->ireserv = 0; + + ucret = nsfw_mgr_send_req_wait_rsp(pmsg, prsp_msg); + + if (FALSE == ucret) + { + NSRTP_LOGERR("mem lookup fail] ret=%u", ucret); + goto release; + } + + /*interrupt mgs head */ + pack_head = GET_USER_MSG(nsfw_shmem_msg_head, prsp_msg); + NSFW_SHMEM_MSGHEAD_CHK_GOTO(pack_head, NSFW_MEM_LOOKUP_ACK_MSG, + sizeof(nsfw_shmem_ack), perr); + + lpack_data = NSFW_SHMEM_GET_DATA(pack_head, nsfw_shmem_ack); + NSFW_SHMEM_ACKSTATE_CHK_GOTO(NSFW_MEM_ALLOC_SUCC, lpack_data->cstate, 0, + lpack_data->usseq, perr); + + addr = ADDR_SHTOL(lpack_data->pbase_addr); + NSRTP_LOGDBG("shmem lookup] name=%s, handle=%p, seg=%u", name, addr, + lpack_data->usseq); + goto release; + perr: + addr = NULL; + + release: + NSFW_SHMEM_MSG_FREE(pmsg, prsp_msg); + return addr; +} diff --git a/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_rshmem_mng.h b/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_rshmem_mng.h new file mode 100644 index 0000000..0ae5cd5 --- /dev/null +++ b/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_rshmem_mng.h @@ -0,0 +1,51 @@ +/* +* +* Copyright (c) 2018 Huawei Technologies Co.,Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef _NSFW_RSHMEM_MNG_H +#define _NSFW_RSHMEM_MNG_H + +mzone_handle nsfw_memzone_remote_reserv(const i8 * name, size_t mlen, + i32 socket_id); +i32 nsfw_memzone_remote_reserv_v(nsfw_mem_zone * pmeminfo, + mzone_handle * paddr_array, i32 inum, + pid_t pid); +i32 nsfw_remote_free(const i8 * name, nsfw_mem_struct_type entype); +mpool_handle nsfw_remote_shmem_mbf_create(const i8 * name, unsigned int n, + unsigned cache_size, + unsigned priv_size, + unsigned data_room_size, + i32 socket_id, + nsfw_mpool_type entype); +i32 nsfw_remote_shmem_mbf_createv(nsfw_mem_mbfpool * pmbfname, + mpool_handle * phandle_array, i32 inum, + pid_t pid); +mring_handle nsfw_remote_shmem_mpcreate(const char *name, unsigned int n, + unsigned int elt_size, i32 socket_id, + nsfw_mpool_type entype); +i32 nsfw_remote_shmem_mpcreatev(nsfw_mem_sppool * pmpinfo, + mring_handle * pringhandle_array, i32 inum, + pid_t pid); +mring_handle nsfw_remote_shmem_ringcreate(const char *name, unsigned int n, + i32 socket_id, + nsfw_mpool_type entype); +i32 nsfw_remote_shmem_ringcreatev(const char *name, i32 ieltnum, + mring_handle * pringhandle_array, + i32 iringnum, i32 socket_id, + nsfw_mpool_type entype); + +void *nsfw_remote_shmem_lookup(const i8 * name, nsfw_mem_struct_type entype); + +#endif diff --git a/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_mdesc.c b/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_mdesc.c new file mode 100644 index 0000000..3d4dd42 --- /dev/null +++ b/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_mdesc.c @@ -0,0 +1,48 @@ +/* +* +* Copyright (c) 2018 Huawei Technologies Co.,Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "nsfw_mem_api.h" +#include "nsfw_shmem_mng.h" +#include "nsfw_shmem_mdesc.h" +#include "common_pal_bitwide_adjust.h" +/*the inferaces accessing memory*/ +nsfw_mem_ops g_shmem_ops = { + nsfw_shmem_init, + nsfw_shmem_destroy, + nsfw_shmem_create, + nsfw_shmem_createv, + nsfw_shmem_lookup, + nsfw_shmem_release, + nsfw_shmem_mbfmpcreate, + nsfw_shmem_mbfmpcreatev, + nsfw_shmem_mbfmplookup, + nsfw_shmem_mbfmprelease, + nsfw_shmem_spcreate, + nsfw_shmem_spcreatev, + nswf_shmem_sp_ringcreate, + nsfw_shmem_sprelease, + nsfw_shmem_sp_lookup, + nsfw_shmem_ringcreate, + nsfw_shmem_ring_lookup, + nsfw_shmem_ringrelease, + nsfw_shmem_static, + nsfw_shmem_sp_iterator, + nsfw_shmem_mbuf_iterator, + NULL, + shmem_shddr_to_laddr, + shmem_laddr_to_shddr, + nsfw_attach_core_id +}; diff --git a/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_mdesc.h b/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_mdesc.h new file mode 100644 index 0000000..afd9e29 --- /dev/null +++ b/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_mdesc.h @@ -0,0 +1,22 @@ +/* +* +* Copyright (c) 2018 Huawei Technologies Co.,Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef _NSFW_SHMEM_MDESC_H_ +#define _NSFW_SHMEM_MDESC_H_ + +extern nsfw_mem_ops g_shmem_ops; + +#endif diff --git a/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_mng.c b/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_mng.c new file mode 100644 index 0000000..1066b9a --- /dev/null +++ b/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_mng.c @@ -0,0 +1,800 @@ +/* +* +* Copyright (c) 2018 Huawei Technologies Co.,Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "nstack_securec.h" +#include "nstack_log.h" +#include "nsfw_mem_api.h" +#include "nsfw_ring_fun.h" +#include "nsfw_shmem_ring.h" +#include "nsfw_shmem_mng.h" +#include "common_mem_mempool.h" +#include "common_mem_memzone.h" +#include "common_mem_buf.h" +#include "common_mem_mbuf.h" +#include "nsfw_rshmem_mng.h" +#include "common_mem_api.h" +#include "common_sys_config.h" +#include "nsfw_maintain_api.h" +#include "common_pal_bitwide_adjust.h" + +#include "common_func.h" + +#define NSFW_SHMEM_PID (get_sys_pid()) +#define NSFW_SHMEM_FLAG (g_shmem_localdata->enflag) + +/* app_mode 1: simple stack with APP*/ +extern u8 app_mode; +u8 app_mode = 0; + +nsfw_mem_localdata *g_shmem_localdata = NULL; + +/*check g_mem_localdata*/ +#define NSFW_INIT_CHK_RET() \ + if (!g_shmem_localdata) \ + { \ + return NSFW_MEM_ERR; \ + } + +#define NSFW_INIT_CHK_RET_NULL() \ + if (!g_shmem_localdata) \ + { \ + return NULL; \ + } + +/* + *share memory mng module init + * + */ +i32 nsfw_shmem_init(nsfw_mem_para * para) +{ + common_mem_pal_module_info rteinfo = { 0 }; + i32 iret = NSFW_MEM_ERR; + int flag = 0; + if (!para) + { + return NSFW_MEM_ERR; + } + + NSRTP_LOGINF("nsfw shmem init begin"); + + LCORE_MASK_SET(rteinfo.ilcoremask, 1); + rteinfo.ucproctype = DMM_PROC_T_SECONDARY; + iret = common_pal_module_init(para, &rteinfo, app_mode); + + if (DMM_MBUF_RET_OK != iret) + { + NSRTP_LOGERR("rte init fail] ret=0x%x", iret); + return NSFW_MEM_ERR; + } + + flag = dmm_pal_addr_align(); + if ((0 == flag) && (NSFW_PROC_MAIN == para->enflag)) + { + dmm_addr_print(); + NSRTP_LOGERR + ("rte init addr is not the same with primary] nstackmain flag=%d", + flag); + return NSFW_MEM_ERR; + } + + g_shmem_localdata = + (nsfw_mem_localdata *) malloc(sizeof(nsfw_mem_localdata)); + + if (NULL == g_shmem_localdata) + { + NSRTP_LOGERR("g_shmem_localdata malloc fail"); + return NSFW_MEM_ERR; + } + + iret = + memset_s(g_shmem_localdata, sizeof(nsfw_mem_localdata), 0, + sizeof(nsfw_mem_localdata)); + if (EOK != iret) + { + NSRTP_LOGERR("memset fail] g_shmem_localdata=%p ", g_shmem_localdata); + free(g_shmem_localdata); + g_shmem_localdata = NULL; + return NSFW_MEM_ERR; + } + + g_shmem_localdata->enflag = para->enflag; + + NSRTP_LOGINF("nsfw shmem init end] enflag=%d", para->enflag); + return NSFW_MEM_OK; + +} + +/* + *module destroy + */ +void nsfw_shmem_destroy(void) +{ + if (g_shmem_localdata) + { + free(g_shmem_localdata); + g_shmem_localdata = NULL; + } + + return; +} + +/* + * create a shared memory + * nsfw_mem_zone::stname memory name + * nsfw_mem_zone::isize + */ +mzone_handle nsfw_shmem_create(nsfw_mem_zone * pinfo) +{ + i8 aname[COMMON_MEM_MEMPOOL_NAMESIZE] = { 0 }; + + NSFW_INIT_CHK_RET_NULL()if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG) + { + return common_memzone_data_reserve_name(pinfo->stname.aname, + pinfo->lenth, + pinfo->isocket_id); + } + else + { + /*app must less than NSFW_MEM_APPNAME_LENGTH */ + NSFW_NAME_LENCHECK_RET_NULL(pinfo->stname.aname, "shmem create") + if (-1 == + sprintf_s(aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s_%x", + pinfo->stname.aname, NSFW_SHMEM_PID)) + { + NSRTP_LOGERR("SPRINTF_S failed]"); + return NULL; + } + } + + return nsfw_memzone_remote_reserv((char *) &aname[0], pinfo->lenth, + SOCKET_ID_ANY); +} + +/* + *create some memory + *inum must be equal iarray_num + */ +i32 +nsfw_shmem_createv(nsfw_mem_zone * pmeminfo, i32 inum, + mzone_handle * paddr_array, i32 iarray_num) +{ + NSFW_INIT_CHK_RET(); + + if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG) + { + return nsfw_memzone_remote_reserv_v(pmeminfo, paddr_array, iarray_num, + 0); + } + else + { + return nsfw_memzone_remote_reserv_v(pmeminfo, paddr_array, iarray_num, + NSFW_SHMEM_PID); + } + return NSFW_MEM_ERR; +} + +mzone_handle nsfw_shmem_lookup(nsfw_mem_name * pname) +{ + i8 aname[COMMON_MEM_MEMPOOL_NAMESIZE] = { 0 }; + NSFW_INIT_CHK_RET_NULL(); + + if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG) + { + return common_memzone_data_lookup_name(pname->aname); + } + + if ((NSFW_PROC_NULL == pname->enowner) + || (NSFW_PROC_MAIN == pname->enowner)) + { + int retVal = + sprintf_s(aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s", pname->aname); + if (-1 == retVal) + { + NSRTP_LOGERR("SPRINTF_S failed"); + return NULL; + } + } + else + { + /*app must less than NSFW_MEM_APPNAME_LENGTH */ + NSFW_NAME_LENCHECK_RET_NULL(pname->aname, "shmem lookup") + int retVal = + sprintf_s(aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s_%x", + pname->aname, + NSFW_SHMEM_PID); + if (-1 == retVal) + { + NSRTP_LOGERR("SPRINTF_S failed"); + return NULL; + } + } + + return nsfw_remote_shmem_lookup(aname, NSFW_MEM_MZONE); +} + +i32 nsfw_shmem_release(nsfw_mem_name * pname) +{ + i8 aname[COMMON_MEM_MEMPOOL_NAMESIZE] = { 0 }; + const struct common_mem_memzone *pmzone = NULL; + NSFW_INIT_CHK_RET(); + + if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG) + { + pmzone = common_mem_memzone_lookup(pname->aname); + + if (pmzone) + { + common_mem_memzone_free(pmzone); + } + return NSFW_MEM_OK; + } + else + { + NSFW_NAME_LENCHECK_RET(pname->aname, "shmem free") + if (-1 == + sprintf_s(aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s_%x", + pname->aname, NSFW_SHMEM_PID)) + { + NSRTP_LOGERR("SPRINTF_S failed"); + return NSFW_MEM_ERR; + } + } + + return nsfw_remote_free(aname, NSFW_MEM_MZONE); +} + +mpool_handle nsfw_shmem_mbfmpcreate(nsfw_mem_mbfpool * pbufinfo) +{ + i8 aname[COMMON_MEM_MEMPOOL_NAMESIZE] = { 0 }; + + NSFW_INIT_CHK_RET_NULL(); + + if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG) + { + return common_mem_pktmbuf_pool_create(pbufinfo->stname.aname, + pbufinfo->usnum, + pbufinfo->uscash_size, + pbufinfo->uspriv_size, + pbufinfo->usdata_room, + pbufinfo->isocket_id); + } + else + { + /*app must less than NSFW_MEM_APPNAME_LENGTH */ + NSFW_NAME_LENCHECK_RET_NULL(pbufinfo->stname.aname, "mbufpool create") + if (-1 == + sprintf_s(aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s_%x", + pbufinfo->stname.aname, NSFW_SHMEM_PID)) + { + NSRTP_LOGERR("SPRINTF_S failed]"); + } + } + + return nsfw_remote_shmem_mbf_create(aname, pbufinfo->usnum, + pbufinfo->uscash_size, + pbufinfo->uspriv_size, + pbufinfo->usdata_room, SOCKET_ID_ANY, + pbufinfo->enmptype); +} + +/* + *create some mbuf pools + */ +i32 +nsfw_shmem_mbfmpcreatev(nsfw_mem_mbfpool * pmbfname, i32 inum, + mpool_handle * phandle_array, i32 iarray_num) +{ + NSFW_INIT_CHK_RET(); + + if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG) + { + return nsfw_remote_shmem_mbf_createv(pmbfname, phandle_array, + iarray_num, 0); + } + else + { + return nsfw_remote_shmem_mbf_createv(pmbfname, phandle_array, + iarray_num, NSFW_SHMEM_PID); + } + + return NSFW_MEM_ERR; +} + +mbuf_handle nsfw_shmem_mbfalloc(mpool_handle mhandle) +{ + return (mbuf_handle) + common_mem_pktmbuf_alloc((struct common_mem_mempool *) mhandle); +} + +i32 nsfw_shmem_mbffree(mbuf_handle mhandle) +{ + common_mem_pktmbuf_free((struct common_mem_mbuf *) mhandle); + return NSFW_MEM_OK; +} + +i32 nsfw_shmem_mbfmprelease(nsfw_mem_name * pname) +{ + return NSFW_MEM_OK; +} + +mpool_handle nsfw_shmem_mbfmplookup(nsfw_mem_name * pmbfname) +{ + i8 aname[COMMON_MEM_MEMPOOL_NAMESIZE] = { 0 }; + + NSFW_INIT_CHK_RET_NULL(); + + if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG) + { + return common_mem_mempool_lookup(pmbfname->aname); + } + + if ((NSFW_PROC_NULL == pmbfname->enowner) + || (NSFW_PROC_MAIN == pmbfname->enowner)) + { + if (-1 == + sprintf_s(aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s", + pmbfname->aname)) + { + NSRTP_LOGERR("SPRINTF_S failed]"); + } + } + else + { + /*app must less than NSFW_MEM_APPNAME_LENGTH */ + NSFW_NAME_LENCHECK_RET_NULL(pmbfname->aname, "shmem lookup") + if (-1 == + sprintf_s(aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s_%x", + pmbfname->aname, NSFW_SHMEM_PID)) + { + NSRTP_LOGERR("SPRINTF_S failed]"); + } + } + + return nsfw_remote_shmem_lookup(aname, NSFW_MEM_MBUF); +} + +mring_handle nsfw_shmem_spcreate(nsfw_mem_sppool * pmpinfo) +{ + i8 aname[COMMON_MEM_MEMPOOL_NAMESIZE] = { 0 }; + + NSFW_INIT_CHK_RET_NULL(); + + if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG) + { + return nsfw_shmem_pool_create(pmpinfo->stname.aname, pmpinfo->usnum, + pmpinfo->useltsize, pmpinfo->isocket_id, + pmpinfo->enmptype); + } + else + { + NSFW_NAME_LENCHECK_RET_NULL(pmpinfo->stname.aname, "mpool create") + if (-1 == + sprintf_s(aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s_%x", + pmpinfo->stname.aname, NSFW_SHMEM_PID)) + { + NSRTP_LOGERR("SPRINTF_S failed]"); + } + } + + return nsfw_remote_shmem_mpcreate(aname, pmpinfo->usnum, + pmpinfo->useltsize, SOCKET_ID_ANY, + pmpinfo->enmptype); +} + +i32 +nsfw_shmem_spcreatev(nsfw_mem_sppool * pmpinfo, i32 inum, + mring_handle * pringhandle_array, i32 iarray_num) +{ + NSFW_INIT_CHK_RET(); + + if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG) + { + return nsfw_remote_shmem_mpcreatev(pmpinfo, pringhandle_array, inum, + 0); + } + else + { + return nsfw_remote_shmem_mpcreatev(pmpinfo, pringhandle_array, inum, + NSFW_SHMEM_PID); + } + return NSFW_MEM_ERR; +} + +i32 +nsfw_lshmem_ringcreatev(const char *name, i32 ieltnum, + mring_handle * pringhandle_array, i32 iringnum, + i32 socket_id, nsfw_mpool_type entype) +{ + i32 useltsize = 0; + mring_handle nhandle = NULL; + i32 icount = 0; + i32 n = 0; + uint64_t baseaddr = 0; + uint64_t endaddr = 0; + i32 usnum = common_mem_align32pow2(ieltnum + 1); + + useltsize = + sizeof(struct nsfw_mem_ring) + usnum * sizeof(union RingData_U); + nhandle = + nsfw_shmem_pool_create(name, iringnum, useltsize, socket_id, + NSFW_MRING_SPSC); + if (NULL == (nhandle)) + { + return NSFW_MEM_ERR; + } + + n = nsfw_shmem_ring_sc_dequeuev(nhandle, (void **) pringhandle_array, + iringnum); + + if (n != iringnum) + { + NSRTP_LOGERR + ("ring dequeuev failed] ring=%p, dequeue num=%d, expect num=%d", + nhandle, n, iringnum); + return NSFW_MEM_ERR; + } + + nsfw_shmem_ring_baseaddr_query(&baseaddr, &endaddr); + + for (icount = 0; icount < iringnum; icount++) + { + nsfw_mem_ring_init(pringhandle_array[icount], usnum, + (void *) baseaddr, NSFW_SHMEM, entype); + } + + return NSFW_MEM_OK; +} + +i32 +nswf_shmem_sp_ringcreate(nsfw_mem_mring * prpoolinfo, + mring_handle * pringhandle_array, i32 iringnum) +{ + i8 aname[COMMON_MEM_MEMPOOL_NAMESIZE] = { 0 }; + + NSFW_INIT_CHK_RET(); + + if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG) + { + return nsfw_lshmem_ringcreatev(prpoolinfo->stname.aname, + prpoolinfo->usnum, pringhandle_array, + iringnum, SOCKET_ID_ANY, + prpoolinfo->enmptype); + } + else + { + NSFW_NAME_LENCHECK_RET(prpoolinfo->stname.aname, "ring pool") + int retVal = + sprintf_s(aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s_%x", + prpoolinfo->stname.aname, NSFW_SHMEM_PID); + if (-1 == retVal) + { + NSRTP_LOGERR("SPRINTF_S failed]"); + } + } + + return nsfw_remote_shmem_ringcreatev(aname, prpoolinfo->usnum, + pringhandle_array, iringnum, + SOCKET_ID_ANY, prpoolinfo->enmptype); +} + +i32 nsfw_shmem_sprelease(nsfw_mem_name * pname) +{ + i8 aname[COMMON_MEM_MEMPOOL_NAMESIZE] = { 0 }; + void *mz_mem = NULL; + struct nsfw_mem_ring *ring_ptr = NULL; + NSFW_INIT_CHK_RET(); + + if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG) + { + mz_mem = common_memzone_data_lookup_name(pname->aname); + + if (mz_mem) + { + ring_ptr = + (struct nsfw_mem_ring *) ((char *) mz_mem + + sizeof(struct + nsfw_shmem_ring_head)); + nsfw_shmem_pool_free(ring_ptr); + } + return NSFW_MEM_OK; + } + else + { + NSFW_NAME_LENCHECK_RET(pname->aname, "shmem free") + if (-1 == + sprintf_s(aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s_%x", + pname->aname, NSFW_SHMEM_PID)) + { + NSRTP_LOGERR("SPRINTF_S failed]"); + } + } + + return nsfw_remote_free(aname, NSFW_MEM_SPOOL); +} + +mring_handle nsfw_shmem_sp_lookup(nsfw_mem_name * pname) +{ + i8 aname[COMMON_MEM_MEMPOOL_NAMESIZE] = { 0 }; + void *mz_mem = NULL; + struct nsfw_mem_ring *ring_ptr = NULL; + NSFW_INIT_CHK_RET_NULL(); + + if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG) + { + mz_mem = common_memzone_data_lookup_name(pname->aname); + + if (mz_mem) + { + ring_ptr = + (struct nsfw_mem_ring *) ((char *) mz_mem + + sizeof(struct + nsfw_shmem_ring_head)); + return ring_ptr; + } + return mz_mem; + } + + if ((NSFW_PROC_NULL == pname->enowner) + || (NSFW_PROC_MAIN == pname->enowner)) + { + if (-1 == + sprintf_s(aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s", pname->aname)) + { + NSRTP_LOGERR("SPRINTF_S fails]"); + } + } + else + { + /*app's name can not over NSFW_MEM_APPNAME_LENGTH */ + NSFW_NAME_LENCHECK_RET_NULL(pname->aname, "shmem lookup") + if (-1 == + sprintf_s(aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s_%x", + pname->aname, NSFW_SHMEM_PID)) + { + NSRTP_LOGERR("SPRINTF_S failed]"); + } + } + + return nsfw_remote_shmem_lookup(aname, NSFW_MEM_SPOOL); +} + +mring_handle nsfw_shmem_ringcreate(nsfw_mem_mring * pringinfo) +{ + i8 aname[COMMON_MEM_MEMPOOL_NAMESIZE] = { 0 }; + + NSFW_INIT_CHK_RET_NULL(); + + if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG) + { + return nsfw_shmem_ring_create(pringinfo->stname.aname, + pringinfo->usnum, pringinfo->isocket_id, + pringinfo->enmptype); + } + else + { + NSFW_NAME_LENCHECK_RET_NULL(pringinfo->stname.aname, "ring create") + if (-1 == + sprintf_s(aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s_%x", + pringinfo->stname.aname, NSFW_SHMEM_PID)) + { + NSRTP_LOGERR("SPRINTF_S failed]"); + } + } + + return nsfw_remote_shmem_ringcreate(aname, pringinfo->usnum, + SOCKET_ID_ANY, pringinfo->enmptype); +} + +mring_handle nsfw_shmem_ring_lookup(nsfw_mem_name * pname) +{ + return nsfw_shmem_lookup(pname); +} + +i32 nsfw_shmem_ringrelease(nsfw_mem_name * pname) +{ + return nsfw_shmem_release(pname); +} + +size_t nsfw_shmem_mbufpool_statics(mpool_handle mbufpool) +{ + struct common_mem_mempool *mp = (struct common_mem_mempool *) mbufpool; + return (size_t) mp->size * (mp->header_size + mp->elt_size + + mp->trailer_size) + + (size_t) mp->private_data_size + + (size_t) + common_mem_ring_get_memsize(common_mem_align32pow2(mp->size + 1)); +} + +size_t nsfw_shmem_sppool_statics(mring_handle sppool) +{ + struct nsfw_shmem_ring_head *temp = NULL; + size_t lent = 0; + temp = + (struct nsfw_shmem_ring_head *) ((char *) sppool - + sizeof(struct nsfw_shmem_ring_head)); + + while (temp) + { + lent += temp->mem_zone->len; + temp = temp->next; + } + + return lent; +} + +size_t nsfw_shmem_ring_statics(mring_handle handle) +{ + struct nsfw_mem_ring *ring = (struct nsfw_mem_ring *) handle; + return ring->size * sizeof(union RingData_U) + + sizeof(struct nsfw_mem_ring); +} + +ssize_t nsfw_shmem_static(void *handle, nsfw_mem_struct_type type) +{ + switch (type) + { + case NSFW_MEM_MBUF: + return nsfw_shmem_mbufpool_statics(handle); + case NSFW_MEM_SPOOL: + return nsfw_shmem_sppool_statics(handle); + case NSFW_MEM_RING: + return nsfw_shmem_ring_statics(handle); + default: + break; + } + return -1; +} + +i32 nsfw_shmem_mbuf_recycle(mpool_handle handle) +{ + return NSFW_MEM_OK; +} + +/***************************************************************************** +* Prototype : nsfw_shmem_sp_iterator +* Description : sp pool iterator +* Input : mpool_handle handle +* u32 start +* u32 end +* nsfw_mem_item_fun fun +* void *argv +* Output : None +* Return Value : i32 +* Calls : +* Called By : +*****************************************************************************/ +i32 +nsfw_shmem_sp_iterator(mpool_handle handle, u32 start, u32 end, + nsfw_mem_item_fun fun, void *argv) +{ + struct nsfw_mem_ring *perfring_ptr = (struct nsfw_mem_ring *) handle; + if (NULL == perfring_ptr || NULL == fun) + { + return 0; + } + + if (0 == perfring_ptr->eltsize) + { + return 0; + } + + int num = perfring_ptr->size; + if (start >= (u32) num || end <= start) + { + return 0; + } + + struct nsfw_shmem_ring_head *ring_head = + (struct nsfw_shmem_ring_head *) ((char *) handle - + sizeof(struct nsfw_shmem_ring_head)); + void *mz = + (void *) ((char *) perfring_ptr + sizeof(struct nsfw_mem_ring) + + num * sizeof(union RingData_U)); + + if (ring_head->mem_zone->len < + sizeof(struct nsfw_shmem_ring_head) + sizeof(struct nsfw_mem_ring) + + num * sizeof(union RingData_U)) + { + return 0; + } + + u32 mz_len = + ring_head->mem_zone->len - sizeof(struct nsfw_shmem_ring_head) - + sizeof(struct nsfw_mem_ring) - num * sizeof(union RingData_U); + + u32 start_idx = 0; + u32 elm_num = 0; + elm_num = mz_len / perfring_ptr->eltsize; + while (start > start_idx + elm_num) + { + if (NULL == ring_head->next || NULL == ring_head->next->mem_zone + || 0 == elm_num) + { + return 0; + } + + ring_head = + (struct nsfw_shmem_ring_head *) ring_head->next-> + mem_zone->addr_64; + mz_len = + ring_head->mem_zone->len - sizeof(struct nsfw_shmem_ring_head); + + elm_num = mz_len / perfring_ptr->eltsize; + mz = (void *) ((char *) ring_head + + sizeof(struct nsfw_shmem_ring_head)); + start_idx += elm_num; + } + + u32 cur_idx = start - start_idx; + char *cur_elm = NULL; + int proc_count = 0; + while (cur_idx + start_idx < end && cur_idx + start_idx < (u32) num) + { + if (cur_idx >= elm_num) + { + if (NULL == ring_head->next || NULL == ring_head->next->mem_zone + || 0 == elm_num) + { + break; + } + + ring_head = + (struct nsfw_shmem_ring_head *) ring_head->next-> + mem_zone->addr_64; + mz_len = + ring_head->mem_zone->len - + sizeof(struct nsfw_shmem_ring_head); + + elm_num = mz_len / perfring_ptr->eltsize; + mz = (void *) ((char *) ring_head + + sizeof(struct nsfw_shmem_ring_head)); + start_idx += elm_num; + + cur_idx = 0; + cur_elm = NULL; + continue; + } + + if (NULL == cur_elm) + { + cur_elm = ((char *) mz + cur_idx * perfring_ptr->eltsize); + } + else + { + cur_elm += perfring_ptr->eltsize; + } + + cur_idx++; + proc_count++; + (void) fun(cur_elm, argv); + } + + return proc_count; +} + +i32 +nsfw_shmem_mbuf_iterator(mpool_handle handle, u32 start, u32 end, + nsfw_mem_item_fun fun, void *argv) +{ + return dmm_pktmbuf_pool_iterator((struct common_mem_mempool *) handle, + start, end, (dmm_mbuf_item_fun) fun, + argv); +} + +int nsfw_attach_core_id(nsfw_mem_name * name) +{ + return 0; +} diff --git a/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_mng.h b/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_mng.h new file mode 100644 index 0000000..6fbff59 --- /dev/null +++ b/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_mng.h @@ -0,0 +1,135 @@ +/* +* +* Copyright (c) 2018 Huawei Technologies Co.,Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef _NSFW_SHMEM_MNG_H +#define _NSFW_SHMEM_MNG_H + +/* + * mem mgr module init + * para:point to nstack_fwmem_para + */ +i32 nsfw_shmem_init(nsfw_mem_para * para); + +/* + * mem mgr module destory + * + */ +void nsfw_shmem_destroy(void); + +/* + * create a block memory with name + * fw_mem_zone::stname name of memory + * fw_mem_zone::isize memory size + */ +mzone_handle nsfw_shmem_create(nsfw_mem_zone * pinfo); + +/* + *create some blocks memory + */ +i32 nsfw_shmem_createv(nsfw_mem_zone * pmeminfo, i32 inum, + mzone_handle * paddr_array, i32 iarray_num); + +/* + *lookup a memory + */ +mzone_handle nsfw_shmem_lookup(nsfw_mem_name * pname); + +/*release the memory*/ +i32 nsfw_shmem_release(nsfw_mem_name * pname); + +/* + *create mbuf pool + */ +mpool_handle nsfw_shmem_mbfmpcreate(nsfw_mem_mbfpool * pbufinfo); + +/* + *create some mbuf pool + */ +i32 nsfw_shmem_mbfmpcreatev(nsfw_mem_mbfpool * pmbfname, i32 inum, + mpool_handle * phandle_array, i32 iarray_num); + +/* + *alloc a mbuf from mbuf pool + */ +mbuf_handle nsfw_shmem_mbfalloc(mpool_handle mhandle); + +/* + *release a mbuf pool + */ +i32 nsfw_shmem_mbffree(mbuf_handle mhandle); + +/* + *put mbuf back to mbuf pool + */ +i32 nsfw_shmem_mbfmprelease(nsfw_mem_name * pname); + +/*look up mbuf mpool*/ +mpool_handle nsfw_shmem_mbfmplookup(nsfw_mem_name * pmbfname); + +/* + *create simple pool + */ +mring_handle nsfw_shmem_spcreate(nsfw_mem_sppool * pmpinfo); + +/* + *create some simple pools + */ +i32 nsfw_shmem_spcreatev(nsfw_mem_sppool * pmpinfo, i32 inum, + mring_handle * pringhandle_array, i32 iarray_num); + +/* + *create a simple pool that members are rings + */ +i32 nswf_shmem_sp_ringcreate(nsfw_mem_mring * prpoolinfo, + mring_handle * pringhandle_array, i32 iringnum); + +/* + *release a simple pool + */ +i32 nsfw_shmem_sprelease(nsfw_mem_name * pname); + +/* + *look up a simple pool + */ +mring_handle nsfw_shmem_sp_lookup(nsfw_mem_name * pname); + +/* + *create a ring with name + */ +mring_handle nsfw_shmem_ringcreate(nsfw_mem_mring * pringinfo); + +/* + *look up a ring with name + */ +mring_handle nsfw_shmem_ring_lookup(nsfw_mem_name * pname); + +/* + *release ring + */ +i32 nsfw_shmem_ringrelease(nsfw_mem_name * pname); + +ssize_t nsfw_shmem_static(void *handle, nsfw_mem_struct_type type); + +i32 nsfw_shmem_mbuf_recycle(mpool_handle handle); + +i32 nsfw_shmem_sp_iterator(mpool_handle handle, u32 start, u32 end, + nsfw_mem_item_fun fun, void *argv); +i32 nsfw_shmem_mbuf_iterator(mpool_handle handle, u32 start, u32 end, + nsfw_mem_item_fun fun, void *argv); + +int nsfw_attach_core_id(nsfw_mem_name * name); + +#endif diff --git a/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_ring.c b/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_ring.c new file mode 100644 index 0000000..f580640 --- /dev/null +++ b/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_ring.c @@ -0,0 +1,843 @@ +/* +* +* Copyright (c) 2018 Huawei Technologies Co.,Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include <string.h> +#include <common_sys_config.h> + +#include "common_mem_pal_memconfig.h" +#include "nstack_securec.h" +#include "nsfw_shmem_ring.h" +#include "nsfw_ring_fun.h" +#include "common_mem_buf.h" +#include "common_func.h" +#include "common_pal_bitwide_adjust.h" + +void +nsfw_shmem_ring_baseaddr_query(uint64_t * rte_lowest_addr, + uint64_t * rte_highest_addr) +{ + struct common_mem_mem_config *pMemCfg = + common_mem_pal_get_configuration()->mem_config; + struct common_mem_memseg *PMemSegArry = pMemCfg->memseg; + + *rte_lowest_addr = PMemSegArry[0].addr_64; + *rte_highest_addr = PMemSegArry[0].addr_64 + PMemSegArry[0].len; + + int s = 1; + + while (s < COMMON_MEM_MAX_MEMSEG && PMemSegArry[s].len > 0) + { + if (*rte_lowest_addr > PMemSegArry[s].addr_64) + { + *rte_lowest_addr = PMemSegArry[s].addr_64; + } + + if (*rte_highest_addr < PMemSegArry[s].addr_64 + PMemSegArry[s].len) + { + *rte_highest_addr = PMemSegArry[s].addr_64 + PMemSegArry[s].len; + } + + s++; + } + +} + +static unsigned +nsfw_shmem_pool_node_alloc(struct nsfw_mem_ring *perfring_ptr, + unsigned alloc_index, unsigned max_index, + void *mz, size_t mz_len, unsigned elt_size) +{ + size_t alloc_size = 0; + unsigned offset_idx = 0; + NSTCP_LOGINF("mz(%p), mz_len = 0x%x", mz, mz_len); + + while (alloc_size + elt_size <= mz_len) + { + perfring_ptr->ring[alloc_index + offset_idx].data_s.ver = + alloc_index + offset_idx; + perfring_ptr->ring[alloc_index + offset_idx].data_s.val = + ADDR_LTOSH_EXT(mz) - ((uint64_t) perfring_ptr->Addrbase); + mz = (char *) mz + elt_size; + alloc_size += elt_size; + offset_idx++; + + if (alloc_index + offset_idx == max_index) + { + break; + } + } + + return offset_idx; +} + +void nsfw_shmem_pool_free(struct nsfw_mem_ring *perfring_ptr) +{ + struct nsfw_shmem_ring_head *ptemp; + + if (NULL == perfring_ptr) + { + return; + } + + struct nsfw_shmem_ring_head *pnode = + (struct nsfw_shmem_ring_head *) ((char *) perfring_ptr - + sizeof(struct nsfw_shmem_ring_head)); + + while (pnode) + { + // phead is involved in phead->mem_zone + ptemp = pnode->next; + common_mem_memzone_free(pnode->mem_zone); + pnode = ptemp; + } +} + +struct nsfw_mem_ring *nsfw_shmem_pool_create(const char *name, unsigned int n, + unsigned int elt_size, + int socket_id, + unsigned char flag) +{ + struct nsfw_mem_ring *perfring_ptr = NULL; + struct common_mem_memzone *mz_mem; + void *mz = NULL; + + /*get pool size, pool size must pow of 2 */ + unsigned int num = common_mem_align32pow2(n + 1); + + struct nsfw_shmem_ring_head *pcur = NULL; + /*calculate the empty rte_perf_ring Size */ + size_t len = + sizeof(struct nsfw_shmem_ring_head) + sizeof(struct nsfw_mem_ring) + + (size_t) num * sizeof(union RingData_U) + (size_t) num * elt_size; + size_t alloc_len = len; + unsigned int alloc_num = 0; + unsigned int alloc_index = 0; + + size_t mz_len = 0; + + unsigned int mz_index = 1; + char mz_name[128] = { 0 }; + int retVal; + /*we'd better use `strlen(src)` or `sizeof(dst)` to explain copying length of src string. + it's meaningless using `sizeof(dst) - 1` to reserve 1 byte for '\0'. + if copying length equals to or bigger than dst length, just let STRNCPY_S() returns failure. */ + retVal = strncpy_s(mz_name, sizeof(mz_name), name, sizeof(mz_name)); + + if (EOK != retVal) + { + NSTCP_LOGERR("STRNCPY_S failed]ret=%d", retVal); + return NULL; + } + + mz_mem = common_memzone_data_lookup_name(name); + NSTCP_LOGINF("memzone data look up] n=%u,num=%u,len=%zu", n, num, len); + + if (mz_mem) + { + perfring_ptr = + (struct nsfw_mem_ring *) ((char *) mz_mem + + sizeof(struct nsfw_shmem_ring_head)); + return perfring_ptr; + } + + while (alloc_len > 0) + { + if (NULL != perfring_ptr) + { + retVal = + sprintf_s(mz_name, sizeof(mz_name), "%s_%03d", name, + mz_index); + + if (-1 == retVal) + { + NSRTP_LOGERR("SPRINTF_S failed]ret=%d", retVal); + nsfw_shmem_pool_free(perfring_ptr); + return NULL; + } + } + + mz_mem = + (struct common_mem_memzone *) common_mem_memzone_reserve(mz_name, + alloc_len, + socket_id, + 0); + + if (mz_mem == NULL) + { + mz_mem = + (struct common_mem_memzone *) + common_mem_memzone_reserve(mz_name, 0, socket_id, 0); + } + + if (mz_mem == NULL) + { + nsfw_shmem_pool_free(perfring_ptr); + return NULL; + } + + if (NULL == perfring_ptr + && (mz_mem->len < + sizeof(struct nsfw_shmem_ring_head) + + sizeof(struct nsfw_mem_ring) + + num * sizeof(union RingData_U))) + { + common_mem_memzone_free(mz_mem); + return NULL; + } + + if (NULL == perfring_ptr) + { + pcur = + (struct nsfw_shmem_ring_head *) ADDR_SHTOL(mz_mem->addr_64); + pcur->mem_zone = mz_mem; + pcur->next = NULL; + + perfring_ptr = + (struct nsfw_mem_ring *) ((char *) pcur + + sizeof(struct + nsfw_shmem_ring_head)); + + mz = (void *) ((char *) perfring_ptr + + sizeof(struct nsfw_mem_ring) + + num * sizeof(union RingData_U)); + mz_len = + mz_mem->len - sizeof(struct nsfw_shmem_ring_head) - + sizeof(struct nsfw_mem_ring) - num * sizeof(union RingData_U); + + uint64_t rte_base_addr; + uint64_t rte_highest_addr; + nsfw_shmem_ring_baseaddr_query(&rte_base_addr, &rte_highest_addr); + nsfw_mem_pool_head_init(perfring_ptr, num, elt_size, + (void *) rte_base_addr, NSFW_SHMEM, + (nsfw_mpool_type) flag); + } + else + { + if (pcur) + { + pcur->next = + (struct nsfw_shmem_ring_head *) + ADDR_SHTOL(mz_mem->addr_64); + pcur = pcur->next; + pcur->mem_zone = mz_mem; + pcur->next = NULL; + + if (mz_mem->len < sizeof(struct nsfw_shmem_ring_head)) + { + NSRTP_LOGERR("mz_len error %d", mz_mem->len); + nsfw_shmem_pool_free(perfring_ptr); + return NULL; + } + + mz = (void *) ((char *) pcur + + sizeof(struct nsfw_shmem_ring_head)); + mz_len = mz_mem->len - sizeof(struct nsfw_shmem_ring_head); + } + } + + alloc_num = + nsfw_shmem_pool_node_alloc(perfring_ptr, alloc_index, num, mz, + mz_len, elt_size); + alloc_index += alloc_num; + + if (alloc_index >= num) + { + break; + } + + // second time allocate should not contained all ring head + alloc_len = + (size_t) (num - alloc_index) * elt_size + + sizeof(struct nsfw_shmem_ring_head); + mz_index++; + } + + return perfring_ptr; +} + +/*ring create*/ +struct nsfw_mem_ring *nsfw_shmem_ring_create(const char *name, unsigned int n, + int socket_id, + unsigned char flag) +{ + struct nsfw_mem_ring *perfring_ptr; + struct common_mem_memzone *mz; + uint64_t rte_base_addr; + uint64_t rte_highest_addr; + + unsigned int num = common_mem_align32pow2(n); + + mz = (struct common_mem_memzone *) common_mem_memzone_reserve(name, + sizeof + (struct + nsfw_mem_ring) + + + num * + sizeof(union + RingData_U), + socket_id, + 0); + + if (mz == NULL) + { + return NULL; + } + + perfring_ptr = mz->addr; + + nsfw_shmem_ring_baseaddr_query(&rte_base_addr, &rte_highest_addr); + nsfw_mem_ring_init(perfring_ptr, num, (void *) rte_base_addr, NSFW_SHMEM, + flag); + + return perfring_ptr; +} + +/* +this is a multi thread/process enqueue function, please pay attention to the bellow point +1. while Enqueue corrupt, we may lose one element; because no one to add the Head +*/ +int nsfw_shmem_ring_mp_enqueue(struct nsfw_mem_ring *ring, void *box) +{ + union RingData_U expectPostVal; + union RingData_U curVal; + unsigned int tmpHead; + unsigned int tmpTail; + unsigned int CurHead = ring->prod.head; + unsigned int mask = ring->mask; + unsigned int size = ring->size; + void *prmBox = NULL; + + prmBox = (void *) ADDR_LTOSH_EXT(box); + + /*do box range check */ + if ((char *) prmBox <= (char *) ring->Addrbase + || (char *) prmBox > (char *) ring->Addrbase + PERFRING_ADDR_RANGE) + { + /*invalid addr of box, can't put in rte_perf_ring, maybe should set a errno here */ + return -1; + } + + do + { + /* + if the ring is Full return directly; this not a exact check, cause we made tail++ after dequeue success. + the thing we could make sure is ring[ring->Tail&mask] already dequeue + */ + tmpTail = ring->cons.tail; + + if (tmpTail + size - CurHead == 0) + { + /* + here we give enqueue a chance to recorrect the Tail, if tail not has Data let tail++ + */ + if (ring->ring[tmpTail & mask].data_s.val == 0) + { + (void) __sync_bool_compare_and_swap(&ring->cons.tail, tmpTail, + tmpTail + 1); + } + else + { + return 0; + } + } + + /* + the old version of ring->ring[CurHead&mask] must CurHead - size, which enqueue set to this pos lasttime + & the val must already dequeue. otherwise this pos can't enqueue; + */ + expectPostVal.data_l = + (((unsigned long long) (CurHead - size)) << VALUE_LEN); + + /* + the new version of ring->ring[CurHead&mask] must CurHead, which enqueue set to this pos this time. + */ + curVal.data_l = + ((((unsigned long long) CurHead) << VALUE_LEN) | + ((char *) prmBox - (char *) ring->Addrbase)); + if (ring->ring[CurHead & mask].data_s.ver == expectPostVal.data_s.ver + && __sync_bool_compare_and_swap(&ring-> + ring[CurHead & mask].data_l, + expectPostVal.data_l, + curVal.data_l)) + { + /* + enqueue success, add Head Value now + here we using CAS set instead __sync_fetch_and_add(&ring->Head, 1) to assume that, if one process enqueue success && been killed before + add Head, other process can recorrect the Head Value; + one more thing the direction of Tail must been add-direction, so we using the condition (ring->Head - CurHead >0x80000000); + while many thread do enqueue at same time, Head may not correct,exp: + thread A get old head 10, thread A want set head to 11 + thread B get old head 10, thread B want set head to 12 + thread A do CAS && thread B do CAS at same time, thread A do CAS success; + the result of head is 11, but the correct Value should be 12; + + then thread C get old head 11, thread C will set head to 13[cause pos 12 already has value, thread C will skill 12], + the head will be recorrect by thread C. + if no thread C, thread A& B are the last enqueue thread; the head must recorrect by the deque function. + */ + tmpHead = ring->prod.head; + + if (0 == (CurHead & 0x03) && tmpHead - CurHead > 0x80000000) + { + (void) __sync_bool_compare_and_swap(&ring->prod.head, tmpHead, + CurHead + 1); + } + + break; + } + + /* + CurHead++ here; + may be cpu slice is end here; while re-sched CurHead < ring->Tail < ring->Head; to avoid multi try + we using a cmp & CurHead++ instead CurHead++ directly. + if using CurHead++ will amplify the probability of ABA problem + */ + /*CurHead++; */ + tmpHead = ring->prod.head; + CurHead = CurHead - tmpHead < mask - 1 ? CurHead + 1 : tmpHead; + } + while (1); + + return 1; +} + +/* + this is a single thread/process enqueue function + */ +int nsfw_shmem_ring_sp_enqueue(struct nsfw_mem_ring *ring, void *box) +{ + union RingData_U texpectPostVal; + union RingData_U curVal; + unsigned int tmpTail; + unsigned int CurHead = ring->prod.head; + unsigned int mask = ring->mask; + unsigned int uisize = ring->size; + void *prmBox = NULL; + + prmBox = (void *) ADDR_LTOSH_EXT(box); + + if ((char *) prmBox <= (char *) ring->Addrbase + || (char *) prmBox > (char *) ring->Addrbase + PERFRING_ADDR_RANGE) + { + return -1; + } + + do + { + tmpTail = ring->cons.tail; + if (tmpTail + uisize - CurHead == 0) + { + /* + *here we give enqueue a chance to recorrect the Tail, if tail not has Data let tail++ + */ + if (ring->ring[tmpTail & mask].data_s.val == 0) + { + (void) __sync_bool_compare_and_swap(&ring->cons.tail, tmpTail, + tmpTail + 1); + } + else + { + return 0; + } + } + texpectPostVal.data_l = + (((unsigned long long) (CurHead - uisize)) << VALUE_LEN); + + curVal.data_l = + ((((unsigned long long) CurHead) << VALUE_LEN) | + ((char *) prmBox - (char *) ring->Addrbase)); + + if (ring->ring[CurHead & mask].data_l == texpectPostVal.data_l) + { + ring->ring[CurHead & mask].data_l = curVal.data_l; + ring->prod.head = CurHead + 1; + break; + } + + CurHead++; + } + while (1); + return 1; +} + +/*this is a multi thread/process dequeue function, please pay attention to the bellow point +*/ +int nsfw_shmem_ring_mc_dequeue(struct nsfw_mem_ring *ring, void **box) +{ + unsigned int CurTail; + unsigned int tmpTail; + unsigned int tmpHead; + unsigned int mask = ring->mask; + union RingData_U curNullVal; + union RingData_U ExcpRingVal; + + CurTail = ring->cons.tail; + do + { + /*if ring is empty return directly */ + tmpHead = ring->prod.head; + + if (CurTail == tmpHead) + { + /* + here we give deque a chance to recorrect the Head, if head has Data let Head++ + */ + if (ring->ring[tmpHead & mask].data_s.val != 0) + { + (void) __sync_bool_compare_and_swap(&ring->prod.head, tmpHead, + tmpHead + 1); + } + else + { + return 0; + } + } + curNullVal.data_l = (((unsigned long long) CurTail) << VALUE_LEN); + ExcpRingVal = ring->ring[CurTail & mask]; + /* + *the version of ring->ring[CurTail&mask] must CurTail&0xFFFFFF + */ + if ((curNullVal.data_s.ver == ExcpRingVal.data_s.ver) + && (ExcpRingVal.data_s.val) + && __sync_bool_compare_and_swap(&ring-> + ring[CurTail & mask].data_l, + ExcpRingVal.data_l, + curNullVal.data_l)) + { + + *box = + ADDR_SHTOL(((char *) ring->Addrbase + + ExcpRingVal.data_s.val)); + + /* + enqueue success, add Tail Value now + here we using CAS set instead __sync_fetch_and_add(&ring->Tail, 1) to assume that, if one process dequeue success && been killed before + add Tail, other process can recorrect the Tail Value; + one more thing the direction of Tail must been add-direction, so we using the condition (rlTail - CurTail >0x80000000); + while multi CAS done the result value of CurTail may not correct, but we don't care, it will be recorrect while next deque done. + + avg CAS cost 200-300 Cycles, so we using cache loop to instead some CAS;[head&tail not exact guide, so no need Do CAS evertime] + here we using 0 == (CurTail&0x11) means we only do CAS while head/tail low bit is 0x11; four times do one CAS. + */ + tmpTail = ring->cons.tail; + + if (0 == (CurTail & 0x03) && tmpTail - CurTail > 0x80000000) + { + (void) __sync_bool_compare_and_swap(&ring->cons.tail, tmpTail, + CurTail + 1); + } + break; + } + + /* + CurTail++ here; + may be cpu slice is end here; while re-sched CurTail < ring->Tail < ring->Head; to avoid multi try + we using a cmp & CurTail++ instead CurTail++ directly. + if using CurTail++ will amplify the probability of ABA problem + */ + /*CurTail++; */ + tmpTail = ring->cons.tail; + CurTail = CurTail - tmpTail < mask - 1 ? CurTail + 1 : tmpTail; + } + while (1); + + return 1; +} + +/* + this is enhanced mc_ring_dequeue, support dequeue multi element one time. +*/ +int +nsfw_shmem_ring_mc_dequeuev(struct nsfw_mem_ring *ring, void **box, + unsigned int n) +{ + unsigned int uiCurTail; + unsigned int tmpTail; + unsigned int tmpHead; + unsigned int uimask = ring->mask; + union RingData_U curNullVal; + union RingData_U ExcpRingVal; + unsigned int deqNum = 0; + uiCurTail = ring->cons.tail; + do + { + /*if ring is empty return directly */ + tmpHead = ring->prod.head; + if (uiCurTail == tmpHead) + { + /* + here we give deque a chance to recorrect the Head, if head has Data let Head++; + here must done to avoid some msg can't deque. + */ + if (deqNum == 0 && ring->ring[tmpHead & uimask].data_s.val != 0) + { + (void) __sync_bool_compare_and_swap(&ring->prod.head, tmpHead, + tmpHead + 1); + } + else + { + return deqNum; + } + } + + curNullVal.data_l = (((unsigned long long) uiCurTail) << VALUE_LEN); + ExcpRingVal = ring->ring[uiCurTail & uimask]; + + /* + *the version of ring->ring[CurTail&mask] must CurTail&0xFFFFFF + */ + if ((curNullVal.data_s.ver == ExcpRingVal.data_s.ver) + && (ExcpRingVal.data_s.val) + && __sync_bool_compare_and_swap(&ring-> + ring[uiCurTail & uimask].data_l, + ExcpRingVal.data_l, + curNullVal.data_l)) + { + + box[deqNum] = + ADDR_SHTOL(((char *) ring->Addrbase + + ExcpRingVal.data_s.val)); + + /* + enqueue success, add Tail Value now + here we using CAS set instead __sync_fetch_and_add(&ring->Tail, 1) to assume that, if one process dequeue success && been killed before + add Tail, other process can recorrect the Tail Value; + one more thing the direction of Tail must been add-direction, so we using the condition (rlTail - CurTail >0x80000000); + + avg CAS cost 200-300 Cycles, so we using cache loop to instead some CAS;[head&tail not exact guide, so no need Do CAS evertime] + here we using 0 == (CurTail&0x11) means we only do CAS while head/tail low bit is 0x11; four times do one CAS. + */ + tmpTail = ring->cons.tail; + + if (0 == (uiCurTail & 0x03) && tmpTail - uiCurTail > 0x80000000) + { + (void) __sync_bool_compare_and_swap(&ring->cons.tail, tmpTail, + uiCurTail + 1); + } + + deqNum++; + } + + /* + CurTail++ here; + may be cpu slice is end here; while re-sched CurTail < ring->Tail < ring->Head; to avoid multi try + we using a cmp & CurTail++ instead CurTail++ directly. + if using CurTail++ will amplify the probability of ABA problem + */ + /*CurTail++; */ + tmpTail = ring->cons.tail; + uiCurTail = + uiCurTail - tmpTail < uimask - 1 ? uiCurTail + 1 : tmpTail; + + } + while (n > deqNum); + + return deqNum; +} + +/* + this is enhanced mc_ring_dequeue, support dequeue multi element one time. +*/ +int nsfw_shmem_ring_sc_dequeue(struct nsfw_mem_ring *ring, void **box) +{ + unsigned int CurTail; + unsigned int mask = ring->mask; + union RingData_U curNullVal; + union RingData_U ExcpRingVal; + unsigned int uitmpHead; + + CurTail = ring->cons.tail; + + do + { + /*if ring is empty return directly */ + uitmpHead = ring->prod.head; + if (CurTail == uitmpHead) + { + /* + here we give deque a chance to recorrect the Head, if head has Data let Head++ + */ + if (ring->ring[uitmpHead & mask].data_s.val != 0) + { + (void) __sync_bool_compare_and_swap(&ring->prod.head, + uitmpHead, uitmpHead + 1); + } + else + { + return 0; + } + } + curNullVal.data_l = (((unsigned long long) CurTail) << VALUE_LEN); + ExcpRingVal = ring->ring[CurTail & mask]; + + if ((curNullVal.data_s.ver == ExcpRingVal.data_s.ver) + && (ExcpRingVal.data_s.val)) + { + ring->ring[CurTail & mask].data_l = curNullVal.data_l; + + *box = + ADDR_SHTOL(((char *) ring->Addrbase + + ExcpRingVal.data_s.val)); + + ring->cons.tail = CurTail + 1; + break; + } + + CurTail++; + } + while (1); + + return 1; +} + +/* + this is a single thread/process dequeue function +*/ +int +nsfw_shmem_ring_sc_dequeuev(struct nsfw_mem_ring *ring, void **box, + unsigned int n) +{ + unsigned int CurTail; + unsigned int tmpHead; + unsigned int mask = ring->mask; + union RingData_U curNullVal; + union RingData_U ExcpRingVal; + unsigned int usdeqNum = 0; + + CurTail = ring->cons.tail; + + do + { + /*if ring is empty return directly */ + tmpHead = ring->prod.head; + if (CurTail == tmpHead) + { + /* + here we give deque a chance to recorrect the Head, if head has Data let Head++; + here must done to avoid some msg can't deque. + */ + if (usdeqNum == 0 && ring->ring[tmpHead & mask].data_s.val != 0) + { + (void) __sync_bool_compare_and_swap(&ring->prod.head, tmpHead, + tmpHead + 1); + } + else + { + return usdeqNum; + } + } + curNullVal.data_l = (((unsigned long long) CurTail) << VALUE_LEN); + ExcpRingVal = ring->ring[CurTail & mask]; + + /* + the version of ring->ring[CurTail&mask] must CurTail&0xFFFFFF + */ + if ((curNullVal.data_s.ver == ExcpRingVal.data_s.ver) + && (ExcpRingVal.data_s.val)) + { + ring->ring[CurTail & mask].data_l = curNullVal.data_l; + + box[usdeqNum] = + ADDR_SHTOL(((char *) ring->Addrbase + + ExcpRingVal.data_s.val)); + + ring->cons.tail = CurTail + 1; + usdeqNum++; + } + + CurTail++; + } + while (n > usdeqNum); + + return usdeqNum; +} + +/* nstack just using one thread, for performance using que not support multi thread*/ +int +nsfw_shmem_ring_singlethread_enqueue(struct nsfw_mem_ring *ring, void *box) +{ + u32 head = 0; + void *prmBox = NULL; + + /*if queue is full, just return 0 */ + if (ring->prod.head >= (ring->size + ring->cons.tail)) + { + return 0; + } + + prmBox = (void *) ADDR_LTOSH_EXT(box); + + head = ring->prod.head; + ring->prod.head = head + 1; + ring->ring[head & ring->mask].data_s.ver = head; + ring->ring[head & ring->mask].data_s.val = + (char *) prmBox - (char *) ring->Addrbase; + return 1; +} + +/* nstack just using one thread, for performance using que not support multi thread*/ +int +nsfw_shmem_ring_singlethread_dequeue(struct nsfw_mem_ring *ring, void **box) +{ + u32 tail = 0; + + /* if all entries are dequeued return 0 */ + if (unlikely(ring->prod.head == ring->cons.tail)) + { + return 0; + } + + tail = ring->cons.tail; + *box = + ADDR_SHTOL((char *) ring->Addrbase + + ring->ring[tail & ring->mask].data_s.val); + ring->ring[tail & ring->mask].data_s.val = 0; + ring->ring[tail & ring->mask].data_s.ver = tail; + ring->cons.tail++; + return 1; +} + +/* nstack just using one thread, for performance using que not support multi thread*/ +int +nsfw_shmem_ring_singlethread_dequeuev(struct nsfw_mem_ring *ring, void **box, + unsigned int n) +{ + u32 tail = 0; + u32 num = 0; + + while (num < n) + { + tail = ring->cons.tail; + + /* if all entries are dequeued return 0 */ + if (unlikely(ring->prod.head == ring->cons.tail)) + { + return num; + } + + ring->cons.tail = tail + 1; + + box[num] = + ADDR_SHTOL((char *) ring->Addrbase + + ring->ring[tail & ring->mask].data_s.val); + + ring->ring[tail & ring->mask].data_s.val = 0; + ring->ring[tail & ring->mask].data_s.ver = tail; + num++; + } + + return num; +} diff --git a/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_ring.h b/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_ring.h new file mode 100644 index 0000000..af7c30c --- /dev/null +++ b/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_ring.h @@ -0,0 +1,60 @@ +/* +* +* Copyright (c) 2018 Huawei Technologies Co.,Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef _NSFW_SHMEM_RING_H_ +#define _NSFW_SHMEM_RING_H_ + +#include <stdint.h> + +#include "common_func.h" + +struct nsfw_shmem_ring_head +{ + struct common_mem_memzone *mem_zone; + struct nsfw_shmem_ring_head *next; + unsigned int uireserv[4]; +}; + +void nsfw_shmem_ring_baseaddr_query(uint64_t * rte_lowest_addr, + uint64_t * rte_highest_addr); +struct nsfw_mem_ring *nsfw_shmem_pool_create(const char *name, + unsigned int n, + unsigned int elt_size, + int socket_id, + unsigned char flag); +struct nsfw_mem_ring *nsfw_shmem_ring_create(const char *name, + unsigned int n, int socket_id, + unsigned char flag); + +void nsfw_shmem_pool_free(struct nsfw_mem_ring *perfring_ptr); + +void nsfw_shmem_ring_reset(struct nsfw_mem_ring *ring, unsigned char flag); +int nsfw_shmem_ring_mp_enqueue(struct nsfw_mem_ring *ring, void *box); +int nsfw_shmem_ring_sp_enqueue(struct nsfw_mem_ring *ring, void *box); +int nsfw_shmem_ring_mc_dequeue(struct nsfw_mem_ring *ring, void **box); +int nsfw_shmem_ring_mc_dequeuev(struct nsfw_mem_ring *ring, void **box, + unsigned int n); +int nsfw_shmem_ring_sc_dequeue(struct nsfw_mem_ring *ring, void **box); +int nsfw_shmem_ring_sc_dequeuev(struct nsfw_mem_ring *ring, void **box, + unsigned int n); +int nsfw_shmem_ring_singlethread_enqueue(struct nsfw_mem_ring *ring, + void *box); +int nsfw_shmem_ring_singlethread_dequeue(struct nsfw_mem_ring *ring, + void **box); +int nsfw_shmem_ring_singlethread_dequeuev(struct nsfw_mem_ring *ring, + void **box, unsigned int n); + +#endif /*_NSFW_SHMEM_RING_H_*/ |