summaryrefslogtreecommitdiffstats
path: root/stacks/lwip_stack/lwip_src/netif/sc_dpdk.c
diff options
context:
space:
mode:
Diffstat (limited to 'stacks/lwip_stack/lwip_src/netif/sc_dpdk.c')
-rw-r--r--stacks/lwip_stack/lwip_src/netif/sc_dpdk.c563
1 files changed, 563 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..a1497b6
--- /dev/null
+++ b/stacks/lwip_stack/lwip_src/netif/sc_dpdk.c
@@ -0,0 +1,563 @@
+/*
+*
+* 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
+#include "nsfw_shmem_mng.h"
+
+#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_LENTH - 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_LENTH - 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, 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, 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_LENTH - 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_LENTH - 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_LENTH - 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_shmem_mbfalloc(mp);
+ 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_shmem_mbffree((mbuf_handle) mbuf);
+}
+
+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;
+}