diff options
Diffstat (limited to 'stacks/lwip_stack/lwip_src/netif/sc_dpdk.c')
-rw-r--r-- | stacks/lwip_stack/lwip_src/netif/sc_dpdk.c | 574 |
1 files changed, 574 insertions, 0 deletions
diff --git a/stacks/lwip_stack/lwip_src/netif/sc_dpdk.c b/stacks/lwip_stack/lwip_src/netif/sc_dpdk.c new file mode 100644 index 0000000..95f3eec --- /dev/null +++ b/stacks/lwip_stack/lwip_src/netif/sc_dpdk.c @@ -0,0 +1,574 @@ +/* +* +* 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 "sc_dpdk.h" +#include "common_mem_mbuf.h" +#include "netif/common.h" +#include "nstack_log.h" +#include "nstack_securec.h" +#include "nsfw_msg_api.h" +#include "nsfw_maintain_api.h" +#include "nsfw_recycle_api.h" +#include "stackx_app_res.h" +#include "stackx_pbuf.h" +#ifdef SYS_MEM_RES_STAT +#include "memp.h" +#endif +#include "spl_instance.h" +#ifdef HAL_LIB +#else +#include "rte_memzone.h" +#endif + +#define SPL_MEM_MODULE "spl_mem_module" + +#define TMR_TICK_LENGTH TCP_TMR_INTERVAL /* define the tick length */ + +u32_t uStackArgIndex = 0; +int stackx_core_mask = 40; + +int g_nstack_bind_cpu = 0; +int g_tcpip_thread_sleep_time = 0; + +extern int sbr_create_tx_pool (); +extern int stackx_stat_zone_create (); + +#define GLOBAL_STACK_CORE_ARG "-c" +#define GLOBAL_STACK_CORE_BINE "-bind_cpu" + +u32 g_type; +struct memory_statics memory_used_size[80]; + +void +printmeminfo () +{ + unsigned int i = 0; + long size = 0; + + NSPOL_LOGDBG (SC_DPDK_INFO, + "*************************************************************"); + for (i = 0; i < g_type; i++) + { + NSPOL_LOGDBG (SC_DPDK_INFO, "%s : %ld", memory_used_size[i].name, + memory_used_size[i].size); + size += memory_used_size[i].size; + } + + size += (g_type * sizeof (struct common_mem_memzone)); + NSPOL_LOGDBG (SC_DPDK_INFO, "total size %ld", size); + NSPOL_LOGDBG (SC_DPDK_INFO, + "*************************************************************"); +} + +void +print_call_stack () +{ +} + +/* Parse the argument given in the command line of the application */ +void +smp_parse_stack_args (int argc, char **argv) +{ + int i = 0; + + const unsigned int global_core_length = 2; //GLOBAL_STACK_CORE_ARG "-c" string length is 2 + + for (i = uStackArgIndex + 1; i < argc; i++) + { + if ((i + 1) < argc) + { + if (strncmp (argv[i], "-sleep", 6) == 0) //compare "-sleep" string, length is 6 + { + g_tcpip_thread_sleep_time = atoi (argv[++i]); + NSPOL_LOGDBG (SC_DPDK_INFO, "g_tcpip_thread_sleep_time=%d", + g_tcpip_thread_sleep_time); + continue; + } + + if (strncmp (argv[i], GLOBAL_STACK_CORE_ARG, global_core_length) == + 0) + { + stackx_core_mask = atoi (argv[++i]); + if (stackx_core_mask < 1) + { + NSPOL_LOGDBG (SC_DPDK_INFO, + "Invalid Args:core_mask can't be less than 1,input value is:%s", + argv[i]); + } + + continue; + } + + if (strncmp + (argv[i], GLOBAL_STACK_CORE_BINE, + sizeof (GLOBAL_STACK_CORE_BINE)) == 0) + { + if (argv[++i]) + { + g_nstack_bind_cpu = atoi (argv[i]); + } + + if (g_nstack_bind_cpu < 0) + { + g_nstack_bind_cpu = 0; + } + + continue; + } + } + else + { + NSPOL_LOGDBG (SC_DPDK_INFO, "Invalid args:%s miss value ", argv[i]); //now ,only support this format ,others maybe supported in future + } + } + + return; +} + +mpool_handle +create_tx_mbuf_pool () +{ + mpool_handle mbf_pool_handle = NULL; + + nsfw_mem_mbfpool mbuf_pool; + + mbuf_pool.stname.entype = NSFW_SHMEM; + int retval = + spl_snprintf (mbuf_pool.stname.aname, NSFW_MEM_NAME_LENGTH - 1, "%s", + get_mempoll_tx_name ()); + if (retval < 0) + { + NSPOL_LOGERR ("spl_snprintf failed"); + return NULL; + } + + mbuf_pool.usnum = TX_MBUF_POOL_SIZE - 1; + mbuf_pool.uscash_size = 0; + mbuf_pool.uspriv_size = 0; + mbuf_pool.usdata_room = TX_MBUF_MAX_LEN; + mbuf_pool.isocket_id = SOCKET_ID_ANY; + mbuf_pool.enmptype = NSFW_MRING_SPSC; + mbf_pool_handle = nsfw_mem_mbfmp_create (&mbuf_pool); + if (NULL == mbf_pool_handle) + { + NSPOL_LOGERR ("create_tx_mbuf_pool failed]name=%s, num=%u, room=%u", + mbuf_pool.stname.aname, mbuf_pool.usnum, + mbuf_pool.usdata_room); + return NULL; + } + + NSPOL_LOGINF (SC_DPDK_INFO, + "tx_mempool_malloc=%p, num=%u, room=%u, total_mem=%d", + mbf_pool_handle, TX_MBUF_POOL_SIZE, mbuf_pool.usdata_room, + nsfw_mem_get_len (mbf_pool_handle, NSFW_MEM_MBUF)); + DPDK_MEMORY_COUNT ((get_mempoll_tx_name ()), + nsfw_mem_get_len (mbf_pool_handle, NSFW_MEM_MBUF)); + MEM_STAT (SPL_MEM_MODULE, "spl_mbuf_pool", NSFW_SHMEM, + nsfw_mem_get_len (mbf_pool_handle, NSFW_MEM_MBUF)); + + return mbf_pool_handle; +} + +mring_handle +create_segment_pool () +{ + nsfw_mem_sppool seg_pool; + seg_pool.stname.entype = NSFW_SHMEM; + int retval = + spl_snprintf (seg_pool.stname.aname, NSFW_MEM_NAME_LENGTH - 1, "%s", + get_mempoll_seg_name ()); + if (retval < 0) + { + NSPOL_LOGERR ("spl_snprintf failed"); + return NULL; + } + + seg_pool.usnum = 16; + seg_pool.useltsize = sizeof (struct common_pcb); + seg_pool.isocket_id = SOCKET_ID_ANY; + seg_pool.enmptype = NSFW_MRING_SPSC; + + mring_handle seg_mp_handle = nsfw_mem_sp_create (&seg_pool); + if (NULL == seg_mp_handle) + { + NSPOL_LOGERR + ("create_segment_pool common failed]name=%s, num=%u, size=%u", + seg_pool.stname.aname, SPL_MEMP_NUM_TCP_SEG, seg_pool.useltsize); + return NULL; + } + + NSPOL_LOGINF (SC_DPDK_INFO, + "common seg_mempool_malloc=%p, num=%u, size=%u, total_mem=%d", + seg_mp_handle, SPL_MEMP_NUM_TCP_SEG, seg_pool.useltsize, + nsfw_mem_get_len (seg_mp_handle, NSFW_MEM_SPOOL)); + DPDK_MEMORY_COUNT ((get_mempoll_seg_name ()), + nsfw_mem_get_len (seg_mp_handle, NSFW_MEM_SPOOL)); + MEM_STAT (SPL_MEM_MODULE, "spl_seg_pool", NSFW_SHMEM, + nsfw_mem_get_len (seg_mp_handle, NSFW_MEM_SPOOL)); + return seg_mp_handle; +} + +mring_handle +create_msg_pool () +{ + nsfw_mem_sppool msg_pool; + msg_pool.stname.entype = NSFW_SHMEM; + int retval = + spl_snprintf (msg_pool.stname.aname, NSFW_MEM_NAME_LENGTH - 1, "%s", + get_mempoll_msg_name ()); + if (retval < 0) + { + NSPOL_LOGERR ("spl_snprintf fail"); + return NULL; + } + + msg_pool.usnum = TX_MSG_POOL_SIZE; + msg_pool.useltsize = sizeof (data_com_msg); + msg_pool.isocket_id = SOCKET_ID_ANY; + msg_pool.enmptype = NSFW_MRING_MPMC; + mring_handle msg_mp_handle = nsfw_mem_sp_create (&msg_pool); + + if (NULL == msg_mp_handle) + { + NSPOL_LOGERR ("create_msg_pool failed]name=%s, num=%u, size=%u", + msg_pool.stname.aname, TX_MSG_POOL_SIZE, + msg_pool.useltsize); + return NULL; + } + + NSPOL_LOGINF (SC_DPDK_INFO, + "msg_pool_malloc=%p, num=%u, size=%u, total_mem=%d", + msg_mp_handle, TX_MSG_POOL_SIZE, msg_pool.useltsize, + nsfw_mem_get_len (msg_mp_handle, NSFW_MEM_SPOOL)); + DPDK_MEMORY_COUNT ((get_mempoll_msg_name ()), + nsfw_mem_get_len (msg_mp_handle, NSFW_MEM_SPOOL)); + MEM_STAT (SPL_MEM_MODULE, "spl_msg_pool", NSFW_SHMEM, + nsfw_mem_get_len (msg_mp_handle, NSFW_MEM_SPOOL)); + return msg_mp_handle; +} + +mring_handle +create_primary_box () +{ + nsfw_mem_mring mbox_pool; + mbox_pool.stname.entype = NSFW_SHMEM; + int retval = + spl_snprintf (mbox_pool.stname.aname, NSFW_MEM_NAME_LENGTH - 1, "%s", + get_stackx_ring_name ()); + if (retval < 0) + { + NSPOL_LOGERR ("spl_snprintf failed"); + return NULL; + } + + mbox_pool.usnum = MBOX_RING_SIZE - 1; + mbox_pool.isocket_id = SOCKET_ID_ANY; + mbox_pool.enmptype = NSFW_MRING_MPSC; + mring_handle mbox_handle = nsfw_mem_ring_create (&mbox_pool); + if (NULL == mbox_handle) + { + NSPOL_LOGERR ("create_primary_mbox failed]name=%s, num=%u", + mbox_pool.stname.aname, mbox_pool.usnum + 1); + return NULL; + } + + NSPOL_LOGINF (SC_DPDK_INFO, "primary_mbox_malloc=%p, num=%u, total_mem=%d", + mbox_handle, MBOX_RING_SIZE, + (nsfw_mem_get_len (mbox_handle, NSFW_MEM_RING))); + DPDK_MEMORY_COUNT ((get_stackx_ring_name ()), + (nsfw_mem_get_len (mbox_handle, NSFW_MEM_RING))); + MEM_STAT (SPL_MEM_MODULE, "primary_mbox_ring", NSFW_SHMEM, + (nsfw_mem_get_len (mbox_handle, NSFW_MEM_RING))); + return mbox_handle; +} + +mring_handle +create_priority_box (u32 prio) +{ + nsfw_mem_mring mbox_pool; + mbox_pool.stname.entype = NSFW_SHMEM; + int retval = + spl_snprintf (mbox_pool.stname.aname, NSFW_MEM_NAME_LENGTH - 1, "%s", + get_stackx_priority_ring_name (prio)); + if (retval < 0) + { + NSPOL_LOGERR ("spl_snprintf failed"); + return NULL; + } + + mbox_pool.usnum = MBOX_RING_SIZE - 1; + mbox_pool.isocket_id = SOCKET_ID_ANY; + mbox_pool.enmptype = NSFW_MRING_MPSC; + mring_handle mbox_handle = nsfw_mem_ring_create (&mbox_pool); + if (NULL == mbox_handle) + { + NSPOL_LOGERR ("Create priority mbox fail]name=%s, num=%u", + mbox_pool.stname.aname, mbox_pool.usnum + 1); + return NULL; + } + + NSPOL_LOGINF (SC_DPDK_INFO, "prio=%u, mbox=%p, num=%u, total_mem=%d", prio, + mbox_handle, MBOX_RING_SIZE, + (nsfw_mem_get_len (mbox_handle, NSFW_MEM_RING))); + DPDK_MEMORY_COUNT ((get_stackx_priority_ring_name (prio)), + (nsfw_mem_get_len (mbox_handle, NSFW_MEM_RING))); + MEM_STAT (SPL_MEM_MODULE, mbox_pool.stname.aname, NSFW_SHMEM, + (nsfw_mem_get_len (mbox_handle, NSFW_MEM_RING))); + return mbox_handle; + +} + +int +init_instance () +{ + int ret; + p_def_stack_instance = + (stackx_instance *) malloc (sizeof (stackx_instance)); + if (NULL == p_def_stack_instance) + { + NSPOL_LOGERR ("malloc failed"); + return -1; + } + + ret = MEMSET_S (p_def_stack_instance, sizeof (stackx_instance), 0, + sizeof (stackx_instance)); + if (EOK != ret) + { + NSPOL_LOGERR ("MEMSET_S failed]ret=%d", ret); + return -1; + } + + p_def_stack_instance->rss_queue_id = 0; + p_def_stack_instance->netif_list = NULL; + p_def_stack_instance->mp_tx = create_tx_mbuf_pool (); + if (!p_def_stack_instance->mp_tx) + { + return -1; + } + + (void) spl_reg_res_tx_mgr (p_def_stack_instance->mp_tx); // will only return 0, no need to check return value + + /* Modified above code to hold common_pcb */ + p_def_stack_instance->cpcb_seg = create_segment_pool (); + if (!p_def_stack_instance->cpcb_seg) + { + return -1; + } + + p_def_stack_instance->lmsg_pool = create_msg_pool (); + if (!p_def_stack_instance->lmsg_pool) + { + return -1; + } + + mring_handle mbox_array[SPL_MSG_BOX_NUM] = { NULL }; + p_def_stack_instance->lstack.primary_mbox.llring = create_primary_box (); + if (!p_def_stack_instance->lstack.primary_mbox.llring) + { + return -1; + } + mbox_array[0] = p_def_stack_instance->lstack.primary_mbox.llring; + + u32 m = 0; + while (m < MSG_PRIO_QUEUE_NUM) + { + p_def_stack_instance->lstack.priority_mbox[m].llring = + create_priority_box (m); + if (!p_def_stack_instance->lstack.priority_mbox[m].llring) + { + return -1; + } + mbox_array[m + 1] = + p_def_stack_instance->lstack.priority_mbox[m].llring; + m++; + } + + (void) spl_add_mbox (mbox_array, SPL_MSG_BOX_NUM); + + g_nsfw_rti_primary_stat = &p_def_stack_instance->lstat.primary_stat; //save to g_nsfw_rti_primary_stat(this is a SH addr) + return 0; +} + +void +spl_free_msgs_in_box (mring_handle r) +{ + i32 count = 0, i = 0; + + void **msgs = NULL; + data_com_msg *m = NULL; + + while ((count = nsfw_mem_ring_dequeuev (r, msgs, 32)) > 0) + { + /* drop all of them */ + if (msgs == NULL) + break; + + for (i = 0; i < count; i++) + { + m = (data_com_msg *) msgs[i]; + if (m->param.op_type == MSG_ASYN_POST) + ASYNC_MSG_FREE (m); + else + SYNC_MSG_ACK (m); + } + } +} + +inline int +spl_msg_malloc (data_com_msg ** p_msg_entry) +{ + mring_handle msg_pool = NULL; + int rslt; + stackx_instance *instance = p_def_stack_instance; + msg_pool = instance->lmsg_pool; + if (!msg_pool) + { + NSPOL_LOGERR ("msg_pool is NULL"); + return -1; + } + + rslt = nsfw_mem_ring_dequeue (msg_pool, (void **) p_msg_entry); + if ((rslt == 0) || (*p_msg_entry == NULL)) + { + NSPOL_LOGERR ("failed to get msg from ring"); + return -1; + } + + res_alloc (&(*p_msg_entry)->param.res_chk); + + (*p_msg_entry)->param.msg_from = msg_pool; + (*p_msg_entry)->param.err = ERR_OK; + return 0; +} + +struct spl_pbuf * +spl_mbuf_malloc (uint16_t len, spl_pbuf_type Type, u16_t * count) +{ + struct common_mem_mbuf *mbuf = NULL; + struct common_mem_mbuf *mbuf_first = NULL; + struct common_mem_mbuf *mbuf_tail = NULL; + struct spl_pbuf *buf = NULL; + struct spl_pbuf *first = NULL; + struct spl_pbuf *tail = NULL; + + mpool_handle mp = NULL; + + mp = p_def_stack_instance->mp_tx; + if (mp == NULL) + { + return NULL; /*if mp is NULL when init app will Inform */ + } + + while (len > 0) + { + mbuf = (struct common_mem_mbuf *) nsfw_mem_mbf_alloc (mp, NSFW_SHMEM); + if (unlikely (mbuf == NULL)) + { + if (mbuf_first != NULL) + { + if (res_free + (& + (((struct spl_pbuf *) ((char *) mbuf_first + + sizeof (struct + common_mem_mbuf)))->res_chk))) + { + NSPOL_LOGERR ("res_free failed"); + } + spl_mbuf_free (mbuf_first); + } + + return NULL; + } + + uint16_t alloc = TX_MBUF_MAX_LEN; + if (len < TX_MBUF_MAX_LEN) + { + alloc = len; + } + + (*count)++; + mbuf->data_len = alloc; + mbuf->next = NULL; + buf = + (struct spl_pbuf *) ((char *) mbuf + sizeof (struct common_mem_mbuf)); + res_alloc (&buf->res_chk); + + buf->next_a = 0; + buf->payload_a = ADDR_LTOSH_EXT (common_pktmbuf_mtod (mbuf, void *)); + buf->tot_len = len; + buf->len = alloc; + buf->type = Type; + buf->flags = 0; + + buf->freeNext = NULL; + + buf->conn_a = 0; + + if (first == NULL) + { + first = buf; + mbuf_first = mbuf; + tail = buf; + mbuf_tail = mbuf; + mbuf_first->nb_segs = 1; + mbuf_first->pkt_len = alloc; + } + else + { + /* Already there is a check for the return value of rtp_pktmbuf_alloc, + hence not an issue */ + + tail->next_a = ADDR_LTOSH_EXT (buf); + tail = buf; +#ifdef HAL_LIB +#else + mbuf_tail->next = mbuf; +#endif + mbuf_tail = mbuf; + + mbuf_first->pkt_len = (mbuf_first->pkt_len + mbuf->data_len); + mbuf_first->nb_segs++; + + } + + len -= alloc; + } + + return first; +} + +/* + * Ring distribution function: protocol stack once a packet processing, so there is no use of bulk package + * @param buf pbuf means * @param packet_inport the packet from which the port to enter, for the configuration table with the ip comparison + * @ Protocol stack add location: ip.c-> ip_input () -> (if (netif == NULL) branch) + * @ Return value: 0 for the send into * 0 for the transmission failed: send the original failure 1, + * err = -20 did not match to the client, err = -1Ring full, overflow, will release the package +*/ + +inline void +spl_mbuf_free (void *mbuf) +{ + (void) nsfw_mem_mbf_free ((mbuf_handle) mbuf, NSFW_SHMEM); +} + +inline uint16_t +spl_mbuf_refcnt_update (void *mbuf, int16_t value) +{ + common_mbuf_refcnt_set ((struct common_mem_mbuf *) mbuf, + common_mbuf_refcnt_read ((struct common_mem_mbuf *) + mbuf) + value); + return 1; +} |