summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQiuwen Lu <[email protected]>2016-10-28 10:42:16 +0800
committerQiuwen Lu <[email protected]>2016-10-28 10:42:16 +0800
commitb88cf32a2d358882b9734fece1067ecaca3533d6 (patch)
treec0d473e25dde0ea8ce039faa9cd0c363ca2cfe00
parentf274e8a4d27e56d8e1600a7a3181017a4b538574 (diff)
parenta6a6c0630d71df0ed391966a859d77833d785e2a (diff)
Merge branch 'dev-4.X.X' into rel-4.X.Xv4.0.3-20161028
-rw-r--r--CMakeLists.txt13
-rw-r--r--cmake/FindDPDK.cmake5
-rw-r--r--conf/mrglobal.conf19
-rw-r--r--conf/pag.conf7
-rw-r--r--core/CMakeLists.txt5
-rw-r--r--core/include/mr_core.h34
-rw-r--r--core/include/mr_ctx.h135
-rw-r--r--core/include/mr_device.h73
-rw-r--r--core/include/mr_hwinfo.h14
-rw-r--r--core/include/mr_mrbuf.h10
-rw-r--r--core/include/mr_procman.h104
-rw-r--r--core/include/mr_rtdev.h47
-rw-r--r--core/include/mr_stat.h17
-rw-r--r--core/include/mr_vman.h4
-rw-r--r--core/include/mr_vnode.h6
-rw-r--r--core/src/core.c184
-rw-r--r--core/src/device.c367
-rw-r--r--core/src/mrbuf.c181
-rw-r--r--core/src/proc.c452
-rw-r--r--core/src/rtdev.c475
-rw-r--r--core/src/stat.c47
-rw-r--r--core/src/vman.c170
-rw-r--r--core/src/vnode.c137
-rw-r--r--include/mr_common.h (renamed from core/include/mr_common.h)16
-rw-r--r--include/mr_config.h.in6
-rw-r--r--include/mr_mask.h (renamed from core/include/mr_mask.h)0
-rw-r--r--include/mr_rawio.h4
-rw-r--r--pag/CMakeLists.txt2
-rw-r--r--pag/libpag.c125
-rw-r--r--pag/libpag.h14
-rw-r--r--runtime/CMakeLists.txt11
-rw-r--r--runtime/include/mr_runtime.h63
-rw-r--r--runtime/include/runtime.h54
-rw-r--r--runtime/src/app.c608
-rw-r--r--runtime/src/ctx.c (renamed from core/src/ctx.c)47
-rw-r--r--runtime/src/export.c105
-rw-r--r--runtime/src/hwinfo.c (renamed from core/src/hwinfo.c)77
-rw-r--r--runtime/src/id.c117
-rw-r--r--runtime/src/runtime.c235
-rw-r--r--service/CMakeLists.txt6
-rw-r--r--service/include/sc_common.h42
-rw-r--r--service/src/config.c151
-rw-r--r--service/src/core.c44
-rw-r--r--service/src/init.c18
-rw-r--r--service/src/ldbc.c6
-rw-r--r--service/src/register.c318
-rw-r--r--service/src/runtime.c140
-rw-r--r--service/src/rxtx.c83
-rw-r--r--slave/CMakeLists.txt2
-rw-r--r--slave/include/mrlib.h8
-rw-r--r--slave/include/mrlib_common.h25
-rw-r--r--slave/src/marsio.c (renamed from slave/src/mrlib.c)55
-rw-r--r--slave/src/rawio.c217
-rw-r--r--slave/src/rtdev.c100
-rw-r--r--stack/CMakeLists.txt12
-rw-r--r--stack/include/port_bitmap.h114
-rw-r--r--stack/include/sk_device.h124
-rw-r--r--stack/include/sk_neigh.h82
-rw-r--r--stack/include/sk_protocol_arp.h22
-rw-r--r--stack/include/sk_protocol_icmp.h6
-rw-r--r--stack/include/sk_protocol_tcp.h4
-rw-r--r--stack/include/sk_protocol_udp.h4
-rw-r--r--stack/include/sk_stack.h48
-rw-r--r--stack/src/device.c196
-rw-r--r--stack/src/neigh.c230
-rw-r--r--stack/src/protocol-arp.c66
-rw-r--r--stack/src/protocol-icmp.c9
-rw-r--r--stack/src/protocol-tcp.c8
-rw-r--r--stack/src/protocol-udp.c9
-rw-r--r--stack/src/rxtx.c88
-rw-r--r--stack/src/stack.c33
-rw-r--r--test/CMakeLists.txt15
-rw-r--r--test/TestStackNeigh.cc30
-rw-r--r--tools/CMakeLists.txt10
-rw-r--r--tools/stat/app_stat.c34
-rw-r--r--tools/stat/dev_stat.c (renamed from tools/stat/dev_stat_log.c)0
-rw-r--r--tools/stat/event_stat.c118
-rw-r--r--tools/stat/libstat.c15
-rw-r--r--tools/stat/libstat.h3
-rw-r--r--tools/tcpdump/rx_tcpdump.c347
80 files changed, 4786 insertions, 2046 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3cd5ccd..918735d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -30,18 +30,21 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXX_FLAGS}")
# Default Install Destination Directory
# set(CMAKE_INSTALL_PREFIX /opt/iiesoft/marsio)
-add_definitions(-fPIC)
-add_definitions(-D_GNU_SOURCE)
+add_definitions(-fPIC -Wall)
+add_definitions(-D_GNU_SOURCE -D__STDC_LIMIT_MACROS)
+include_directories(include)
add_subdirectory(${CMAKE_SOURCE_DIR}/support ${CMAKE_BINARY_DIR}/support)
+add_subdirectory(${CMAKE_SOURCE_DIR}/include)
+add_subdirectory(${CMAKE_SOURCE_DIR}/runtime)
add_subdirectory(${CMAKE_SOURCE_DIR}/core)
+add_subdirectory(${CMAKE_SOURCE_DIR}/stack)
add_subdirectory(${CMAKE_SOURCE_DIR}/service)
add_subdirectory(${CMAKE_SOURCE_DIR}/slave)
-add_subdirectory(${CMAKE_SOURCE_DIR}/include)
add_subdirectory(${CMAKE_SOURCE_DIR}/pag)
-add_subdirectory(${CMAKE_SOURCE_DIR}/examples)
+#add_subdirectory(${CMAKE_SOURCE_DIR}/examples)
add_subdirectory(${CMAKE_SOURCE_DIR}/tools)
-#add_subdirectory(${CMAKE_SOURCE_DIR}/test)
+add_subdirectory(${CMAKE_SOURCE_DIR}/test)
add_subdirectory(${CMAKE_SOURCE_DIR}/conf)
if(BUILD_TESTS)
diff --git a/cmake/FindDPDK.cmake b/cmake/FindDPDK.cmake
index 9938985..046a5fd 100644
--- a/cmake/FindDPDK.cmake
+++ b/cmake/FindDPDK.cmake
@@ -19,6 +19,8 @@ find_path(DPDK_INCLUDE_DIR
find_library(DPDK_LIBRARY
NAMES dpdk HINTS ${DPDK_ROOT_DIR}/lib)
+set(DPDK_LIBRARY_DIR ${DPDK_ROOT_DIR}/lib)
+
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(DPDK DEFAULT_MSG
DPDK_ROOT_DIR DPDK_INCLUDE_DIR DPDK_LIBRARY)
@@ -103,7 +105,8 @@ if(CMAKE_SYSTEM_PROCESSOR MATCHES "i686")
endif()
# Additional library
-set(DPDK_LIBRARY ${DPDK_LIBRARY} rt m dl)
+file(GLOB DPDK_LIBRARY_GEN "${DPDK_LIBRARY_DIR}/librte*.a" "${DPDK_LIBRARY_DIR}/libeth*.a")
+set(DPDK_LIBRARY -Wl,--whole-archive ${DPDK_LIBRARY_GEN} -Wl,--no-whole-archive rt m dl)
# Force Include
set(DPDK_FORCE_INCLUDE "-include ${DPDK_INCLUDE_DIR}/rte_config.h")
diff --git a/conf/mrglobal.conf b/conf/mrglobal.conf
index c3de750..ab9b8c9 100644
--- a/conf/mrglobal.conf
+++ b/conf/mrglobal.conf
@@ -1,8 +1,21 @@
+[device]
+device=mr0,mr1
+[device:mr0]
+in_addr=192.168.44.101
+in_mask=255.255.255.0
+gateway=192.168.44.1
+mtu=1500
+promisc=1
+[device:mr1]
+mtu=1500
+promisc=1
+vlan-strip=0
+vlan-filter=0
+rssmode=1
+
[service]
# lcore id for i/o service, use comma to split
iocore=1,2
-# device enabled. defined in mrdevice.conf
-device=mr0,mr1,mr2,mr3
# packet distributer mode
# value can be:
# 0:tuple2,source ip and dest ip(software)
@@ -35,4 +48,4 @@ txstream=4
[stat]
enable=1
[eal]
-virtaddr=0x7f40c4a00000 \ No newline at end of file
+virtaddr=0x7f40c4a00000
diff --git a/conf/pag.conf b/conf/pag.conf
new file mode 100644
index 0000000..18edee3
--- /dev/null
+++ b/conf/pag.conf
@@ -0,0 +1,7 @@
+[pag]
+dev_name=mr0,mr1
+app_name=sapp
+burst_rx=64
+burst_tx=64
+coremask=0xff
+autoexit=0
diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt
index bc33fc6..3a64c8c 100644
--- a/core/CMakeLists.txt
+++ b/core/CMakeLists.txt
@@ -6,8 +6,7 @@ include_directories(${DPDK_INCLUDE_DIR})
add_definitions(${DPDK_C_PREDEFINED})
include_directories(include)
-add_library(core src/core.c src/device.c src/hwinfo.c src/vnode.c src/proc.c src/ctx.c src/mrbuf.c
- src/vman.c src/stat.c)
-target_link_libraries(core ${DPDK_LIBRARY} MESA_prof_load_static)
+add_library(core src/core.c src/device.c src/vnode.c src/mrbuf.c src/vman.c src/stat.c src/rtdev.c)
+target_link_libraries(core MESA_prof_load_static mruntime)
target_link_libraries(core rt pthread dl)
target_include_directories(core INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/include/") \ No newline at end of file
diff --git a/core/include/mr_core.h b/core/include/mr_core.h
index 8a8308f..f39c901 100644
--- a/core/include/mr_core.h
+++ b/core/include/mr_core.h
@@ -1,6 +1,32 @@
#pragma once
-void mr_core_stage_preinit();
-void mr_core_stage_config();
-void mr_core_stage_init();
-void mr_core_stage_slaveinit(); \ No newline at end of file
+// ǰ������������ͷ�ļ���ѭ������
+struct mr_global_config;
+struct devman_ctx;
+struct stat_ctx;
+struct vnodeman_ctx;
+struct mrbuf_ctx;
+
+// Core��ʵ���ṹ�壨ȫ�֣�
+struct mr_core_instance
+{
+ struct mr_global_config * g_cfg;
+ struct devman_ctx * devman_ctx;
+ struct stat_ctx * stat_ctx;
+ struct vnodeman_ctx * vnodeman_ctx;
+ struct mrbuf_ctx * mrbuf_ctx;
+};
+
+// Core��ʵ���ṹ�壨���̼���
+struct mr_core_slave_instance
+{
+ void * _reserved;
+};
+
+struct mr_core_instance * mr_core_instance_create(struct mr_global_config * g_cfg);
+void mr_core_instance_destory(struct mr_core_instance * object);
+void mr_core_instance_config(struct mr_core_instance * object);
+void mr_core_instance_init(struct mr_core_instance * object);
+struct mr_core_slave_instance * mr_core_instance_slave_init(struct mr_core_instance * core_ctx);
+void mr_core_default_instance_set(struct mr_core_instance * object);
+struct mr_core_instance * mr_core_default_instance_get(); \ No newline at end of file
diff --git a/core/include/mr_ctx.h b/core/include/mr_ctx.h
deleted file mode 100644
index 497e431..0000000
--- a/core/include/mr_ctx.h
+++ /dev/null
@@ -1,135 +0,0 @@
-#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <rte_config.h>
-#include <mr_common.h>
-
-#ifndef MR_MAX_MODULES_NR
-#define MR_MAX_MODULES_NR 128
-#endif
-
-#ifndef MR_MAX_GSID
-#define MR_MAX_GSID 512
-#endif
-
-#ifndef MR_MAX_NR_THREAD
-#define MR_MAX_NR_THREAD 64
-#endif
-
-// Module ID Define
-enum _mr_mid_enum
-{
- MR_MID_PROCMAN = 0,
- MR_MID_MRBUF_MGR = 1,
- MR_MID_DEVICE_MGR = 2,
- MR_MID_FIB_MGR = 3,
- MR_MID_HWINFO = 4,
- MR_MID_VNODEMAN = 5,
- MR_MID_STAT = 6,
- MR_MID_MAX
-};
-
-// Global MARSIO Runtime Context
-struct mr_global_ctx
-{
- void * procinfos;
- void * modules_ctxs[MR_MAX_MODULES_NR];
-};
-
-// Process MARSIO Runtime Context
-struct mr_proc_ctx
-{
- struct mr_global_ctx * global_ctx;
- /* 进程序号 */
- process_id_t proc_id;
- /* 进程名称 */
- const char * procsym;
- /* CPU绑定掩码*/
- cpu_mask_t cpu_mask;
- /* 最大线程数量 */
- unsigned int nr_max_thread;
- /* 各模块上下文 */
- void * modules_ctxs[MR_MAX_MODULES_NR];
- /* 各进程上下文 */
- void * threads_ctxs;
- /* 进程私有空间 */
- void * priv;
-};
-
-// Thread MARSIO Runtime Context
-struct mr_thread_ctx
-{
- thread_id_t thread_id;
- struct mr_global_ctx * global_ctx;
- struct mr_proc_ctx * proc_ctx;
- void * modules_ctxs[MR_MAX_MODULES_NR];
- void * priv;
-
- cpu_id_t cpu_id;
- socket_id_t socket_id;
-};
-
-// Gloabl Marsio Configure Information
-struct mr_config
-{
- char glob_cfg_file[MR_STRING_MAX];
- void * modules_cfgs[MR_MAX_MODULES_NR];
-};
-
-struct mr_module;
-
-// Module Description
-typedef int(* mr_module_entry_t)(struct mr_module * m_desc,
- struct mr_config *, struct mr_global_ctx *);
-
-struct mr_module
-{
- unsigned int mid;
- const char * sym;
- mr_module_entry_t preinit;
- mr_module_entry_t config;
- mr_module_entry_t init;
- mr_module_entry_t destory;
- mr_module_entry_t slaveinit;
-};
-
-typedef uint32_t mid_t;
-
-static int __default_module_handler(struct mr_module * m_desc,
- struct mr_config * g_cfg, struct mr_global_ctx * g_ctx)
-{
- return 0;
-}
-
-
-#define MODULE_CTX(g_ctx, mid) (g_ctx->modules_ctxs[mid])
-#define MODULE_CFG(g_cfg, mid) (g_cfg->modules_cfgs[mid])
-
-int mr_global_ctx_init();
-int mr_global_ctx_slave_init();
-int mr_global_cfg_init();
-int mr_global_cfg_slave_init();
-
-struct mr_global_ctx * mr_global_ctx_get();
-struct mr_config * mr_global_config_get();
-struct mr_proc_ctx * mr_proc_ctx_get();
-void mr_proc_ctx_set(void * ctx);
-void mr_thread_ctx_set(void * ctx);
-struct mr_thread_ctx* mr_thread_ctx_get();
-
-static inline thread_id_t mr_thread_id()
-{
- return mr_thread_ctx_get()->thread_id;
-}
-
-static inline process_id_t mr_proc_id()
-{
- return mr_proc_ctx_get()->proc_id;
-}
-
-#ifdef __cplusplus
-}
-#endif \ No newline at end of file
diff --git a/core/include/mr_device.h b/core/include/mr_device.h
index d992df6..fb1578f 100644
--- a/core/include/mr_device.h
+++ b/core/include/mr_device.h
@@ -4,12 +4,62 @@
extern "C" {
#endif
+#include <limits.h>
#include <mr_common.h>
#include <rte_mbuf.h>
#include <rte_ether.h>
#include <rte_pci.h>
#include <rte_config.h>
-#include "mr_ctx.h"
+
+// RSSģʽ
+enum rssmode
+{
+ MR_DEV_RSSMODE_DEFAULT = 0,
+ MR_DEV_RSSMODE_2TUPLE_SYM = 1,
+ MR_DEV_RSSMODE_4TUPLE_SYM = 2,
+ MR_DEV_RSSMODE_4TUPLE_ASYM = 3
+};
+
+
+struct mr_dev_info
+{
+ /* ����MAC��ַ*/
+ struct ether_addr phy_ether_addr;
+ /* PCI��ַ */
+ struct rte_pci_addr pci_addr;
+ /* Ĭ��MTU */
+ unsigned short default_mtu;
+ /* RX����������� */
+ unsigned int nr_rxq_max;
+ /* TX����������� */
+ unsigned int nr_txq_max;
+};
+
+struct mr_dev_param
+{
+ /* �豸���� */
+ char symbol[MR_SYMBOL_MAX];
+ /* �û�MAC��ַ*/
+ struct ether_addr usr_ether_addr;
+ /* ������ */
+ unsigned int nr_queues;
+ /* MTU */
+ unsigned short mtu;
+ /* ����ģʽ */
+ unsigned int promisc;
+ /* VLAN Filter */
+ unsigned int en_vlan_filter;
+ /* VLAN Strip */
+ unsigned int en_vlan_strip;
+ /* Drop-En */
+ unsigned int en_drop;
+ /* RSSģʽ*/
+ unsigned int rssmode;
+ /* RX������������ */
+ unsigned int nr_rxdesc;
+ /* TX������������ */
+ unsigned int nr_txdesc;
+};
struct mr_dev
{
@@ -18,22 +68,19 @@ struct mr_dev
char symbol[MR_SYMBOL_MAX];
/* �豸�� */
port_id_t port_id;
- /* MAC��ַ*/
- struct ether_addr ether_addr;
- /* PCI��ַ */
- struct rte_pci_addr pci_addr;
+ /* �豸��Ϣ */
+ struct mr_dev_info info;
+ /* �û����� */
+ struct mr_dev_param param;
/* RX�������� */
unsigned int nr_rxq;
/* TX�������� */
unsigned int nr_txq;
- /* RX����������� */
- unsigned int nr_rxq_max;
- /* TX����������� */
- unsigned int nr_txq_max;
- /* MTU */
+ /* ����ʱMTU */
unsigned short mtu;
- /* ����ģʽ */
- unsigned int promisc;
+ /* ����ʱMAC��ַ*/
+ struct ether_addr ether_addr;
+
/* �Ƿ����� */
unsigned int enable;
/* �豸�Ƿ��ѳ�ʼ�� */
@@ -62,7 +109,7 @@ struct mr_devq
typedef struct mr_devq mr_devq_t;
typedef struct mr_dev mr_dev_t;
-mr_dev_t * mr_device_open(const char * devsym, unsigned int nr_queue, flags_t flags);
+mr_dev_t * mr_device_open(struct mr_dev_param * param);
int mr_device_close(mr_devq_t * devq);
mr_devq_t * mr_device_attach(const char * devsym);
int mr_device_list(mr_dev_t * devs[], int nr_max_devs, flags_t flags);
diff --git a/core/include/mr_hwinfo.h b/core/include/mr_hwinfo.h
deleted file mode 100644
index fe816f6..0000000
--- a/core/include/mr_hwinfo.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-int mr_hwinfo_nr_sockets();
-int mr_hwinfo_nr_cpus();
-int mr_hwinfo_physical_cpu_id(int cpu_id);
-int mr_hwinfo_socket_id(int cpu_id);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/core/include/mr_mrbuf.h b/core/include/mr_mrbuf.h
index bf30fa0..01c3595 100644
--- a/core/include/mr_mrbuf.h
+++ b/core/include/mr_mrbuf.h
@@ -27,19 +27,17 @@ struct marsio_pri_t{
};
-typedef struct{
+struct mrbuf_ctx
+{
uint32_t mempool_block_num;
uint32_t mempool_dataroom_size;
uint32_t mempool_priv_size;
-}mrbuf_cfg_t;
-typedef struct{
rte_atomic32_t mr_ctrl_zone_id;
int32_t mr_buf_pool_num;
struct rte_mempool **mr_buf_pool;
-}mrbuf_global_ctx_t;
-
-
+};
+
typedef struct{
uint32_t lcore_id;
uint32_t __pad1;
diff --git a/core/include/mr_procman.h b/core/include/mr_procman.h
deleted file mode 100644
index 05a8c44..0000000
--- a/core/include/mr_procman.h
+++ /dev/null
@@ -1,104 +0,0 @@
-#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <mr_common.h>
-#include <sys/queue.h>
-
-enum proc_state
-{
- MR_PROC_STATE_READY,
- MR_PROC_STATE_RUN,
- MR_PROC_STATE_SUSPEND
-};
-
-struct thread_info
-{
- /* �߳�˳��� */
- thread_id_t sid;
- /* ȫ���߳�˳��� */
- thread_id_t gsid;
- /* ���̺� */
- thread_id_t proc_id;
-
- /* ����CPU��� */
- cpu_id_t cpu_id;
- /* ����NUMA�ڵ���� */
- socket_id_t socket_id;
- /* ����˽�������� */
- struct mr_thread_ctx * thread_ctx;
-};
-
-struct proc_info
-{
- /* ��һ�� */
- TAILQ_ENTRY(proc_info) next;
- /* ���̱�ʶ�� */
- char symbol[MR_SYMBOL_MAX];
- /* ������� */
- process_id_t proc_id;
- /* ȫ���߳���ţ���ʼ��ţ�����ҿ� */
- thread_id_t gsid_start;
- /* ȫ���߳���ţ���ֹ��ţ�����ҿ� */
- thread_id_t gsid_end;
- /* ����״̬ */
- volatile unsigned int state;
- /* ����˽��Ctx */
- struct mr_proc_ctx * proc_ctx;
- /* ���������е��߳���Ϣ */
- struct thread_info * thread_info;
- /* ����CPU������ */
- cpu_mask_t proc_cpu_mask;
- /* ��������������߳����� */
- unsigned int nr_max_thread;
- /* Ŀǰ������߳���� */
- unsigned int cur_sid;
- /* Ŀǰ�����ȫ���߳���� */
- unsigned int cur_gsid;
-};
-
-/**
-* \brief �ڽ��̹������д���һ�����̽ṹ��������Ͷ������״̬
-* \param sym ���̱�־��
-* \param cpu_mask ����CPU�׺�������
-* \return ִ��״̬������0���гɹ�
-*/
-int procman_process_create(const char * sym, cpu_mask_t cpu_mask);
-
-/**
-* \brief ��ѯ�ض����ƵĽ����Ƿ����
-* \param sym ���̱�ʶ��
-* \return 1Ϊ���ڣ�0Ϊ������
-*/
-int procman_process_lookup(const char * sym);
-
-/**
-* \brief ע����������Ļ���
-* �ڽ��̻����е��ã�ע��Ľ��̱�ʶ������֮ǰע�����
-* \param sym ���̱�ʶ��
-* \return �Ƿ�ɹ���0Ϊ�ɹ���<0ʧ�ܡ�
-*/
-int procman_register_myself(const char * sym);
-
-/**
- * \brief ��ע����������Ļ���
- * ͨ���ڽ����˳�ʱ����
- * \return �Ƿ�ɹ���0Ϊ�ɹ���<0ʧ�ܡ�
- */
-int procman_unregister_myself();
-int procman_thread_register_myself();
-int procman_thread_unregister_myself();
-
-/**
- * \brief �г�ע������н���
- * \param infos �����������洢�ռ�[OUT]
- * \param nr_max_infos �����������洢�ռ��С
- * \return ʵ�ʽ�������������
- */
-int procman_list_all(struct proc_info * infos[], int nr_max_infos);
-
-#ifdef __cplusplus
-}
-#endif \ No newline at end of file
diff --git a/core/include/mr_rtdev.h b/core/include/mr_rtdev.h
new file mode 100644
index 0000000..0dda88c
--- /dev/null
+++ b/core/include/mr_rtdev.h
@@ -0,0 +1,47 @@
+#pragma once
+
+/* \brief ����ʱ�����豸������
+*
+* ����ʱ�����豸������Ϊ����ʱӦ�õ��豸��VNode�ڵ㽨����Ӧ��ϵ��
+* ����������ʱ��ͨ�����ñ���������豸��Ӧ��vnodeman_desc��������
+*
+*/
+
+
+#include <mr_vman.h>
+#include <mr_common.h>
+
+struct mr_rtdev_stream
+{
+ char symbol[MR_SYMBOL_MAX];
+ struct vnodeman_attach_desc * rxd;
+ struct vnodeman_attach_desc * txd;
+ struct vnodeman_attach_desc * fasttxd;
+};
+
+// ����һ������ʱ�����豸
+int rt_device_serv_create(const char * devsym, const char * servsym, unsigned int nr_serv_thread,
+ unsigned int sz_tunnel, unsigned int sz_buffer);
+
+// ����һ������ʱ�����豸
+int rt_device_serv_destory(const char * devsym);
+
+// ���豸��ͨ����Slave������ʹ��
+int rt_device_open(const char * devsym, const char * appsym,
+ unsigned int nr_rxstream, unsigned int nr_txstream);
+
+// ���豸����ÿ���̵߳���һ�Σ���ȡ��ǰ�̵߳������������������ʹ�ã�
+struct mr_rtdev_stream * rt_dev_serv_open_stream(const char * devsym,
+ const char * servsym);
+
+#define RTDEV_FLAGS_OPEN_STREAM_RX ( 1UL << 0 )
+#define RTDEV_FLAGS_OPEN_STREAM_TX ( 1UL << 1 )
+#define RTDEV_FLAGS_OPEN_STREAM_ALL ( RTDEV_FLAGS_OPEN_STREAM_RX | RTDEV_FLAGS_OPEN_STREAM_TX )
+
+// ���豸����ÿ���̵߳���һ�Σ���ȡ��ǰ�̵߳���������
+struct mr_rtdev_stream * rt_dev_open_stream(const char * devsym,
+ const char * appsym, flags_t flags);
+
+int rt_dev_stream_close(struct mr_rtdev_stream * stream);
+
+int rt_device_close(const char * devsym, const char * appsym); \ No newline at end of file
diff --git a/core/include/mr_stat.h b/core/include/mr_stat.h
index 5fc6026..66eec40 100644
--- a/core/include/mr_stat.h
+++ b/core/include/mr_stat.h
@@ -3,9 +3,11 @@
#include <rte_config.h>
#include <rte_cycles.h>
#include <rte_memory.h>
-#include <mr_ctx.h>
#include <rte_mbuf.h>
+#include <mr_common.h>
+#include <mr_runtime.h>
+
#define MR_STAT_MAX_DEVICE RTE_MAX_ETHPORTS
#define MR_STAT_MAX_THREAD MR_MAX_GSID
@@ -21,7 +23,7 @@ struct mr_device_stat
volatile uint64_t dev_rx_bit[RTE_MAX_ETHPORTS];
volatile uint64_t dev_tx_frame[RTE_MAX_ETHPORTS];
volatile uint64_t dev_tx_bit[RTE_MAX_ETHPORTS];
- } __rte_cache_aligned _per_thread[MR_MAX_GSID];
+ } __rte_cache_aligned _per_thread[MR_GSID_MAX];
};
struct mr_vnode_stat
@@ -34,7 +36,7 @@ struct mr_vnode_stat
volatile uint64_t block_enqueue;
volatile uint64_t tunnel_enqueue;
volatile uint64_t tunnel_enqueue_fail;
- } __rte_cache_aligned _per_thread[MR_MAX_GSID];
+ } __rte_cache_aligned _per_thread[MR_GSID_MAX];
};
struct mr_app_stat
@@ -47,7 +49,8 @@ struct mr_app_stat
volatile uint64_t tx_frame;
volatile uint64_t rx_byte;
volatile uint64_t tx_byte;
- } __rte_cache_aligned _per_thread[MR_MAX_GSID];
+ volatile uint64_t drop_frame;
+ } __rte_cache_aligned _per_thread[MR_GSID_MAX];
} __per_app[MR_APP_MAX];
};
@@ -68,7 +71,7 @@ struct mr_perf_stat
struct mr_perf_item sc_rx_loop_dispatch;
struct mr_perf_item pag_get_frame;
struct mr_perf_item pag_get;
- } __rte_cache_aligned _per_thread[MR_MAX_GSID];
+ } __rte_cache_aligned _per_thread[MR_GSID_MAX];
};
struct mr_event_stat
@@ -78,7 +81,7 @@ struct mr_event_stat
volatile uint64_t ev_rx_dup_failed;
volatile uint64_t ev_rx_entunnel_failed;
- } __rte_cache_aligned _per_thread[MR_MAX_GSID];
+ } __rte_cache_aligned _per_thread[MR_GSID_MAX];
};
extern struct mr_vnode_stat * mr_vnode_stat_get();
@@ -109,7 +112,7 @@ do { \
do { \
struct mr_app_stat * st = mr_app_stat_get(); \
if(st) \
- st->__per_app[mr_proc_id()]. \
+ st->__per_app[mr_app_id()]. \
_per_thread[mr_thread_id()]._s += _n; \
}while(0)
diff --git a/core/include/mr_vman.h b/core/include/mr_vman.h
index 27550fb..6433063 100644
--- a/core/include/mr_vman.h
+++ b/core/include/mr_vman.h
@@ -31,6 +31,10 @@ int mr_vnodeman_register_consumer(const char * vnode_sym, const char * cons_sym,
int mr_vnodeman_register_producer(const char * vnode_sym, const char * prod_sym,
unsigned int nr_prod_queue);
+int mr_vnodeman_unregister_consumer(const char * vnode_sym, const char * cons_sym);
+
+int mr_vnodeman_unregister_producer(const char * vnode_sym, const char * cons_sym);
+
struct vnodeman_attach_desc * mr_vnodeman_consumer_attach(const char * vnode_sym,
const char * cons_sym);
diff --git a/core/include/mr_vnode.h b/core/include/mr_vnode.h
index 1e97fe0..e787df8 100644
--- a/core/include/mr_vnode.h
+++ b/core/include/mr_vnode.h
@@ -1,5 +1,4 @@
#pragma once
-#include "mr_ctx.h"
#ifdef __cplusplus
extern "C" {
@@ -14,6 +13,7 @@ extern "C" {
struct tunnel_block
{
+ unsigned int deleted;
unsigned int nr_prodq;
unsigned int nr_consq;
struct tunnel_desc * descs[0];
@@ -113,6 +113,10 @@ struct vnode_prod * vnode_create_prod(struct vnode * vnode, struct vnode_ops * o
struct vnode_cons * vnode_create_cons(struct vnode * vnode, struct vnode_ops * ops,
const char * symbol, int nr_consq);
+int vnode_delete_prod(struct vnode_prod * prod, struct vnode_ops * ops);
+
+int vnode_delete_cons(struct vnode_cons * cons, struct vnode_ops * ops);
+
int vnode_delete(struct vnode * vnode, struct vnode_ops * ops);
struct vnode_prod * vnode_prod_lookup(struct vnode * vnode, const char * sym);
diff --git a/core/src/core.c b/core/src/core.c
index 059c41d..105370d 100644
--- a/core/src/core.c
+++ b/core/src/core.c
@@ -6,130 +6,132 @@
#include <stdio.h>
#include <assert.h>
#include <mr_common.h>
-#include <mr_ctx.h>
-#include <mr_procman.h>
-
-extern struct mr_module module_desc_hwinfo;
-extern struct mr_module module_desc_procman;
-extern struct mr_module module_desc_device;
-extern struct mr_module module_desc_mrbuf;
-extern struct mr_module module_desc_vnodeman;
-extern struct mr_module module_desc_stat;
-
-#if 0
-#define __EXEUCATE_MODULE_FUNCTION(_m, _f, _strm, _strf) \
-do { \
- assert(_m._f != NULL); \
- int ret = _m._f(&_m, g_cfg, g_ctx) \
- MR_CHECK(ret >= 0, "Failed at "#_strm)
-#endif
-
-void mr_core_stage_preinit()
+#include <mr_runtime.h>
+#include <rte_ip_frag.h>
+#include <mr_core.h>
+
+// �ⲿ�����������豸������
+extern int devman_ctx_init(struct mr_core_instance * core_instance);
+extern int devman_config(struct mr_core_instance * core_instance);
+extern int devman_init(struct mr_core_instance * core_instance);
+extern int devman_destory(struct mr_core_instance * core_instance);
+extern int devman_slave_init(struct mr_core_instance * core_instance,
+ struct mr_core_slave_instance * slave_instance);
+
+// �ⲿ����������ͳ��
+extern int stat_ctx_init(struct mr_core_instance * core_instance);
+extern int stat_config(struct mr_core_instance * core_instance);
+extern int stat_init(struct mr_core_instance * core_instance);
+extern int stat_slave_init(struct mr_core_instance * core_instance,
+ struct mr_core_slave_instance * slave_instance);
+extern int stat_destory(struct mr_core_instance * core_instance);
+
+// �ⲿ�������������Ļ�����������
+extern int mrbuf_ctx_init(struct mr_core_instance * core_instance);
+extern int mrbuf_config(struct mr_core_instance * core_instance);
+extern int mrbuf_init(struct mr_core_instance * core_instance);
+extern int mrbuf_destory(struct mr_core_instance * core_instance);
+extern int mrbuf_slave_init(struct mr_core_instance * core_instance,
+ struct mr_core_slave_instance * slave_instance);
+
+// �ⲿ�����������������ݽڵ������
+extern int vnodeman_ctx_init(struct mr_core_instance * core_instance);
+extern int vnodeman_config(struct mr_core_instance * core_instance);
+extern int vnodeman_init(struct mr_core_instance * core_instance);
+extern int vnodeman_slave_init(struct mr_core_instance * core_instance,
+ struct mr_core_slave_instance * slave_instance);
+extern int vnodeman_destory(struct mr_core_instance * core_instance);
+
+// Ĭ�ϵ�CoreInstance
+static struct mr_core_instance * default_core_instance = NULL;
+
+struct mr_core_instance * mr_core_instance_create(struct mr_global_config * g_cfg)
{
- int ret = 0;
- struct mr_global_ctx * g_ctx = mr_global_ctx_get();
- struct mr_config * g_cfg = mr_global_config_get();
-
- assert(module_desc_hwinfo.preinit != NULL);
- ret = module_desc_hwinfo.preinit(&module_desc_hwinfo, g_cfg, g_ctx);
- MR_CHECK(ret >= 0, "Failed at CoreHwinfo Preinit stage.");
+ struct mr_core_instance * instance;
+ instance = rte_zmalloc("CoreInstance", sizeof(struct mr_core_instance), 0);
+ MR_CHECK(instance != NULL, "Cannot alloc memory for CoreInstance. ");
- assert(module_desc_procman.preinit != NULL);
- ret = module_desc_procman.preinit(&module_desc_procman, g_cfg, g_ctx);
- MR_CHECK(ret >= 0, "Failed at CoreProcman Preinit stage.");
+ int ret = 0;
+ instance->g_cfg = g_cfg;
- assert(module_desc_mrbuf.preinit != NULL);
- ret = module_desc_mrbuf.preinit(&module_desc_mrbuf, g_cfg, g_ctx);
+ ret = mrbuf_ctx_init(instance);
MR_CHECK(ret >= 0, "Failed at CoreMrbuf Preinit stage.");
- assert(module_desc_device.preinit != NULL);
- ret = module_desc_device.preinit(&module_desc_device, g_cfg, g_ctx);
+ ret = devman_ctx_init(instance);
MR_CHECK(ret >= 0, "Failed at CoreDevice Preinit stage.");
- assert(module_desc_vnodeman.preinit != NULL);
- ret = module_desc_vnodeman.preinit(&module_desc_vnodeman, g_cfg, g_ctx);
- MR_CHECK(ret >= 0, "Failed at CoreVNodeMan Preinit stage.");
+ ret = vnodeman_ctx_init(instance);
+ MR_CHECK(ret >= 0, "Failed at CoreVNodeMan Preinit stage.");
- assert(module_desc_stat.preinit != NULL);
- ret = module_desc_stat.preinit(&module_desc_stat, g_cfg, g_ctx);
+ ret = stat_ctx_init(instance);
MR_CHECK(ret >= 0, "Failed at CoreStat Preinit stage.");
- return;
+ return instance;
}
-void mr_core_stage_config()
+void mr_core_instance_destory(struct mr_core_instance * object)
{
- int ret = 0;
- struct mr_global_ctx * g_ctx = mr_global_ctx_get();
- struct mr_config * g_cfg = mr_global_config_get();
+ return;
+}
- assert(module_desc_mrbuf.config != NULL);
- ret = module_desc_mrbuf.config(&module_desc_mrbuf, g_cfg, g_ctx);
+void mr_core_instance_config(struct mr_core_instance * object)
+{
+ int ret = mrbuf_config(object);
MR_CHECK(ret >= 0, "Failed at CoreMrbuf Config stage.");
- assert(module_desc_device.config != NULL);
- ret = module_desc_device.config(&module_desc_device, g_cfg, g_ctx);
+ ret = devman_config(object);
MR_CHECK(ret >= 0, "Failed at CoreDevice Config stage.");
- assert(module_desc_stat.config != NULL);
- ret = module_desc_stat.config(&module_desc_stat, g_cfg, g_ctx);
+ ret = stat_config(object);
MR_CHECK(ret >= 0, "Failed at CoreStat Config stage.");
-
return;
}
-void mr_core_stage_init()
+void mr_core_instance_init(struct mr_core_instance * object)
{
- int ret = 0;
- struct mr_global_ctx * g_ctx = mr_global_ctx_get();
- struct mr_config * g_cfg = mr_global_config_get();
-
- assert(module_desc_hwinfo.init != NULL);
- ret = module_desc_hwinfo.init(&module_desc_hwinfo, g_cfg, g_ctx);
- MR_CHECK(ret >= 0, "Failed at CoreHwInfo Init stage.");
-
- assert(module_desc_procman.init != NULL);
- ret = module_desc_procman.init(&module_desc_procman, g_cfg, g_ctx);
- MR_CHECK(ret >= 0, "Failed at CoreProcman Init stage.");
-
- assert(module_desc_mrbuf.init != NULL);
- ret = module_desc_mrbuf.init(&module_desc_mrbuf, g_cfg, g_ctx);
+ int ret = mrbuf_init(object);
MR_CHECK(ret >= 0, "Failed at CoreMrbuf Init stage.");
-
- assert(module_desc_device.init != NULL);
- ret = module_desc_device.init(&module_desc_device, g_cfg, g_ctx);
- MR_CHECK(ret >= 0, "Failed at CoreDevice Init stage.");
+ ret = devman_init(object);
+ MR_CHECK(ret >= 0, "Failed at CoreDevice Init stage.");
return;
}
-void mr_core_stage_slaveinit()
+/* default_instance: Ĭ�ϵ�instance��������core���е��ⲿ������
+ * �ⲿ������ȱ��objectָ���ʱ�򣬶�ȡĬ��instance������֮��
+ *
+ * �ⲿ�����׼�÷���
+ * ��1������create���������instance��
+ * ��2���������instance�������ڴ������Ӧλ�á�
+ * ��3���������instanceΪĬ�ϵ�instance.
+ *
+ * ��һ��Ƶ�Ŀ���ǽ�instance�빲���ڴ���
+ */
+
+void mr_core_default_instance_set(struct mr_core_instance * object)
{
- int ret = 0;
- struct mr_global_ctx * g_ctx = mr_global_ctx_get();
- struct mr_config * g_cfg = mr_global_config_get();
+ default_core_instance = object;
+ return;
+}
- assert(module_desc_hwinfo.slaveinit != NULL);
- ret = module_desc_hwinfo.slaveinit(&module_desc_hwinfo, g_cfg, g_ctx);
- MR_CHECK(ret >= 0, "Failed at CoreHwinfo slaveinit stage.");
+struct mr_core_instance * mr_core_default_instance_get()
+{
+ assert(default_core_instance != NULL);
+ return default_core_instance;
+}
- assert(module_desc_procman.slaveinit != NULL);
- ret = module_desc_procman.slaveinit(&module_desc_procman, g_cfg, g_ctx);
- MR_CHECK(ret >= 0, "Failed at CoreProcman slaveinit stage.");
+struct mr_core_slave_instance * mr_core_instance_slave_init(struct mr_core_instance * object)
+{
+ struct mr_core_slave_instance * slave_instance;
+ slave_instance = rte_zmalloc("CoreSlaveInstance", sizeof(struct mr_core_slave_instance), 0);
+ MR_CHECK(slave_instance != NULL, "Cannot alloc memory for CoreSlaveInstance. ");
- assert(module_desc_mrbuf.slaveinit != NULL);
- ret = module_desc_mrbuf.slaveinit(&module_desc_mrbuf, g_cfg, g_ctx);
+ int ret = mrbuf_slave_init(object, slave_instance);
MR_CHECK(ret >= 0, "Failed at CoreMrbuf slaveinit stage.");
-
- assert(module_desc_device.slaveinit != NULL);
- ret = module_desc_device.slaveinit(&module_desc_device, g_cfg, g_ctx);
+ ret = devman_slave_init(object, slave_instance);
MR_CHECK(ret >= 0, "Failed at CoreDevice slaveinit stage.");
-
- assert(module_desc_vnodeman.slaveinit != NULL);
- ret = module_desc_vnodeman.slaveinit(&module_desc_vnodeman, g_cfg, g_ctx);
+ ret = vnodeman_slave_init(object, slave_instance);
MR_CHECK(ret >= 0, "Failed at CoreVNodeMan slaveinit stage.");
-
- assert(module_desc_stat.slaveinit != NULL);
- ret = module_desc_stat.slaveinit(&module_desc_stat, g_cfg, g_ctx);
+ ret = stat_slave_init(object, slave_instance);
MR_CHECK(ret >= 0, "Failed at CoreStat slaveinit stage.");
- return;
+ return slave_instance;
} \ No newline at end of file
diff --git a/core/src/device.c b/core/src/device.c
index 49a3a58..31c7f0a 100644
--- a/core/src/device.c
+++ b/core/src/device.c
@@ -16,9 +16,10 @@
#include <MESA_prof_load.h>
#include <mr_common.h>
-#include <mr_ctx.h>
#include <mr_mrbuf.h>
#include <mr_device.h>
+#include <mr_core.h>
+#include <mr_runtime.h>
#ifndef MR_DEVICE_DEFAULT_NR_RX_DESC
#define MR_DEVICE_DEFAULT_NR_RX_DESC 512
@@ -54,26 +55,28 @@ static struct rte_eth_conf eth_conf_default = {
}
};
+static uint8_t default_sym_rss_key[40] =
+{
+ 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a,
+ 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a,
+ 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a,
+ 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a,
+ 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a
+};
+
TAILQ_HEAD(mr_deivce_list, mr_dev);
struct devman_ctx
{
+ unsigned int default_nr_rx_desc;
+ unsigned int default_nr_tx_desc;
+ struct rte_eth_conf * default_eth_conf;
+
struct mr_deivce_list device_list;
struct mr_dev * rte_device[RTE_MAX_ETHPORTS];
};
-struct devman_config
-{
- unsigned int nr_rx_desc;
- unsigned int nr_tx_desc;
- unsigned int en_stat;
- struct rte_eth_conf eth_conf;
-};
-
-// Module Global Ctx
-static struct devman_ctx * module_ctx;
-// Module Global Config
-static struct devman_config * module_config;
+#if 0
static int kni_change_mtu(__attribute__((unused)) uint8_t port_id,
__attribute__((unused)) unsigned new_mtu)
@@ -86,7 +89,7 @@ static int kni_config_network_interface(__attribute__((unused)) uint8_t port_id,
return 1;
}
-static struct rte_kni * kni_alloc(const char * sym,
+static struct rte_kni * __rte_unused kni_alloc(const char * sym,
uint8_t port_id, struct rte_mempool * pktmbuf_pool)
{
struct rte_kni *kni;
@@ -112,18 +115,21 @@ static struct rte_kni * kni_alloc(const char * sym,
return kni;
}
-static void kni_free(struct rte_kni * kni)
+static void __rte_unused kni_free(struct rte_kni * kni)
{
rte_kni_release(kni);
}
+#endif
+
// 设备预打开,真正的初始化过程在设备初始化时进行。
-struct mr_devq * __device_open_devq(struct mr_dev * dev, flags_t flags)
+struct mr_devq * __device_open_devq(struct mr_dev * dev)
{
// 越界检测
+ struct mr_dev_info * dev_info = &dev->info;
assert(dev->nr_devq <= RTE_DIM(dev->devq));
- assert(dev->nr_rxq <= dev->nr_rxq_max);
- assert(dev->nr_txq <= dev->nr_txq_max);
+ assert(dev->nr_rxq <= dev_info->nr_rxq_max);
+ assert(dev->nr_txq <= dev_info->nr_txq_max);
// 检查队列数量,超过队列数申请即失败
if (dev->nr_devq >= RTE_DIM(dev->devq))
@@ -133,14 +139,14 @@ struct mr_devq * __device_open_devq(struct mr_dev * dev, flags_t flags)
return NULL;
}
- if (dev->nr_rxq >= dev->nr_rxq_max)
+ if (dev->nr_rxq >= dev_info->nr_rxq_max)
{
MR_LOG(INFO, BASE, "DeviceManager, DeviceOpen, Device %s, "
"Too many recieve queues\n", dev->symbol);
return NULL;
}
- if (dev->nr_txq >= dev->nr_txq_max)
+ if (dev->nr_txq >= dev_info->nr_txq_max)
{
MR_LOG(INFO, BASE, "DeviceManager, DeviceOpen, Device %s, "
"Too many xmit queues\n", dev->symbol);
@@ -169,11 +175,11 @@ struct mr_devq * __device_open_devq(struct mr_dev * dev, flags_t flags)
}
// 设备预打开,一次打开多个队列
-int __device_open_multidevq(struct mr_dev * dev, flags_t flags, int count)
+int __device_open_multidevq(struct mr_dev * dev, int count)
{
for(int i = 0; i < count; i++)
{
- struct mr_devq * devq = __device_open_devq(dev, flags);
+ struct mr_devq * devq = __device_open_devq(dev);
if (devq == NULL) return -1;
}
@@ -196,26 +202,25 @@ static struct mr_dev * __device_lookup(struct devman_ctx * ctx,
return dev_ret;
}
-static struct mr_dev * __device_open(struct devman_ctx * ctx, const char * devsym,
- unsigned int nr_queue, flags_t flags)
+static struct mr_dev * __device_open(struct devman_ctx * ctx,
+ struct mr_dev_param * param)
{
- struct mr_dev * dev = __device_lookup(ctx, devsym);
+ struct mr_dev * dev = __device_lookup(ctx, param->symbol);
if (dev == NULL)
{
MR_LOG(INFO, BASE, "DeviceManager, DeviceOpen, "
- "Cannot found device %s\n", devsym);
+ "Cannot found device %s\n", param->symbol);
return NULL;
}
- if (flags & MR_DEVICE_FLAGS_PROMISC)
- dev->promisc = 1;
+ dev->param = *param;
+ int ret = __device_open_multidevq(dev, param->nr_queues);
- int ret = __device_open_multidevq(dev, flags, nr_queue);
if (ret < 0)
{
MR_LOG(INFO, BASE, "DeviceManager, DeviceOpen, "
- "Cannot open device %s\n", devsym);
+ "Cannot open device %s\n", param->symbol);
return NULL;
}
@@ -227,8 +232,8 @@ static struct mr_devq * __device_attach(struct devman_ctx * ctx, struct mr_dev *
if(dev->nr_devq_attach >= dev->nr_devq)
{
MR_LOG(INFO, BASE, "DeviceManager, DeviceAttach, "
- "Too many attach queues for device %s"
- "(nr_devq=%d, nr_devq_attach=%d)\n", dev->nr_devq, dev->nr_devq_attach);
+ "Too many attach queues for device %s (nr_devq=%d, nr_devq_attach=%d)\n",
+ dev->symbol, dev->nr_devq, dev->nr_devq_attach);
return NULL;
}
return dev->devq[dev->nr_devq_attach++];
@@ -257,9 +262,12 @@ static int __device_scan(struct devman_ctx * ctx)
struct mr_dev * device = (struct mr_dev*)rte_zmalloc("DEVICE_DESC", sizeof(struct mr_dev), 0);
MR_CHECK(device != NULL, "Cannot alloc memory for device description");
+ // 取设备物理信息
device->port_id = port_id;
- device->nr_rxq_max = dev_info.max_rx_queues;
- device->nr_txq_max = dev_info.max_tx_queues;
+ device->info.nr_rxq_max = dev_info.max_rx_queues;
+ device->info.nr_txq_max = dev_info.max_tx_queues;
+ rte_eth_macaddr_get(device->port_id, &device->info.phy_ether_addr);
+ rte_eth_dev_get_mtu(device->port_id, &device->info.default_mtu);
snprintf(device->symbol, sizeof(device->symbol), "mr%u", device->port_id);
// 加入设备链表
@@ -270,15 +278,144 @@ static int __device_scan(struct devman_ctx * ctx)
return 0;
}
-static int __device_init(struct mr_global_ctx * g_ctx,
- struct devman_ctx * ctx, struct devman_config * cfg)
+const char * __str_rssmode(unsigned int rssmode)
+{
+ switch(rssmode)
+ {
+ case MR_DEV_RSSMODE_DEFAULT: return "Default";
+ case MR_DEV_RSSMODE_2TUPLE_SYM: return "SAddr/DAddr(Sym)";
+ case MR_DEV_RSSMODE_4TUPLE_SYM: return "SAddr/DAddr/SPort/DPort(Sym)";
+ case MR_DEV_RSSMODE_4TUPLE_ASYM: return "SAddr/DAddr/SPort/DPort(Asym)";
+ default: return "Unknown";
+ }
+}
+const char * __str_enable_or_disable(unsigned int value)
{
-#if 0
- // 初始化KNI子系统
- rte_kni_init(128);
-#endif
+ if (value) return "ENABLE";
+ else return "DISABLE";
+}
+
+static int device_info_dump(struct mr_dev * dev)
+{
+ char str_phy_addr[MR_SYMBOL_MAX];
+ char str_usr_addr[MR_SYMBOL_MAX];
+
+ ether_format_addr(str_phy_addr, sizeof(str_phy_addr),
+ &dev->info.phy_ether_addr);
+ ether_format_addr(str_usr_addr, sizeof(str_phy_addr),
+ &dev->ether_addr);
+
+ MR_LOG(INFO, BASE,
+ "Physical Device %s: PortID=%d\n"
+ "=====================================================\n"
+ " Physical Hwaddr : %s\n"
+ " Runtime Hwaddr : %s\n"
+ " MTU: %u\n"
+ " Promisc : %s\n"
+ " VLAN-Filter: %s\n"
+ " VLAN-Strip: %s\n"
+ " Drop-En: %s\n"
+ " RSSMode: %s\n"
+ "=====================================================\n",
+ dev->symbol, dev->port_id,
+ str_phy_addr,
+ str_usr_addr,
+ dev->mtu,
+ __str_enable_or_disable(dev->param.promisc),
+ __str_enable_or_disable(dev->param.en_vlan_strip),
+ __str_enable_or_disable(dev->param.en_vlan_filter),
+ __str_enable_or_disable(dev->param.en_drop),
+ __str_rssmode(dev->param.rssmode));
+
+ return 0;
+}
+
+/* 用户参数解析:网卡队列参数设置 */
+static int device_usrset_qconf(struct mr_dev * dev, struct rte_eth_rxconf * rxconf,
+ struct rte_eth_txconf * txconf, unsigned int * nr_rxdesc, unsigned int * nr_txdesc)
+{
+ // 获取默认的RX、TX队列设置
+ struct mr_dev_param * param = &dev->param;
+ struct rte_eth_dev_info rte_dev_info;
+ rte_eth_dev_info_get(dev->port_id, &rte_dev_info);
+
+ // 复制默认配置
+ *rxconf = rte_dev_info.default_rxconf;
+ *txconf = rte_dev_info.default_txconf;
+
+ // Drop-En开关设置,丢弃处理不过来的包
+ rxconf->rx_drop_en = param->en_drop ? 1 : 0;
+ *nr_rxdesc = param->nr_rxdesc > 0 ? param->nr_rxdesc : MR_DEVICE_DEFAULT_NR_RX_DESC;
+ *nr_txdesc = param->nr_txdesc > 0 ? param->nr_txdesc : MR_DEVICE_DEFAULT_NR_TX_DESC;
+ return 0;
+}
+
+/* 用户参数解析:网卡参数设置 */
+static int device_usrset_ethconf(struct mr_dev * dev, struct rte_eth_conf * out_eth_conf)
+{
+ struct rte_eth_conf eth_conf = eth_conf_default;
+ struct mr_dev_param * param = &dev->param;
+
+ // 配置RSS模式
+ if (param->rssmode == MR_DEV_RSSMODE_2TUPLE_SYM)
+ {
+ eth_conf.rx_adv_conf.rss_conf.rss_hf = ETH_RSS_IP;
+ eth_conf.rx_adv_conf.rss_conf.rss_key = default_sym_rss_key;
+ eth_conf.rx_adv_conf.rss_conf.rss_key_len = sizeof(default_sym_rss_key);
+ }
+ else if (param->rssmode == MR_DEV_RSSMODE_4TUPLE_SYM)
+ {
+ eth_conf.rx_adv_conf.rss_conf.rss_hf = ETH_RSS_PROTO_MASK;
+ eth_conf.rx_adv_conf.rss_conf.rss_key = default_sym_rss_key;
+ eth_conf.rx_adv_conf.rss_conf.rss_key_len = sizeof(default_sym_rss_key);
+ }
+ else if (param->rssmode == MR_DEV_RSSMODE_4TUPLE_ASYM)
+ {
+ eth_conf.rx_adv_conf.rss_conf.rss_hf = ETH_RSS_PROTO_MASK;
+ eth_conf.rx_adv_conf.rss_conf.rss_key = NULL;
+ }
+
+ // 配置VLAN相关功能
+ eth_conf.rxmode.hw_vlan_filter = param->en_vlan_filter ? 1 : 0;
+ eth_conf.rxmode.hw_vlan_strip = param->en_vlan_strip ? 1 : 0;
+ *out_eth_conf = eth_conf;
+ return 0;
+}
+
+// 杂项参数解析、设置
+static int device_usrset_misc(struct mr_dev * dev)
+{
+ struct mr_dev_param * param = &dev->param;
+ // 混杂模式开关
+ if (param->promisc) rte_eth_promiscuous_enable(dev->port_id);
+
+ // 配置MTU
+ if (param->mtu)
+ {
+ rte_eth_dev_set_mtu(dev->port_id, param->mtu);
+ }
+
+ rte_eth_dev_get_mtu(dev->port_id, &dev->mtu);
+
+ // 配置以太网地址
+ if (!is_zero_ether_addr(&param->usr_ether_addr))
+ {
+ rte_eth_dev_default_mac_addr_set(dev->port_id, &param->usr_ether_addr);
+ ether_addr_copy(&param->usr_ether_addr, &dev->ether_addr);
+ }
+ else
+ {
+ ether_addr_copy(&dev->info.phy_ether_addr, &dev->ether_addr);
+ }
+
+ return 0;
+}
+
+static int __device_init(struct devman_ctx * ctx)
+
+{
// 对设备链上的所有设备初始化,计算队列数量。
struct mr_dev * dev;
TAILQ_FOREACH(dev, &ctx->device_list, next)
@@ -295,6 +432,10 @@ static int __device_init(struct mr_global_ctx * g_ctx,
unsigned int nr_txq_use = dev->nr_txq > 1 ? dev->nr_rxq : 1;
socket_id_t socket_id = rte_eth_dev_socket_id(dev->port_id);
+ // 配置端口信息
+ struct rte_eth_conf local_eth_conf;
+ device_usrset_ethconf(dev, &local_eth_conf);
+
retval = rte_eth_dev_configure(dev->port_id, nr_rxq_use,
nr_txq_use, &eth_conf_default);
@@ -306,10 +447,17 @@ static int __device_init(struct mr_global_ctx * g_ctx,
return retval;
}
+ // 配置队列信息
+ unsigned int nr_rxdesc;
+ unsigned int nr_txdesc;
+ struct rte_eth_rxconf rxconf;
+ struct rte_eth_txconf txconf;
+ device_usrset_qconf(dev, &rxconf, &txconf, &nr_rxdesc, &nr_txdesc);
+
for (int rxq = 0; rxq < nr_rxq_use; rxq++)
{
- retval = rte_eth_rx_queue_setup(dev->port_id, rxq, cfg->nr_rx_desc,
- socket_id, NULL, mrbuf_get_mempool(socket_id));
+ retval = rte_eth_rx_queue_setup(dev->port_id, rxq,
+ nr_rxdesc, socket_id, &rxconf, mrbuf_get_mempool(socket_id));
if (retval < 0)
{
@@ -322,8 +470,8 @@ static int __device_init(struct mr_global_ctx * g_ctx,
for (int txq = 0; txq < nr_txq_use; txq++)
{
- retval = rte_eth_tx_queue_setup(dev->port_id, txq, cfg->nr_tx_desc,
- socket_id, NULL);
+ retval = rte_eth_tx_queue_setup(dev->port_id, txq,
+ nr_txdesc,socket_id, &txconf);
if (retval < 0)
{
@@ -343,34 +491,12 @@ static int __device_init(struct mr_global_ctx * g_ctx,
return retval;
}
-#if 0
- dev->kni = kni_alloc(dev->symbol, dev->port_id,
- mrbuf_get_mempool(socket_id));
-#endif
-
- if(dev->kni == NULL)
- {
- MR_LOG(WARNING, BASE, "DeviceManager, DeviceInit, "
- "Cannot create virtual kernel device(sym=%s) : %s\n",
- dev->symbol, __str_errno());
- }
-
- rte_eth_macaddr_get(dev->port_id, &dev->ether_addr);
- rte_eth_dev_get_mtu(dev->port_id, &dev->mtu);
dev->nr_rxq = nr_rxq_use;
dev->nr_txq = nr_txq_use;
- if (dev->promisc)
- rte_eth_promiscuous_enable(dev->port_id);
-
- char str_mac_addr[MR_SYMBOL_MAX];
- ether_format_addr(str_mac_addr, sizeof(str_mac_addr), &dev->ether_addr);
-
- MR_LOG(INFO, BASE, "DeviceManager, DeviceInit, "
- "Device %s is enable: PortID=%d, NR RXQ=%d, NR TXQ=%d, MAC=%s, MTU=%d\n",
- dev->symbol, dev->port_id, dev->nr_rxq, dev->nr_txq, str_mac_addr,
- dev->mtu);
-
+ // 其他项目配置
+ device_usrset_misc(dev);
+ device_info_dump(dev);
dev->inited = 1;
dev->enable = 1;
}
@@ -393,24 +519,32 @@ static int __device_list(struct devman_ctx * ctx, mr_dev_t * devs[],
return nr_in_use;
}
-mr_dev_t * mr_device_open(const char * devsym, unsigned int nr_queue, flags_t flags)
+mr_dev_t * mr_device_open(struct mr_dev_param * param)
{
- assert(module_ctx != NULL);
- return (mr_dev_t *)__device_open(module_ctx, devsym, nr_queue, flags);
+ struct devman_ctx * module_ctx;
+ module_ctx = mr_core_default_instance_get()->devman_ctx;
+ return (mr_dev_t *)__device_open(module_ctx, param);
}
mr_dev_t * mr_device_lookup(const char * devsym)
{
+ struct devman_ctx * module_ctx;
+ module_ctx = mr_core_default_instance_get()->devman_ctx;
return (mr_dev_t *)__device_lookup(module_ctx, devsym);
}
int mr_device_list(mr_dev_t * devs[], int nr_max_devs, flags_t flags)
{
+ struct devman_ctx * module_ctx;
+ module_ctx = mr_core_default_instance_get()->devman_ctx;
return __device_list(module_ctx, devs, nr_max_devs, flags);
}
mr_devq_t * mr_device_attach(const char * devsym)
{
+ struct devman_ctx * module_ctx;
+ module_ctx = mr_core_default_instance_get()->devman_ctx;
+
struct mr_dev * dev = __device_lookup(module_ctx, devsym);
if (dev == NULL)
{
@@ -427,96 +561,33 @@ int mr_device_close(mr_devq_t * devq)
return 0;
}
-#if 0
-int mr_device_raw_recv_burst(mr_devq_t * devq, struct rte_mbuf ** pkts,
- const unsigned int nr_max_pkts)
-{
- struct mr_devq * __devq = (struct mr_devq *)devq;
- assert(__devq != NULL && __devq->enable && __devq->device != NULL);
-
- return rte_eth_rx_burst(__devq->device->port_id, __devq->rx_queue_id,
- pkts, nr_max_pkts);
-}
-
-int mr_device_raw_send_burst(mr_devq_t * devq, struct rte_mbuf ** pkts,
- const unsigned int nr_pkts)
+int devman_ctx_init(struct mr_core_instance * core_instance)
{
- struct mr_devq * __devq = (struct mr_devq *)devq;
- assert(__devq != NULL && __devq->enable && __devq->device != NULL);
-
- return rte_eth_tx_burst(__devq->device->port_id, __devq->tx_queue_id,
- pkts, nr_pkts);
-}
-#endif
+ core_instance->devman_ctx = rte_zmalloc("DEVMAN_CTX", sizeof(struct devman_ctx), 0);
+ MR_CHECK(core_instance->devman_ctx != NULL, "Cannot alloc memory for devman context");
-static int devman_preinit(struct mr_module * m_desc, struct mr_config * g_cfg, struct mr_global_ctx * g_ctx)
-{
- /* 初始化设备管理各句柄 */
- MODULE_CTX(g_ctx, m_desc->mid) = rte_zmalloc("DEVICE_MANAGER_CTX",
- sizeof(struct devman_ctx), 0);
- MR_CHECK(MODULE_CTX(g_ctx, m_desc->mid) != NULL,
- "Device Manager Preinit Error, cannot alloc memory for devmgr context");
-
- MODULE_CFG(g_cfg, m_desc->mid) = rte_zmalloc("DEVICE_MANAGER_CONFIG",
- sizeof(struct devman_config), 0);
- MR_CHECK(MODULE_CFG(g_cfg, m_desc->mid) != NULL,
- "Device Manager Preinit Error, cannot alloc memory for devmgr config");
-
- module_ctx = (struct devman_ctx *)MODULE_CTX(g_ctx, m_desc->mid);
- module_config = (struct devman_config *)MODULE_CFG(g_cfg, m_desc->mid);
-
- TAILQ_INIT(&module_ctx->device_list);
- return __device_scan(module_ctx);
+ TAILQ_INIT(&core_instance->devman_ctx->device_list);
+ return __device_scan(core_instance->devman_ctx);
}
-static int devman_config(struct mr_module * m_desc, struct mr_config * g_cfg, struct mr_global_ctx * g_ctx)
+int devman_config(struct mr_core_instance * core_instance)
{
- struct devman_config * cfg = module_config;
- struct devman_ctx * ctx = module_ctx;
-
- /* 加载网卡描述符数量配置 */
- MESA_load_profile_uint_def(g_cfg->glob_cfg_file, "device", "nr_rx_desc",
- &cfg->nr_rx_desc, MR_DEVICE_DEFAULT_NR_RX_DESC);
- MESA_load_profile_uint_def(g_cfg->glob_cfg_file, "device", "nr_tx_desc",
- &cfg->nr_tx_desc, MR_DEVICE_DEFAULT_NR_TX_DESC);
-
- /* 统计开关 */
- MESA_load_profile_uint_def(g_cfg->glob_cfg_file, "device", "stat",
- &cfg->en_stat, 1);
-
- MR_LOG(INFO, BASE, "Devman, ModuleConfig, nr_rx_desc = %d, nr_tx_desc = %d\n",
- cfg->nr_rx_desc, cfg->nr_tx_desc);
return 0;
}
-static int devman_init(struct mr_module * m_desc, struct mr_config * g_cfg, struct mr_global_ctx * g_ctx)
+int devman_init(struct mr_core_instance * core_instance)
{
- struct devman_config * cfg = module_config;
- struct devman_ctx * ctx = module_ctx;
- return __device_init(g_ctx, ctx, cfg);
+ struct devman_ctx * ctx = core_instance->devman_ctx;
+ return __device_init(ctx);
}
-static int devman_destory(struct mr_module * m_desc, struct mr_config * g_cfg, struct mr_global_ctx * g_ctx)
+int devman_destory(struct mr_core_instance * core_instance)
{
- struct devman_config * cfg = module_config;
- struct devman_ctx * ctx = module_ctx;
return 0;
}
-static int devman_slaveinit(struct mr_module * m_desc, struct mr_config * g_cfg, struct mr_global_ctx * g_ctx)
+int devman_slave_init(struct mr_core_instance * core_instance,
+ struct mr_core_slave_instance * slave_instance)
{
- module_ctx = (struct devman_ctx *)MODULE_CTX(g_ctx, m_desc->mid);
- module_config = (struct devman_config *)MODULE_CFG(g_cfg, m_desc->mid);
return 0;
-}
-
-struct mr_module module_desc_device =
-{
- .mid = MR_MID_DEVICE_MGR,
- .sym = "devman",
- .preinit = devman_preinit,
- .init = devman_init,
- .destory = devman_destory,
- .config = devman_config,
- .slaveinit = devman_slaveinit
-}; \ No newline at end of file
+} \ No newline at end of file
diff --git a/core/src/mrbuf.c b/core/src/mrbuf.c
index a71283f..5acfe60 100644
--- a/core/src/mrbuf.c
+++ b/core/src/mrbuf.c
@@ -12,20 +12,15 @@
#include <string.h>
#include <unistd.h>
#include <assert.h>
-#include <mr_ctx.h>
-#include <mr_hwinfo.h>
#include <MESA_prof_load.h>
-#include <rte_errno.h>
+
#include <mr_mrbuf.h>
#include <mr_buffer.h>
+#include <mr_runtime.h>
+#include <mr_core.h>
-#define SELF_TEST 0
-#define MEM_RECORD (SELF_TEST & 0)
-
-#ifdef MR_BASE_ON_DPDK /* 基于Intel-DPDK rte_mbuf封装 */
-#include "rte_mbuf.h"
-#include "rte_malloc.h"
-#endif
+#include <rte_malloc.h>
+#include <rte_mbuf.h>
#ifndef MR_MRBUF_DEFAULT_BLOCK_NUM
#define MR_MRBUF_DEFAULT_BLOCK_NUM 8192
@@ -39,21 +34,17 @@
#define MR_MRBUF_DEFAULT_PRIV_SIZE 128
#endif
-#ifdef MR_BASE_ON_DPDK /* 基于Intel-DPDK rte_mbuf封装 */
-
static int __mr_ctrl_zone_index = 0; /* 纪录私有数据结构CTRLZONE的序号 */
int marsio_buf_ctrlzone_alloc_id(void)
{
- mrbuf_global_ctx_t *ctx;
-
- ctx = MODULE_CTX(mr_global_ctx_get(), MR_MID_MRBUF_MGR);
-
- return rte_atomic32_add_return(&ctx->mr_ctrl_zone_id, 1);
+ assert(0);
+ return 0;
}
void marsio_buf_set_ctrlzone(marsio_buf_t *m, int ctrlzone_id, void *ctrl_ptr)
{
+ assert(0);
struct marsio_pri_t *mpr;
assert((ctrlzone_id >= 0) && (ctrlzone_id < MAX_CZ_NUM));
@@ -65,6 +56,7 @@ void marsio_buf_set_ctrlzone(marsio_buf_t *m, int ctrlzone_id, void *ctrl_ptr)
void *marsio_buf_get_ctrlzone(marsio_buf_t *m, int ctrlzone_id)
{
+ assert(0);
struct marsio_pri_t *mpr;
assert((ctrlzone_id >= 0) && (ctrlzone_id < MAX_CZ_NUM));
@@ -77,6 +69,7 @@ void *marsio_buf_get_ctrlzone(marsio_buf_t *m, int ctrlzone_id)
/* 将next作为previous的下一个包, 注意不是append下一个数据段 */
void marsio_buf_append_pkt(marsio_buf_t *previous, marsio_buf_t *next)
{
+ assert(0);
struct marsio_pri_t *mpr_previous;
mpr_previous = (struct marsio_pri_t *)((char *)previous + sizeof(struct rte_mbuf));
@@ -86,6 +79,7 @@ void marsio_buf_append_pkt(marsio_buf_t *previous, marsio_buf_t *next)
marsio_buf_t *marsio_buf_get_nextpkt(marsio_buf_t *m)
{
+ assert(0);
struct marsio_pri_t *mpr;
mpr = (struct marsio_pri_t *)((char *)m + sizeof(struct rte_mbuf));
@@ -95,6 +89,7 @@ marsio_buf_t *marsio_buf_get_nextpkt(marsio_buf_t *m)
void marsio_buf_reset(marsio_buf_t *m)
{
+ assert(0);
struct rte_mbuf *rtem = (struct rte_mbuf *)m;
struct marsio_pri_t *mpr;
@@ -108,96 +103,37 @@ void marsio_buf_reset(marsio_buf_t *m)
<= (int)((char *)rtem->buf_addr - (char *)rtem));
}
-static inline struct rte_mempool *marsio_buf_get_mpool(void)
-{
- socket_id_t socket_id = 0;
- mrbuf_global_ctx_t *pri_global_ctx;
-
- struct mr_thread_ctx* thread_ctx = mr_thread_ctx_get();
-
- if (MR_SOCKET_ANY == thread_ctx->socket_id) {
- socket_id = 0;
- }
-
- pri_global_ctx = (mrbuf_global_ctx_t *)MODULE_CTX(thread_ctx->global_ctx, MR_MID_MRBUF_MGR);
-
- MR_CHECK(socket_id < pri_global_ctx->mr_buf_pool_num, "marsio_buf_get_mpool(): socket number error.");
-
- return pri_global_ctx->mr_buf_pool[socket_id];
-}
-
struct rte_mempool * mrbuf_get_mempool(socket_id_t socket_id)
{
- struct mr_global_ctx * g_ctx = mr_global_ctx_get();
- mrbuf_global_ctx_t *pri_global_ctx = MODULE_CTX(g_ctx, MR_MID_MRBUF_MGR);
-
+ struct mrbuf_ctx * module_ctx;
+ module_ctx = mr_core_default_instance_get()->mrbuf_ctx;
+
+ assert(socket_id < module_ctx->mr_buf_pool_num);
if (MR_SOCKET_ANY == socket_id) socket_id = 0;
- MR_CHECK(socket_id < pri_global_ctx->mr_buf_pool_num, "marsio_buf_get_mpool(): socket number error.");
- return pri_global_ctx->mr_buf_pool[socket_id];
+ return module_ctx->mr_buf_pool[socket_id];
}
marsio_buf_t *marsio_buf_alloc(void)
{
- mr_process_ctx_t *proc_ctx;
-
- struct rte_mempool *mp = marsio_buf_get_mpool();
- marsio_buf_t *mbuf = rte_pktmbuf_alloc(mp);
-
- marsio_buf_reset(mbuf);
-
-#if MEM_RECORD
- proc_ctx = (mr_process_ctx_t *)MODULE_CTX(mr_proc_ctx_get(), MR_MID_MRBUF_MGR);
- proc_ctx->mr_buf_stat.alloc_mbuf_num++;
-#endif
-
- return mbuf;
+ assert(0);
+ return NULL;
}
void marsio_buf_free(marsio_buf_t *m)
{
- mr_process_ctx_t *proc_ctx;
+ assert(0);
rte_pktmbuf_free((struct rte_mbuf *)m);
-
-#if MEM_RECORD
- proc_ctx = (mr_process_ctx_t *)MODULE_CTX(mr_proc_ctx_get(), MR_MID_MRBUF_MGR);
- proc_ctx->mr_buf_stat.alloc_mbuf_num--;
-#endif
}
int marsio_buf_batch_alloc(marsio_buf_t *m[], int num)
{
- int i;
- mr_process_ctx_t *proc_ctx;
- struct rte_mempool *mp = marsio_buf_get_mpool();
-
- proc_ctx = (mr_process_ctx_t *)MODULE_CTX(mr_proc_ctx_get(), MR_MID_MRBUF_MGR);
-
- for (i = 0; i < num; i++) {
- m[i] = (marsio_buf_t *)rte_pktmbuf_alloc(mp);
-#if MEM_RECORD
- proc_ctx->mr_buf_stat.alloc_mbuf_num++;
-#endif
- }
-
return 0;
}
void marsio_buf_batch_free(marsio_buf_t *m[], int num)
{
- int i;
- mr_process_ctx_t *proc_ctx;
-
- proc_ctx = (mr_process_ctx_t *)MODULE_CTX(mr_proc_ctx_get(), MR_MID_MRBUF_MGR);
-
- for (i = 0; i < num; i++) {
- rte_pktmbuf_free((struct rte_mbuf *)m[i]);
-#if MEM_RECORD
- proc_ctx->mr_buf_stat.alloc_mbuf_num--;
-#endif
- }
}
-
char *marsio_buf_mtod(marsio_buf_t *m)
{
return rte_pktmbuf_mtod((struct rte_mbuf *)m, char *);
@@ -242,78 +178,62 @@ marsio_buf_t *marsio_buf_dup(marsio_buf_t *m)
{
mr_process_ctx_t *proc_ctx;
rte_mbuf_refcnt_update((struct rte_mbuf *)m, 1);
-
-#if MEM_RECORD
- proc_ctx = (mr_process_ctx_t *)MODULE_CTX(mr_proc_ctx_get(), MR_MID_MRBUF_MGR);
- proc_ctx->mr_buf_stat.alloc_mbuf_num++;
-#endif
return m;
}
-#endif
-
-int mrbuf_preinit(struct mr_module * m_desc, struct mr_config * g_cfg, struct mr_global_ctx * g_ctx)
+int mrbuf_ctx_init(struct mr_core_instance * core_instance)
{
- void *tmp;
- tmp = rte_zmalloc("MRBUF_MANAGER_CTX", sizeof(mrbuf_global_ctx_t), 0);
- MODULE_CTX(g_ctx, m_desc->mid) = tmp;
- MR_CHECK(MODULE_CTX(g_ctx, m_desc->mid) != NULL,
- "MRBUF Manager Preinit Error, cannot alloc memory for mrbuf context");
-
- tmp = rte_zmalloc("MRBUF_MANAGER_CONFIG", sizeof(mrbuf_cfg_t), 0);
- MODULE_CFG(g_cfg, m_desc->mid) = tmp;
- MR_CHECK(MODULE_CFG(g_cfg, m_desc->mid) != NULL,
- "MRBUF Manager Preinit Error, cannot alloc memory for mrbuf config");
-
+ core_instance->mrbuf_ctx = rte_zmalloc("MRBUF_CTX", sizeof(struct mrbuf_ctx), 0);
+ MR_CHECK(core_instance->mrbuf_ctx != NULL, "Cannot alloc memory for mrbuf context. ");
return 0;
}
-int mrbuf_config(struct mr_module * m_desc, struct mr_config * g_cfg, struct mr_global_ctx * g_ctx)
+int mrbuf_config(struct mr_core_instance * core_instance)
{
- mrbuf_cfg_t * cfg = MODULE_CFG(g_cfg, m_desc->mid);
- mrbuf_global_ctx_t * ctx = MODULE_CTX(g_ctx, m_desc->mid);
+ struct mr_global_config * g_cfg = core_instance->g_cfg;
+ struct mrbuf_ctx * ctx = core_instance->mrbuf_ctx;
MESA_load_profile_uint_def(g_cfg->glob_cfg_file, "buffer", "block_num",
- &cfg->mempool_block_num, MR_MRBUF_DEFAULT_BLOCK_NUM);
+ &ctx->mempool_block_num, MR_MRBUF_DEFAULT_BLOCK_NUM);
MESA_load_profile_uint_def(g_cfg->glob_cfg_file, "buffer", "dataroom_size",
- &cfg->mempool_dataroom_size, MR_MRBUF_DEFAULT_DATAROOM_SIZE);
+ &ctx->mempool_dataroom_size, MR_MRBUF_DEFAULT_DATAROOM_SIZE);
MESA_load_profile_uint_def(g_cfg->glob_cfg_file, "buffer", "priv_size",
- &cfg->mempool_priv_size, MR_MRBUF_DEFAULT_PRIV_SIZE);
+ &ctx->mempool_priv_size, MR_MRBUF_DEFAULT_PRIV_SIZE);
- MR_LOG(INFO, BASE, "MRBUF, ModuleConfig, "
+ MR_LOG(INFO, BASE, "MRBUF Config, "
"block_num = %d, dataroom_size = %d, priv_size = %d\n",
- cfg->mempool_block_num, cfg->mempool_dataroom_size, cfg->mempool_priv_size);
-
+ ctx->mempool_block_num, ctx->mempool_dataroom_size, ctx->mempool_priv_size);
+
return 0;
}
-int mrbuf_init(struct mr_module * m_desc, struct mr_config * g_cfg, struct mr_global_ctx * g_ctx)
+int mrbuf_init(struct mr_core_instance * core_instance)
{
- mrbuf_global_ctx_t * ctx = MODULE_CTX(g_ctx, MR_MID_MRBUF_MGR);
- mrbuf_cfg_t *cfg = MODULE_CFG(g_cfg, MR_MID_MRBUF_MGR);
+ struct mr_global_config * g_cfg = core_instance->g_cfg;
+ struct mrbuf_ctx * ctx = core_instance->mrbuf_ctx;
ctx->mr_buf_pool_num = mr_hwinfo_nr_sockets();
MR_CHECK(ctx->mr_buf_pool_num > 0, "MRBUF, ModuleInit, "
"Get socket number error(socket_nr = %d)", ctx->mr_buf_pool_num);
ctx->mr_buf_pool = (struct rte_mempool **)
- rte_zmalloc("MRBUF_MANAGER_CTX", sizeof(void *) *ctx->mr_buf_pool_num, 0);
-
+ rte_zmalloc("MRBUF_MANAGER_CTX", sizeof(void *) *ctx->mr_buf_pool_num, 0);
+
for (int socket_id = 0; socket_id < ctx->mr_buf_pool_num; socket_id++)
{
char sym[MR_SYMBOL_MAX];
snprintf(sym, sizeof(sym), "mbuf_pool_%d", socket_id);
-
- ctx->mr_buf_pool[socket_id] = rte_pktmbuf_pool_create(sym,
- cfg->mempool_block_num, 256, cfg->mempool_priv_size,
- cfg->mempool_dataroom_size, socket_id);
+
+ ctx->mr_buf_pool[socket_id] = rte_pktmbuf_pool_create(sym,
+ ctx->mempool_block_num, 256, ctx->mempool_priv_size,
+ ctx->mempool_dataroom_size, socket_id);
MR_CHECK(ctx->mr_buf_pool[socket_id] != NULL, "MRBUF, ModuleInit, "
"Call rte_pktmbuf_pool_create() failed");
MR_LOG(INFO, BASE, "MRBUF, ModuleInit, "
"Pktmbuf Pool %s(block_num=%d, priv_size=%d, dataroom_size=%d) created.\n",
- sym, cfg->mempool_block_num, cfg->mempool_priv_size, cfg->mempool_dataroom_size);
+ sym, ctx->mempool_block_num, ctx->mempool_priv_size, ctx->mempool_dataroom_size);
struct rte_mbuf *test_mbuf = rte_pktmbuf_alloc(ctx->mr_buf_pool[socket_id]);
assert(test_mbuf != NULL);
@@ -324,22 +244,13 @@ int mrbuf_init(struct mr_module * m_desc, struct mr_config * g_cfg, struct mr_gl
return 0;
}
-int mrbuf_slave_init(struct mr_module * m_desc, struct mr_config * g_cfg, struct mr_global_ctx * g_ctx)
+int mrbuf_destory(struct mr_core_instance * core_instance)
{
return 0;
}
-int mrbuf_destory(struct mr_module * m_desc, struct mr_config * g_cfg, struct mr_global_ctx * g_ctx)
+int mrbuf_slave_init(struct mr_core_instance * core_instance,
+ struct mr_core_slave_instance * slave_instance)
{
return 0;
-}
-
-struct mr_module module_desc_mrbuf =
-{
- .mid = MR_MID_MRBUF_MGR,
- .preinit = mrbuf_preinit,
- .init = mrbuf_init,
- .destory = mrbuf_destory,
- .slaveinit = mrbuf_slave_init,
- .config = mrbuf_config
-}; \ No newline at end of file
+} \ No newline at end of file
diff --git a/core/src/proc.c b/core/src/proc.c
deleted file mode 100644
index bab8332..0000000
--- a/core/src/proc.c
+++ /dev/null
@@ -1,452 +0,0 @@
-/* Application, Process and Dataplane Manager
- *
- * This manager is used to manage application, process and thread.
- * It gives one unique id for each application, process and dataplane thread.
- *
- * Author : Lu Qiuwen<[email protected]>
- * Date : 2016-08-19
- */
-
-#include <sys/queue.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <mr_common.h>
-#include <mr_ctx.h>
-#include <mr_mask.h>
-#include <mr_hwinfo.h>
-#include <mr_procman.h>
-
-#include <rte_ip_frag.h>
-#include <rte_rwlock.h>
-#include <rte_lcore.h>
-#include <rte_per_lcore.h>
-#include <mr_ctx.h>
-#include <assert.h>
-#include <string.h>
-#include <unistd.h>
-#include <pthread.h>
-
-TAILQ_HEAD(proc_info_list, proc_info);
-
-struct process_ctxs
-{
- /* 读写锁,控制并发访问 */
- mr_spinlock_t lock;
- /* 进程列表 */
- struct proc_info_list proc_info_list;
- /* 在册进程数量 */
- unsigned int nr_process;
- /* 进程序号分配,从0开始分配 */
- process_id_t pid_index;
- /* 全局线程序号分配,从0开始分配 */
- thread_id_t gsid_index;
-};
-
-static struct process_ctxs * __procman_module_ctx;
-static struct proc_info * __procman_local_proc_info;
-static __thread struct thread_info * __procman_local_thread_info;
-
-int procman_preinit(struct mr_module * m_desc, struct mr_config * g_cfg,
- struct mr_global_ctx * g_ctx)
-{
- MODULE_CTX(g_ctx, m_desc->mid) = rte_zmalloc("ProcInfos",
- sizeof(struct process_ctxs), 0);
- MR_CHECK(MODULE_CTX(g_ctx, m_desc->mid) != NULL, "Procman, PreConfig,"
- "Cannot alloc memory for process ctxs in global ctx");
-
- struct process_ctxs * pctxs = (struct process_ctxs *)MODULE_CTX(g_ctx, m_desc->mid);
- assert(pctxs != NULL);
-
- pctxs->pid_index = 0;
- pctxs->nr_process = 0;
- mr_spin_init(&pctxs->lock);
- TAILQ_INIT(&pctxs->proc_info_list);
- __procman_module_ctx = pctxs;
- return 0;
-}
-
-int procman_slave_init(struct mr_module * m_desc, struct mr_config * g_cfg,
- struct mr_global_ctx * g_ctx)
-{
- assert(MODULE_CTX(g_ctx, m_desc->mid) != NULL);
- __procman_module_ctx = MODULE_CTX(g_ctx, m_desc->mid);
- return 0;
-}
-
-/* 进程运行 */
-static int __process_run_unsafe(struct process_ctxs * pctxs, struct proc_info * pinfo)
-{
- pinfo->state = MR_PROC_STATE_RUN;
- return 0;
-}
-
-/* 进程退出,保留上下文 */
-static int __process_suspend_unsafe(struct process_ctxs * pctxs, struct proc_info * pinfo)
-{
- return 0;
-}
-
-/* 进程退出,销毁上下文 */
-static int __process_exit_unsafe(struct process_ctxs * pctxs)
-{
- return 0;
-}
-
-static void __process_dump(struct process_ctxs * pctxs, FILE * stream)
-{
- struct proc_info * pinfo_iter = NULL;
- TAILQ_FOREACH(pinfo_iter, &pctxs->proc_info_list, next)
- {
- fprintf(stream, "ProcessDumpResult: ProcessSymbol=%s, ProcessID=%d\n",
- pinfo_iter->symbol, pinfo_iter->proc_id);
- }
- return;
-}
-
-static struct proc_info * __process_lookup_unsafe(const struct process_ctxs * pctxs,
- const char * sym)
-{
- struct proc_info * pinfo_iter = NULL;
- struct proc_info * pinfo_ret = NULL;
- TAILQ_FOREACH(pinfo_iter, &pctxs->proc_info_list, next)
- {
- if(strncmp(pinfo_iter->symbol, sym, sizeof(pinfo_iter->symbol)) == 0)
- {
- pinfo_ret = pinfo_iter;
- break;
- }
- }
- return pinfo_ret;
-}
-
-/* 创建一个新的进程 */
-static int __process_new_unsafe(struct process_ctxs * pctxs, const char * sym,
- cpu_mask_t cpu_mask, unsigned int nr_max_thread)
-{
- struct proc_info * pinfo;
- int ret = 0;
- assert(__procman_module_ctx != NULL);
-
- // 检查进程是否已经存在
- pinfo = __process_lookup_unsafe(pctxs, sym);
- if (pinfo != NULL)
- {
- MR_LOG(INFO, BASE, "Procman, ProcessNew, "
- "Process %s is already exists, failed. \n", sym);
- ret = -1; goto out;
- }
-
- // 进程不存在,创建新的描述符
- pinfo = (struct proc_info *)rte_zmalloc(NULL, sizeof(struct proc_info), 0);
- if (unlikely(pinfo == NULL))
- {
- MR_LOG(INFO, BASE, "Procman, ProcessNew, "
- "Cannot alloc memory for Process %s info.\n", sym);
- ret = -2; goto errout;
- }
-
- // 分配进程上下文空间
- struct mr_proc_ctx * proc_ctx;
- proc_ctx = (struct mr_proc_ctx *)rte_zmalloc(NULL, sizeof(struct mr_proc_ctx), 0);
- if (unlikely(proc_ctx == NULL))
- {
- MR_LOG(INFO, BASE, "Procman, ProcessNew, "
- "Cannot alloc memory for Process %s Ctx Space.\n", sym);
- ret = -3; goto errout;
- }
-
- // 填充进程信息
- snprintf(pinfo->symbol, sizeof(pinfo->symbol), "%s", sym);
- pinfo->proc_id = pctxs->pid_index;
- pinfo->gsid_start = pctxs->gsid_index;
- pinfo->gsid_end = pctxs->gsid_index + nr_max_thread;
- pinfo->proc_ctx = proc_ctx;
- pinfo->state = MR_PROC_STATE_READY;
- pinfo->proc_cpu_mask = cpu_mask;
- pinfo->nr_max_thread = nr_max_thread;
-
- // 填充进程上下文结构
- proc_ctx->proc_id = pinfo->proc_id;
- proc_ctx->procsym = pinfo->symbol;
- proc_ctx->nr_max_thread = pinfo->nr_max_thread;
- proc_ctx->cpu_mask = pinfo->proc_cpu_mask;
-
- // 增加进程、线程序号
- pctxs->pid_index++;
- pctxs->gsid_index += nr_max_thread;
-
- // 插入进程链表
- TAILQ_INSERT_TAIL(&pctxs->proc_info_list, pinfo, next);
-
- // 初始化线程
- pinfo->thread_info = (struct thread_info *)rte_zmalloc(NULL,
- sizeof(struct thread_info)*nr_max_thread, 0);
-
- if (pinfo->thread_info == NULL)
- {
- MR_LOG(INFO, BASE, "ThreadMan, HandleNewProcess, "
- "Cannot alloc memory for thread_info sturcture, failed");
- ret = -4; goto errout;
- }
-
- pinfo->cur_sid = 0;
- pinfo->cur_gsid = pinfo->gsid_start;
- ret = 0; goto out;
-
-errout:
- if (pinfo != NULL) rte_free(pinfo);
- if (proc_ctx != NULL) rte_free(proc_ctx);
- goto out;
-
-out:
- return ret;
-}
-
-int procman_process_create(const char * sym, cpu_mask_t cpu_mask)
-{
- struct process_ctxs * pctxs = __procman_module_ctx;
- assert(pctxs != NULL);
-
- int nr_max_thread = mask_popcnt(cpu_mask);
- if(unlikely(nr_max_thread < 0))
- {
- MR_LOG(WARNING, BASE, "Procman, ProcessCreate, "
- "Process %s CPU Mask error(mask=%x, nr_max_thread=%d)\n",
- sym, nr_max_thread);
- return -1;
- }
-
- mr_spin_lock(&pctxs->lock);
- int ret = __process_new_unsafe(pctxs, sym, cpu_mask, nr_max_thread);
- mr_spin_unlock(&pctxs->lock);
- return ret;
-}
-
-int procman_process_lookup(const char * sym)
-{
- return 0;
-}
-
-int procman_register_myself(const char * sym)
-{
- struct process_ctxs * pctxs = __procman_module_ctx;
- struct proc_info * pinfo;
- int ret = 0;
-
- mr_spin_lock(&pctxs->lock);
- pinfo = __process_lookup_unsafe(pctxs, sym);
-
- if(pinfo == NULL)
- {
- MR_LOG(INFO, BASE, "Procman, ProcmanRegisterMySelf, "
- "LocalProcess %s is not existed, failed.\n", sym);
- ret = -1; goto out;
- }
-
- // TODO: 防止重复启动
-#if 0
- if(pinfo->state == MR_PROC_STATE_RUN)
- {
- MR_LOG(INFO, BASE, "Procman, ProcmanRegisterMySelf, "
- "LocalProcess %s is already running, failed\n", sym);
- ret = -2; goto out;
- }
-#endif
-
- mr_proc_ctx_set(pinfo->proc_ctx);
- __process_run_unsafe(pctxs, pinfo);
- __procman_local_proc_info = pinfo;
-
-out:
- mr_spin_unlock(&pctxs->lock);
- return ret;
-}
-
-int procman_unregister_myself()
-{
- return 0;
-}
-
-struct thread_info * __thread_new_unsafe(struct proc_info * pinfo)
-{
- struct thread_info * tinfo;
- tinfo = &pinfo->thread_info[pinfo->cur_sid];
-
- // 分配线程序号,全局序号和上下文空间
- tinfo->proc_id = pinfo->proc_id;
- tinfo->sid = pinfo->cur_sid;
- tinfo->gsid = pinfo->cur_gsid;
- tinfo->thread_ctx = (struct mr_thread_ctx *)
- rte_zmalloc(NULL, sizeof(struct mr_thread_ctx), 0);
-
- if(unlikely(tinfo->thread_ctx == NULL))
- {
- MR_LOG(INFO, BASE, "ProcMan, ThreadNew, "
- "Cannot alloc memory for thread ctx\n");
- return NULL;
- }
-
- // 填充线程上下文信息
- struct mr_thread_ctx * tctx = tinfo->thread_ctx;
- tctx->thread_id = tinfo->sid;
- tctx->proc_ctx = pinfo->proc_ctx;
- tctx->global_ctx = pinfo->proc_ctx->global_ctx;
- tctx->cpu_id = MR_CPU_ID_ANY;
- tctx->socket_id = MR_SOCKET_ANY;
-
- // 增加线程计数
- pinfo->cur_sid++;
- pinfo->cur_gsid++;
- return tinfo;
-}
-
-//TODO: 线程Recover机制:线程正常(或异常)退出之后,如何恢复上下文空间。
-
-struct thread_info * __thread_lookup_unsafe(struct proc_info * pinfo, thread_id_t sid)
-{
- if (sid < pinfo->cur_sid)
- return &pinfo->thread_info[sid];
- return NULL;
-}
-
-int __set_affinity(cpu_mask_t mask)
-{
- pthread_t ppid = pthread_self();
- int ret = pthread_setaffinity_np(ppid, sizeof(cpu_mask_t), (cpu_set_t *)&mask);
- return ret;
-}
-
-int __thread_set_affinity(struct proc_info * pinfo,
- struct thread_info * tinfo)
-{
- cpu_id_t cpu_id = mask_location(pinfo->proc_cpu_mask, tinfo->sid);
-
- if (unlikely(cpu_id >= mr_hwinfo_nr_cpus()))
- {
- MR_LOG(INFO, BASE, "Procman, ThreadSetAffinity, "
- "Thread %d in Process %s, Invalided CPU_ID %d "
- "(Exceed Physical CPU Count %d)\n",
- tinfo->sid, pinfo->symbol, cpu_id, mr_hwinfo_nr_cpus());
- return -1;
- }
-
- if(unlikely(cpu_id < 0))
- {
- MR_LOG(INFO, BASE, "Procman, ThreadSetAffinity, "
- "Thread %d in Process %s, Invailided CPU_ID %d"
- "(Invailed CPU Mask or SID)\n", tinfo->sid,
- pinfo->symbol, cpu_id);
- return -2;
- }
-
- socket_id_t socket_id = mr_hwinfo_socket_id(cpu_id);
- assert(socket_id >= 0 && socket_id < mr_hwinfo_nr_sockets());
-
- cpu_mask_t thread_cpu_mask = 1 << cpu_id;
- if(__set_affinity(thread_cpu_mask) < 0)
- {
- MR_LOG(INFO, BASE, "Procman, ThreadSetAffinity, "
- "Thread %d in Process %s, Call Pthread Error : %s\n",
- tinfo->cpu_id, pinfo->symbol, strerror(errno));
- return -3;
- }
-
- tinfo->cpu_id = cpu_id;
- tinfo->socket_id = socket_id;
- tinfo->thread_ctx->cpu_id = cpu_id;
- tinfo->thread_ctx->socket_id = socket_id;
- return 0;
-}
-
-int __thread_register_myself(struct proc_info * pinfo, thread_id_t suppose_sid)
-{
- struct thread_info * tinfo;
-
- // 查找当前的SID是否已经注册过
- tinfo = __thread_lookup_unsafe(pinfo, suppose_sid);
-
- // 没有注册过,注册一个新的线程
- if (tinfo != NULL)
- {
- MR_LOG(INFO, BASE, "Procman, ThreadRegister"
- "Thread %d in Process %s existed, recover it.\n",
- suppose_sid, pinfo->symbol);
- }
- else
- {
- MR_LOG(INFO, BASE, "Procman, ThreadRegister, "
- "Thread %d in Process %s, create new thread.\n",
- suppose_sid, pinfo->symbol);
- tinfo = __thread_new_unsafe(pinfo);
- }
-
- // 检测tinfo是否为空,此时为空就是异常情况了
- if(unlikely(tinfo == NULL))
- {
- MR_LOG(WARNING, BASE, "Procman, ThreadRegister, "
- "Thread %d in Process %s Info Structure is NULL, failed.\n",
- suppose_sid, pinfo->symbol);
- return -1;
- }
-
- // 注册上下文空间
- mr_thread_ctx_set(tinfo->thread_ctx);
- RTE_PER_LCORE(_lcore_id) = tinfo->gsid;
-
- if(__thread_set_affinity(pinfo, tinfo) < 0)
- {
- MR_LOG(WARNING, BASE, "Procman, ThreadRegister, "
- "Thread %d in Process %s, SetThreadAffinity failed.\n");
- return -2;
- }
-
- MR_LOG(DEBUG, BASE, "Procman, ThreadRegister, "
- "ThreadID=%d, GThreadID=%d, Process %s, thread registered. \n",
- tinfo->sid, tinfo->gsid, pinfo->symbol);
-
- return 0;
-}
-
-int procman_thread_register_myself()
-{
- struct process_ctxs * pctxs = __procman_module_ctx;
- struct proc_info * pinfo = __procman_local_proc_info;
- static thread_id_t suppose_sid = 0;
- int ret = 0;
-
- mr_spin_lock(&pctxs->lock);
- ret = __thread_register_myself(pinfo, suppose_sid);
- mr_spin_unlock(&pctxs->lock);
- if (ret >= 0) suppose_sid++;
- return ret;
-}
-
-int procman_thread_unregister_myself()
-{
- return 0;
-}
-
-int procman_list_all(struct proc_info * infos[], int nr_max_infos)
-{
- struct process_ctxs * pctxs = __procman_module_ctx;
- struct proc_info * pinfo_iter;
- int ret = 0;
-
- mr_spin_lock(&pctxs->lock);
- TAILQ_FOREACH(pinfo_iter, &pctxs->proc_info_list, next)
- {
- if (ret > nr_max_infos) break;
- infos[ret++] = pinfo_iter;
- }
- mr_spin_unlock(&pctxs->lock);
- return ret;
-}
-
-struct mr_module module_desc_procman =
-{
- .mid = MR_MID_PROCMAN,
- .preinit = procman_preinit,
- .slaveinit = procman_slave_init,
- .init = __default_module_handler,
- .destory = __default_module_handler
-}; \ No newline at end of file
diff --git a/core/src/rtdev.c b/core/src/rtdev.c
new file mode 100644
index 0000000..bed0c37
--- /dev/null
+++ b/core/src/rtdev.c
@@ -0,0 +1,475 @@
+/* \brief ����ʱ�����豸������
+ *
+ * ����ʱ�����豸������Ϊ����ʱӦ�õ��豸��VNode�ڵ㽨����Ӧ��ϵ��
+ * ����������ʱ��ͨ�����ñ���������豸��Ӧ��vnodeman_desc��������
+ *
+ */
+
+#include <rte_malloc.h>
+#include <mr_device.h>
+#include <mr_vman.h>
+#include <mr_common.h>
+#include <mr_rtdev.h>
+
+#define __PATTERN_DEV_RX "%s-RX"
+#define __PATTERN_DEV_TX "%s-TX"
+#define __PATTERN_DEV_FTX "%s-FTX"
+#define __PATTERN_PROD_SERVICE "%s"
+#define __PATTERN_CONS_SERVICE "%s"
+#define __PATTERN_PROD_APP "%s"
+#define __PATTERN_CONS_APP "%s"
+
+static int __unregister_app_for_rxvnode(const char * devsym, const char * appsym)
+{
+ char vnodesym[MR_SYMBOL_MAX];
+ char conssym[MR_SYMBOL_MAX];
+
+ snprintf(vnodesym, sizeof(vnodesym), __PATTERN_DEV_RX, devsym);
+ snprintf(conssym, sizeof(conssym), __PATTERN_CONS_APP, appsym);
+
+ int ret = mr_vnodeman_unregister_consumer(vnodesym, conssym);
+ if (ret < 0)
+ {
+ MR_LOG(WARNING, BASE, "Rtdevice, RtdeviceClose, "
+ "Cannot unregister consumer %s for vnode %s. \n",
+ conssym, vnodesym);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int __unregister_app_for_txvnode(const char * devsym, const char * appsym)
+{
+ char vnodesym[MR_SYMBOL_MAX];
+ char prodsym[MR_SYMBOL_MAX];
+
+ snprintf(vnodesym, sizeof(vnodesym), __PATTERN_DEV_TX, devsym);
+ snprintf(prodsym, sizeof(prodsym), __PATTERN_PROD_APP, appsym);
+
+ int ret = mr_vnodeman_unregister_producer(vnodesym, prodsym);
+ if (ret < 0)
+ {
+ MR_LOG(WARNING, BASE, "Rtdevice, RtdeviceClose, "
+ "Cannot unregister consumer %s for vnode %s. \n",
+ prodsym, vnodesym);
+ return ret;
+ }
+
+ snprintf(vnodesym, sizeof(vnodesym), __PATTERN_DEV_FTX, devsym);
+ snprintf(prodsym, sizeof(prodsym), __PATTERN_PROD_APP, appsym);
+
+ ret = mr_vnodeman_unregister_producer(vnodesym, prodsym);
+ if (ret < 0)
+ {
+ MR_LOG(WARNING, BASE, "Rtdevice, RtdeviceClose, "
+ "Cannot unregister consumer %s for vnode %s. \n",
+ prodsym, vnodesym);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int __register_app_for_rxvnode(const char * devsym, const char * appsym,
+ unsigned int nr_queues)
+{
+ char vnodesym[MR_SYMBOL_MAX];
+ char conssym[MR_SYMBOL_MAX];
+
+ snprintf(vnodesym, sizeof(vnodesym), __PATTERN_DEV_RX, devsym);
+ snprintf(conssym, sizeof(conssym), __PATTERN_CONS_APP, appsym);
+
+ int ret = mr_vnodeman_register_consumer(vnodesym, conssym, nr_queues);
+ if (ret < 0)
+ {
+ MR_LOG(WARNING, BASE, "Rtdevice, RtdeviceOpen, "
+ "Cannot register consumer %s(nr_queues=%d) for vnode %s. \n",
+ conssym, nr_queues, vnodesym);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int __register_app_for_txvnode(const char * devsym, const char * appsym,
+ unsigned int nr_queues)
+{
+ char vnodesym[MR_SYMBOL_MAX];
+ char prodsym[MR_SYMBOL_MAX];
+
+ snprintf(vnodesym, sizeof(vnodesym), __PATTERN_DEV_TX, devsym);
+ snprintf(prodsym, sizeof(prodsym), __PATTERN_PROD_APP, appsym);
+
+ int ret = mr_vnodeman_register_producer(vnodesym, prodsym, nr_queues);
+ if (ret < 0)
+ {
+ MR_LOG(WARNING, BASE, "Rtdevice, RtdeviceOpen, "
+ "Cannot register consumer %s(nr_queues=%d) for vnode %s. \n",
+ prodsym, nr_queues, vnodesym);
+ return ret;
+ }
+
+ snprintf(vnodesym, sizeof(vnodesym), __PATTERN_DEV_FTX, devsym);
+ snprintf(prodsym, sizeof(prodsym), __PATTERN_PROD_APP, appsym);
+
+ ret = mr_vnodeman_register_producer(vnodesym, prodsym, nr_queues);
+ if (ret < 0)
+ {
+ MR_LOG(WARNING, BASE, "Rtdevice, RtdeviceOpen, "
+ "Cannot register consumer %s(nr_queues=%d) for vnode %s. \n",
+ prodsym, nr_queues, vnodesym);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int __register_service_for_rxvnode(const char * devsym, const char * servsym,
+ unsigned int nr_queues)
+{
+ char vnodesym[MR_STRING_MAX];
+ char prodsym[MR_STRING_MAX];
+
+ // ����VNode������
+ snprintf(vnodesym, sizeof(vnodesym), __PATTERN_DEV_RX, devsym);
+ snprintf(prodsym, sizeof(prodsym), __PATTERN_PROD_SERVICE, servsym);
+
+ // ע�������ߣ������ߵĶ��������������߳���һ��
+ int ret = mr_vnodeman_register_producer(vnodesym, prodsym, nr_queues);
+
+ if (ret < 0)
+ {
+ MR_LOG(WARNING, SERVICE, "Rtdevice, RtdeviceCreate, "
+ "Cannot register producer %s(nr_queues=%d) for vnode %s. \n",
+ prodsym, nr_queues, vnodesym);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int __register_service_for_txvnode(const char * devsym, const char * servsym,
+ unsigned int nr_queues)
+{
+ char vnodesym[MR_SYMBOL_MAX];
+ char conssym[MR_SYMBOL_MAX];
+
+ // ����VNode�����֣���ͨ����·��
+ snprintf(vnodesym, sizeof(vnodesym), __PATTERN_DEV_TX, devsym);
+ snprintf(conssym, sizeof(conssym), __PATTERN_CONS_SERVICE, servsym);
+
+ // ע��������
+ int ret = mr_vnodeman_register_consumer(vnodesym, conssym, nr_queues);
+
+ if (ret < 0)
+ {
+ MR_LOG(WARNING, SERVICE, "Rtdevice, RtdeviceCreate, "
+ "Cannot register consumer %s(nr_queues=%d) for vnode %s. \n",
+ conssym, nr_queues, vnodesym);
+ return ret;
+ }
+
+ // ����VNode�����֣����ٷ���·��
+ snprintf(vnodesym, sizeof(vnodesym), __PATTERN_DEV_FTX, devsym);
+ snprintf(conssym, sizeof(conssym), __PATTERN_CONS_SERVICE, servsym);
+
+ // ע��������
+ ret = mr_vnodeman_register_consumer(vnodesym, conssym, nr_queues);
+
+ if (ret < 0)
+ {
+ MR_LOG(WARNING, SERVICE, "Rtdevice, RtdeviceCreate, "
+ "Cannot register consumer %s(nr_queues=%d) for vnode %s. \n",
+ conssym, nr_queues, vnodesym);
+ return ret;
+ }
+
+ return 0;
+}
+
+// ΪRtdevice����VNode�ڵ�
+static int __create_device_vnode(const char * symbol, unsigned int sz_tunnel, unsigned int sz_buffer)
+{
+ char vnodesym[MR_SYMBOL_MAX];
+ int ret = 0;
+
+ // Ϊ�ձ�·��ע���µ�VNode�ڵ�
+ snprintf(vnodesym, sizeof(vnodesym), __PATTERN_DEV_RX, symbol);
+ ret = mr_vnodeman_create(vnodesym, sz_tunnel, sz_buffer, 0);
+
+ if (ret < 0)
+ {
+ MR_LOG(WARNING, BASE, "Rtdevice, RtdeviceCreate, "
+ "Cannot create vnode %s(sz_tunnel=%d, sz_buffer=%d) for rt-device %s\n",
+ vnodesym, sz_tunnel, sz_buffer, symbol);
+ return ret;
+ }
+
+ // Ϊ����·��ע���µ�VNode�ڵ�
+ snprintf(vnodesym, sizeof(vnodesym), __PATTERN_DEV_TX, symbol);
+ ret = mr_vnodeman_create(vnodesym, sz_tunnel, sz_buffer, 0);
+
+ if (ret < 0)
+ {
+ MR_LOG(WARNING, BASE, "Rtdevice, RtdeviceCreate, "
+ "Cannot create vnode %s(sz_tunnel=%d, sz_buffer=%d) for rt-device %s\n",
+ vnodesym, sz_tunnel, sz_buffer, symbol);
+ return ret;
+ }
+
+ // Ϊ���ٱ��ķ���·��ע���µ�VNode�ڵ�
+ snprintf(vnodesym, sizeof(vnodesym), __PATTERN_DEV_FTX, symbol);
+ ret = mr_vnodeman_create(vnodesym, sz_tunnel, sz_buffer, 0);
+
+ if(ret < 0)
+ {
+ MR_LOG(WARNING, BASE, "Rtdevice, RtdeviceCreate, "
+ "Cannot create vnode %s(sz_tunnel=%d, sz_buffer=%d) for rt-device %s\n",
+ vnodesym, sz_tunnel, sz_buffer, symbol);
+ return ret;
+ }
+
+ MR_LOG(DEBUG, BASE, "Rtdevice, RtdeviceCreate, "
+ "Create vnodes for rt-device %s successful. \n", symbol);
+
+ return 0;
+}
+
+// ����һ������ʱ�����豸
+int rt_device_serv_create(const char * devsym,
+ const char * servsym, unsigned int nr_serv_thread,
+ unsigned int sz_tunnel, unsigned int sz_buffer)
+{
+ // ����VNode�ڵ�
+ int ret = __create_device_vnode(devsym, sz_tunnel, sz_buffer);
+ if(unlikely(ret < 0))
+ {
+ MR_LOG(ERR, BASE, "Rtdevice, RtdeviceCreate, "
+ "Cannot create vnodes for rt-device %s\n", devsym);
+ return ret;
+ }
+
+ // ע��Service���ձ���������
+ ret = __register_service_for_rxvnode(devsym, servsym, nr_serv_thread);
+ if(unlikely(ret < 0))
+ {
+ MR_LOG(ERR, BASE, "Rtdevice, RtdeviceCreate, "
+ "Cannot register rxvnodes for rt-device %s\n", devsym);
+ return ret;
+ }
+
+ // ע��Service�ķ�����������
+ ret = __register_service_for_txvnode(devsym, servsym, nr_serv_thread);
+ if(unlikely(ret < 0))
+ {
+ MR_LOG(ERR, BASE, "Rtdevice, RtdeviceCreate, "
+ "Cannot register txvnodes for rt-device %s\n", devsym);
+ return ret;
+ }
+
+ return 0;
+}
+
+// ����һ������ʱ�����豸
+int rt_device_serv_destory(const char * devsym)
+{
+ return 0;
+}
+
+// ���豸��ͨ����Slave������ʹ��
+int rt_device_open(const char * devsym, const char * appsym,
+ unsigned int nr_rxstream, unsigned int nr_txstream)
+{
+ // ע��App���ձ���������
+ int ret = __register_app_for_rxvnode(devsym, appsym, nr_rxstream);
+ if(unlikely(ret < 0))
+ {
+ MR_LOG(ERR, BASE, "Rtdevice, RtdeviceOpen, "
+ "Cannot register rxvnodes for rt-device %s\n", devsym);
+ return ret;
+ }
+
+ // ע��App�ķ�����������
+ ret = __register_app_for_txvnode(devsym, appsym, nr_txstream);
+ if(unlikely(ret < 0))
+ {
+ MR_LOG(ERR, BASE, "Rtdevice, RtdeviceOpen, "
+ "Cannot register txvnodes for rt-device %s\n", devsym);
+ return ret;
+ }
+
+ return 0;
+}
+
+int rt_device_close(const char * devsym, const char * appsym)
+{
+ int ret = __unregister_app_for_rxvnode(devsym, appsym);
+ if (unlikely(ret < 0))
+ {
+ MR_LOG(ERR, BASE, "Rtdevice, RtdeviceClose, "
+ "Cannot unregister rxvnodes for rt-device %s\n", devsym);
+ return ret;
+ }
+
+ ret = __unregister_app_for_txvnode(devsym, appsym);
+ if (unlikely(ret < 0))
+ {
+ MR_LOG(ERR, BASE, "Rtdevice, RtdeviceOpen, "
+ "Cannot register txvnodes for rt-device %s\n", devsym);
+ return ret;
+ }
+
+ return 0;
+}
+
+struct mr_rtdev_stream * rt_dev_serv_open_stream(const char * devsym,
+ const char * servsym)
+{
+ char vnodesym[MR_STRING_MAX];
+ char prod_or_cons_sym[MR_STRING_MAX];
+
+ struct mr_rtdev_stream * rtdev_stream;
+ rtdev_stream = rte_zmalloc(NULL, sizeof(struct mr_rtdev_stream), 0);
+ if (unlikely(rtdev_stream == NULL))
+ {
+ MR_LOG(WARNING, BASE, "Rtdevice, RtdeviceServOpen, "
+ "Cannot alloc rtdev_stream for rtdevice %s", devsym);
+ goto errout;
+ }
+
+ snprintf(vnodesym, sizeof(vnodesym), __PATTERN_DEV_RX, devsym);
+ snprintf(prod_or_cons_sym, sizeof(prod_or_cons_sym), __PATTERN_PROD_SERVICE, servsym);
+
+ struct vnodeman_attach_desc * attach_rxd;
+ attach_rxd = mr_vnodeman_producer_attach(vnodesym, prod_or_cons_sym);
+ if (unlikely(attach_rxd == NULL))
+ {
+ MR_LOG(WARNING, BASE, "Rtdevice, RtdeviceServOpen, "
+ "Cannot attach vnode(sym=%s) producer=(%s). \n",
+ vnodesym, prod_or_cons_sym);
+ goto errout;
+ }
+
+ snprintf(vnodesym, sizeof(vnodesym), __PATTERN_DEV_TX, devsym);
+ snprintf(prod_or_cons_sym, sizeof(prod_or_cons_sym), __PATTERN_CONS_SERVICE, servsym);
+
+ struct vnodeman_attach_desc * attach_txd;
+ attach_txd = mr_vnodeman_consumer_attach(vnodesym, prod_or_cons_sym);
+ if (unlikely(attach_txd == NULL))
+ {
+ MR_LOG(WARNING, BASE, "Rtdevice, RtdeviceServOpen, "
+ "Cannot attach vnode(sym=%s) consumer=(%s). \n",
+ vnodesym, prod_or_cons_sym);
+ goto errout;
+ }
+
+ snprintf(vnodesym, sizeof(vnodesym), __PATTERN_DEV_FTX, devsym);
+ snprintf(prod_or_cons_sym, sizeof(prod_or_cons_sym), __PATTERN_CONS_SERVICE, servsym);
+
+ struct vnodeman_attach_desc * attach_ftxd;
+ attach_ftxd = mr_vnodeman_consumer_attach(vnodesym, prod_or_cons_sym);
+ if (unlikely(attach_ftxd == NULL))
+ {
+ MR_LOG(WARNING, BASE, "Rtdevice, RtdeviceServOpen, "
+ "Cannot attach vnode(sym=%s) consumer=(%s). \n",
+ vnodesym, prod_or_cons_sym);
+ goto errout;
+ }
+
+ rtdev_stream->rxd = attach_rxd;
+ rtdev_stream->txd = attach_txd;
+ rtdev_stream->fasttxd = attach_ftxd;
+ snprintf(rtdev_stream->symbol, sizeof(rtdev_stream->symbol), "%s", devsym);
+ return rtdev_stream;
+
+errout:
+ //TODO: ��׼ȷ���ͷš�
+ if (rtdev_stream != NULL) rte_free(rtdev_stream);
+ return NULL;
+}
+
+// �ر��豸����û��ʵ���Ե��߼������򿪺�Ͳ��ܹرգ�����Ҫ�ر�����
+// Ӧ���ر������豸Ȼ�����´򿪡�
+int rt_dev_stream_close(struct mr_rtdev_stream * stream)
+{
+ rte_free(stream);
+ return 0;
+}
+
+// ���豸����ÿ���̵߳���һ�Σ���ȡ��ǰ�̵߳���������
+struct mr_rtdev_stream * rt_dev_open_stream(const char * devsym,
+ const char * appsym, flags_t flags)
+{
+ char vnodesym[MR_STRING_MAX];
+ char prod_or_cons_sym[MR_STRING_MAX];
+
+ struct vnodeman_attach_desc * attach_rxd = NULL;
+ struct vnodeman_attach_desc * attach_txd = NULL;
+ struct vnodeman_attach_desc * attach_ftxd = NULL;
+
+ // �����������ռ�
+ struct mr_rtdev_stream * rtdev_stream;
+ rtdev_stream = rte_zmalloc(NULL, sizeof(struct mr_rtdev_stream), 0);
+ if(unlikely(rtdev_stream == NULL))
+ {
+ MR_LOG(WARNING, BASE, "Rtdevice, RtdeviceOpen, "
+ "Cannot alloc rtdev_stream for rtdevice %s", devsym);
+ goto errout;
+ }
+
+ // �����򿪣����ձ���
+ if (flags & RTDEV_FLAGS_OPEN_STREAM_RX)
+ {
+ snprintf(vnodesym, sizeof(vnodesym), __PATTERN_DEV_RX, devsym);
+ snprintf(prod_or_cons_sym, sizeof(prod_or_cons_sym), __PATTERN_CONS_APP, appsym);
+
+ attach_rxd = mr_vnodeman_consumer_attach(vnodesym, prod_or_cons_sym);
+ if (unlikely(attach_rxd == NULL))
+ {
+ MR_LOG(WARNING, BASE, "Rtdevice, RtdeviceOpen, "
+ "Cannot attach vnode(sym=%s) consumer=(%s). \n",
+ vnodesym, prod_or_cons_sym);
+ goto errout;
+ }
+ }
+
+ // �����򿪣���������
+ if (flags & RTDEV_FLAGS_OPEN_STREAM_TX)
+ {
+ snprintf(vnodesym, sizeof(vnodesym), __PATTERN_DEV_TX, devsym);
+ snprintf(prod_or_cons_sym, sizeof(prod_or_cons_sym), __PATTERN_PROD_APP, appsym);
+
+ attach_txd = mr_vnodeman_producer_attach(vnodesym, prod_or_cons_sym);
+ if (unlikely(attach_txd == NULL))
+ {
+ MR_LOG(WARNING, BASE, "Rtdevice, RtdeviceOpen, "
+ "Cannot attach vnode(sym=%s) producer=(%s). \n",
+ vnodesym, prod_or_cons_sym);
+ goto errout;
+ }
+
+ snprintf(vnodesym, sizeof(vnodesym), __PATTERN_DEV_FTX, devsym);
+ snprintf(prod_or_cons_sym, sizeof(prod_or_cons_sym), __PATTERN_PROD_APP, appsym);
+
+ attach_ftxd = mr_vnodeman_producer_attach(vnodesym, prod_or_cons_sym);
+ if (unlikely(attach_ftxd == NULL))
+ {
+ MR_LOG(WARNING, BASE, "Rtdevice, RtdeviceOpen, "
+ "Cannot attach vnode(sym=%s) producer=(%s). \n",
+ vnodesym, prod_or_cons_sym);
+ goto errout;
+ }
+ }
+
+ rtdev_stream->rxd = attach_rxd;
+ rtdev_stream->txd = attach_txd;
+ rtdev_stream->fasttxd = attach_ftxd;
+ snprintf(rtdev_stream->symbol, sizeof(rtdev_stream->symbol), "%s", devsym);
+ return rtdev_stream;
+
+errout:
+ //TODO: ��׼ȷ���ͷš�
+ if (rtdev_stream != NULL) rte_free(rtdev_stream);
+ return NULL;
+} \ No newline at end of file
diff --git a/core/src/stat.c b/core/src/stat.c
index 35f2839..486f20e 100644
--- a/core/src/stat.c
+++ b/core/src/stat.c
@@ -6,10 +6,11 @@
#include <stdint.h>
#include <rte_config.h>
-#include <mr_ctx.h>
#include <rte_memory.h>
#include <rte_malloc.h>
#include <mr_stat.h>
+#include <mr_core.h>
+#include <mr_runtime.h>
#include "MESA_prof_load.h"
#ifndef MR_STAT_OPT_DEFAULT_DEV_STAT_ENABLE
@@ -47,50 +48,53 @@ struct stat_ctx
struct mr_event_stat event_stat_handle;
};
-static struct stat_ctx * module_ctx;
-
struct mr_device_stat * mr_device_stat_get()
{
+ struct stat_ctx * module_ctx = mr_core_default_instance_get()->stat_ctx;
if (module_ctx->device_stat_enable) return &module_ctx->device_stat_handle;
return NULL;
}
struct mr_vnode_stat * mr_vnode_stat_get()
{
+ struct stat_ctx * module_ctx = mr_core_default_instance_get()->stat_ctx;
if (module_ctx->vnode_stat_enable) return &module_ctx->vnode_stat_handle;
return NULL;
}
struct mr_perf_stat * mr_perf_stat_get()
{
+ struct stat_ctx * module_ctx = mr_core_default_instance_get()->stat_ctx;
if(module_ctx->perf_stat_enable) return &module_ctx->perf_stat_handle;
return NULL;
}
struct mr_app_stat * mr_app_stat_get()
{
+ struct stat_ctx * module_ctx = mr_core_default_instance_get()->stat_ctx;
if(module_ctx->app_stat_enable) return &module_ctx->app_stat_handle;
return NULL;
}
struct mr_event_stat * mr_event_stat_get()
{
+ struct stat_ctx * module_ctx = mr_core_default_instance_get()->stat_ctx;
if(module_ctx->event_stat_enable) return &module_ctx->event_stat_handle;
return NULL;
}
-static int stat_preinit(struct mr_module * m_desc, struct mr_config * g_cfg,
- struct mr_global_ctx * g_ctx)
+int stat_ctx_init(struct mr_core_instance * core_instance)
{
- MODULE_CTX(g_ctx, m_desc->mid) = rte_zmalloc("STAT_CTX", sizeof(struct stat_ctx), 0);
- MR_CHECK(MODULE_CTX(g_ctx, m_desc->mid) != NULL, "Cannot alloc memory for stat context");
- module_ctx = MODULE_CTX(g_ctx, m_desc->mid);
+ core_instance->stat_ctx = rte_zmalloc("STAT_CTX", sizeof(struct stat_ctx), 0);
+ MR_CHECK(core_instance->stat_ctx != NULL, "Cannot alloc memory for stat context");
return 0;
}
-static int stat_config(struct mr_module * m_desc, struct mr_config * g_cfg,
- struct mr_global_ctx * g_ctx)
+int stat_config(struct mr_core_instance * core_instance)
{
+ struct mr_global_config * g_cfg = core_instance->g_cfg;
+ struct stat_ctx * module_ctx = mr_core_default_instance_get()->stat_ctx;
+
MESA_load_profile_uint_def(g_cfg->glob_cfg_file, "stat", "device_stat_enable",
&module_ctx->device_stat_enable, MR_STAT_OPT_DEFAULT_DEV_STAT_ENABLE);
MESA_load_profile_uint_def(g_cfg->glob_cfg_file, "stat", "vnode_stat_enable",
@@ -104,31 +108,18 @@ static int stat_config(struct mr_module * m_desc, struct mr_config * g_cfg,
return 0;
}
-static int stat_init(struct mr_module * m_desc, struct mr_config * g_cfg,
- struct mr_global_ctx * g_ctx)
+int stat_init(struct mr_core_instance * core_instance)
{
return 0;
}
-static int stat_slave_init(struct mr_module * m_desc, struct mr_config * g_cfg,
- struct mr_global_ctx * g_ctx)
+int stat_slave_init(struct mr_core_instance * core_instance,
+ struct mr_core_slave_instance * slave_instance)
{
- module_ctx = MODULE_CTX(g_ctx, m_desc->mid);
return 0;
}
-static int stat_destory(struct mr_module * m_desc, struct mr_config * g_cfg,
- struct mr_global_ctx * g_ctx)
+int stat_destory(struct mr_core_instance * core_instance)
{
return 0;
-}
-
-struct mr_module module_desc_stat =
-{
- .sym = "stat",
- .mid = MR_MID_STAT,
- .preinit = stat_preinit,
- .config = stat_config,
- .slaveinit = stat_slave_init,
- .destory = stat_destory
-}; \ No newline at end of file
+} \ No newline at end of file
diff --git a/core/src/vman.c b/core/src/vman.c
index 97630ad..4d0ea4b 100644
--- a/core/src/vman.c
+++ b/core/src/vman.c
@@ -10,15 +10,17 @@
#include <stdlib.h>
#include <sys/queue.h>
-#include <mr_ctx.h>
-#include <mr_common.h>
-#include <rte_log.h>
-#include <mr_vnode.h>
-#include <rte_ip_frag.h>
#include <assert.h>
#include <string.h>
+#include <rte_log.h>
+#include <rte_malloc.h>
+
+#include <mr_common.h>
+#include <mr_vnode.h>
#include <mr_vman.h>
-#include "mr_mrbuf.h"
+#include <mr_mrbuf.h>
+#include <mr_runtime.h>
+#include <mr_core.h>
struct vnode_record
{
@@ -35,23 +37,20 @@ struct vnodeman_ctx
struct vnode_record_list vnode_list;
};
-static struct vnodeman_ctx * ctx = NULL;
-
static void __wrap_object_delete(void * object)
{
return rte_pktmbuf_free(object);
}
+//TODO: 报文缓冲区池决定机制
static void * __wrap_object_new(void * object)
{
- struct mr_thread_ctx * tctx = mr_thread_ctx_get();
- return rte_pktmbuf_alloc(mrbuf_get_mempool(tctx->socket_id));
+ return rte_pktmbuf_alloc(mrbuf_get_mempool(0));
}
static void * __wrap_object_dup(void * object)
{
- struct mr_thread_ctx * tctx = mr_thread_ctx_get();
- return rte_pktmbuf_clone(object, mrbuf_get_mempool(tctx->socket_id));
+ return rte_pktmbuf_clone(object, mrbuf_get_mempool(0));
}
// VNode操作指针
@@ -108,7 +107,7 @@ static int __vnodeman_create_unsafe(struct vnodeman_ctx * ctx_, const char * sym
if(node == NULL)
{
MR_LOG(INFO, BASE, "VNodeMan, VNodeManCreate, "
- "Cannot create vnode, sym=%s, sz_tunnel=%d, sz_buffer=%d\n",
+ "Cannot create vnode, sym=%s, sz_tunnel=%zu, sz_buffer=%zu\n",
sym, sz_tunnel, sz_buffer);
return -2;
}
@@ -129,12 +128,88 @@ static int __vnodeman_create_unsafe(struct vnodeman_ctx * ctx_, const char * sym
TAILQ_INSERT_TAIL(&ctx_->vnode_list, node_record, next);
MR_LOG(INFO, BASE, "VNodeMan, VNodeCreate, "
- "Vnode %s(sz_tunnel=%d, sz_buffer=%d) created. \n",
+ "Vnode %s(sz_tunnel=%zu, sz_buffer=%zu) created. \n",
node_record->sym, sz_tunnel, sz_buffer);
return 0;
}
+static int __vnodeman_unregister_consumer_unsafe(struct vnodeman_ctx * ctx_,
+ const char * vnode_sym, const char * cons_sym)
+{
+ struct vnode_record * vnode_record = NULL;
+ struct vnode_cons * cons = NULL;
+ int ret = 0;
+
+ vnode_record = __vnodeman_lookup_unsafe(ctx_, vnode_sym);
+ if (vnode_record == NULL)
+ {
+ MR_LOG(WARNING, BASE, "VNodeMan, VNodeManUnregisterConsumer, "
+ "Vnode %s does not existed, failed. \n", vnode_sym);
+ ret = -1; goto errout;
+ }
+
+ cons = vnode_cons_lookup(vnode_record->node, cons_sym);
+ if (cons == NULL)
+ {
+ MR_LOG(WARNING, BASE, "VNodeMan, VNodeManUnregisterConsumer, "
+ "Vnode %s consumer %s does not existed, failed. \n",
+ vnode_sym, cons_sym);
+ ret = -2; goto errout;
+ }
+
+ ret = vnode_delete_cons(cons, &vnodeman_ops);
+ if(ret < 0)
+ {
+ MR_LOG(WARNING, BASE, "VNodeMan, VNodeManUnregisterConsumer, "
+ "Cannot delete cons %s for vnode %s, failed. \n",
+ cons_sym, vnode_sym);
+ ret = -3; goto errout;
+ }
+
+ return 0;
+errout:
+ return ret;
+}
+
+static int __vnodeman_unregister_producer_unsafe(struct vnodeman_ctx * ctx_,
+ const char * vnode_sym, const char * prod_sym)
+{
+ struct vnode_record * vnode_record = NULL;
+ struct vnode_prod * prod = NULL;
+ int ret = 0;
+
+ vnode_record = __vnodeman_lookup_unsafe(ctx_, vnode_sym);
+ if (vnode_record == NULL)
+ {
+ MR_LOG(WARNING, BASE, "VNodeMan, VNodeManUnregisterProducer, "
+ "Vnode %s does not existed, failed. \n", vnode_sym);
+ ret = -1; goto errout;
+ }
+
+ prod = vnode_prod_lookup(vnode_record->node, prod_sym);
+ if (prod == NULL)
+ {
+ MR_LOG(WARNING, BASE, "VNodeMan, VNodeManUnregisterProducer, "
+ "Vnode %s producer %s does not existed, failed. \n",
+ vnode_sym, prod_sym);
+ ret = -2; goto errout;
+ }
+
+ ret = vnode_delete_prod(prod, &vnodeman_ops);
+ if (ret < 0)
+ {
+ MR_LOG(WARNING, BASE, "VNodeMan, VNodeManUnregisterProducer, "
+ "Cannot delete cons %s for vnode %s, failed. \n",
+ prod_sym, vnode_sym);
+ ret = -3; goto errout;
+ }
+
+ return 0;
+errout:
+ return ret;
+}
+
static int __vnodeman_register_consumer_unsafe(struct vnodeman_ctx * ctx_,
const char * vnode_sym, const char * cons_sym, unsigned int nr_cons_queue)
{
@@ -307,16 +382,42 @@ errout:
int mr_vnodeman_create(const char * sym, size_t sz_tunnel, size_t sz_buffer, flags_t flags)
{
int ret = 0;
+ struct vnodeman_ctx * ctx = mr_core_default_instance_get()->vnodeman_ctx;
+
mr_spin_lock(&ctx->lock);
ret = __vnodeman_create_unsafe(ctx, sym, sz_tunnel, sz_buffer, flags);
mr_spin_unlock(&ctx->lock);
return ret;
}
+int mr_vnodeman_unregister_consumer(const char * vnode_sym, const char * cons_sym)
+{
+ int ret = 0;
+ struct vnodeman_ctx * ctx = mr_core_default_instance_get()->vnodeman_ctx;
+
+ mr_spin_lock(&ctx->lock);
+ ret = __vnodeman_unregister_consumer_unsafe(ctx, vnode_sym, cons_sym);
+ mr_spin_unlock(&ctx->lock);
+ return ret;
+}
+
+int mr_vnodeman_unregister_producer(const char * vnode_sym, const char * cons_sym)
+{
+ int ret = 0;
+ struct vnodeman_ctx * ctx = mr_core_default_instance_get()->vnodeman_ctx;
+
+ mr_spin_lock(&ctx->lock);
+ ret = __vnodeman_unregister_producer_unsafe(ctx, vnode_sym, cons_sym);
+ mr_spin_unlock(&ctx->lock);
+ return ret;
+}
+
int mr_vnodeman_register_consumer(const char * vnode_sym, const char * cons_sym,
unsigned int nr_cons_queue)
{
int ret = 0;
+ struct vnodeman_ctx * ctx = mr_core_default_instance_get()->vnodeman_ctx;
+
mr_spin_lock(&ctx->lock);
ret = __vnodeman_register_consumer_unsafe(ctx, vnode_sym, cons_sym, nr_cons_queue);
mr_spin_unlock(&ctx->lock);
@@ -327,6 +428,8 @@ int mr_vnodeman_register_producer(const char * vnode_sym, const char * prod_sym,
unsigned int nr_prod_queue)
{
int ret = 0;
+ struct vnodeman_ctx * ctx = mr_core_default_instance_get()->vnodeman_ctx;
+
mr_spin_lock(&ctx->lock);
ret = __vnodeman_register_producer_unsafe(ctx, vnode_sym, prod_sym, nr_prod_queue);
mr_spin_unlock(&ctx->lock);
@@ -336,6 +439,7 @@ int mr_vnodeman_register_producer(const char * vnode_sym, const char * prod_sym,
struct vnodeman_attach_desc * mr_vnodeman_consumer_attach(const char * vnode_sym,
const char * cons_sym)
{
+ struct vnodeman_ctx * ctx = mr_core_default_instance_get()->vnodeman_ctx;
struct vnodeman_attach_desc * desc;
mr_spin_lock(&ctx->lock);
desc = __vnodeman_consumer_attach_unsafe(ctx, vnode_sym, cons_sym);
@@ -346,6 +450,8 @@ struct vnodeman_attach_desc * mr_vnodeman_consumer_attach(const char * vnode_sym
struct vnodeman_attach_desc * mr_vnodeman_producer_attach(const char * vnode_sym,
const char * prod_sym)
{
+ struct vnodeman_ctx * ctx = mr_core_default_instance_get()->vnodeman_ctx;
+
struct vnodeman_attach_desc * desc;
mr_spin_lock(&ctx->lock);
desc = __vnodeman_producer_attach_unsafe(ctx, vnode_sym, prod_sym);
@@ -353,52 +459,36 @@ struct vnodeman_attach_desc * mr_vnodeman_producer_attach(const char * vnode_sym
return desc;
}
-static int vnodeman_preinit(struct mr_module * m_desc, struct mr_config * g_cfg,
- struct mr_global_ctx * g_ctx)
+int vnodeman_ctx_init(struct mr_core_instance * core_instance)
{
- MODULE_CTX(g_ctx, m_desc->mid) = rte_zmalloc("VNODEMAN_CTX",
+ core_instance->vnodeman_ctx = rte_zmalloc("VNODEMAN_CTX",
sizeof(struct vnodeman_ctx), 0);
- MR_CHECK(MODULE_CTX(g_ctx, m_desc->mid) != NULL, "VNodeman, ModulePreinit, "
+ MR_CHECK(core_instance->vnodeman_ctx != NULL,
"Cannot alloc memory for vnodeman context, Failed. ");
- ctx = MODULE_CTX(g_ctx, m_desc->mid);
+ struct vnodeman_ctx * ctx = core_instance->vnodeman_ctx;
TAILQ_INIT(&ctx->vnode_list);
mr_spin_init(&ctx->lock);
return 0;
}
-static int vnodeman_config(struct mr_module * m_desc, struct mr_config * g_cfg,
- struct mr_global_ctx * g_ctx)
+int vnodeman_config(struct mr_core_instance * core_instance)
{
return 0;
}
-static int vnodeman_init(struct mr_module * m_desc, struct mr_config * g_cfg,
- struct mr_global_ctx * g_ctx)
+int vnodeman_init(struct mr_core_instance * core_instance)
{
return 0;
}
-static int vnodeman_slave_init(struct mr_module * m_desc, struct mr_config * g_cfg,
- struct mr_global_ctx * g_ctx)
+int vnodeman_slave_init(struct mr_core_instance * core_instance,
+ struct mr_core_slave_instance * slave_instance)
{
- ctx = (struct vnodeman_ctx *)MODULE_CTX(g_ctx, m_desc->mid);
- assert(ctx != NULL);
return 0;
}
-static int vnodeman_destory(struct mr_module * m_desc, struct mr_config * g_cfg,
- struct mr_global_ctx * g_ctx)
+int vnodeman_destory(struct mr_core_instance * core_instance)
{
return 0;
-}
-
-struct mr_module module_desc_vnodeman =
-{
- .sym = "vnodeman",
- .mid = MR_MID_VNODEMAN,
- .preinit = vnodeman_preinit,
- .config = vnodeman_config,
- .slaveinit = vnodeman_slave_init,
- .destory = vnodeman_destory
-}; \ No newline at end of file
+} \ No newline at end of file
diff --git a/core/src/vnode.c b/core/src/vnode.c
index 422f714..5fda579 100644
--- a/core/src/vnode.c
+++ b/core/src/vnode.c
@@ -112,8 +112,8 @@ struct tunnel_desc * tunnel_new(const char * symbol, unsigned int size,
/* Delete a tunnel */
int tunnel_delete(struct tunnel_desc * desc)
{
- //TODO: delete ring object, only aviliabe in higher version dpdk.
- assert(0);
+ rte_free(desc->en_buffer);
+ rte_ring_free(desc->tunnel_object);
rte_free(desc);
return 0;
}
@@ -216,11 +216,25 @@ int tunnel_block_delete(struct tunnel_block * block, struct vnode_ops * ops)
return 0;
}
-/* Try to delete a tunnel block, when the block is in used, disable it but not
- * real delete it. */
+// 删除Block。当Block没有被删除过时,进入GC状态,等待GC回收。
int tunnel_block_try_delete(struct tunnel_block * block, struct vnode_ops * ops)
{
- return tunnel_block_delete(block, ops);
+ if (block->deleted == 0)
+ {
+ block->deleted = 1;
+ return 0;
+ }
+ else
+ {
+ return tunnel_block_delete(block, ops);
+ }
+}
+
+int tunnel_block_try_gc(struct tunnel_block * block, struct vnode_ops * ops)
+{
+ if (block->deleted)
+ return tunnel_block_delete(block, ops);
+ return -1;
}
/* Alloc a block of tunnels, and init all the tunnels */
@@ -235,7 +249,7 @@ struct tunnel_block * tunnel_block_new(struct vnode_ops * ops, const char * symb
if(block == NULL)
{
- MR_LOG(INFO, BASE, "LibVNode, TunnelBlockNew, ",
+ MR_LOG(INFO, BASE, "LibVNode, TunnelBlockNew, "
"Cannot alloc memory for block storage, nr_prodq=%d"
"nr_consq=%d\n, total_memory=%d\n",
nr_prodq, nr_consq, block_size);
@@ -245,6 +259,7 @@ struct tunnel_block * tunnel_block_new(struct vnode_ops * ops, const char * symb
block->nr_consq = nr_consq;
block->nr_prodq = nr_prodq;
+ block->deleted = 0;
// create tunnel for each prodq and consq in block
for (int prodq_id = 0; prodq_id < nr_prodq; prodq_id++)
@@ -486,6 +501,38 @@ struct vnode_cons * cons)
return 0;
}
+// 垃圾回收,回收已经没有用的TunnelBlock
+void vnode_cons_block_gc_unsafe(struct vnode_cons * cons, struct vnode_ops * ops)
+{
+ struct tunnel_block_list_item * tblist_item_iter;
+ TAILQ_FOREACH(tblist_item_iter, &cons->block_list, next)
+ {
+ int ret = tunnel_block_try_gc(tblist_item_iter->block, ops);
+ if (ret < 0) continue;
+
+ TAILQ_REMOVE(&cons->block_list, tblist_item_iter, next);
+ tblist_item_delete(tblist_item_iter);
+ }
+
+ return;
+}
+
+// 垃圾回收,回收已经没有用的TunnelBlock
+void vnode_prod_block_gc_unsafe(struct vnode_prod * prod, struct vnode_ops * ops)
+{
+ struct tunnel_block_list_item * tblist_item_iter;
+ TAILQ_FOREACH(tblist_item_iter, &prod->block_list, next)
+ {
+ int ret = tunnel_block_try_gc(tblist_item_iter->block, ops);
+ if (ret < 0) continue;
+
+ TAILQ_REMOVE(&prod->block_list, tblist_item_iter, next);
+ tblist_item_delete(tblist_item_iter);
+ }
+
+ return;
+}
+
/* VNode的生产者、消费者注册 */
struct vnode_prod * vnode_create_prod(struct vnode * vnode, struct vnode_ops * ops,
const char * symbol, int nr_prodq)
@@ -623,7 +670,7 @@ int vnode_cons_attach(struct vnode * node, struct vnode_cons * cons)
{
MR_LOG(INFO, BASE, "LibVNode, VNodeConsAttach, "
"Too much attach request(cur_attach=%d, nr_consq=%d)\n",
- cons->cur_attach, cons->consq);
+ cons->cur_attach, cons->nr_consq);
ret = -1;
}
else
@@ -644,7 +691,7 @@ int vnode_prod_attach(struct vnode * node, struct vnode_prod* prod)
{
MR_LOG(INFO, BASE, "LibVNode, VNodeProdAttach, "
"Too much attach request(cur_attach=%d, nr_prodq=%d)\n",
- prod->cur_attach, prod->prodq);
+ prod->cur_attach, prod->nr_prodq);
ret = -1;
}
else
@@ -661,9 +708,11 @@ int vnode_delete_prod(struct vnode_prod * prod, struct vnode_ops * ops)
assert(prod != NULL && prod->vnode != NULL && ops != NULL);
__write_lock(&prod->vnode->rwlock);
-
- // delete all the blocks.
+
+ struct vnode * vnode = prod->vnode;
struct tunnel_block_list_item * tblist_item_iter;
+
+ // 删除引用的Block
TAILQ_FOREACH(tblist_item_iter, &prod->block_list, next)
{
assert(tblist_item_iter != NULL);
@@ -671,19 +720,17 @@ int vnode_delete_prod(struct vnode_prod * prod, struct vnode_ops * ops)
tblist_item_delete(tblist_item_iter);
}
- // remove prod desc from vnode prod list
- struct vnode_prod * prod_iter;
+ // 从VNode中移除生产者描述符
struct vnode_prod_list * prod_list_head = &prod->vnode->prod_list;
-
- TAILQ_FOREACH(prod_iter, prod_list_head, next)
+ TAILQ_REMOVE(prod_list_head, prod, next);
+
+ // 执行GC,移除所有消费者描述符中引用的Block
+ struct vnode_cons * cons_iter;
+ TAILQ_FOREACH(cons_iter, &vnode->cons_list, next)
{
- if (prod_iter == prod)
- {
- TAILQ_REMOVE(prod_list_head, prod_iter, next);
- break;
- }
+ vnode_cons_block_gc_unsafe(cons_iter, ops);
}
-
+
__write_unlock(&prod->vnode->rwlock);
return 0;
}
@@ -693,8 +740,10 @@ int vnode_delete_cons(struct vnode_cons * cons, struct vnode_ops * ops)
assert(cons != NULL && ops != NULL);
__write_lock(&cons->vnode->rwlock);
- // delete all the blocks.
+ struct vnode * vnode = cons->vnode;
struct tunnel_block_list_item * tblist_item_iter;
+
+ // 删除引用的Block
TAILQ_FOREACH(tblist_item_iter, &cons->block_list, next)
{
assert(tblist_item_iter != NULL);
@@ -702,17 +751,15 @@ int vnode_delete_cons(struct vnode_cons * cons, struct vnode_ops * ops)
tblist_item_delete(tblist_item_iter);
}
- // remove prod desc from vnode prod list
- struct vnode_cons * cons_iter;
+ // 从VNode中移除消费者描述符
struct vnode_cons_list * cons_list_head = &cons->vnode->cons_list;
+ TAILQ_REMOVE(cons_list_head, cons, next);
- TAILQ_FOREACH(cons_iter, cons_list_head, next)
+ // 执行GC,移除所有生产者描述符中引用的Block
+ struct vnode_prod * prod_iter;
+ TAILQ_FOREACH(prod_iter, &vnode->prod_list, next)
{
- if (cons_iter == cons)
- {
- TAILQ_REMOVE(cons_list_head, cons_iter, next);
- break;
- }
+ vnode_prod_block_gc_unsafe(prod_iter, ops);
}
__write_unlock(&cons->vnode->rwlock);
@@ -746,36 +793,23 @@ int vnode_delete(struct vnode * vnode, struct vnode_ops * ops)
int vnode_enqueue_burst_with_hash(struct vnode_prod * prod, struct vnode_ops * ops,
unsigned int prodq, void * objects[], uint32_t hash[], int nr_objects)
{
- struct vnode * vnode = prod->vnode;
int ret;
+ assert(nr_objects <= MR_LIBVNODE_MAX_SZ_BURST);
__read_lock(&prod->vnode->rwlock);
UPDATE_VNODE_STAT(object_enqueue, nr_objects);
-
-#if MR_LIBVNODE_DEBUG_CHECK_PARAMS
- if (unlikely(nr_objects > MR_LIBVNODE_MAX_SZ_BURST))
- {
- MR_LOG(INFO, BASE, "LibVNode, VNodeEnqueueBurstWithHash, "
- "Burst Size %s is larger than limits(MR_LIBVNODE_MAX_SZ_BURST=%d)\n",
- nr_objects, MR_LIBVNODE_MAX_SZ_BURST);
- ret = -1; goto out;
- }
-#endif
-
-#if MR_LIBVNODE_DEBUG_CHECK_PARAMS
- if(unlikely(prod->nr_block <= 0))
- {
- MR_LOG(INFO, BASE, "LibVNode, VNodeEnqueueBurstWithHash, "
- "Producer %s does not have a consumer, failed\n", prod->symbol);
- ret = -1; goto out;
- }
-#endif
// get the last block, this block are enqueued with the original objects.
struct tunnel_block_list_item * tblist_item_last;
tblist_item_last = TAILQ_LAST(&prod->block_list, tunnel_block_list);
- assert(tblist_item_last != NULL && tblist_item_last->block != NULL);
+ // tblist_item_last is null when there is not registerd consumer.
+ if(unlikely(tblist_item_last == NULL))
+ {
+ ret = -1; goto out;
+ }
+
+ assert(tblist_item_last != NULL && tblist_item_last->block != NULL);
// check all the blocks expect last block, and dup objects and enqueue them.
struct tunnel_block_list_item * tblist_item_iter;
TAILQ_FOREACH(tblist_item_iter, &prod->block_list, next)
@@ -821,7 +855,6 @@ out:
int vnode_dequeue_burst(struct vnode_cons * cons, struct vnode_ops * ops,
unsigned int consq, void * objects[], int nr_max_objects)
{
- struct vnode * vnode = cons->vnode;
int nr_used = 0;
int nr_left = nr_max_objects;
int nr_dequeue = 0;
@@ -838,8 +871,6 @@ int vnode_dequeue_burst(struct vnode_cons * cons, struct vnode_ops * ops,
assert(nr_left <= nr_max_objects);
assert(nr_used <= nr_max_objects);
-
-out:
__read_unlock(&cons->vnode->rwlock);
return nr_dequeue;
} \ No newline at end of file
diff --git a/core/include/mr_common.h b/include/mr_common.h
index ad808c4..88a2140 100644
--- a/core/include/mr_common.h
+++ b/include/mr_common.h
@@ -8,6 +8,7 @@ extern "C" {
#include <rte_spinlock.h>
#include <rte_errno.h>
#include <rte_config.h>
+#include <rte_log.h>
#ifndef MR_STRING_MAX
#define MR_STRING_MAX 2048
@@ -29,10 +30,17 @@ extern "C" {
#define MR_APP_MAX 64
#endif
+#ifndef MR_SID_MAX
+#define MR_SID_MAX 64
+#endif
+
+#ifndef MR_GSID_MAX
+#define MR_GSID_MAX 64
+#endif
+
#ifndef MR_DEVICE_MAX
#define MR_DEVICE_MAX RTE_MAX_ETHPORTS
#endif
-
#define MR_CHECK(exp, fmt, ...) \
do { \
@@ -46,7 +54,7 @@ typedef uint64_t cpu_mask_t;
typedef uint32_t port_id_t;
typedef uint32_t queue_id_t;
typedef uint32_t thread_id_t;
-typedef uint32_t process_id_t;
+typedef uint32_t app_id_t;
typedef uint32_t flags_t;
typedef int32_t cpu_id_t;
@@ -68,6 +76,10 @@ typedef uint32_t hash_t;
#define RTE_LOGTYPE_MRLIB RTE_LOGTYPE_USER3
#endif
+#ifndef RTE_LOGTYPE_STACK
+#define RTE_LOGTYPE_STACK RTE_LOGTYPE_USER4
+#endif
+
#define MR_LOG(level, module, ...) \
RTE_LOG(level, module, ##__VA_ARGS__)
diff --git a/include/mr_config.h.in b/include/mr_config.h.in
new file mode 100644
index 0000000..009cf7b
--- /dev/null
+++ b/include/mr_config.h.in
@@ -0,0 +1,6 @@
+#pragma once
+
+#cmakedefine MR_INSTALL_PREFIX "@CMAKE_INSTALL_PREFIX@"
+#cmakedefine MR_GLOBAL_CONFFILE "@MR_GLOBAL_CONFFILE@"
+#cmakedefine MR_LOCAL_CONFFILE "@MR_LOCAL_CONFFILE@"
+#cmakedefine PAG_LOCAL_CONFFILE "@PAG_LOCAL_CONFFILE@" \ No newline at end of file
diff --git a/core/include/mr_mask.h b/include/mr_mask.h
index f3b85ec..f3b85ec 100644
--- a/core/include/mr_mask.h
+++ b/include/mr_mask.h
diff --git a/include/mr_rawio.h b/include/mr_rawio.h
index 0679d1b..11b806e 100644
--- a/include/mr_rawio.h
+++ b/include/mr_rawio.h
@@ -15,7 +15,9 @@ extern "C" {
/* Basic Raw Packet I/O Interface */
typedef void * raw_socket_t;
-raw_socket_t * marsio_raw_socket(const char * dev);
+raw_socket_t * marsio_raw_socket(const char * devsym, unsigned int nr_rx_stream,
+ unsigned int nr_tx_stream, unsigned int flags);
+int marsio_raw_close(raw_socket_t * socket);
int marsio_raw_recv(raw_socket_t * socket, struct rte_mbuf * mbufs[], int nr_max_mbufs);
int marsio_raw_send(raw_socket_t * socket, struct rte_mbuf * mbufs[], int nr_mbufs);
diff --git a/pag/CMakeLists.txt b/pag/CMakeLists.txt
index 3777f0e..5911903 100644
--- a/pag/CMakeLists.txt
+++ b/pag/CMakeLists.txt
@@ -6,7 +6,7 @@ include_directories(${DPDK_INCLUDE_DIR})
add_definitions(${DPDK_C_PREDEFINED})
add_library(pag SHARED libpag.c)
-target_link_libraries(pag ${DPDK_LIBRARY} MESA_prof_load_static marsio)
+target_link_libraries(pag MESA_prof_load_static marsio core)
target_link_libraries(pag rt pthread dl core)
set_target_properties(pag PROPERTIES LINK_FLAGS "-Wl,--version-script=${CMAKE_CURRENT_LIST_DIR}/version.map")
target_include_directories(pag INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}")
diff --git a/pag/libpag.c b/pag/libpag.c
index 2a4c116..f1066ee 100644
--- a/pag/libpag.c
+++ b/pag/libpag.c
@@ -14,6 +14,7 @@
#include <mr_rawio.h>
#include <mr_stat.h>
#include <mrlib.h>
+#include <mr_mask.h>
#include "libpag.h"
struct pag_instance
@@ -22,8 +23,12 @@ struct pag_instance
char dev_name[MR_STRING_MAX];
raw_socket_t * raw_sockets[MR_DEVICE_MAX];
unsigned int nr_raw_sockets;
+ unsigned int nr_rx_stream;
+ unsigned int nr_tx_stream;
unsigned int burst_rx;
unsigned int burst_tx;
+ unsigned int autoexit;
+ uint64_t coremask;
};
struct pag_thread_instance
@@ -44,7 +49,6 @@ struct pag_thread_instance
};
static int __pag_inited = 0;
-static __thread int __pag_thread_inited = 0;
static __thread struct pag_thread_instance thread_instance_;
struct pag_instance pag_config_;
@@ -57,8 +61,70 @@ do { \
#define PAG_CFGFILE "pag.conf"
#define PAG_DEFAULT_RX_BURST 32
#define PAG_DEFAULT_TX_BURST 32
+#define PAG_DEFAULT_AUTOEXIT 0
-static int __read_burst_info(struct pag_instance * instance)
+static int pag_config_load_app_info(struct pag_instance * instance)
+{
+ int ret = MESA_load_profile_string_nodef(PAG_CFGFILE, "pag", "app_name",
+ instance->app_name, sizeof(instance->app_name));
+
+ if (ret < 0)
+ {
+ PAG_LOG("load pag.conf failed(section=pag, key=app_name).");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int pag_config_load_stream_info(struct pag_instance * instance)
+{
+ uint64_t coremask = 0;
+ char * str_coremask_ptr = NULL;
+ char str_coremask[MR_STRING_MAX];
+
+ // ��CPU��������
+ int ret = MESA_load_profile_string_nodef(PAG_CFGFILE, "pag", "coremask",
+ str_coremask, sizeof(str_coremask));
+
+ if(ret < 0)
+ {
+ PAG_LOG("coremask is missing, please recheck %s", PAG_CFGFILE);
+ return -1;
+ }
+
+ coremask = strtoull(str_coremask, &str_coremask_ptr, 0);
+ if(coremask == 0 && str_coremask_ptr == NULL)
+ {
+ PAG_LOG("coremask is invalid, please recheck %s", PAG_CFGFILE);
+ return -2;
+ }
+
+ // ��Ĭ���豸������û��ָ��ʹ���߳���
+ unsigned int nr_rx_stream;
+ unsigned int nr_tx_stream;
+ unsigned int nr_stream_default = mask_popcnt(coremask);
+
+ MESA_load_profile_uint_def(PAG_CFGFILE, "pag", "rxstream",
+ &nr_rx_stream, nr_stream_default);
+ MESA_load_profile_uint_def(PAG_CFGFILE, "pag", "txstream",
+ &nr_tx_stream, nr_stream_default);
+
+ instance->coremask = coremask;
+ instance->nr_rx_stream = nr_rx_stream;
+ instance->nr_tx_stream = nr_tx_stream;
+
+ MESA_load_profile_uint_def(PAG_CFGFILE, "pag", "autoexit",
+ &instance->autoexit, PAG_DEFAULT_AUTOEXIT);
+
+ PAG_LOG("coremask=%"PRIx64", rxstream=%u, txstream=%u, autoexit=%d",
+ instance->coremask, instance->nr_rx_stream, instance->nr_tx_stream,
+ instance->autoexit);
+
+ return 0;
+}
+
+static int pag_config_load_burst_info(struct pag_instance * instance)
{
MESA_load_profile_uint_def(PAG_CFGFILE, "pag", "burst_rx", &instance->burst_rx,
PAG_DEFAULT_RX_BURST);
@@ -109,7 +175,9 @@ static int __open_all_device(struct pag_instance * instance)
for (int i = 0; i < nr_devices; i++)
{
- raw_socket_t * socket = marsio_raw_socket(str_devices[i]);
+ raw_socket_t * socket = marsio_raw_socket(str_devices[i],
+ instance->nr_rx_stream, instance->nr_tx_stream, 0);
+
if (socket == NULL)
{
PAG_LOG("cannot open device %s.\n", str_devices[i]);
@@ -131,35 +199,51 @@ static int pag_thread_init(struct pag_instance * instance,
if (likely(tinstance->thread_inited != 0))
return 0;
- mrlib_thread_init();
+ marsio_thread_init();
tinstance->rxmbuf_max = instance->burst_rx;
tinstance->txmbuf_max = instance->burst_tx;
tinstance->thread_inited = 1;
return 0;
}
-int pag_open()
+static int pag_config(struct pag_instance * instance)
{
- if (__pag_inited != 0) return 0;
-
- struct pag_instance * instance = &pag_config_;
-
if (access(PAG_CFGFILE, R_OK) != 0)
{
PAG_LOG("load pag.conf failed, pag.conf doesnot existed.");
return -1;
}
+
+ int ret = pag_config_load_app_info(instance);
+ if (ret < 0) return ret;
+ ret = pag_config_load_burst_info(instance);
+ if (ret < 0) return ret;
+ ret = pag_config_load_stream_info(instance);
+ if (ret < 0) return ret;
+ return 0;
+}
- int ret = MESA_load_profile_string_nodef(PAG_CFGFILE, "pag", "app_name",
- instance->app_name, sizeof(instance->app_name));
+static void __on_exit_pag_close(void * arg)
+{
+ pag_close();
+}
+int pag_open()
+{
+ if (__pag_inited != 0) return 0;
+
+ struct pag_instance * instance = &pag_config_;
+
+ int ret = pag_config(instance);
if(ret < 0)
{
- PAG_LOG("load pag.conf failed(section=pag, key=app_name).");
- return -2;
+ PAG_LOG("load configure failed.");
+ return -1;
}
- ret = mrlib_init(instance->app_name, stderr);
+ ret = marsio_init(instance->app_name, instance->coremask,
+ instance->autoexit, stderr);
+
if(ret < 0)
{
PAG_LOG("marsio library init failed(ret=%d).", ret);
@@ -173,12 +257,8 @@ int pag_open()
return -4;
}
- ret = __read_burst_info(instance);
- if(ret < 0)
- {
- PAG_LOG("burst info load failed(ret=%d)", ret);
- return -5;
- }
+ if (instance->autoexit)
+ mr_on_exit_register(__on_exit_pag_close, NULL);
__pag_inited = 1;
return 0;
@@ -219,8 +299,6 @@ static int inline __get_frames_from_rtdevice(struct pag_instance * instance,
return ret;
}
-static int __debug_count = 0;
-
void * pag_get_frame(int sid __rte_unused)
{
struct pag_thread_instance * tinstance = &thread_instance_;
@@ -277,6 +355,9 @@ void * pag_get(int sid __rte_unused)
int pag_close()
{
+ struct pag_instance * instance = &pag_config_;
+ for (int i = 0; i < instance->nr_raw_sockets; i++)
+ marsio_raw_close(instance->raw_sockets[i]);
return 0;
}
diff --git a/pag/libpag.h b/pag/libpag.h
index 5fbdb66..d349b27 100644
--- a/pag/libpag.h
+++ b/pag/libpag.h
@@ -24,6 +24,20 @@ int pag_send_eth(int sid, int eth_datalen, int port);
void pag_freesendbuf_eth(int sid, int port);
uint64_t pag_time(void *pkt);
+#if 0
+/* Compatible with DF dual stack system, running on line */
+typedef void packet_t;
+packet_t * pag_get_packet(int sid);
+void * pag_get_frame_with_packet(packet_t * packet);
+
+#define pag_get_frame(x) \
+ __builtin_choose_expr( \
+ __builtin_types_compatible_p(typeof(x), int), pag_get_frame(x) \
+ __builtin_choose_expr(__builtin_types_compatible_p(typeof(x), packet_t *), \
+ pag_get_frame_with_packet(x))) \
+
+#endif
+
/* Extended Interface */
void * pag_get_frame_with_len(int sid, unsigned int * len);
diff --git a/runtime/CMakeLists.txt b/runtime/CMakeLists.txt
new file mode 100644
index 0000000..e2ad0c6
--- /dev/null
+++ b/runtime/CMakeLists.txt
@@ -0,0 +1,11 @@
+find_package(DPDK REQUIRED)
+include_directories(${CMAKE_SOURCE_DIR}/include)
+include_directories(${CMAKE_SOURCE_DIR}/include/extern)
+include_directories(${CMAKE_SOURCE_DIR}/include/internal)
+include_directories(${DPDK_INCLUDE_DIR})
+
+add_definitions(${DPDK_C_PREDEFINED})
+include_directories(include)
+add_library(mruntime src/app.c src/ctx.c src/runtime.c src/hwinfo.c src/id.c src/export.c)
+target_link_libraries(mruntime PRIVATE rt pthread dl)
+target_include_directories(mruntime INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/include/") \ No newline at end of file
diff --git a/runtime/include/mr_runtime.h b/runtime/include/mr_runtime.h
new file mode 100644
index 0000000..098d0a0
--- /dev/null
+++ b/runtime/include/mr_runtime.h
@@ -0,0 +1,63 @@
+#pragma once
+
+#include <mr_common.h>
+#include <sys/queue.h>
+
+struct appinfo;
+
+struct mr_global_ctx
+{
+ void * ctx_runtime;
+ void * ctx_core;
+ void * ctx_stack;
+};
+
+struct mr_global_config
+{
+ char glob_cfg_file[MR_STRING_MAX];
+};
+
+int mr_hwinfo_nr_sockets();
+int mr_hwinfo_nr_cpus();
+int mr_hwinfo_physical_cpu_id(int cpu_id);
+int mr_hwinfo_socket_id(int cpu_id);
+
+int mr_app_manager_appinfo_create(const char * sym, cpu_mask_t cpu_mask);
+int mr_app_manager_appinfo_register(const char * sym, cpu_mask_t cpu_mask);
+int mr_app_manager_appinfo_unregister();
+int mr_app_manager_thread_register();
+int mr_app_manager_thread_unregister();
+int mr_app_manager_appinfo_iterate(struct appinfo ** appinfo);
+
+int mr_id_manager_apply_app_id(app_id_t * result);
+int mr_id_manager_release_app_id(app_id_t app_id);
+int mr_id_manager_apply_gsid(int nr_thread, thread_id_t * result);
+int mr_id_manager_release_gsid(thread_id_t start_gsid, int nr_thread);
+
+void mr_runtime_init();
+void mr_runtime_slave_init();
+struct mr_global_ctx * mr_global_ctx_get();
+struct mr_global_config * mr_global_config_get();
+
+int mr_app_register(const char * appsym, cpu_mask_t cpumask,
+ unsigned int autoexit);
+int mr_thread_register();
+void mr_thread_on_exit_register(void(*exit_fn)(void * arg), void * arg);
+void mr_on_exit_register(void(*exit_fn)(void * arg), void * arg);
+void mr_thread_hook();
+
+thread_id_t mr_thread_id();
+socket_id_t mr_socket_id();
+cpu_id_t mr_cpu_id();
+app_id_t mr_app_id();
+
+struct appinfo * mr_app_info_get();
+struct thread_info * mr_thread_info_get();
+app_id_t mr_appinfo_get_app_id(struct appinfo * appinfo);
+const char * mr_appinfo_get_symbol(struct appinfo * appinfo);
+unsigned int mr_appinfo_get_nr_max_thread(struct appinfo * appinfo);
+
+void * mr_app_priv_get();
+void mr_app_priv_set(void * ptr);
+void * mr_thread_priv_get();
+void mr_thread_priv_set(void * ptr); \ No newline at end of file
diff --git a/runtime/include/runtime.h b/runtime/include/runtime.h
new file mode 100644
index 0000000..744f9d0
--- /dev/null
+++ b/runtime/include/runtime.h
@@ -0,0 +1,54 @@
+#pragma once
+
+#include <mr_common.h>
+
+struct app_manager;
+struct hwinfo_manager;
+struct id_manager;
+
+#ifndef MR_RUNTIME_MAX_NR_EXIT_HANDLER
+#define MR_RUNTIME_MAX_NR_EXIT_HANDLER 64
+#endif
+
+struct mr_runtime_ctx
+{
+ // ģ�鴦�����
+ struct app_manager * app_ctx;
+ struct hwinfo_manager * hwinfo_ctx;
+ struct id_manager * id_ctx;
+};
+
+extern struct app_manager * app_manager_create();
+extern int app_manager_destory(struct app_manager * object);
+
+// Ӳ��������Ϣ��������
+extern int hwinfo_manager_destory(struct hwinfo_manager * object);
+extern struct hwinfo_manager * hwinfo_manager_create();
+extern int hwinfo_nr_sockets(struct hwinfo_manager * object);
+extern int hwinfo_nr_cpus(struct hwinfo_manager * object);
+extern int hwinfo_physical_cpu_id(struct hwinfo_manager * object, int cpu_id);
+extern int hwinfo_socket_id(struct hwinfo_manager * object, int cpu_id);
+
+// Ӧ�ù�����Ϣ��������
+extern int app_manager_appinfo_create(struct app_manager * object,
+ const char * sym, cpu_mask_t cpu_mask);
+extern int app_manager_appinfo_register(struct app_manager * object,
+ const char * sym, cpu_mask_t cpu_mask);
+extern int app_manager_appinfo_unregister(struct app_manager * object);
+extern int app_manager_thread_register(struct app_manager * object);
+extern int app_manager_thread_unregister(struct app_manager * object);
+extern int app_manager_appinfo_iterate(struct app_manager * object, struct appinfo ** appinfo);
+
+// ���������������
+extern struct id_manager * id_manager_create();
+extern int id_manager_destory(struct id_manager * object);
+extern int id_manager_apply_app_id(struct id_manager* object, app_id_t* result);
+extern int id_manager_release_app_id(struct id_manager * object, app_id_t app_id);
+extern int id_manager_apply_gsid(struct id_manager* object, int nr_thread, thread_id_t* result);
+extern int id_manager_release_gsid(struct id_manager * object, thread_id_t start_gsid,
+ int nr_thread);
+
+extern int mr_global_ctx_init();
+extern int mr_global_ctx_slave_init();
+extern int mr_global_cfg_init();
+extern int mr_global_cfg_slave_init(); \ No newline at end of file
diff --git a/runtime/src/app.c b/runtime/src/app.c
new file mode 100644
index 0000000..9533066
--- /dev/null
+++ b/runtime/src/app.c
@@ -0,0 +1,608 @@
+/* Application, Process and Dataplane Manager
+ *
+ * This manager is used to manage application, process and thread.
+ * It gives one unique id for each application, process and dataplane thread.
+ *
+ * Author : Lu Qiuwen<[email protected]>
+ * Date : 2016-08-19
+ */
+
+#include <sys/queue.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <mr_common.h>
+#include <mr_mask.h>
+#include <mr_runtime.h>
+
+#include <rte_malloc.h>
+#include <rte_rwlock.h>
+#include <rte_lcore.h>
+#include <rte_per_lcore.h>
+#include <assert.h>
+#include <string.h>
+#include <unistd.h>
+#include <pthread.h>
+
+struct appinfo
+{
+ /* 下一个 */
+ TAILQ_ENTRY(appinfo) next;
+ /* 应用标识符 */
+ char symbol[MR_SYMBOL_MAX];
+ /* 应用序号 */
+ app_id_t app_id;
+ /* 全局线程序号,起始序号,左闭右开 */
+ thread_id_t gsid_start;
+ /* 全局线程序号,终止序号,左闭右开 */
+ thread_id_t gsid_end;
+ /* 进程状态 */
+ volatile unsigned int state;
+ /* 运行的线程信息 */
+ struct thread_info * thread_info;
+ /* CPU绑定掩码 */
+ cpu_mask_t cpu_mask;
+ /* 进程最大数据面线程数量 */
+ unsigned int nr_max_thread;
+ /* 目前分配的线程序号 */
+ unsigned int cur_sid;
+ /* 目前分配的全局线程序号 */
+ unsigned int cur_gsid;
+ /* 应用私有句柄 */
+ void * priv;
+};
+
+struct thread_info
+{
+ /* 线程顺序号 */
+ thread_id_t sid;
+ /* 全局线程顺序号 */
+ thread_id_t gsid;
+ /* 进程号 */
+ thread_id_t proc_id;
+ /* 物理CPU序号 */
+ cpu_id_t cpu_id;
+ /* 物理NUMA节点序号 */
+ socket_id_t socket_id;
+ /* 进程私有上下文 */
+ void * priv;
+ /* 标志位,当前线程是否运行 */
+ unsigned int in_use;
+};
+
+/* 当前运行应用的描述符 */
+static struct appinfo * currect_app_info = NULL;
+/* 当前线程描述符 */
+static __thread struct thread_info * currect_thread_info = NULL;
+
+TAILQ_HEAD(appinfo_list, appinfo);
+
+struct app_manager
+{
+ /* 读写锁,控制并发访问 */
+ mr_spinlock_t lock;
+ /* 进程列表 */
+ struct appinfo_list appinfo_list;
+ /* 在册进程数量 */
+ unsigned int nr_app;
+};
+
+struct app_manager * app_manager_create()
+{
+ struct app_manager * object = rte_zmalloc(NULL, sizeof(struct app_manager), 0);
+ MR_CHECK(object != NULL, "AppObjectCreate, Cannot alloc memory for app manager");
+
+ object->nr_app = 0;
+ mr_spin_init(&object->lock);
+ TAILQ_INIT(&object->appinfo_list);
+ return object;
+}
+
+//TODO: 应用管理器销毁
+int app_manager_destory(struct app_manager * object)
+{
+ return 0;
+}
+
+/* 应用运行 */
+static int __rte_unused __app_run_unsafe(struct app_manager * object, struct appinfo * pinfo)
+{
+ return 0;
+}
+
+/* 应用挂起,保留上下文 */
+static int __rte_unused __app_suspend_unsafe(struct app_manager * object, struct appinfo * pinfo)
+{
+ return 0;
+}
+
+/* 应用退出,销毁上下文 */
+static int __rte_unused __app_exit_unsafe(struct app_manager * object, struct appinfo * pinfo)
+{
+ return 0;
+}
+
+static struct appinfo * __appinfo_lookup_unsafe(const struct app_manager * object,
+ const char * sym)
+{
+ struct appinfo * pinfo_iter = NULL;
+ struct appinfo * pinfo_ret = NULL;
+
+ TAILQ_FOREACH(pinfo_iter, &object->appinfo_list, next)
+ {
+ if(strncmp(pinfo_iter->symbol, sym, sizeof(pinfo_iter->symbol)) == 0)
+ {
+ pinfo_ret = pinfo_iter;
+ break;
+ }
+ }
+
+ return pinfo_ret;
+}
+
+/* 删除一个进程 */
+static int __appinfo_delete_unsafe(struct app_manager * object,
+ struct appinfo * pinfo)
+{
+ // 检查进程所属的线程是否全部退出。线程全部退出后才允许销毁这个进程
+ for(int i = 0; i < pinfo->nr_max_thread; i++)
+ {
+ if (pinfo->thread_info[i].in_use == 0) continue;
+ // 检查失败,有一个或多个线程仍然在使用
+ MR_LOG(INFO, BASE, "AppInfo, AppInfoDelete, "
+ "Thread %d in use, cannot delete app %s. \n",
+ pinfo->thread_info[i].sid, pinfo->symbol);
+ return -1;
+ }
+
+ // 回收应用序号和全局线程号
+ mr_id_manager_release_app_id(pinfo->app_id);
+ mr_id_manager_release_gsid(pinfo->gsid_start, pinfo->nr_max_thread);
+
+ // 移除AppInfo,释放资源
+ TAILQ_REMOVE(&object->appinfo_list, pinfo, next);
+ object->nr_app--;
+ rte_free(pinfo->thread_info);
+ rte_free(pinfo);
+
+ // 当前的应用信息置空
+ currect_app_info = NULL;
+ return 0;
+}
+
+
+/* 创建一个新的进程 */
+static int __appinfo_new_unsafe(struct app_manager * object, const char * sym,
+ cpu_mask_t cpu_mask, unsigned int nr_max_thread)
+{
+ struct appinfo * pinfo;
+ int ret = 0;
+
+ // 检查进程是否已经存在
+ pinfo = __appinfo_lookup_unsafe(object, sym);
+ if (pinfo != NULL)
+ {
+ MR_LOG(INFO, BASE, "AppInfo, AppInfoNew, "
+ "Application %s is already exists, failed. \n", sym);
+ ret = -1; goto out;
+ }
+
+ // 进程不存在,创建新的描述符
+ pinfo = (struct appinfo *)rte_zmalloc(NULL, sizeof(struct appinfo), 0);
+ if (unlikely(pinfo == NULL))
+ {
+ MR_LOG(INFO, BASE, "AppInfo, AppInfoNew, "
+ "Cannot alloc appinfo mem for app %s info.\n", sym);
+ ret = -2; goto errout;
+ }
+
+ // 填充进程信息
+ snprintf(pinfo->symbol, sizeof(pinfo->symbol), "%s", sym);
+
+ // 申请应用序号
+ app_id_t app_id;
+ ret = mr_id_manager_apply_app_id(&app_id);
+ if(unlikely(ret < 0))
+ {
+ MR_LOG(INFO, BASE, "AppInfo, AppInfoNew, "
+ "Cannot apply app_id for app %s. \n", sym);
+ ret = -3; goto errout;
+ }
+
+ // 申请全局线程号
+ thread_id_t gsid_start;
+ ret = mr_id_manager_apply_gsid(nr_max_thread, &gsid_start);
+ if(unlikely(ret < 0))
+ {
+ MR_LOG(INFO, BASE, "AppInfo, AppInfoNew, "
+ "Cannot apply gsid for app %s. \n", sym);
+ ret = -4; goto errout;
+ }
+
+ // 计算全局线程号终止序号,全局线程号在单个应用内是连续的
+ thread_id_t gsid_end = gsid_start + nr_max_thread;
+
+ pinfo->app_id = app_id;
+ pinfo->gsid_start = gsid_start;
+ pinfo->gsid_end = gsid_end;
+ pinfo->cpu_mask = cpu_mask;
+ pinfo->nr_max_thread = nr_max_thread;
+
+ // 插入到应用链表
+ TAILQ_INSERT_TAIL(&object->appinfo_list, pinfo, next);
+
+ // 初始化线程
+ pinfo->thread_info = (struct thread_info *)rte_zmalloc(NULL,
+ sizeof(struct thread_info)*nr_max_thread, 0);
+
+ if (pinfo->thread_info == NULL)
+ {
+ MR_LOG(INFO, BASE, "AppInfo, AppInfoNew, "
+ "Cannot alloc memory for thread_info sturcture, failed\n");
+ ret = -5; goto errout;
+ }
+
+ pinfo->cur_sid = 0;
+ pinfo->cur_gsid = pinfo->gsid_start;
+ ret = 0; goto out;
+
+errout:
+ if (pinfo != NULL) rte_free(pinfo);
+ goto out;
+
+out:
+ return ret;
+}
+
+struct thread_info * __thread_new_unsafe(struct appinfo * pinfo)
+{
+ struct thread_info * tinfo;
+ tinfo = &pinfo->thread_info[pinfo->cur_sid];
+
+ // 分配线程序号,全局序号和上下文空间
+ tinfo->proc_id = pinfo->app_id;
+ tinfo->sid = pinfo->cur_sid;
+ tinfo->gsid = pinfo->cur_gsid;
+ tinfo->priv = NULL;
+
+ // 增加线程计数
+ pinfo->cur_sid++;
+ pinfo->cur_gsid++;
+ return tinfo;
+}
+
+//TODO: 线程Recover机制:线程正常(或异常)退出之后,如何恢复上下文空间。
+struct thread_info * __thread_lookup_unsafe(struct appinfo * pinfo, thread_id_t sid)
+{
+ if (sid < pinfo->cur_sid)
+ return &pinfo->thread_info[sid];
+ return NULL;
+}
+
+int __set_affinity(cpu_mask_t mask)
+{
+ pthread_t ppid = pthread_self();
+ int ret = pthread_setaffinity_np(ppid, sizeof(cpu_mask_t), (cpu_set_t *)&mask);
+ return ret;
+}
+
+int __thread_set_affinity(struct appinfo * pinfo,
+ struct thread_info * tinfo)
+{
+ cpu_id_t cpu_id = mask_location(pinfo->cpu_mask, tinfo->sid);
+
+ if (unlikely(cpu_id >= mr_hwinfo_nr_cpus()))
+ {
+ MR_LOG(INFO, BASE, "Procman, ThreadSetAffinity, "
+ "Thread %d in Process %s, Invalided CPU_ID %d "
+ "(Exceed Physical CPU Count %d)\n",
+ tinfo->sid, pinfo->symbol, cpu_id, mr_hwinfo_nr_cpus());
+ return -1;
+ }
+
+ if(unlikely(cpu_id < 0))
+ {
+ MR_LOG(INFO, BASE, "AppInfo, ThreadSetAffinity, "
+ "Thread %d in Process %s, Invailided CPU_ID %d"
+ "(Invailed CPU Mask or SID)\n", tinfo->sid,
+ pinfo->symbol, cpu_id);
+ return -2;
+ }
+
+ socket_id_t socket_id = mr_hwinfo_socket_id(cpu_id);
+ assert(socket_id >= 0 && socket_id < mr_hwinfo_nr_sockets());
+
+ cpu_mask_t thread_cpu_mask = 1 << cpu_id;
+ if(__set_affinity(thread_cpu_mask) < 0)
+ {
+ MR_LOG(INFO, BASE, "AppInfo, ThreadSetAffinity, "
+ "Thread %d in Process %s, Call Pthread Error : %s\n",
+ tinfo->cpu_id, pinfo->symbol, strerror(errno));
+ return -3;
+ }
+
+ tinfo->cpu_id = cpu_id;
+ tinfo->socket_id = socket_id;
+ return 0;
+}
+
+int __thread_register_unsafe(struct appinfo * pinfo, thread_id_t suppose_sid)
+{
+ struct thread_info * tinfo;
+
+ // 查找当前的SID是否已经注册过
+ tinfo = __thread_lookup_unsafe(pinfo, suppose_sid);
+
+ // 没有注册过,注册一个新的线程
+ if (tinfo != NULL)
+ {
+ MR_LOG(INFO, BASE, "AppInfo, ThreadRegister"
+ "Thread %d in Process %s existed, recover it.\n",
+ suppose_sid, pinfo->symbol);
+ }
+ else
+ {
+ MR_LOG(INFO, BASE, "AppInfo, ThreadRegister, "
+ "Thread %d in Process %s, create new thread.\n",
+ suppose_sid, pinfo->symbol);
+ tinfo = __thread_new_unsafe(pinfo);
+ }
+
+ // 检测tinfo是否为空,此时为空就是异常情况了
+ if(unlikely(tinfo == NULL))
+ {
+ MR_LOG(WARNING, BASE, "AppInfo, ThreadRegister, "
+ "Thread %d in Process %s Info Structure is NULL, failed.\n",
+ suppose_sid, pinfo->symbol);
+ return -1;
+ }
+
+ // 注册上下文空间
+ RTE_PER_LCORE(_lcore_id) = tinfo->gsid;
+ currect_thread_info = tinfo;
+
+ if(__thread_set_affinity(pinfo, tinfo) < 0)
+ {
+ MR_LOG(WARNING, BASE, "AppInfo, ThreadRegister, "
+ "Thread %d in Process %s, SetThreadAffinity failed.\n",
+ tinfo->sid, pinfo->symbol);
+ return -2;
+ }
+
+ MR_LOG(DEBUG, BASE, "AppInfo, ThreadRegister, "
+ "ThreadID=%d, GThreadID=%d, App=%s, thread registered. \n",
+ tinfo->sid, tinfo->gsid, pinfo->symbol);
+
+ return 0;
+}
+
+int __thread_unregister_unsafe()
+{
+ assert(currect_thread_info != NULL);
+ currect_thread_info->in_use = 0;
+ return 0;
+}
+
+int app_manager_appinfo_create(struct app_manager * object,
+ const char * sym, cpu_mask_t cpu_mask)
+{
+ int nr_max_thread = mask_popcnt(cpu_mask);
+ if (unlikely(nr_max_thread < 0))
+ {
+ MR_LOG(WARNING, BASE, "AppInfo, AppInfoNew, "
+ "Process %s CPU Mask error(mask=%"PRIx64", nr_max_thread=%d)\n",
+ sym, cpu_mask, nr_max_thread);
+ return -1;
+ }
+
+ mr_spin_lock(&object->lock);
+ int ret = __appinfo_new_unsafe(object, sym, cpu_mask, nr_max_thread);
+ mr_spin_unlock(&object->lock);
+ return ret;
+}
+
+int app_manager_appinfo_register(struct app_manager * object,
+ const char * sym, cpu_mask_t cpu_mask)
+{
+ struct appinfo * pinfo;
+ int ret = 0;
+
+ mr_spin_lock(&object->lock);
+
+ // 查找应用是否以前注册过
+ pinfo = __appinfo_lookup_unsafe(object, sym);
+
+ // 应用已经存在,跳过创建过程进入后续流程
+ if (pinfo != NULL) goto after_create;
+
+ // 创建应用
+ int nr_max_thread = mask_popcnt(cpu_mask);
+ if(nr_max_thread == 0)
+ {
+ MR_LOG(WARNING, BASE, "AppInfo, AppInfoNew, "
+ "App %s CPU Mask error(mask=%"PRIx64", nr_max_thread=%d)\n",
+ sym, cpu_mask, nr_max_thread);
+ ret = -1; goto out;
+ }
+
+ ret = __appinfo_new_unsafe(object, sym, cpu_mask, nr_max_thread);
+ if (unlikely(ret < 0)) goto out;
+
+ // 成功创建,再次查找描述符
+ pinfo = __appinfo_lookup_unsafe(object, sym);
+ assert(pinfo != NULL);
+
+after_create:
+ __app_run_unsafe(object, pinfo);
+ currect_app_info = pinfo;
+
+out:
+ mr_spin_unlock(&object->lock);
+ return ret;
+}
+
+// 应用反注册流程
+int app_manager_appinfo_unregister(struct app_manager * object)
+{
+ struct appinfo * pinfo = currect_app_info;
+ if (pinfo == NULL) return -1;
+
+ int ret = 0;
+
+ // 反注册
+ mr_spin_lock(&object->lock);
+ ret = __appinfo_delete_unsafe(object, pinfo);
+ mr_spin_unlock(&object->lock);
+
+ // 反注册成功,当前APPInfo指针置空,防止再次引用。
+ if (ret >= 0) currect_app_info = NULL;
+ return ret;
+}
+
+int app_manager_thread_register(struct app_manager * object)
+{
+ struct appinfo * pinfo = currect_app_info;
+
+ // 进程重启后,原来的线程可能注册过。因此设置一个变量supposed_sid
+ // 在进程重启后清零。如果线程号以前注册过,就不再创建线程的描述符
+ // 直接恢复就可以了。因此,需要两个计数器,一个全局共享,表示多少
+ // 个线程已经创建描述符,另一个计数器用于进程恢复,表示当前进程的
+ // 线程计数。
+ // supposed_sid在临界区中访问,不存在线程安全问题。
+
+ static thread_id_t suppose_sid = 0;
+ int ret = 0;
+
+ mr_spin_lock(&object->lock);
+ ret = __thread_register_unsafe(pinfo, suppose_sid);
+ if (ret >= 0) suppose_sid++;
+ mr_spin_unlock(&object->lock);
+ return ret;
+}
+
+int app_manager_thread_unregister(struct app_manager * object)
+{
+ mr_spin_lock(&object->lock);
+ int ret = __thread_unregister_unsafe();
+ mr_spin_unlock(&object->lock);
+ return ret;
+}
+
+int app_manager_appinfo_iterate(struct app_manager * object, struct appinfo ** appinfo)
+{
+ // 迭代器为空,从头开始迭代,否则查找迭代器下一个对象
+ if (*appinfo == NULL)
+ {
+ *appinfo = TAILQ_FIRST(&object->appinfo_list);
+ return 0;
+ }
+ else
+ {
+ *appinfo = TAILQ_NEXT(*appinfo, next);
+ }
+
+ // 迭代到尾部,返回错误码
+ if (*appinfo == NULL) return -ENOENT;
+ return 0;
+}
+
+int app_manager_list_all_appinfo(struct app_manager * object,
+ struct appinfo * infos[], int nr_max_infos)
+{
+ struct appinfo * pinfo_iter;
+ int ret = 0;
+
+ mr_spin_lock(&object->lock);
+ TAILQ_FOREACH(pinfo_iter, &object->appinfo_list, next)
+ {
+ if (ret > nr_max_infos) break;
+ infos[ret++] = pinfo_iter;
+ }
+
+ mr_spin_unlock(&object->lock);
+ return ret;
+}
+
+int app_manager_tinfo_iterate(struct appinfo * appinfo,
+ struct thread_info ** tinfo, int * iterate)
+{
+ if (*iterate >= appinfo->nr_max_thread) return -ENOENT;
+ *tinfo = &appinfo->thread_info[*iterate];
+ return *iterate++;
+}
+
+
+// 外部接口,获取当前应用、线程的信息
+thread_id_t mr_thread_id()
+{
+ assert(currect_thread_info != NULL);
+ return currect_thread_info->sid;
+}
+
+socket_id_t mr_socket_id()
+{
+ assert(currect_thread_info != NULL);
+ return currect_thread_info->socket_id;
+}
+
+cpu_id_t mr_cpu_id()
+{
+ assert(currect_thread_info != NULL);
+ return currect_thread_info->cpu_id;
+}
+
+app_id_t mr_app_id()
+{
+ assert(currect_app_info != NULL);
+ return currect_app_info->app_id;
+}
+
+app_id_t mr_appinfo_get_app_id(struct appinfo * appinfo)
+{
+ return appinfo->app_id;
+}
+
+const char * mr_appinfo_get_symbol(struct appinfo * appinfo)
+{
+ return appinfo->symbol;
+}
+
+unsigned int mr_appinfo_get_nr_max_thread(struct appinfo * appinfo)
+{
+ return appinfo->nr_max_thread;
+}
+
+struct appinfo * mr_app_info_get()
+{
+ return currect_app_info;
+}
+
+struct thread_info * mr_thread_info_get()
+{
+ return currect_thread_info;
+}
+
+// 外部接口,读取(或写入)应用级、线程级私有句柄指针
+void * mr_app_priv_get()
+{
+ assert(currect_app_info != NULL);
+ return currect_app_info->priv;
+}
+
+void mr_app_priv_set(void * ptr)
+{
+ assert(currect_app_info != NULL);
+ currect_app_info->priv = ptr;
+}
+
+void * mr_thread_priv_get()
+{
+ assert(currect_thread_info != NULL);
+ return currect_thread_info->priv;
+}
+
+void mr_thread_priv_set(void * ptr)
+{
+ assert(currect_thread_info != NULL);
+ currect_thread_info->priv = ptr;
+} \ No newline at end of file
diff --git a/core/src/ctx.c b/runtime/src/ctx.c
index 784c608..e82a142 100644
--- a/core/src/ctx.c
+++ b/runtime/src/ctx.c
@@ -16,17 +16,15 @@
#include <rte_ip_frag.h>
#include <rte_eal.h>
#include <rte_version.h>
-
-#include "mr_ctx.h"
+#include <mr_common.h>
+#include <mr_runtime.h>
static struct mr_global_ctx * __global_ctx;
-static struct mr_config * __global_cfg;
-static struct mr_proc_ctx * __proc_ctx;
-static __thread struct mr_thread_ctx * __thread_ctx;
+static struct mr_global_config * __global_cfg;
#define __SHM_FILEMODE 00777
-#define __SHM_SYM_GLOBAL_CTX "MR_CORE_GLOBAL_CTX_SHM"
-#define __SHM_SYM_GLOBAL_CFG "MR_CORE_GLOBAL_CFG_SHM"
+#define __SHM_SYM_GLOBAL_CTX "MR_RUNTIME_GLOBAL_CTX_SHM"
+#define __SHM_SYM_GLOBAL_CFG "MR_RUNTIME_GLOBAL_CFG_SHM"
static void * shared_memory_create(const char * sym, size_t size)
{
@@ -101,8 +99,8 @@ int mr_global_ctx_slave_init()
int mr_global_cfg_init()
{
- __global_cfg = (struct mr_config *)shared_memory_create(
- __SHM_SYM_GLOBAL_CFG, sizeof(struct mr_config));
+ __global_cfg = (struct mr_global_config *)shared_memory_create(
+ __SHM_SYM_GLOBAL_CFG, sizeof(struct mr_global_config));
MR_CHECK(__global_cfg != NULL, "CoreCtxMan, GlobalConfigInit, "
"Cannot create shared memory for global config");
@@ -112,8 +110,8 @@ int mr_global_cfg_init()
int mr_global_cfg_slave_init()
{
- __global_cfg = (struct mr_config *)shared_memory_lookup(
- __SHM_SYM_GLOBAL_CFG, sizeof(struct mr_config));
+ __global_cfg = (struct mr_global_config *)shared_memory_lookup(
+ __SHM_SYM_GLOBAL_CFG, sizeof(struct mr_global_config));
MR_CHECK(__global_cfg != NULL, "CoreCtxMan, GlobalConfigLookup, "
"Cannot lookup shared memory for global config");
@@ -126,33 +124,8 @@ struct mr_global_ctx * mr_global_ctx_get()
return __global_ctx;
}
-struct mr_config * mr_global_config_get()
+struct mr_global_config * mr_global_config_get()
{
assert(__global_cfg != NULL);
return __global_cfg;
-}
-
-struct mr_proc_ctx * mr_proc_ctx_get()
-{
- assert(__proc_ctx != NULL);
- return __proc_ctx;
-}
-
-void mr_proc_ctx_set(void * ctx)
-{
- assert(ctx != NULL);
- __proc_ctx = ctx;
- return;
-}
-
-void mr_thread_ctx_set(void * ctx)
-{
- __thread_ctx = ctx;
- return;
-}
-
-struct mr_thread_ctx* mr_thread_ctx_get()
-{
- assert(__thread_ctx != NULL);
- return __thread_ctx;
} \ No newline at end of file
diff --git a/runtime/src/export.c b/runtime/src/export.c
new file mode 100644
index 0000000..6a145c3
--- /dev/null
+++ b/runtime/src/export.c
@@ -0,0 +1,105 @@
+
+#include <mr_runtime.h>
+#include <runtime.h>
+
+// Ӳ��������Ϣ�����������û����ⲿ���á����ú��ҵ���Ӧ��object����Ȼ���ٵ����ڲ�������
+int mr_hwinfo_nr_sockets()
+{
+ struct mr_global_ctx * g_ctx = mr_global_ctx_get();
+ struct mr_runtime_ctx * rt_ctx = (struct mr_runtime_ctx *)g_ctx->ctx_runtime;
+ return hwinfo_nr_sockets(rt_ctx->hwinfo_ctx);
+}
+
+int mr_hwinfo_nr_cpus()
+{
+ struct mr_global_ctx * g_ctx = mr_global_ctx_get();
+ struct mr_runtime_ctx * rt_ctx = (struct mr_runtime_ctx *)g_ctx->ctx_runtime;
+ return hwinfo_nr_cpus(rt_ctx->hwinfo_ctx);
+}
+
+int mr_hwinfo_physical_cpu_id(int cpu_id)
+{
+ struct mr_global_ctx * g_ctx = mr_global_ctx_get();
+ struct mr_runtime_ctx * rt_ctx = (struct mr_runtime_ctx *)g_ctx->ctx_runtime;
+ return hwinfo_physical_cpu_id(rt_ctx->hwinfo_ctx, cpu_id);
+}
+
+int mr_hwinfo_socket_id(int cpu_id)
+{
+ struct mr_global_ctx * g_ctx = mr_global_ctx_get();
+ struct mr_runtime_ctx * rt_ctx = (struct mr_runtime_ctx *)g_ctx->ctx_runtime;
+ return hwinfo_socket_id(rt_ctx->hwinfo_ctx, cpu_id);
+}
+
+// Ӧ�ù�������������ͬӲ��������Ϣ������
+int mr_app_manager_appinfo_create(const char * sym, cpu_mask_t cpu_mask)
+{
+ struct mr_global_ctx * g_ctx = mr_global_ctx_get();
+ struct mr_runtime_ctx * rt_ctx = (struct mr_runtime_ctx *)g_ctx->ctx_runtime;
+ return app_manager_appinfo_create(rt_ctx->app_ctx, sym, cpu_mask);
+}
+
+int mr_app_manager_appinfo_register(const char * sym, cpu_mask_t cpu_mask)
+{
+ struct mr_global_ctx * g_ctx = mr_global_ctx_get();
+ struct mr_runtime_ctx * rt_ctx = (struct mr_runtime_ctx *)g_ctx->ctx_runtime;
+ return app_manager_appinfo_register(rt_ctx->app_ctx, sym, cpu_mask);
+}
+
+int mr_app_manager_appinfo_unregister()
+{
+ struct mr_global_ctx * g_ctx = mr_global_ctx_get();
+ struct mr_runtime_ctx * rt_ctx = (struct mr_runtime_ctx *)g_ctx->ctx_runtime;
+ return app_manager_appinfo_unregister(rt_ctx->app_ctx);
+}
+
+int mr_app_manager_thread_register()
+{
+ struct mr_global_ctx * g_ctx = mr_global_ctx_get();
+ struct mr_runtime_ctx * rt_ctx = (struct mr_runtime_ctx *)g_ctx->ctx_runtime;
+ return app_manager_thread_register(rt_ctx->app_ctx);
+}
+
+int mr_app_manager_thread_unregister()
+{
+ struct mr_global_ctx * g_ctx = mr_global_ctx_get();
+ struct mr_runtime_ctx * rt_ctx = (struct mr_runtime_ctx *)g_ctx->ctx_runtime;
+ return app_manager_thread_unregister(rt_ctx->app_ctx);
+}
+
+int mr_app_manager_appinfo_iterate(struct appinfo ** appinfo)
+{
+ struct mr_global_ctx * g_ctx = mr_global_ctx_get();
+ struct mr_runtime_ctx * rt_ctx = (struct mr_runtime_ctx *)g_ctx->ctx_runtime;
+ return app_manager_appinfo_iterate(rt_ctx->app_ctx, appinfo);
+}
+
+// ���������������
+int mr_id_manager_apply_app_id(app_id_t * result)
+{
+ struct mr_global_ctx * g_ctx = mr_global_ctx_get();
+ struct mr_runtime_ctx * rt_ctx = (struct mr_runtime_ctx *)g_ctx->ctx_runtime;
+ return id_manager_apply_app_id(rt_ctx->id_ctx, result);
+}
+
+int mr_id_manager_release_app_id(app_id_t app_id)
+{
+ struct mr_global_ctx * g_ctx = mr_global_ctx_get();
+ struct mr_runtime_ctx * rt_ctx = (struct mr_runtime_ctx *)g_ctx->ctx_runtime;
+ return id_manager_release_app_id(rt_ctx->id_ctx, app_id);
+}
+
+int mr_id_manager_apply_gsid(int nr_thread, thread_id_t * result)
+{
+ struct mr_global_ctx * g_ctx = mr_global_ctx_get();
+ struct mr_runtime_ctx * rt_ctx = (struct mr_runtime_ctx *)g_ctx->ctx_runtime;
+ return id_manager_apply_gsid(rt_ctx->id_ctx, nr_thread, result);
+}
+
+int mr_id_manager_release_gsid(thread_id_t start_gsid,
+ int nr_thread)
+{
+ struct mr_global_ctx * g_ctx = mr_global_ctx_get();
+ struct mr_runtime_ctx * rt_ctx = (struct mr_runtime_ctx *)g_ctx->ctx_runtime;
+ return id_manager_release_gsid(rt_ctx->id_ctx, start_gsid, nr_thread);
+}
diff --git a/core/src/hwinfo.c b/runtime/src/hwinfo.c
index f5c320a..a680323 100644
--- a/core/src/hwinfo.c
+++ b/runtime/src/hwinfo.c
@@ -12,7 +12,7 @@
#include <rte_log.h>
#include <rte_malloc.h>
#include <rte_config.h>
-#include <mr_ctx.h>
+#include <mr_common.h>
struct hwinfo_core
{
@@ -22,7 +22,7 @@ struct hwinfo_core
unsigned int socket_id;
};
-struct hwinfo_ctx
+struct hwinfo_manager
{
/* logical cpus, including hardware-thread cpus */
unsigned int nr_total_cpus;
@@ -36,8 +36,6 @@ struct hwinfo_ctx
#define __FILE_LINUX_PCPU_ID "/sys/devices/system/cpu/cpu%" PRIu32 "/topology/core_id"
#define __FILE_LINUX_SOCKET_ID "/sys/devices/system/cpu/cpu%" PRIu32 "/topology/physical_package_id"
-static struct hwinfo_ctx * hwinfo_global_ctx;
-
static int linux_get_nr_total_cpus(void)
{
char buffer[MR_STRING_MAX], *string;
@@ -108,7 +106,7 @@ static int linux_get_socket_id(int cpu_id)
return socket_id;
}
-static int hwinfo_cpu_scan(struct hwinfo_ctx * ctx)
+static int hwinfo_cpu_scan(struct hwinfo_manager * ctx)
{
int nr_cpus = linux_get_nr_total_cpus();
if (nr_cpus < 0)
@@ -164,66 +162,49 @@ static int hwinfo_cpu_scan(struct hwinfo_ctx * ctx)
return 0;
}
-int hwinfo_preinit(struct mr_module * m_desc,
- struct mr_config * g_cfg, struct mr_global_ctx * g_ctx)
-{
- MODULE_CTX(g_ctx, m_desc->mid) = rte_zmalloc("HWINFO_CTX", sizeof(struct hwinfo_ctx), 0);
- MR_CHECK(MODULE_CTX(g_ctx, MR_MID_HWINFO) != NULL, "HwInfo, Preconfig Init Error,"
- "Cannot alloc memory for module ctx");
- hwinfo_global_ctx = MODULE_CTX(g_ctx, m_desc->mid);
- int retval = hwinfo_cpu_scan(MODULE_CTX(g_ctx, m_desc->mid));
- if (retval < 0) return retval;
- return 0;
-}
-
-int hwinfo_config(struct mr_module * m_desc,
- struct mr_config * g_cfg, struct mr_global_ctx * g_ctx)
+int hwinfo_manager_destory(struct hwinfo_manager * object)
{
return 0;
}
-int hwinfo_init(struct mr_module * m_desc,
- struct mr_config * g_cfg, struct mr_global_ctx * g_ctx)
+struct hwinfo_manager * hwinfo_manager_create()
{
- return 0;
-}
+ struct hwinfo_manager * hwinfo_ctx;
-int hwinfo_slaveinit(struct mr_module * m_desc,
- struct mr_config * g_cfg, struct mr_global_ctx * g_ctx)
-{
- hwinfo_global_ctx = MODULE_CTX(g_ctx, m_desc->mid);
- return 0;
+ // 分配存储空间
+ hwinfo_ctx = rte_zmalloc(NULL, sizeof(struct hwinfo_manager), 0);
+ MR_CHECK(hwinfo_ctx != NULL, "HwInfoManagerCreate, "
+ "Cannot alloc memory for hwinfo manager. ");
+
+ // 检测处理器信息
+ int retval = hwinfo_cpu_scan(hwinfo_ctx);
+ if (retval < 0) goto errout;
+ return hwinfo_ctx;
+
+errout:
+ if (hwinfo_ctx != NULL) hwinfo_manager_destory(hwinfo_ctx);
+ return NULL;
}
-struct mr_module module_desc_hwinfo =
-{
- .mid = MR_MID_HWINFO,
- .preinit = hwinfo_preinit,
- .config = __default_module_handler,
- .init = __default_module_handler,
- .slaveinit = hwinfo_slaveinit
-};
-
-// Export Functions
-int mr_hwinfo_nr_sockets()
+int hwinfo_nr_sockets(struct hwinfo_manager * object)
{
- return hwinfo_global_ctx->nr_total_sockets;
+ return object->nr_total_sockets;
}
-int mr_hwinfo_nr_cpus()
+int hwinfo_nr_cpus(struct hwinfo_manager * object)
{
- return hwinfo_global_ctx->nr_total_cpus;
+ return object->nr_total_cpus;
}
-int mr_hwinfo_physical_cpu_id(int cpu_id)
+int hwinfo_physical_cpu_id(struct hwinfo_manager * object, int cpu_id)
{
- if (!hwinfo_global_ctx->coreinfo[cpu_id].enable) return -1;
- return hwinfo_global_ctx->coreinfo[cpu_id].physical_cpu_id;
+ if (!object->coreinfo[cpu_id].enable) return -1;
+ return object->coreinfo[cpu_id].physical_cpu_id;
}
-int mr_hwinfo_socket_id(int cpu_id)
+int hwinfo_socket_id(struct hwinfo_manager * object, int cpu_id)
{
- if (!hwinfo_global_ctx->coreinfo[cpu_id].enable) return -1;
- return hwinfo_global_ctx->coreinfo[cpu_id].socket_id;
+ if (!object->coreinfo[cpu_id].enable) return -1;
+ return object->coreinfo[cpu_id].socket_id;
} \ No newline at end of file
diff --git a/runtime/src/id.c b/runtime/src/id.c
new file mode 100644
index 0000000..380d774
--- /dev/null
+++ b/runtime/src/id.c
@@ -0,0 +1,117 @@
+/* \brief 序号管理器
+ * 负责管理应用号、线程号、全局线程号的分配与撤销
+ *
+ * \author Qiuwen Lu<[email protected]>
+ * \date 2016-10-11
+ */
+
+#include <stdint.h>
+#include <rte_ip_frag.h>
+#include "mr_common.h"
+#include <assert.h>
+
+/* 连续数组组成的位图类型 */
+struct bitmap
+{
+ size_t sz_bitmap;
+ uint8_t array[0];
+};
+
+// 在位图中找到最靠前的连续空间
+int bitmap_find_continous_space(struct bitmap * object, int space_len, int value)
+{
+ if (space_len > object->sz_bitmap) return -1;
+ for(int i = 0; i <= object->sz_bitmap - space_len; i++)
+ {
+ int is_useful_space = 1;
+ for(int j = 0; j < space_len; j++)
+ {
+ if (object->array[i + j] == value) continue;
+ is_useful_space = 0; break;
+ }
+
+ if (is_useful_space) return i;
+ }
+
+ return -1;
+}
+
+// 设置位图中连续空间的值
+int bitmap_set_continous_space(struct bitmap * object, int pos, int len, int value)
+{
+ if (pos >= object->sz_bitmap) return -1;
+ if (pos + len >= object->sz_bitmap) return -1;
+ for (int i = pos; i < pos + len; i++) object->array[i] = value;
+ return 0;
+}
+
+struct id_manager
+{
+ struct bitmap * bitmap_app_id;
+ struct bitmap * bitmap_gsid;
+};
+
+struct id_manager * id_manager_create()
+{
+ struct id_manager * object;
+ object = rte_zmalloc("IDManagerCtx", sizeof(struct id_manager), 0);
+ MR_CHECK(object != NULL, "Runtime, Cannot alloc memory for ID Manager. ");
+
+ // 计算位图空间大小
+ size_t total_sz_app_id = sizeof(struct bitmap) + sizeof(uint8_t) * MR_APP_MAX;
+ size_t total_sz_gsid = sizeof(struct bitmap) + sizeof(uint8_t) * MR_GSID_MAX;
+
+ // 分配位图对象空间
+ object->bitmap_app_id = rte_zmalloc(NULL, total_sz_app_id, 0);
+ MR_CHECK(object->bitmap_app_id != NULL, "Runtime, IDManagerCreate, "
+ "Cannot alloc memory for bitmap_app_id. ");
+
+ object->bitmap_gsid = rte_zmalloc(NULL, total_sz_gsid, 0);
+ MR_CHECK(object->bitmap_app_id != NULL, "Runtime, IDManagerCreate, "
+ "Cannot alloc memory for bitmap_gsid. ");
+
+ // 写位图大小
+ object->bitmap_app_id->sz_bitmap = MR_APP_MAX;
+ object->bitmap_gsid->sz_bitmap = MR_GSID_MAX;
+ return object;
+}
+
+int id_manager_destory(struct id_manager * object)
+{
+ rte_free(object->bitmap_app_id);
+ rte_free(object->bitmap_gsid);
+ rte_free(object);
+ return 0;
+}
+
+int id_manager_apply_app_id(struct id_manager* object, app_id_t* result)
+{
+ app_id_t id = bitmap_find_continous_space(object->bitmap_app_id, 1, 0);
+ if (id < 0) return -1;
+ bitmap_set_continous_space(object->bitmap_app_id, id, 1, 1);
+ *result = id;
+ return id;
+}
+
+int id_manager_release_app_id(struct id_manager * object, app_id_t app_id)
+{
+ bitmap_set_continous_space(object->bitmap_app_id, app_id, 1, 0);
+ return 0;
+}
+
+int id_manager_apply_gsid(struct id_manager* object, int nr_thread, thread_id_t* result)
+{
+ thread_id_t gsid_start;
+ gsid_start = bitmap_find_continous_space(object->bitmap_gsid, nr_thread, 0);
+ if (gsid_start < 0) return -1;
+ bitmap_set_continous_space(object->bitmap_gsid, gsid_start, nr_thread, 1);
+ *result = gsid_start;
+ return 0;
+}
+
+int id_manager_release_gsid(struct id_manager * object, thread_id_t start_gsid,
+ int nr_thread)
+{
+ bitmap_set_continous_space(object->bitmap_gsid, start_gsid, nr_thread, 0);
+ return 0;
+} \ No newline at end of file
diff --git a/runtime/src/runtime.c b/runtime/src/runtime.c
new file mode 100644
index 0000000..6707416
--- /dev/null
+++ b/runtime/src/runtime.c
@@ -0,0 +1,235 @@
+/* \brief MARSIO运行时环境管理器
+ *
+ * 运行时环境管理器提供重要的基础设施服务,包括:
+ * (1)全局共享内存映射及管理;
+ * (2)应用及应用数据面线程管理。
+ *
+ * \author Qiuwen Lu<[email protected]>
+ * \date 2016-10-19
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <mr_common.h>
+#include <mr_runtime.h>
+#include <rte_malloc.h>
+
+#include <runtime.h>
+#include <signal.h>
+#include <sys/select.h>
+#include <sys/signalfd.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+void mr_runtime_init()
+{
+ int ret = mr_global_ctx_init();
+ MR_CHECK(ret >= 0, "RuntimeInit, Initialize global ctx failed(ret = %d). ", ret);
+ ret = mr_global_cfg_init();
+ MR_CHECK(ret >= 0, "RuntimeInit, Initialize global config failed(ret = %d). ", ret);
+
+ struct mr_global_ctx * g_ctx = mr_global_ctx_get();
+ assert(g_ctx != NULL);
+
+ struct mr_runtime_ctx * rt_ctx;
+ rt_ctx = rte_zmalloc("RuntimeCtx", sizeof(struct mr_runtime_ctx), 0);
+ MR_CHECK(rt_ctx != NULL, "RuntimeInit, Cannot alloc memory for runtime ctx.");
+
+ rt_ctx->app_ctx = app_manager_create();
+ MR_CHECK(rt_ctx->app_ctx != NULL, "RuntimeInit, App manager initialize failed. ");
+
+ rt_ctx->hwinfo_ctx = hwinfo_manager_create();
+ MR_CHECK(rt_ctx->hwinfo_ctx != NULL, "RuntimeInit, HwInfo manager initialize failed. ");
+
+ rt_ctx->id_ctx = id_manager_create();
+ MR_CHECK(rt_ctx->id_ctx != NULL, "RuntimeInit, ID Manager initialize failed. ");
+
+ g_ctx->ctx_runtime = rt_ctx;
+ return;
+}
+
+void mr_runtime_slave_init()
+{
+ int ret = mr_global_ctx_slave_init();
+ MR_CHECK(ret >= 0, "RuntimeSlaveInit, Initialize global ctx failed(ret = %d). ", ret);
+
+ ret = mr_global_cfg_slave_init();
+ MR_CHECK(ret >= 0, "RuntimeSlaveInit, Initialize global config failed(ret = %d). ", ret);
+
+ struct mr_global_ctx * g_ctx = mr_global_ctx_get();
+ assert(g_ctx != NULL);
+
+ struct mr_runtime_ctx * rt_ctx = (struct mr_runtime_ctx *)g_ctx->ctx_runtime;
+ assert(g_ctx->ctx_runtime != NULL);
+ assert(rt_ctx->app_ctx != NULL);
+ assert(rt_ctx->hwinfo_ctx != NULL);
+ assert(rt_ctx->app_ctx != NULL);
+ return;
+}
+
+// 是否自动退出:处理信号和exit函数
+static int autoexit = 0;
+
+struct exit_handler
+{
+ void(* fn)(void * arg);
+ void * arg;
+};
+
+// 退出处理函数
+struct exit_handler exit_handlers[MR_RUNTIME_MAX_NR_EXIT_HANDLER];
+unsigned int nr_exit_handlers;
+
+// 当前运行线程信息
+pthread_t thread_ids[MR_SID_MAX];
+unsigned int nr_thread_ids;
+
+// 信号屏蔽信息
+sigset_t __autoexit_sigmask;
+
+
+/* 处理运行时异常退出的情况。该模块保证应用触发异常,收到退出信号时,
+ * 调用退出处理函数,释放资源,保证内存的一致性。*/
+static void __autoexit_raise(int status __rte_unused, void * arg __rte_unused)
+{
+ void * rtvalue;
+
+ // 通知其他线程退出
+ for (int i = 0; i < nr_thread_ids; i++)
+ {
+ if (pthread_kill(thread_ids[i], 0) < 0) continue;
+ pthread_cancel(thread_ids[i]);
+ }
+
+
+ // 等待其他线程退出
+ for (int i = 0; i < nr_thread_ids; i++)
+ {
+ if (pthread_kill(thread_ids[i], 0) < 0) continue;
+ pthread_join(thread_ids[i], &rtvalue);
+ }
+
+ // 运行注册的退出处理函数
+ for (int i = 0; i < nr_exit_handlers; i++)
+ exit_handlers[i].fn(arg);
+
+ // 应用信息注销
+ mr_app_manager_appinfo_unregister();
+ return;
+}
+
+static void __autoexit_thread_setup()
+{
+ // 记录线程ID
+ pthread_t pid = pthread_self();
+ thread_ids[nr_thread_ids++] = pid;
+
+ // 设置线程信号屏蔽,不处理SIGINT、SIGSEGV等信号
+ sigset_t oldset;
+ pthread_sigmask(SIG_BLOCK, &__autoexit_sigmask, &oldset);
+}
+
+// 信号处理线程
+void * __autoexit_thread(void * arg)
+{
+ pthread_t self_pid = pthread_self();
+ pthread_detach(self_pid);
+
+ int sfd;
+ ssize_t s;
+ struct signalfd_siginfo fdsi;
+
+ sfd = signalfd(-1, &__autoexit_sigmask, 0);
+ assert(sfd != 0);
+
+ while(1)
+ {
+ s = read(sfd, &fdsi, sizeof(struct signalfd_siginfo));
+ if(s != sizeof(struct signalfd_siginfo))
+ {
+ continue;
+ }
+
+ switch(fdsi.ssi_signo)
+ {
+ case SIGINT:
+ case SIGSEGV:
+ case SIGTERM:
+ default:
+ exit(EXIT_SUCCESS);
+ }
+ }
+}
+
+ static void __autoexit_signal_handler(int signo)
+{
+ switch (signo)
+ {
+ case SIGINT:
+ case SIGSEGV:
+ case SIGTERM:
+ default:
+ __autoexit_raise(1, NULL);
+ _Exit(EXIT_SUCCESS);
+ }
+}
+
+static void __autoexit_setup()
+{
+ sigemptyset(&__autoexit_sigmask);
+ sigaddset(&__autoexit_sigmask, SIGINT);
+ sigaddset(&__autoexit_sigmask, SIGTERM);
+ sigprocmask(SIG_BLOCK, &__autoexit_sigmask, NULL);
+
+#if MR_RUNTIME_SIGHANDLE_BY_SIGFD
+ pthread_t pid;
+ pthread_create(&pid, NULL, __autoexit_thread, NULL);
+#else
+ struct sigaction act, oact;
+ act.sa_handler = __autoexit_signal_handler;
+ act.sa_mask = __autoexit_sigmask;
+ act.sa_flags = 0;
+
+ int ret = sigaction(SIGINT, &act, &oact);
+ assert(ret >= 0);
+ ret = sigaction(SIGTERM, &act, &oact);
+ assert(ret >= 0);
+#endif
+
+ autoexit = 1;
+}
+
+int mr_app_register(const char * appsym, cpu_mask_t cpumask,
+ unsigned int autoexit)
+{
+ if (autoexit) __autoexit_setup();
+ mr_runtime_slave_init();
+ mr_app_manager_appinfo_register(appsym, cpumask);
+ on_exit(__autoexit_raise, NULL);
+ return 0;
+}
+
+int mr_thread_register()
+{
+ if (autoexit) __autoexit_thread_setup();
+ mr_app_manager_thread_register();
+ return 0;
+}
+
+void mr_thread_on_exit_register(void(*exit_fn)(void * arg), void * arg)
+{
+ return;
+}
+
+void mr_thread_hook()
+{
+ if(autoexit) pthread_testcancel();
+}
+
+void mr_on_exit_register(void(*exit_fn)(void * arg), void * arg)
+{
+ exit_handlers[nr_exit_handlers].fn = exit_fn;
+ exit_handlers[nr_exit_handlers].arg = arg;
+ nr_exit_handlers++;
+ return;
+} \ No newline at end of file
diff --git a/service/CMakeLists.txt b/service/CMakeLists.txt
index 5fec962..4a00981 100644
--- a/service/CMakeLists.txt
+++ b/service/CMakeLists.txt
@@ -6,10 +6,10 @@ include_directories(${DPDK_INCLUDE_DIR})
include_directories(include)
add_definitions(${DPDK_C_PREDEFINED})
-add_executable(zcpd src/core.c src/runtime.c src/config.c src/init.c
- src/register.c src/rxtx.c src/ldbc.c)
+
+add_executable(zcpd src/core.c src/runtime.c src/config.c src/register.c src/rxtx.c src/ldbc.c)
target_link_libraries(zcpd ${DPDK_LIBRARY} MESA_prof_load_static)
-target_link_libraries(zcpd rt pthread dl core)
+target_link_libraries(zcpd rt pthread dl core stack)
target_include_directories(zcpd INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/include/")
install(TARGETS zcpd RUNTIME DESTINATION bin COMPONENT Program) \ No newline at end of file
diff --git a/service/include/sc_common.h b/service/include/sc_common.h
index 59f7f05..394aaee 100644
--- a/service/include/sc_common.h
+++ b/service/include/sc_common.h
@@ -3,8 +3,13 @@
#include <mr_common.h>
#include <mr_device.h>
#include <sys/queue.h>
-#include "mr_mask.h"
+#include <mr_mask.h>
+#include <mr_core.h>
+#include <mr_rtdev.h>
+#include <sk_stack.h>
+
+//TODO: �����豸��Ϣ�����ع������豸��Ϣ������һ���ṹ��
struct sc_device
{
TAILQ_ENTRY(sc_device) next;
@@ -12,10 +17,14 @@ struct sc_device
char symbol[MR_STRING_MAX];
/* ������� */
mr_dev_t * dev;
- /* Ԥ�������������շ����ĵ��߳����� */
- mask_t __reserved;
- /* ������ */
- unsigned int nr_queues;
+ /* ����ʹ�� */
+ unsigned int en_mr_dev;
+ /* �������� */
+ struct mr_dev_param mr_dev_param;
+ /* Э��ջ�豸ʹ�� */
+ unsigned int en_sk_dev;
+ /* Э��ջ�豸���� */
+ struct sk_dev_param sk_dev_param;
};
TAILQ_HEAD(sc_device_list, sc_device);
@@ -91,25 +100,28 @@ struct sc_instance
unsigned int distmode;
/* Ӳ��RSS��ʽ */
unsigned int rssmode;
-};
+ /* Э��ջ���� */
+ struct mr_stack_param sk_param;
-#define __PATTERN_DEV_RX "%s-RX"
-#define __PATTERN_DEV_TX "%s-TX"
-#define __PATTERN_PROC_SERVICE "%s"
-#define __PATTERN_CONS_SERVICE "%s"
-#define __PATTERN_PROD_APP "%s"
-#define __PATTERN_CONS_APP "%s"
+ /* ���Ŀ�ȫ�־�� */
+ struct mr_core_instance * core_instance;
+ /* Э��ջȫ�־�� */
+ struct mr_stack_instance * sk_instance;
+};
// �й��豸������ʱ��Դ��ÿ���̣߳�ÿ���豸һ���ṹ��
struct sc_rt_device
{
+ /* ��ʵ�豸������ */
mr_devq_t * devq;
- struct vnodeman_attach_desc * rxvnode_desc;
- struct vnodeman_attach_desc * txvnode_desc;
+ /* ��Ӧ������ʱ�豸������ */
+ struct mr_rtdev_stream * rtstream;
+ /* ��Ӧ��Э��ջ�豸������ */
+ struct sk_dev_desc * sk_dev;
};
struct sc_thread_instance
{
unsigned int nr_devices;
struct sc_rt_device * rt_dev;
-};
+}; \ No newline at end of file
diff --git a/service/src/config.c b/service/src/config.c
index 4d4725a..e04f35f 100644
--- a/service/src/config.c
+++ b/service/src/config.c
@@ -8,10 +8,11 @@
#include <string.h>
#include <rte_ip_frag.h>
#include <assert.h>
-#include <mr_ctx.h>
#include <unistd.h>
#include <mr_core.h>
#include <mr_mask.h>
+#include <mr_runtime.h>
+#include <arpa/inet.h>
#ifndef MR_SERVICE_DEFAULT_SZ_RXVNODE_RING
#define MR_SERVICE_DEFAULT_SZ_RXVNODE_RING 1024
@@ -48,7 +49,7 @@
#if MR_SERVICE_DEFAULT_SZ_TX_BURST > MR_BURST_MAX
#error("MR_SERVICE_DEFAULT_TX_BURST is large than MR_BURST_MAX")
#endif
-
+
static int __parser_uint(const char * str)
{
@@ -76,6 +77,14 @@ static int __errlog_invaild_format(const char * function,
return -2;
}
+static int __errlog_no_mem(const char * function, const char * object)
+{
+ MR_LOG(WARNING, SERVICE, "ServiceConfig, %s, "
+ "Cannot alloc memory for %s.\n",
+ function, object);
+ return -3;
+}
+
// 将Core列表解析成CPU掩码
static int __parser_str_core(char * str_core, int sz_buffer,
cpu_mask_t * mask, char delimit)
@@ -190,35 +199,152 @@ int sc_config_app_info(const char * cfg, struct sc_instance * instance)
return 0;
}
+// 读协议栈运行参数
+static int sc_config_stack_info(const char * cfg, struct sc_instance * instance)
+{
+ struct mr_stack_param * sk_param = &instance->sk_param;
+ snprintf(sk_param->servsym, sizeof(sk_param->servsym), "%s", instance->procsym);
+
+ MESA_load_profile_uint_def(cfg, "stack", "sz_deliver_ring",
+ &sk_param->sz_deliver_ring, MR_STACK_DEFAULT_SZ_DELIVER_RING);
+ MESA_load_profile_uint_def(cfg, "stack", "sz_deliver_buffer",
+ &sk_param->sz_deliver_buffer, MR_STACK_DEFAULT_SZ_DELIVER_BUFFER);
+ MESA_load_profile_uint_def(cfg, "stack", "sz_loop_ring",
+ &sk_param->sz_loop_ring, MR_STACK_DEFAULT_SZ_LOOP_RING);
+
+ return 0;
+}
+
+static int __load_device_runtime_info(const char * cfg, struct sc_instance * instance,
+ struct sc_device * sc_dev)
+{
+ char str_section[MR_SYMBOL_MAX];
+ snprintf(str_section, sizeof(str_section), "device:%s", sc_dev->symbol);
+ struct mr_dev_param * dev_param = &sc_dev->mr_dev_param;
+
+ // 写设备名称
+ snprintf(sc_dev->mr_dev_param.symbol, sizeof(sc_dev->mr_dev_param.symbol), "%s", sc_dev->symbol);
+ // 读混杂模式,默认不开启混杂模式
+ MESA_load_profile_uint_def(cfg, str_section, "promisc", &dev_param->promisc, 0);
+ // 读MTU,默认为0,网卡自适应。
+ MESA_load_profile_short_def(cfg, str_section, "mtu", (short *)&dev_param->mtu, 0);
+ // 读VLAN-Strip选项,默认不开启
+ MESA_load_profile_uint_def(cfg, str_section, "vlan-strip", &dev_param->en_vlan_strip, 0);
+ // 读VLAN-Filter选项,默认不开启
+ MESA_load_profile_uint_def(cfg, str_section, "vlan-filter", &dev_param->en_vlan_filter, 0);
+ // 丢包选项
+ MESA_load_profile_uint_def(cfg, str_section, "drop_en", &dev_param->en_drop, 0);
+ // 分流模式
+ MESA_load_profile_uint_def(cfg, str_section, "rssmode", &dev_param->rssmode, 0);
+ // RX描述符数量
+ MESA_load_profile_uint_def(cfg, str_section, "nr_rxdesc", &dev_param->nr_rxdesc, 0);
+ // TX描述符数量
+ MESA_load_profile_uint_def(cfg, str_section, "nr_txdesc", &dev_param->nr_txdesc, 0);
+
+ // 读用户MAC地址
+ struct ether_addr hwaddr;
+ char str_hwaddr[MR_STRING_MAX];
+ MESA_load_profile_string_def(cfg, str_section, "hwaddr", str_hwaddr, sizeof(str_hwaddr), "");
+
+ int ret = sscanf(str_hwaddr, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
+ &hwaddr.addr_bytes[0], &hwaddr.addr_bytes[1],
+ &hwaddr.addr_bytes[2], &hwaddr.addr_bytes[3],
+ &hwaddr.addr_bytes[4], &hwaddr.addr_bytes[5]);
+
+ if (ret == 6) ether_addr_copy(&hwaddr, &dev_param->usr_ether_addr);
+ // 设备使能
+ sc_dev->en_mr_dev = 1;
+ return 0;
+}
+
+
+static int __load_device_stack_info(const char * cfg, struct sc_instance * instance,
+ struct sc_device * sc_dev)
+{
+ // 生成配置文件节名称,例如[device:mr0]
+ char str_section[MR_SYMBOL_MAX];
+ snprintf(str_section, sizeof(str_section), "device:%s", sc_dev->symbol);
+
+ // 读IP地址(必要)
+ char str_in_addr[MR_SYMBOL_MAX];
+ if (MESA_load_profile_string_nodef(cfg, str_section, "in_addr",
+ str_in_addr, sizeof(str_in_addr)) < 0) return 0;
+
+ // 地址转换
+ int ret = inet_pton(AF_INET, str_in_addr, &sc_dev->sk_dev_param.in_addr);
+ if (ret < 0) return __errlog_invaild_format("LoadDeviceInfo", str_section, "in_addr");
+
+ // 读掩码(必要)
+ char str_in_mask[MR_SYMBOL_MAX];
+ if (MESA_load_profile_string_nodef(cfg, str_section, "in_mask",
+ str_in_mask, sizeof(str_in_mask)) < 0) return 0;
+
+ // 掩码转换
+ ret = inet_pton(AF_INET, str_in_mask, &sc_dev->sk_dev_param.in_mask);
+ if (ret < 0) return __errlog_invaild_format("LoadDeviceInfo", str_section, "in_mask");
+
+ // 读默认网关(可选项)
+ char str_gateway[MR_SYMBOL_MAX];
+ if (MESA_load_profile_string_nodef(cfg, str_section, "gateway",
+ str_gateway, sizeof(str_gateway)) >= 0)
+ {
+ ret = inet_pton(AF_INET, str_gateway, &sc_dev->sk_dev_param.in_gateway);
+ if (ret < 0) return __errlog_invaild_format("LoadDeviceInfo", str_section, "gateway");
+ }
+
+ // 读协议栈处理的协议类型,默认全部处理
+ MESA_load_profile_uint_def(cfg, str_section, "en_tcp", &sc_dev->sk_dev_param.en_tcp, 1);
+ MESA_load_profile_uint_def(cfg, str_section, "en_udp", &sc_dev->sk_dev_param.en_udp, 1);
+ MESA_load_profile_uint_def(cfg, str_section, "en_icmp", &sc_dev->sk_dev_param.en_icmp, 1);
+ MESA_load_profile_uint_def(cfg, str_section, "en_arp", &sc_dev->sk_dev_param.en_arp, 1);
+
+ // 协议栈原始套接字默认不开启
+ MESA_load_profile_uint_def(cfg, str_section, "en_raw", &sc_dev->sk_dev_param.en_raw, 0);
+
+ // 写设备名称
+ snprintf(sc_dev->sk_dev_param.symbol, sizeof(sc_dev->sk_dev_param.symbol), "%s", sc_dev->symbol);
+
+ // 参数读取成功,协议栈使能
+ sc_dev->en_sk_dev = 1;
+ return 0;
+}
+
+// 读设备索引
int sc_config_device_info(const char * cfg, struct sc_instance * instance)
{
char str_device_info[MR_STRING_MAX];
- // 读配置文件
- int ret = MESA_load_profile_string_nodef(cfg, "service", "device",
+ // 读设备索引
+ int ret = MESA_load_profile_string_nodef(cfg, "device", "device",
str_device_info, sizeof(str_device_info));
- if (ret < 0) return __errlog_lost_key("LoadDeviceInfo", "service", "device");
+ if (ret < 0) return __errlog_lost_key("LoadDeviceInfo", "device", "device");
char * tokens[MR_TOKENS_MAX];
int nr_tokens = rte_strsplit(str_device_info, sizeof(str_device_info),
tokens, MR_TOKENS_MAX, ',');
if (nr_tokens <= 0) goto _err_fmt;
- // 每个Tokens对应一个设备
+ // 读设备具体信息,每个Tokens对应一个设备
TAILQ_INIT(&instance->device_list);
for (int i = 0; i < nr_tokens; i++)
{
struct sc_device * sc_dev = rte_zmalloc(NULL, sizeof(struct sc_device), 0);
- assert(sc_dev != NULL);
+ if (sc_dev == NULL) return __errlog_no_mem("LoadDeviceInfo", "sc_device");
snprintf(sc_dev->symbol, sizeof(sc_dev->symbol), "%s", tokens[i]);
+
+ ret = __load_device_runtime_info(cfg, instance, sc_dev);
+ if (ret < 0) return ret;
+ ret = __load_device_stack_info(cfg, instance, sc_dev);
+ if (ret < 0) return ret;
+
TAILQ_INSERT_TAIL(&instance->device_list, sc_dev, next);
}
return 0;
_err_fmt:
- return __errlog_invaild_format("LoadDeviceInfo", "service", "device");
+ return __errlog_invaild_format("LoadDeviceInfo", "device", "device");
}
int sc_config_vnode_info(const char * cfg, struct sc_instance * instance)
@@ -294,8 +420,7 @@ int sc_config_check_cfgfile(const char * cfg, struct sc_instance * instance)
/* 第二阶段,配置阶段 */
void sc_stage_config(struct sc_instance * instance)
{
- struct mr_config * g_cfg = mr_global_config_get();
- const char * cfgfile = g_cfg->glob_cfg_file;
+ const char * cfgfile = instance->local_cfgfile;
// 读文件配置
MR_CHECK(sc_config_check_cfgfile(cfgfile, instance) >= 0,
@@ -312,8 +437,8 @@ void sc_stage_config(struct sc_instance * instance)
"Please check configure file %s, Failed. ", cfgfile);
MR_CHECK(sc_config_ldbc_dist_mode(cfgfile, instance) >= 0,
"Please check configure file %s, Failed. ", cfgfile);
-
- // 核心库配置
- mr_core_stage_config();
+ MR_CHECK(sc_config_stack_info(cfgfile, instance) >= 0,
+ "Please check configure file %s, Failed. ", cfgfile);
+
return;
} \ No newline at end of file
diff --git a/service/src/core.c b/service/src/core.c
index f3b6c9d..3c7cd45 100644
--- a/service/src/core.c
+++ b/service/src/core.c
@@ -7,13 +7,11 @@
#include <rte_version.h>
#include <rte_ip_frag.h>
#include <mr_common.h>
-#include <mr_ctx.h>
-#include <mr_procman.h>
#include <mr_device.h>
-#include <mr_core.h>
#include <mr_mask.h>
#include <sc_common.h>
#include <MESA_prof_load.h>
+#include <mr_runtime.h>
#ifdef GITVER
const char service_git_version[] = GITVER;
@@ -39,9 +37,7 @@ const char service_git_version[] = "";
extern void * sc_runtime_thread(void * args);
-extern void sc_stage_preinit(struct sc_instance * instance);
extern void sc_stage_config(struct sc_instance * instance);
-extern void sc_stage_init(struct sc_instance * instance);
extern void sc_stage_register(struct sc_instance * instance);
extern struct mr_module module_desc_hwinfo;
@@ -159,6 +155,7 @@ default_stream:
return;
}
+//TODO: 检查这一段的逻辑是否正确
void sc_instance_init_cfg(struct sc_instance * instance)
{
int ret = strncmp(instance->local_cfgfile, "", sizeof(instance->local_cfgfile));
@@ -168,7 +165,7 @@ void sc_instance_init_cfg(struct sc_instance * instance)
default_cfgfile:
snprintf(instance->local_cfgfile, sizeof(instance->local_logfile), "%s",
MR_SERVICE_GLOB_CFG);
-out:
+
MR_LOG(INFO, SERVICE, "Global Configure File: %s\n", instance->local_cfgfile);
}
@@ -187,23 +184,16 @@ void sc_instance_init(struct sc_instance * instance)
sc_instance_init_progsym(instance);
}
-void sc_procinfo_ready(struct sc_instance * instance)
+void sc_instance_ctx_init(struct sc_instance * instance)
{
- procman_process_create(instance->procsym, instance->cpu_mask);
- procman_register_myself(instance->procsym);
- mr_proc_ctx_get()->priv = instance;
-}
-
-void sc_global_cfg_ready(struct sc_instance * instance)
-{
- struct mr_config * g_cfg = mr_global_config_get();
- snprintf(g_cfg->glob_cfg_file, sizeof(g_cfg->glob_cfg_file),
- "%s", instance->local_cfgfile);
+ // 启动运行时环境,
+ mr_runtime_init();
return;
}
-void sc_dumpinfo()
+void sc_stage_init(struct sc_instance * instance)
{
+ mr_core_instance_init(instance->core_instance);
return;
}
@@ -222,26 +212,28 @@ void sc_launch_thread(struct sc_instance * instance)
return;
}
+/* 初始化流程:
+ * A. 申请进程instance空间(使用普通内存,大页内存还没有初始化);
+ * B. 解析命令行参数,读入基本配置信息供启动EAL环境使用;
+ * C. 初始化运行时环境,启动EAL环境;
+ * D. 初始化各基础库句柄,将进程instance迁移到EAL内存上便于全局使用。
+ */
+
int main(int argc, char * argv[])
{
struct sc_instance * instance = sc_instance_new();
sc_stage_parse_cmd(instance, argc, argv);
sc_instance_init(instance);
sc_stage_eal_init(instance);
+ sc_instance_ctx_init(instance);
MR_LOG(INFO, SERVICE, "Starting IIE MARSIO I/O Service...\n");
MR_LOG(INFO, SERVICE, "Version : %s, Using %s\n", service_git_version, rte_version());
- mr_global_ctx_init();
- mr_global_cfg_init();
-
- sc_global_cfg_ready(instance);
- sc_stage_preinit(instance);
+
sc_stage_config(instance);
- sc_procinfo_ready(instance);
-
sc_stage_register(instance);
+ mr_core_instance_config(instance->core_instance);
sc_stage_init(instance);
-
sc_launch_thread(instance);
assert(0);
return 0;
diff --git a/service/src/init.c b/service/src/init.c
deleted file mode 100644
index 141da1b..0000000
--- a/service/src/init.c
+++ /dev/null
@@ -1,18 +0,0 @@
-
-#include <mr_core.h>
-#include <mr_mask.h>
-#include <sc_common.h>
-#include <assert.h>
-
-void sc_stage_preinit(struct sc_instance * instance)
-{
- mr_core_stage_preinit();
- return;
-}
-
-/* �����׶Σ���ʼ�� */
-void sc_stage_init(struct sc_instance * instance)
-{
- mr_core_stage_init();
- return;
-} \ No newline at end of file
diff --git a/service/src/ldbc.c b/service/src/ldbc.c
index db6b092..8e9f016 100644
--- a/service/src/ldbc.c
+++ b/service/src/ldbc.c
@@ -146,10 +146,10 @@ static void * __complex_parser_mpls_uc(void * data, int this_layer_type,
#define MPLS_BLS_MASK (0x00000100)
#define MPLS_TTL_MASK (0x000000FF)
- unsigned int mpls_label = (ntohl(*_mpls_header) & MPLS_LABEL_MASK) >> 12;
- unsigned int mpls_exp = (ntohl(*_mpls_header) & MPLS_EXP_MASK) >> 9;
+ __rte_unused unsigned int mpls_label = (ntohl(*_mpls_header) & MPLS_LABEL_MASK) >> 12;
+ __rte_unused unsigned int mpls_exp = (ntohl(*_mpls_header) & MPLS_EXP_MASK) >> 9;
+ __rte_unused unsigned int mpls_ttl = (ntohl(*_mpls_header) & MPLS_TTL_MASK);
unsigned int mpls_bls = (ntohl(*_mpls_header) & MPLS_BLS_MASK) >> 8;
- unsigned int mpls_ttl = (ntohl(*_mpls_header) & MPLS_TTL_MASK);
void * data_next_layer = _mpls_header + 1;
diff --git a/service/src/register.c b/service/src/register.c
index 8dbe576..afb0322 100644
--- a/service/src/register.c
+++ b/service/src/register.c
@@ -19,274 +19,178 @@
#include <mr_vman.h>
#include <mr_mask.h>
#include <assert.h>
-#include <mr_ctx.h>
-#include "mr_procman.h"
+#include <mr_runtime.h>
+#include <mr_rtdev.h>
-static int sc_device_register(struct sc_instance * instance)
+static int sc_core_instance_register(struct sc_instance * instance)
{
- // 设备队列数与进程内线程最大数相同
- // 预留功能:对于每一个设备,使用不同的线程进行收发包
- struct sc_device * device_iter;
- int nr_queues = mr_proc_ctx_get()->nr_max_thread;
-
- TAILQ_FOREACH(device_iter, &instance->device_list, next)
- {
- mr_dev_t * dev = NULL;
- dev = mr_device_open(device_iter->symbol,
- nr_queues, MR_DEVICE_FLAGS_PROMISC);
-
- // 打开失败,从设备链表中删除,不再处理这个设备
- if(dev == NULL)
- {
- MR_LOG(WARNING, SERVICE, "Service, DeviceRegister, "
- "Cannot preopen device %s, ignore it.\n",
- device_iter->symbol);
-
- TAILQ_REMOVE(&instance->device_list, device_iter, next);
- continue;
- }
-
- // 预打开成功,保留在设备链表中。
- device_iter->dev = dev;
- device_iter->nr_queues = nr_queues;
- instance->nr_devs++;
- }
-
+ // 获取全局配置句柄和全局运行时句柄
+ struct mr_global_config * g_cfg = mr_global_config_get();
+ struct mr_global_ctx * g_ctx = mr_global_ctx_get();
+ assert(g_cfg != NULL && g_ctx != NULL);
+
+ // 初始化全局配置
+ snprintf(g_cfg->glob_cfg_file, sizeof(g_cfg->glob_cfg_file),
+ "%s", instance->local_cfgfile);
+
+ // 初始化核心库句柄
+ instance->core_instance = mr_core_instance_create(g_cfg);
+ mr_core_default_instance_set(instance->core_instance);
+ g_ctx->ctx_core = instance->core_instance;
return 0;
}
-static int __vnode_register_for_dev(struct sc_instance * instance,
- struct sc_device * sc_dev)
+static int sc_stack_instance_register(struct sc_instance * instance)
{
- char vnodesym[MR_SYMBOL_MAX];
- int ret = 0;
-
- // 为收报路径注册新的VNode节点
- snprintf(vnodesym, sizeof(vnodesym), __PATTERN_DEV_RX, sc_dev->symbol);
- ret = mr_vnodeman_create(vnodesym, instance->sz_rxvnode_ring,
- instance->sz_rxvnode_buffer, 0);
-
- if(ret < 0)
- {
- MR_LOG(WARNING, SERVICE, "Service, VNodeRegister, "
- "Cannot create vnode %s(sz_tunnel=%d, sz_buffer=%d) for device %s\n",
- vnodesym, sc_dev->symbol, instance->sz_rxvnode_ring, instance->sz_rxvnode_buffer);
- return ret;
- }
-
- // 为发报路径注册新的VNode节点
- snprintf(vnodesym, sizeof(vnodesym), __PATTERN_DEV_TX, sc_dev->symbol);
- ret = mr_vnodeman_create(vnodesym, instance->sz_rxvnode_ring,
- instance->sz_rxvnode_buffer, 0);
-
- if(ret < 0)
- {
- MR_LOG(WARNING, SERVICE, "Service, VNodeRegister, "
- "Cannot create vnode %s(sz_tunnel=%d, sz_buffer=%d) for device %s\n",
- vnodesym, sc_dev->symbol, instance->sz_rxvnode_ring, instance->sz_rxvnode_buffer);
- return ret;
- }
-
- //TODO: 快速路径VNode节点
+ // 获取全局配置句柄和全局运行时句柄
+ struct mr_global_config * g_cfg = mr_global_config_get();
+ struct mr_global_ctx * g_ctx = mr_global_ctx_get();
+ assert(g_cfg != NULL && g_ctx != NULL);
+
+ // 初始化协议栈全局句柄
+ instance->sk_instance = mr_stack_instance_create(&instance->sk_param);
+ g_ctx->ctx_stack = instance->sk_instance;
return 0;
}
-static int __register_service_for_rxvnode(struct sc_instance * instance,
+static int __mr_dev_register(struct sc_instance * instance,
struct sc_device * sc_dev)
{
- char vnodesym[MR_STRING_MAX];
- char prodsym[MR_STRING_MAX];
+ // 计算默认队列数,队列数等于IO核心数
+ int nr_queues = mask_popcnt(instance->cpu_mask);
- // 生成VNode的名字
- snprintf(vnodesym, sizeof(vnodesym), __PATTERN_DEV_RX, sc_dev->symbol);
- snprintf(prodsym, sizeof(prodsym), __PATTERN_PROC_SERVICE, instance->procsym);
-
- // 注册生产者,生产者的队列数与进程最大线程数一致
- int nr_queues = mr_proc_ctx_get()->nr_max_thread;
- int ret = mr_vnodeman_register_producer(vnodesym, prodsym, nr_queues);
-
- if(ret < 0)
+ // 没有指定队列数,采用默认的队列数
+ if (sc_dev->mr_dev_param.nr_queues == 0)
+ sc_dev->mr_dev_param.nr_queues = nr_queues;
+
+ // 打开设备
+ mr_dev_t * dev = mr_device_open(&sc_dev->mr_dev_param);
+
+ // 失败
+ if (unlikely(dev == NULL))
{
- MR_LOG(WARNING, SERVICE, "Service, VNodeServiceRegister, "
- "Cannot register producer %s(nr_queues=%d) for vnode %s. \n",
- prodsym, nr_queues, vnodesym);
- return ret;
+ MR_LOG(WARNING, SERVICE, "Service, DeviceRegister, "
+ "Cannot preopen device %s, ignore it.\n",
+ sc_dev->symbol);
+ return -1;
}
- MR_LOG(INFO, SERVICE, "Service, VNodeServiceRegister, "
- "Service(procsym=%s) VNode(sym=%s) Producer(sym=%s, nr_queues=%d) registered.\n",
- instance->procsym, vnodesym, prodsym, nr_queues);
-
+ sc_dev->dev = dev;
return 0;
}
-static int __register_service_for_txvnode(struct sc_instance * instance,
+static int __rt_dev_register(struct sc_instance * instance,
struct sc_device * sc_dev)
{
- char vnodesym[MR_SYMBOL_MAX];
- char conssym[MR_SYMBOL_MAX];
-
- // 生成VNode的名字
- snprintf(vnodesym, sizeof(vnodesym), __PATTERN_DEV_TX, sc_dev->symbol);
- snprintf(conssym, sizeof(conssym), __PATTERN_CONS_SERVICE, instance->procsym);
+ // 计算默认队列数,队列数等于IO核心数
+ int nr_queues = mask_popcnt(instance->cpu_mask);
- // 注册消费者,消费者的队列数与进程最大线程数一致
- int nr_queues = mr_proc_ctx_get()->nr_max_thread;
- int ret = mr_vnodeman_register_consumer(vnodesym, conssym, nr_queues);
+ // 创建运行时设备
+ int ret = rt_device_serv_create(sc_dev->symbol, instance->procsym,
+ nr_queues, instance->sz_rxvnode_ring, instance->sz_rxvnode_buffer);
- if (ret < 0)
+ if (unlikely(ret < 0))
{
- MR_LOG(WARNING, SERVICE, "Service, VNodeServiceRegister, "
- "Cannot register consumer %s(nr_queues=%d) for vnode %s. \n",
- conssym, nr_queues, vnodesym);
+ MR_LOG(WARNING, SERVICE, "Service, RtdeviceRegister, "
+ "Rtdevice %s(nr_queue=%d, sz_tunnel=%d, sz_buffer=%d) create failed. \n",
+ sc_dev->symbol, nr_queues, instance->sz_rxvnode_ring,
+ instance->sz_rxvnode_buffer);
return ret;
}
- MR_LOG(INFO, SERVICE, "Service, VNodeServiceRegister, "
- "Service(procsym=%s) VNode(sym=%s) Consumer(sym=%s, nr_queues=%d) registered.\n",
- instance->procsym, vnodesym, conssym, nr_queues);
+ MR_LOG(INFO, SERVICE, "Service, RtdeviceRegister, "
+ "Rtdevice %s(nr_queue=%d, sz_tunnel=%d, sz_buffer=%d) created. \n",
+ sc_dev->symbol, nr_queues, instance->sz_rxvnode_ring,
+ instance->sz_rxvnode_buffer);
return 0;
}
-static int __register_app_for_rxvnode(struct sc_instance * instance,
+static int __sk_dev_register(struct sc_instance * instance,
struct sc_device * sc_dev)
{
- char vnodesym[MR_SYMBOL_MAX];
- char conssym[MR_SYMBOL_MAX];
-
- // 生成VNode的名字
- snprintf(vnodesym, sizeof(vnodesym), __PATTERN_DEV_RX, sc_dev->symbol);
-
- // 遍历应用注册列表,为每个节点注册消费者
- struct sc_app * app_iter;
- TAILQ_FOREACH(app_iter, &instance->app_list, next)
+ // 跳过没有启用协议栈的设备
+ if(!(sc_dev->en_mr_dev && sc_dev->en_sk_dev))
{
- snprintf(conssym, sizeof(conssym), __PATTERN_CONS_APP, app_iter->symbol);
- int ret = mr_vnodeman_register_consumer(vnodesym, conssym, app_iter->rxstream);
- if(ret < 0)
- {
- MR_LOG(WARNING, SERVICE, "Service, VNodeAppRegister, "
- "Cannot register consumer %s(nr_queues=%d) for vnode %s. \n",
- conssym, app_iter->rxstream, vnodesym);
- return ret;
- }
-
- MR_LOG(INFO, SERVICE, "Service, VNodeAppRegister, "
- "App(symbol=%s) VNode(sym=%s) Consumer(sym=%s, nr_queues=%d) registered.\n",
- app_iter->symbol, vnodesym, conssym, app_iter->rxstream);
+ MR_LOG(INFO, SERVICE, "Service, StackDeviceRegister, "
+ "StackDevice %s is disable, ignore. \n", sc_dev->symbol);
+ return 0;
}
- return 0;
-}
-
-static int __register_app_for_txvnode(struct sc_instance * instance,
- struct sc_device * sc_dev)
-{
- char vnodesym[MR_SYMBOL_MAX];
- char prodsym[MR_SYMBOL_MAX];
-
- // 生成VNode的名字
- snprintf(vnodesym, sizeof(vnodesym), __PATTERN_DEV_TX, sc_dev->symbol);
+ // 创建协议栈设备
+ int ret = mr_stack_device_create(instance->sk_instance,
+ &sc_dev->sk_dev_param);
- // 遍历应用注册列表,为每个节点注册生产者
- struct sc_app * app_iter;
- TAILQ_FOREACH(app_iter, &instance->app_list, next)
+ if(unlikely(ret < 0))
{
- snprintf(prodsym, sizeof(prodsym), __PATTERN_PROD_APP, app_iter->symbol);
- int ret = mr_vnodeman_register_producer(vnodesym, prodsym, app_iter->txstream);
- if (ret < 0)
- {
- MR_LOG(WARNING, SERVICE, "Service, VNodeAppRegister, "
- "Cannot register consumer %s(nr_queues=%d) for vnode %s. \n",
- prodsym, app_iter->txstream, vnodesym);
- return ret;
- }
-
- MR_LOG(INFO, SERVICE, "Service, VNodeAppRegister, "
- "App(symbol=%s) VNode(sym=%s) Producer(sym=%s, nr_queues=%d) registered.\n",
- app_iter->symbol, vnodesym, prodsym, app_iter->txstream);
+ MR_LOG(WARNING, SERVICE, "Service, StackDeviceRegister, "
+ "StackDevice %s create failed. \n", sc_dev->sk_dev_param.symbol);
+ return ret;
}
+ MR_LOG(WARNING, SERVICE, "Service, StackDeviceRegister, "
+ "StackDevice %s created. \n", sc_dev->sk_dev_param.symbol);
return 0;
}
-
-static int sc_vnode_register(struct sc_instance * instance)
+static int sc_device_register(struct sc_instance * instance)
{
+ // 设备队列数与进程内线程最大数相同
+ // 预留功能:对于每一个设备,使用不同的线程进行收发包
+ struct sc_device * device_iter;
int ret = 0;
- struct sc_device_list * dev_list = &instance->device_list;
- struct sc_device * dev_iter = NULL;
-
- // 为每个设备创建自己的VNode节点
- TAILQ_FOREACH(dev_iter, dev_list, next)
- {
- ret = __vnode_register_for_dev(instance, dev_iter);
- if (ret < 0) return ret;
- }
-
- // 为Service服务注册生产者和消费者
- // Service作为RX方向的VNode节点的生产者,队列数与线程数一致
- // Service作为TX方向的VNode节点的消费者,队列数与线程数一致
-
- TAILQ_FOREACH(dev_iter, dev_list, next)
+
+ TAILQ_FOREACH(device_iter, &instance->device_list, next)
{
- ret = __register_service_for_rxvnode(instance, dev_iter);
- if (ret < 0) return ret;
- ret = __register_service_for_txvnode(instance, dev_iter);
- if (ret < 0) return ret;
- }
-
- // 为App注册生产者和消费者
- // App作为RX方向的VNode的节点消费者,队列数规定在rxstream变量中,
- // 从配置文件读取。App作为TX方向的VNode节点的生产者,队列数规定在
- // txstream变量中,从配置文件读取。
+ ret = __mr_dev_register(instance, device_iter);
+ if (ret < 0) goto device_open_fail;
+ ret = __rt_dev_register(instance, device_iter);
+ if (ret < 0) goto device_open_fail;
+ ret = __sk_dev_register(instance, device_iter);
+ if (ret < 0) goto device_open_fail;
+
+ // 打开成功,保留在设备链表中。
+ instance->nr_devs++;
+ continue;
- TAILQ_FOREACH(dev_iter, dev_list, next)
- {
- ret = __register_app_for_rxvnode(instance, dev_iter);
- if (ret < 0) return ret;
- ret = __register_app_for_txvnode(instance, dev_iter);
- if (ret < 0) return ret;
+ // 打开失败,移除设备链表
+device_open_fail:
+ MR_LOG(ERR, SERVICE, "ServiceDeviceRegister, "
+ "Device %s register failed. Disabled. \n", device_iter->symbol);
+ TAILQ_REMOVE(&instance->device_list, device_iter, next);
}
-
+
return 0;
}
-int sc_proc_register(struct sc_instance * instance)
+int sc_app_register(struct sc_instance * instance)
{
- struct sc_app * app_iter;
- char prodsym[MR_SYMBOL_MAX];
-
- TAILQ_FOREACH(app_iter, &instance->app_list, next)
+ // 注册主应用
+ int ret = mr_app_manager_appinfo_register(instance->procsym, instance->cpu_mask);
+ if(ret < 0)
{
- snprintf(prodsym, sizeof(prodsym), __PATTERN_PROD_APP, app_iter->symbol);
- int ret = procman_process_create(prodsym, app_iter->cpu_mask);
-
- if (ret < 0)
- {
- MR_LOG(WARNING, SERVICE, "Service, ProcRegister, "
- "Cannot register app %s(cpu_mask=%x). \n",
- prodsym, app_iter->cpu_mask);
- return ret;
- }
-
- MR_LOG(INFO, SERVICE, "Service, ProcRegister, "
- "App(symbol=%s) Process(sym=%s, cpu_mask=%x) registered.\n",
- app_iter->symbol, prodsym, app_iter->cpu_mask);
+ MR_LOG(ERR, SERVICE, "Service, AppRegister, "
+ "Cannot register service application(sym=%s, cpu_mask=%"PRIx64")",
+ instance->procsym, instance->cpu_mask);
+ return ret;
}
+ MR_LOG(INFO, SERVICE, "Service, AppRegister, "
+ "App(symbol=%s) Process(cpu_mask=%"PRIx64") registered.\n",
+ instance->procsym, instance->cpu_mask);
+
return 0;
}
-
void sc_stage_register(struct sc_instance * instance)
{
- MR_CHECK(sc_proc_register(instance) >= 0,
+ MR_CHECK(sc_core_instance_register(instance) >= 0,
+ "Cannot register core instance, Failed. Please recheck runtime log. ");
+ MR_CHECK(sc_stack_instance_register(instance) >= 0,
+ "Cannot register stack instance, Failed. Please recheck runtime log. ");
+ MR_CHECK(sc_app_register(instance) >= 0,
"Cannot register process, Failed. Please recheck runtime log. ");
MR_CHECK(sc_device_register(instance) >= 0,
"Cannot register device, Failed. Please recheck runtime log. ");
- MR_CHECK(sc_vnode_register(instance) >= 0,
- "Cannot register vnode, Failed. Please recheck runtime log.");
return;
} \ No newline at end of file
diff --git a/service/src/runtime.c b/service/src/runtime.c
index c750cb5..ddb3574 100644
--- a/service/src/runtime.c
+++ b/service/src/runtime.c
@@ -1,15 +1,14 @@
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
-#include <mr_procman.h>
-#include <mr_ctx.h>
-#include <mr_common.h>
+#include <assert.h>
+#include <rte_malloc.h>
#include <rte_log.h>
+#include <mr_common.h>
+#include <mr_runtime.h>
#include <mr_device.h>
-#include <rte_ip_frag.h>
#include <sc_common.h>
-#include <assert.h>
-#include "mr_vman.h"
+
void sc_thread_instance_init(struct sc_instance * instance,
struct sc_thread_instance * tinstance)
@@ -20,10 +19,12 @@ void sc_thread_instance_init(struct sc_instance * instance,
return;
}
-void sc_thread_device_attach(struct sc_instance * instance,
- struct mr_thread_ctx * tctx, struct sc_thread_instance * tinstance)
+void sc_thread_device_attach(struct sc_instance * instance,
+ struct sc_thread_instance * tinstance)
{
struct sc_device * sc_dev_iter;
+ int nr_devices = 0;
+
TAILQ_FOREACH(sc_dev_iter, &instance->device_list, next)
{
// 附着设备,取出队列描述符
@@ -32,132 +33,71 @@ void sc_thread_device_attach(struct sc_instance * instance,
{
MR_LOG(WARNING, SERVICE, "Service, RuntimeThread, "
"Cannot attach device %s for thread %d, Ignore the device.\n",
- sc_dev_iter->symbol, tctx->thread_id);
+ sc_dev_iter->symbol, mr_thread_id());
continue;
}
- MR_LOG(INFO, SERVICE, "Service, RuntimeThread, "
- "Attach Device %s for thread %d success.\n",
- sc_dev_iter->symbol, tctx->thread_id);
-
- // 存储句柄到私有存储空间,下面收发包时使用
- tinstance->rt_dev[tinstance->nr_devices++].devq = devq;
- }
-
- return;
-}
-
-void sc_thread_rxvnode_attach(struct sc_instance * instance,
- struct mr_thread_ctx * tctx, struct sc_thread_instance * tinstance)
-{
- struct sc_device * sc_dev_iter;
- struct vnodeman_attach_desc * vnode_attach_desc;
- char vnodesym[MR_SYMBOL_MAX];
- char prodsym[MR_SYMBOL_MAX];
- unsigned int dev_curser = 0;
-
- TAILQ_FOREACH(sc_dev_iter, &instance->device_list, next)
- {
- snprintf(vnodesym, sizeof(vnodesym), __PATTERN_DEV_RX,
- sc_dev_iter->symbol);
- snprintf(prodsym, sizeof(prodsym), __PATTERN_PROC_SERVICE,
+ // 附着运行时设备
+ struct mr_rtdev_stream * rtstream;
+ rtstream = rt_dev_serv_open_stream(sc_dev_iter->symbol,
instance->procsym);
- vnode_attach_desc = mr_vnodeman_producer_attach(vnodesym, prodsym);
- if(unlikely(vnode_attach_desc == NULL))
+ if (rtstream == NULL)
{
- MR_LOG(WARNING, SERVICE, "Service, ThreadRxVNodeAttach, "
- "Cannot attach vnode(sym=%s) producer=(%s), ignore this device. \n",
- vnodesym, prodsym);
- }
- else
- {
- tinstance->rt_dev[dev_curser].rxvnode_desc = vnode_attach_desc;
- assert(vnode_attach_desc->desc_type == VNODEMAN_ATTACH_PRODUCER);
+ MR_LOG(WARNING, SERVICE, "Service, RuntimeThread, "
+ "Cannot attach rtdevice %s for thread %d, Ignore the device.\n",
+ sc_dev_iter->symbol, mr_thread_id());
+ continue;
}
-
- dev_curser++;
- }
-
- assert(dev_curser == tinstance->nr_devices);
- return;
-}
-
-void sc_thread_txvnode_attach(struct sc_instance * instance,
- struct mr_thread_ctx * tctx, struct sc_thread_instance * tinstance)
-{
- struct sc_device * sc_dev_iter;
- struct vnodeman_attach_desc * vnode_attach_desc;
- char vnodesym[MR_SYMBOL_MAX];
- char conssym[MR_SYMBOL_MAX];
- unsigned int dev_curser = 0;
-
- TAILQ_FOREACH(sc_dev_iter, &instance->device_list, next)
- {
- snprintf(vnodesym, sizeof(vnodesym), __PATTERN_DEV_TX,
- sc_dev_iter->symbol);
- snprintf(conssym, sizeof(conssym), __PATTERN_CONS_SERVICE,
- instance->procsym);
- vnode_attach_desc = mr_vnodeman_consumer_attach(vnodesym, conssym);
- if (unlikely(vnode_attach_desc == NULL))
- {
- MR_LOG(WARNING, SERVICE, "Service, ThreadTxVNodeAttach, "
- "Cannot attach vnode(sym=%s) consumer=(%s), ignore this device. \n",
- vnodesym, conssym);
- }
- else
- {
- tinstance->rt_dev[dev_curser].txvnode_desc = vnode_attach_desc;
- assert(vnode_attach_desc->desc_type == VNODEMAN_ATTACH_CONSUMER);
- }
+ MR_LOG(INFO, SERVICE, "Service, RuntimeThread, "
+ "Attach Device %s for thread %d success.\n",
+ sc_dev_iter->symbol, mr_thread_id());
- dev_curser++;
+ // 存储句柄到私有存储空间,下面收发包时使用
+ tinstance->rt_dev[nr_devices].devq = devq;
+ tinstance->rt_dev[nr_devices].rtstream = rtstream;
+ nr_devices++;
}
- assert(dev_curser == tinstance->nr_devices);
+ tinstance->nr_devices = nr_devices;
return;
}
extern void sc_thread_rx_loop(struct sc_instance * instance,
- struct mr_thread_ctx * tctx, struct sc_thread_instance * tinstance);
+ struct sc_thread_instance * tinstance);
extern void sc_thread_tx_loop(struct sc_instance * instance,
- struct mr_thread_ctx * tctx, struct sc_thread_instance * tinstance);
+ struct sc_thread_instance * tinstance);
extern void sc_thread_timer_loop(struct sc_instance * instance,
- struct mr_thread_ctx * tctx, struct sc_thread_instance * tinstance);
+ struct sc_thread_instance * tinstance);
void * sc_runtime_thread(void * args)
{
- procman_thread_register_myself();
+ mr_app_manager_thread_register();
struct sc_instance * instance = (struct sc_instance *)args;
- struct mr_thread_ctx * tctx = mr_thread_ctx_get();
MR_LOG(INFO, SERVICE, "Service, RuntimeThread, "
"Thread ID %d Running, CPU_ID=%d, Socket_ID=%d\n",
- tctx->thread_id, tctx->cpu_id, tctx->socket_id);
+ mr_thread_id(), mr_cpu_id(), mr_socket_id());
/* 分配线程私有存储空间 */
- tctx->priv = rte_zmalloc(NULL, sizeof(struct sc_thread_instance), 0);
- MR_CHECK(tctx->priv != NULL, "Service, RuntimeThread, "
+ struct sc_thread_instance * tinstance;
+ tinstance = rte_zmalloc(NULL, sizeof(struct sc_thread_instance), 0);
+ MR_CHECK(tinstance != NULL, "Service, RuntimeThread, "
"Cannot alloc memory for thread private instance, Failed.\n");
/* 初始化线程私有存储空间 */
- struct sc_thread_instance * tinstance;
- tinstance = (struct sc_thread_instance *)tctx->priv;
sc_thread_instance_init(instance, tinstance);
-
- /* 线程Attach操作 */
- sc_thread_device_attach(instance, tctx, tinstance);
- sc_thread_rxvnode_attach(instance, tctx, tinstance);
- sc_thread_txvnode_attach(instance, tctx, tinstance);
-
+ /* 线程Attach设备操作 */
+ sc_thread_device_attach(instance, tinstance);
+
while(1)
{
- sc_thread_rx_loop(instance, tctx, tinstance);
- sc_thread_tx_loop(instance, tctx, tinstance);
- sc_thread_timer_loop(instance, tctx, tinstance);
+ sc_thread_rx_loop(instance, tinstance);
+ sc_thread_tx_loop(instance, tinstance);
+ sc_thread_timer_loop(instance, tinstance);
}
return NULL;
diff --git a/service/src/rxtx.c b/service/src/rxtx.c
index aa3197e..cd6fc13 100644
--- a/service/src/rxtx.c
+++ b/service/src/rxtx.c
@@ -1,7 +1,6 @@
#include <rte_ethdev.h>
#include <sc_common.h>
#include <mr_common.h>
-#include <mr_ctx.h>
#include <mr_vman.h>
#include <mr_stat.h>
#include <mr_vnode.h>
@@ -16,55 +15,73 @@ void __free_mbufs(struct rte_mbuf * bufs[], int nr_bufs)
return;
}
-void sc_thread_rx_loop(struct sc_instance * instance,
- struct mr_thread_ctx * tctx, struct sc_thread_instance * tinstance)
+static inline void __rx_loop_one_device(struct sc_instance * instance,
+ struct sc_thread_instance * tinstance, struct sc_rt_device * rtdev,
+ unsigned int nr_rx_burst)
{
struct rte_mbuf * rx_bufs[MR_BURST_MAX];
hash_t hash_result[MR_BURST_MAX];
+ int ret;
+
+ mr_devq_t * devq = rtdev->devq;
+ struct mr_rtdev_stream * rtstream = rtdev->rtstream;
+
+ uint16_t nr_rx_bufs = rte_eth_rx_burst(devq->port_id,
+ devq->rx_queue_id, rx_bufs, nr_rx_burst);
+
+ // û�����ݰ�ֱ������
+ if (unlikely(nr_rx_bufs == 0)) return;
+
+ int nr_rx_bufs_len = pktslen(rx_bufs, nr_rx_bufs);
+ UPDATE_DEV_STAT(dev_rx_frame, devq->port_id, nr_rx_bufs);
+ UPDATE_DEV_STAT(dev_rx_bit, devq->port_id, nr_rx_bufs_len);
+ UPDATE_APP_STAT(rx_frame, nr_rx_bufs);
+ UPDATE_APP_STAT(rx_byte, nr_rx_bufs_len);
+ // �������ݰ����طֵ�ʹ�õ�Hashֵ
+ ret = distributer_hash_caculate(instance->distmode,
+ rx_bufs, nr_rx_bufs, hash_result);
+ if (unlikely(ret < 0)) goto err_free_mbufs;
+
+ // ����VNode�У��ַ�����Ӧ��
+ struct vnodeman_attach_desc * attach_desc = rtstream->rxd;
+ ret = vnode_enqueue_burst_with_hash(attach_desc->prod, &vnodeman_ops,
+ attach_desc->queue_id, (void **)rx_bufs, hash_result, nr_rx_bufs);
+ if (unlikely(ret < 0)) goto err_free_mbufs;
+ return;
+
+err_free_mbufs:
+ for (int i = 0; i < nr_rx_bufs; i++)
+ rte_pktmbuf_free(rx_bufs[i]);
+
+ UPDATE_APP_STAT(drop_frame, nr_rx_bufs);
+ return;
+}
+
+
+void sc_thread_rx_loop(struct sc_instance * instance,
+ struct sc_thread_instance * tinstance)
+{
PERF_BEGIN(sc_rx_loop_all);
- int nr_rx_burst = instance->sz_rx_burst;
-
- for(unsigned int i =0; i < tinstance->nr_devices; i++)
+
+ for (unsigned int i = 0; i < tinstance->nr_devices; i++)
{
- mr_devq_t * devq;
- devq = tinstance->rt_dev[i].devq;
-
- uint16_t nr_rx_bufs = rte_eth_rx_burst(devq->port_id,
- devq->rx_queue_id, rx_bufs, nr_rx_burst);
-
- // û�����ݰ�ֱ������
- if (unlikely(nr_rx_bufs == 0)) continue;
-
- int nr_rx_bufs_len = pktslen(rx_bufs, nr_rx_bufs);
- UPDATE_DEV_STAT(dev_rx_frame, devq->port_id, nr_rx_bufs);
- UPDATE_DEV_STAT(dev_rx_bit, devq->port_id, nr_rx_bufs_len);
- UPDATE_APP_STAT(rx_frame, nr_rx_bufs);
- UPDATE_APP_STAT(rx_byte, nr_rx_bufs_len);
-
- // �������ݰ����طֵ�ʹ�õ�Hashֵ
- distributer_hash_caculate(instance->distmode,
- rx_bufs, nr_rx_bufs, hash_result);
-
- // ����VNode�У��ַ�����Ӧ��
- struct vnodeman_attach_desc * attach_desc;
- attach_desc = tinstance->rt_dev[i].rxvnode_desc;
- vnode_enqueue_burst_with_hash(attach_desc->prod, &vnodeman_ops,
- attach_desc->queue_id, (void **)rx_bufs, hash_result, nr_rx_bufs);
+ __rx_loop_one_device(instance, tinstance,
+ &tinstance->rt_dev[i], instance->sz_rx_burst);
}
-
+
PERF_END(sc_rx_loop_all);
return;
}
void sc_thread_tx_loop(struct sc_instance * instance,
- struct mr_thread_ctx * tctx, struct sc_thread_instance * tinstance)
+ struct sc_thread_instance * tinstance)
{
return;
}
void sc_thread_timer_loop(struct sc_instance * instance,
- struct mr_thread_ctx * tctx, struct sc_thread_instance * tinstance)
+ struct sc_thread_instance * tinstance)
{
return;
} \ No newline at end of file
diff --git a/slave/CMakeLists.txt b/slave/CMakeLists.txt
index 1ff394b..3684199 100644
--- a/slave/CMakeLists.txt
+++ b/slave/CMakeLists.txt
@@ -6,7 +6,7 @@ include_directories(${DPDK_INCLUDE_DIR})
include_directories(include)
add_definitions(${DPDK_C_PREDEFINED})
-add_library(marsio src/mrlib.c src/rawio.c src/rtdev.c)
+add_library(marsio src/marsio.c src/rawio.c)
target_link_libraries(marsio ${DPDK_LIBRARY} MESA_prof_load_static)
target_link_libraries(marsio rt pthread dl core)
target_include_directories(marsio INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/include/") \ No newline at end of file
diff --git a/slave/include/mrlib.h b/slave/include/mrlib.h
index 03d41de..105f25b 100644
--- a/slave/include/mrlib.h
+++ b/slave/include/mrlib.h
@@ -5,9 +5,11 @@ extern "C" {
#endif
#include <stdio.h>
-int mrlib_init(const char * progsym, FILE * logstream);
-int mrlib_destory();
-int mrlib_thread_init();
+
+int marsio_init(const char * appsym, uint64_t coremask, unsigned autoexit, FILE * logstream);
+int marsio_thread_init();
+int marsio_destory();
+
extern struct mrlib_instance * instance;
#ifdef __cplusplus
diff --git a/slave/include/mrlib_common.h b/slave/include/mrlib_common.h
index 229a525..0bc8a7a 100644
--- a/slave/include/mrlib_common.h
+++ b/slave/include/mrlib_common.h
@@ -3,30 +3,17 @@
#include <mr_common.h>
#include <mr_device.h>
-struct mrlib_rt_device
-{
- mr_dev_t * dev;
- struct vnodeman_attach_desc * rxvnode_desc[MR_MAX_NR_THREAD];
- struct vnodeman_attach_desc * txvnode_desc[MR_MAX_NR_THREAD];
-};
+struct __raw_socket;
+TAILQ_HEAD(raw_socket_list, __raw_socket);
struct mrlib_instance
{
- char progsym[MR_SYMBOL_MAX];
- unsigned int nr_rt_device;
- struct mrlib_rt_device * rt_device;
+ /* Ӧ������ */
+ char appsym[MR_SYMBOL_MAX];
+ /* �򿪵�ԭʼ�׽��־�� */
+ struct raw_socket_list raw_socket_list;
};
-/* ȡVNode�ڵ㣬RXVnode�ڵ�attach���� */
-struct vnodeman_attach_desc * rtdev_attach_rxvnode(
- const char * appsym, const char * devsym);
-
-/* ȡVNode�ڵ㣬TXVnode�ڵ�attach���� */
-struct vnodeman_attach_desc * rtdev_attach_txvnode(
- const char * appsym, const char * devsym);
-
-struct mrlib_rt_device * rtdev_lookup(struct mrlib_instance * instance, const char * devsym);
-
/* ��־λ���Ƿ��Ѿ������˳�ʼ��*/
extern int __mrlib_inited;
/* ��־λ�����߳��Ƿ��Ѿ������˳�ʼ�� */
diff --git a/slave/src/mrlib.c b/slave/src/marsio.c
index de3b876..6fd019e 100644
--- a/slave/src/mrlib.c
+++ b/slave/src/marsio.c
@@ -2,13 +2,12 @@
#include <stdlib.h>
#include <assert.h>
#include <rte_log.h>
-#include <mr_ctx.h>
#include <mr_common.h>
-#include <mr_procman.h>
#include <mr_core.h>
#include <mrlib.h>
#include <mrlib_common.h>
-#include <rte_ip_frag.h>
+#include <rte_malloc.h>
+#include <mr_runtime.h>
/* ��־λ���Ƿ��Ѿ������˳�ʼ��*/
int __mrlib_inited = 0;
@@ -19,8 +18,6 @@ struct mrlib_instance * instance = NULL;
#define MR_LIB_MAX_EAL_ARGC 128
-extern int rtdev_slave_init(struct mrlib_instance * instance);
-
/* �Command���� */
static void __write_arg(char * eal_argv[], unsigned int * eal_argc,
unsigned int max_argc, const char * value)
@@ -55,13 +52,14 @@ static void mrlib_stage_eal_init()
static void mrlib_slave_log_ready(FILE * logstream)
{
if (logstream == NULL) logstream = stderr;
- rte_openlog_stream(stderr);
+ rte_openlog_stream(logstream);
}
-static int mrlib_slave_procinfo_ready(const char * progsym)
+static int mrlib_slave_appinfo_register(const char * progsym,
+ uint64_t coremask, unsigned autoexit)
{
- int ret = 0;
- ret = procman_register_myself(progsym);
+ // ע��Ӧ��
+ int ret = mr_app_register(progsym, coremask, autoexit);
if(ret < 0)
{
MR_LOG(ERR, MRLIB, "Mrlib, SlaveProcInfoReady, "
@@ -71,15 +69,19 @@ static int mrlib_slave_procinfo_ready(const char * progsym)
MR_LOG(INFO, MRLIB, "Mrlib, SlaveProcInfoReady, "
"Process %s register success. \n", progsym);
+
+ // ע����Ŀ��Slave���
+ struct mr_global_ctx * g_ctx = mr_global_ctx_get();
+ mr_core_default_instance_set(g_ctx->ctx_core);
return 0;
}
-static int mrlib_slave_instance_ready(const char * progsym)
+static int mrlib_slave_instance_init(const char * progsym)
{
// ������̵�Privָ�벻Ϊ�գ�˵����ǰ���й����ָ�������
- if (mr_proc_ctx_get()->priv != NULL)
+ if (mr_app_priv_get() != NULL)
{
- instance = mr_proc_ctx_get()->priv;
+ instance = mr_app_priv_get();
return 0;
}
@@ -88,43 +90,36 @@ static int mrlib_slave_instance_ready(const char * progsym)
_instance = rte_zmalloc(NULL, sizeof(struct mrlib_instance), 0);
MR_CHECK(_instance != NULL, "Cannot alloc memory for mrlib instance");
- snprintf(_instance->progsym, sizeof(instance->progsym),
- "%s", progsym);
-
- // д��ȫ�ֱ���
+ snprintf(_instance->appsym, sizeof(instance->appsym), "%s", progsym);
+ TAILQ_INIT(&_instance->raw_socket_list);
instance = _instance;
- mr_proc_ctx_get()->priv = _instance;
+ mr_app_priv_set(instance);
return 0;
}
-int mrlib_init(const char * progsym, FILE * logstream)
+int marsio_init(const char * appsym, uint64_t coremask,
+ unsigned autoexit, FILE * logstream)
{
int ret = 0;
mrlib_stage_eal_init();
mrlib_slave_log_ready(logstream);
- mr_global_ctx_slave_init();
- mr_global_cfg_slave_init();
- mr_core_stage_slaveinit();
-
- ret = mrlib_slave_procinfo_ready(progsym);
- if (ret < 0) return ret;
- ret = mrlib_slave_instance_ready(progsym);
+ ret = mrlib_slave_appinfo_register(appsym, coremask, autoexit);
if (ret < 0) return ret;
- ret = rtdev_slave_init(instance);
+ ret = mrlib_slave_instance_init(appsym);
if (ret < 0) return ret;
-
+
__mrlib_inited = 1;
return 0;
}
-int mrlib_thread_init()
+int marsio_thread_init()
{
- procman_thread_register_myself();
+ mr_thread_register();
return 0;
}
-int mrlib_destory()
+int marsio_destory()
{
return 0;
} \ No newline at end of file
diff --git a/slave/src/rawio.c b/slave/src/rawio.c
index b58fe23..395ddf9 100644
--- a/slave/src/rawio.c
+++ b/slave/src/rawio.c
@@ -2,66 +2,215 @@
#include <mr_rawio.h>
#include <mr_vnode.h>
#include <mr_vman.h>
+#include <mr_stat.h>
+#include <mr_rtdev.h>
+#include <rte_malloc.h>
#include <mrlib_common.h>
-#include <mrlib.h>
-#include "mr_stat.h"
+#include <mr_rtdev.h>
+#include <mr_runtime.h>
-raw_socket_t * marsio_raw_socket(const char * dev)
+extern struct mrlib_instance * instance;
+
+struct __raw_socket
+{
+ // ������
+ TAILQ_ENTRY(__raw_socket) next;
+ // �豸������
+ char devsym[MR_SYMBOL_MAX];
+ // Raw�ӿڶ������߳���
+ unsigned int nr_rxstream;
+ // Raw�ӿ�д�����߳���
+ unsigned int nr_txstream;
+ // ����ʱ�豸�����������ձ��IJࣩ
+ struct mr_rtdev_stream * rx_rt_streams[MR_SID_MAX];
+ // ����ʱ�豸���������������IJࣩ
+ struct mr_rtdev_stream * tx_rt_streams[MR_SID_MAX];
+};
+
+// �򿪵�Socket��¼����ɾ����������Ѿ��򿪵�Socket��¼�����������û��ظ�����ɴ���
+static struct __raw_socket * raw_socket_list_query(struct mrlib_instance * instance,
+ const char * devsym)
{
- if (instance == NULL || instance->rt_device == NULL) return NULL;
- return (raw_socket_t *)rtdev_lookup(instance, dev);
+ struct __raw_socket * raw_socket_iter;
+ TAILQ_FOREACH(raw_socket_iter, &instance->raw_socket_list, next)
+ {
+ if (strncmp(raw_socket_iter->devsym, devsym, sizeof(raw_socket_iter->devsym)) == 0)
+ return raw_socket_iter;
+ }
+ return NULL;
}
-int marsio_raw_recv(raw_socket_t * socket, struct rte_mbuf * mbufs[], int nr_max_mbufs)
+static void raw_socket_list_join(struct mrlib_instance * instance, struct __raw_socket * socket)
{
- struct mr_thread_ctx * tctx = mr_thread_ctx_get();
- if (unlikely(tctx == NULL))
+ TAILQ_INSERT_TAIL(&instance->raw_socket_list, socket, next);
+ return;
+}
+
+static void raw_socket_list_remove(struct mrlib_instance * instance, struct __raw_socket * socket)
+{
+ TAILQ_REMOVE(&instance->raw_socket_list, socket, next);
+ return;
+}
+
+int marsio_raw_close(raw_socket_t * socket)
+{
+ struct __raw_socket * _socket = (struct __raw_socket *)socket;
+ raw_socket_list_remove(instance, (struct __raw_socket *)socket);
+
+ for (int i = 0; i < RTE_DIM(_socket->rx_rt_streams); i++)
+ {
+ if (_socket->rx_rt_streams[i] != NULL)
+ rt_dev_stream_close(_socket->rx_rt_streams[i]);
+ }
+
+ for(int i =0; i < RTE_DIM(_socket->tx_rt_streams); i++)
{
- MR_LOG(ERR, MRLIB, "Mrlib, MarsioRawRecv, "
- "Cannot get thread ctx, may be unregister thread, return. \n");
- return -1;
+ if (_socket->tx_rt_streams[i] != NULL)
+ rt_dev_stream_close(_socket->tx_rt_streams[i]);
}
- unsigned int sid = tctx->thread_id;
- struct mrlib_rt_device * rt_device = (struct mrlib_rt_device *)socket;
+ rt_device_close(_socket->devsym, instance->appsym);
+ return 0;
+}
+
+raw_socket_t * marsio_raw_socket(const char * devsym, unsigned int nr_rx_stream,
+ unsigned int nr_tx_stream, unsigned int flags __rte_unused)
+{
+ struct __raw_socket * socket_before;
+ struct __raw_socket * socket;
+
+ // �����ǰ�Ƿ��Ѿ���Socket
+ socket_before = raw_socket_list_query(instance, devsym);
- // �鿴��ǰ��Rxdesc�Ƿ����
- if (unlikely(rt_device->rxvnode_desc[sid] == NULL))
+ // ���Socket�Ѿ���
+ if (socket_before != NULL)
{
- rt_device->rxvnode_desc[sid] = rtdev_attach_rxvnode(
- instance->progsym, rt_device->dev->symbol);
+ // �����ǰ�򿪵IJ��������ڵ��Ƿ�һ��
+ if (socket_before->nr_rxstream != nr_rx_stream)
+ goto release_before_socket;
+ if (socket_before->nr_txstream != nr_tx_stream)
+ goto release_before_socket;
+
+ // ���ͨ���������Ѿ��򿪵�Socket���
+ return (raw_socket_t *)socket_before;
+ }
+ else
+ {
+ goto new_socket;
}
- // ����֮���ټ�飬������ǿ�˵�����󣬱��߳��޷��ձ�
- if(unlikely(rt_device->rxvnode_desc[sid] == NULL))
+ // �ͷ��Ѿ��򿪵�Socket
+release_before_socket:
+ marsio_raw_close((raw_socket_t *)socket_before);
+
+new_socket:
+ socket = rte_zmalloc(NULL, sizeof(struct __raw_socket), 0);
+ if(unlikely(socket == NULL))
{
- MR_LOG(ERR, MRLIB, "Mrlib, MarsioRawRecv, "
- "Attach currect device %s failed, check rxstream in configure file\n",
- rt_device->dev->symbol);
- return -2;
+ MR_LOG(ERR, MRLIB, "MarsioRawSocket, Cannot alloc memory for socket"
+ "(devsym=%s, nr_rx_stream=%d, nr_tx_stream=%d, flags=%x)\n",
+ devsym, nr_rx_stream, nr_tx_stream, flags);
+ goto errout;
}
- // ��Vnode����ȡ����
+ snprintf(socket->devsym, sizeof(socket->devsym), "%s", devsym);
+ socket->nr_rxstream = nr_rx_stream;
+ socket->nr_txstream = nr_tx_stream;
+
+ // ������ʱ�豸
+ int ret = rt_device_open(devsym, instance->appsym, nr_rx_stream, nr_tx_stream);
+ if(unlikely(ret < 0))
+ {
+ MR_LOG(ERR, MRLIB, "MarsioRawSocket, Open rt-device %s"
+ "(nr_rx_stream=%d, nr_tx_stream=%d, flags=%x) failed. \n",
+ devsym, nr_rx_stream, nr_tx_stream, flags);
+ goto errout;
+ }
+
+ raw_socket_list_join(instance, socket);
+ return (raw_socket_t *)socket;
+
+errout:
+ if (socket != NULL) rte_free(socket);
+ return NULL;
+}
+
+int marsio_raw_recv(raw_socket_t * socket, struct rte_mbuf * mbufs[], int nr_max_mbufs)
+{
+ unsigned int sid = mr_thread_id();
+ struct __raw_socket * _socket = (struct __raw_socket *)socket;
+ mr_thread_hook();
+
+ // �жϵ�ǰ�̶߳�Ӧ���ձ����豸���Ƿ�򿪣����û����Ҫ��
+ if(unlikely(_socket->rx_rt_streams[sid] == NULL))
+ {
+ // ������ʱ�豸���ձ�����
+ struct mr_rtdev_stream * stream = rt_dev_open_stream(_socket->devsym,
+ instance->appsym, RTDEV_FLAGS_OPEN_STREAM_RX);
+
+ // ��ʧ��
+ if(unlikely(stream == NULL))
+ {
+ MR_LOG(ERR, MRLIB, "MarsioRawRecv, Cannot open rt-device %s rxstream. \n",
+ _socket->devsym);
+ return -1;
+ }
+
+ _socket->rx_rt_streams[sid] = stream;
+ }
+
struct vnodeman_attach_desc * attach_desc;
- attach_desc = rt_device->rxvnode_desc[sid];
+ attach_desc = _socket->rx_rt_streams[sid]->rxd;
+ // ��Vnode����ȡ����
int ret = vnode_dequeue_burst(attach_desc->cons, &vnodeman_ops,
attach_desc->queue_id, (void **)mbufs, nr_max_mbufs);
UPDATE_APP_STAT(rx_frame, ret);
UPDATE_APP_STAT(rx_byte, pktslen(mbufs, ret));
-
- // ���Ϸ���
-#ifndef NDEBUG
- for (int i = 0; i < ret; i++)
- {
- rte_mbuf_sanity_check(mbufs[i], 1);
- }
-#endif
return ret;
}
+static inline hash_t __raw_send_pkt_hash(struct rte_mbuf * mbuf)
+{
+ return mbuf->hash.rss;
+}
+
int marsio_raw_send(raw_socket_t * socket, struct rte_mbuf * mbufs[], int nr_mbufs)
{
- return 0;
+ unsigned int sid = mr_thread_id();
+ struct __raw_socket * _socket = (struct __raw_socket *)socket;
+ mr_thread_hook();
+
+ // �жϵ�ǰ�̶߳�Ӧ���ձ����豸���Ƿ�򿪣����û����Ҫ��
+ if (unlikely(_socket->tx_rt_streams[sid] == NULL))
+ {
+ struct mr_rtdev_stream * stream = rt_dev_open_stream(_socket->devsym,
+ instance->appsym, RTDEV_FLAGS_OPEN_STREAM_TX);
+
+ if (unlikely(stream == NULL))
+ {
+ MR_LOG(ERR, MRLIB, "MarsioRawSend, Cannot open rt-device %s rxstream. \n",
+ _socket->devsym);
+ return -1;
+ }
+
+ _socket->tx_rt_streams[sid] = stream;
+ }
+
+ // ���㷢�͹�ϣֵ
+ hash_t mbufs_hash[MR_BURST_MAX];
+ for (int i = 0; i < nr_mbufs; i++)
+ mbufs_hash[i] = __raw_send_pkt_hash(mbufs[i]);
+
+ struct vnodeman_attach_desc * attach_desc;
+ attach_desc = _socket->tx_rt_streams[sid]->txd;
+
+ //TODO: ������
+ int ret = vnode_enqueue_burst_with_hash(attach_desc->prod, &vnodeman_ops,
+ attach_desc->queue_id, (void **)mbufs, mbufs_hash, nr_mbufs);
+
+ UPDATE_APP_STAT(tx_frame, nr_mbufs);
+ UPDATE_APP_STAT(tx_byte, pktslen(mbufs, ret));
+ return ret;
} \ No newline at end of file
diff --git a/slave/src/rtdev.c b/slave/src/rtdev.c
deleted file mode 100644
index 6424062..0000000
--- a/slave/src/rtdev.c
+++ /dev/null
@@ -1,100 +0,0 @@
-
-/* ����ʱ�豸����������Slave�ϻ���VNode�������豸������
- * Author : Qiuwen Lu
- * Date : 2016-09-09
- */
-
-#include <rte_malloc.h>
-#include <mr_device.h>
-#include <mr_vman.h>
-#include <mrlib.h>
-#include <mrlib_common.h>
-#include <assert.h>
-
-
-#define MRLIB_MAX_RTDEVICE RTE_MAX_ETHPORTS
-
-#define __PATTERN_DEV_RX "%s-RX"
-#define __PATTERN_DEV_TX "%s-TX"
-#define __PATTERN_PROC_SERVICE "%s"
-#define __PATTERN_CONS_SERVICE "%s"
-#define __PATTERN_PROD_APP "%s"
-#define __PATTERN_CONS_APP "%s"
-
-/* ȡVNode�ڵ㣬RXVnode�ڵ�attach���� */
-struct vnodeman_attach_desc * rtdev_attach_rxvnode(
- const char * appsym, const char * devsym)
-{
- struct vnodeman_attach_desc * desc;
- char vnodesym[MR_SYMBOL_MAX];
- char conssym[MR_SYMBOL_MAX];
-
- snprintf(vnodesym, sizeof(vnodesym), __PATTERN_DEV_RX, devsym);
- snprintf(conssym, sizeof(conssym), __PATTERN_CONS_APP, appsym);
- desc = mr_vnodeman_consumer_attach(vnodesym, conssym);
- return desc;
-}
-
-/* ȡVNode�ڵ㣬TXVnode�ڵ�attach���� */
-struct vnodeman_attach_desc * rtdev_attach_txvnode(
- const char * appsym, const char * devsym)
-{
- struct vnodeman_attach_desc * desc;
- char vnodesym[MR_SYMBOL_MAX];
- char prodsym[MR_SYMBOL_MAX];
-
- snprintf(vnodesym, sizeof(vnodesym), __PATTERN_DEV_TX, devsym);
- snprintf(prodsym, sizeof(prodsym), __PATTERN_PROD_APP, appsym);
- desc = mr_vnodeman_producer_attach(vnodesym, prodsym);
- return desc;
-}
-
-int rtdev_slave_init(struct mrlib_instance * instance)
-{
- if (instance->rt_device != NULL) return 0;
-
- // ���ȫ�����õ��豸����
- mr_dev_t * devlist[MRLIB_MAX_RTDEVICE];
- int nr_devlist = mr_device_list(devlist, MRLIB_MAX_RTDEVICE, 0);
- assert(nr_devlist >= 0);
-
- // ����RTDevice�ڴ�Ŀռ�
- instance->rt_device = rte_zmalloc(NULL, sizeof(struct mrlib_rt_device) *
- nr_devlist, 0);
- instance->nr_rt_device = nr_devlist;
-
- for (int i = 0; i < nr_devlist; i++)
- {
- instance->rt_device[i].dev = devlist[i];
- }
-
- return 0;
-}
-
-int rtdev_lookup_id(struct mrlib_instance * instance, const char * devsym)
-{
- if (unlikely(instance->rt_device == NULL))
- {
- MR_LOG(WARNING, MRLIB, "MrLib, RtDevLookup, "
- "RtDevice handle is null, failed.\n");
- return -1;
- }
-
- for (int i = 0; i < instance->nr_rt_device; i++)
- {
- struct mrlib_rt_device * rt_dev;
- rt_dev = &instance->rt_device[i];
-
- if (strncmp(rt_dev->dev->symbol, devsym, sizeof(rt_dev->dev->symbol)) == 0)
- return i;
- }
-
- return -2;
-}
-
-struct mrlib_rt_device * rtdev_lookup(struct mrlib_instance * instance, const char * devsym)
-{
- int rtdev_id = rtdev_lookup_id(instance, devsym);
- if (rtdev_id < 0) return NULL;
- return &instance->rt_device[rtdev_id];
-} \ No newline at end of file
diff --git a/stack/CMakeLists.txt b/stack/CMakeLists.txt
new file mode 100644
index 0000000..fb4feb1
--- /dev/null
+++ b/stack/CMakeLists.txt
@@ -0,0 +1,12 @@
+find_package(DPDK REQUIRED)
+include_directories(${CMAKE_SOURCE_DIR}/include)
+include_directories(${CMAKE_SOURCE_DIR}/include/extern)
+include_directories(${CMAKE_SOURCE_DIR}/include/internal)
+include_directories(${DPDK_INCLUDE_DIR})
+
+add_definitions(${DPDK_C_PREDEFINED})
+include_directories(include)
+add_library(stack src/stack.c src/device.c src/neigh.c src/arp.c)
+target_link_libraries(stack MESA_prof_load_static mruntime core)
+target_link_libraries(stack rt pthread dl)
+target_include_directories(stack INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/include/") \ No newline at end of file
diff --git a/stack/include/port_bitmap.h b/stack/include/port_bitmap.h
new file mode 100644
index 0000000..4391b76
--- /dev/null
+++ b/stack/include/port_bitmap.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2016 Intel Corporation.
+ * 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 _PORT_BITMAP_H_
+#define _PORT_BITMAP_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <limits.h>
+#include <rte_common.h>
+
+/*
+ * Simple implementation of bitmap for all possible UDP ports [0-UINT16_MAX].
+ */
+
+#define MAX_PORT_NUM (UINT16_MAX + 1)
+
+#define PORT_BLK(p) ((p) / (sizeof(uint32_t) * CHAR_BIT))
+#define PORT_IDX(p) ((p) % (sizeof(uint32_t) * CHAR_BIT))
+
+#define MAX_PORT_BLK PORT_BLK(MAX_PORT_NUM)
+
+struct portmap
+{
+ uint32_t nb_set; /* number of bits set. */
+ uint32_t blk; /* last block with free entry. */
+ uint32_t bm[MAX_PORT_BLK];
+};
+
+static inline void portmap_init(struct portmap *pbm, uint32_t blk)
+{
+ pbm->bm[0] = 1;
+ pbm->nb_set = 1;
+ pbm->blk = blk;
+}
+
+static inline void portmap_set(struct portmap *pbm, uint16_t port)
+{
+ uint32_t i, b, v;
+
+ i = PORT_BLK(port);
+ b = 1 << PORT_IDX(port);
+ v = pbm->bm[i];
+ pbm->bm[i] = v | b;
+ pbm->nb_set += (v & b) == 0;
+}
+
+static inline void portmap_clear(struct portmap *pbm, uint16_t port)
+{
+ uint32_t i, b, v;
+
+ i = PORT_BLK(port);
+ b = 1 << PORT_IDX(port);
+ v = pbm->bm[i];
+ pbm->bm[i] = v & ~b;
+ pbm->nb_set -= (v & b) != 0;
+}
+
+
+static inline uint32_t portmap_check(const struct portmap *pbm, uint16_t port)
+{
+ uint32_t i, v;
+
+ i = PORT_BLK(port);
+ v = pbm->bm[i] >> PORT_IDX(port);
+ return v & 1;
+}
+
+static inline uint16_t portmap_find_range(struct portmap *pbm,
+ uint32_t start_blk, uint32_t end_blk)
+{
+ uint32_t i, v;
+ uint16_t p;
+
+ if (pbm->nb_set == MAX_PORT_NUM)
+ return 0;
+
+ p = 0;
+ for (i = start_blk; i != end_blk; i++) {
+ i %= RTE_DIM(pbm->bm);
+ v = pbm->bm[i];
+ if (v != UINT32_MAX) {
+ for (p = i * (sizeof(pbm->bm[0]) * CHAR_BIT);
+ (v & 1) != 0; v >>= 1, p++)
+ ;
+
+ pbm->blk = i;
+ break;
+ }
+ }
+ return p;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _PORT_BITMAP_H_ */
diff --git a/stack/include/sk_device.h b/stack/include/sk_device.h
new file mode 100644
index 0000000..0af22e7
--- /dev/null
+++ b/stack/include/sk_device.h
@@ -0,0 +1,124 @@
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <mr_common.h>
+#include <sys/queue.h>
+#include <rte_ether.h>
+#include <mr_device.h>
+#include <netinet/in.h>
+
+struct sk_dev_param
+{
+ // �豸����
+ char symbol[MR_SYMBOL_MAX];
+ // MTU
+ unsigned int mtu;
+ // IP��ַ
+ struct in_addr in_addr;
+ // ��������
+ struct in_addr in_mask;
+ // ����
+ struct in_addr in_gateway;
+ // MAC��ַ
+ struct ether_addr mac_addr;
+ // RawЭ��ʹ��
+ unsigned int en_raw;
+ // TCPЭ��ʹ��
+ unsigned int en_tcp;
+ // UDPЭ��ʹ��
+ unsigned int en_udp;
+ // ARPЭ��ʹ��
+ unsigned int en_arp;
+ // ICMPЭ��ʹ��
+ unsigned int en_icmp;
+ // ��ѭ����������С
+ unsigned int sz_rx_loop_buffer;
+ // ��ѭ����������С
+ unsigned int sz_tx_loop_buffer;
+};
+
+// �豸������Ϣ
+struct sk_dev_info
+{
+ // Э��ջCTX
+ struct mr_stack_instance * instance_;
+ // �豸������һ��
+ TAILQ_ENTRY(sk_dev_info) next;
+ // �豸����
+ struct sk_dev_param param;
+ // �豸����
+ char symbol[MR_SYMBOL_MAX];
+ // �Ƿ�����
+ unsigned int enable;
+ // MTU��С
+ unsigned int mtu;
+ // �Ƿ����û���ģʽ
+ unsigned int promisc;
+ // ����IP��ַ
+ struct in_addr in_addr;
+ // ��������
+ struct in_addr in_mask;
+ // ����MAC��ַ
+ struct ether_addr mac_addr;
+};
+
+// �豸��������ӽ���ͨ�ã�
+struct sk_dev_desc
+{
+
+#define SK_DEV_MODE_SERV 0
+#define SK_DEV_MODE_APP 1
+
+ // ������һ��
+ TAILQ_ENTRY(sk_dev_desc) next;
+ // ģʽ�������̻�ӽ��̣�
+ unsigned int mode;
+ // �豸��Ϣ���
+ struct sk_dev_info * dev_info;
+ // ��ѭ�����Ļ��������ڷ����������д�����
+ struct rte_ring * rx_loop_buffer[MR_SID_MAX];
+ // ��ѭ�����Ļ����������ձ��������д�����
+ struct rte_ring * tx_loop_buffer[MR_SID_MAX];
+ // TCP�� Rt-Device Stream
+ struct mr_rtdev_stream * tcp_rtdev_stream[MR_SID_MAX];
+ // UDP�� Rt-Device Stream
+ struct mr_rtdev_stream * udp_rtdev_stream[MR_SID_MAX];
+};
+
+TAILQ_HEAD(sk_dev_info_list, sk_dev_info);
+TAILQ_HEAD(sk_dev_desc_list, sk_dev_desc);
+
+struct sk_dev_info * mr_stack_device_lookup(struct mr_stack_instance * instance, const char * symbol);
+
+// �豸��Ϣ������
+int mr_stack_device_iterate(struct mr_stack_instance * instance, struct sk_dev_info ** dev_info);
+
+// ����һ��Э��ջ�豸
+int mr_stack_device_create(struct mr_stack_instance * instance, struct sk_dev_param * param);
+
+// ����Э��ջ�豸
+int mr_stack_device_destory(struct sk_dev_info * devinfo);
+
+// ����Э��ջ��IP��ַ
+int mr_stack_device_set_inaddr(struct sk_dev_info * dev_info, struct in_addr in_addr,
+ struct in_addr in_mask);
+
+// ��ȡЭ��ջ�豸��IP��ַ
+int mr_stack_device_get_inaddr(struct sk_dev_info * devinfo,
+ struct in_addr * in_addr, struct in_addr * in_mask);
+
+// ����Э��ջ�豸��MTU
+int mr_stack_device_set_mtu(struct sk_dev_info * devinfo, unsigned int mtu);
+// ��ȡЭ��ջ�豸��MTU
+int mr_stack_device_get_mtu(struct sk_dev_info * devinfo);
+// �����豸
+int mr_stack_device_enable(struct sk_dev_info * devinfo);
+// �����豸
+int mr_stack_device_disable(struct sk_dev_info * devinfo);
+
+#ifdef __cplusplus
+}
+#endif \ No newline at end of file
diff --git a/stack/include/sk_neigh.h b/stack/include/sk_neigh.h
new file mode 100644
index 0000000..934ac9e
--- /dev/null
+++ b/stack/include/sk_neigh.h
@@ -0,0 +1,82 @@
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rte_rwlock.h>
+#include <rte_atomic.h>
+#include <rte_timer.h>
+#include <rte_ether.h>
+
+#define SK_NEIGH_MAX_HDR 0x60
+
+struct sk_neigh_table
+{
+ struct rte_timer * event_timer;
+ struct rte_hash * neigh_tbl;
+ rte_rwlock_t neigh_tbl_lock;
+};
+
+struct sk_dest_info
+{
+ uint16_t mtu;
+ uint8_t l2_len;
+ uint8_t l3_len;
+ uint8_t hdr[SK_NEIGH_MAX_HDR];
+};
+
+#define NUD_INCOMPLETE 0x01
+#define NUD_REACHABLE 0x02
+#define NUD_STALE 0x04
+#define NUD_DELAY 0x08
+#define NUD_PROBE 0x10
+#define NUD_FAILED 0x20
+#define NUD_NOARP 0x40
+#define NUD_PERMANENT 0x80
+#define NUD_NONE 0x00
+
+#define NUD_IN_TIMER ( NUD_INCOMPLETE | NUD_REACHABLE | NUD_DELAY | NUD_PROBE )
+#define NUD_VALID ( NUD_PERMANENT | NUD_NOARP | NUD_REACHABLE | NUD_PROBE | NUD_STALE | NUD_DELAY )
+#define NUD_CONNECTED ( NUD_PERMANENT | NUD_NOARP | NUD_REACHABLE )
+
+struct sk_neighbour
+{
+ // ���ü���
+ rte_atomic16_t refcnt;
+ // ������
+ rte_rwlock_t rwlock;
+ // ��ʱ��
+ struct rte_timer timer;
+ // ״̬
+ unsigned int state;
+ // ��Ч��־λ
+ unsigned int dead;
+ // ������ʱ��
+ unsigned int update;
+ // �����豸
+ struct sk_dev_desc * dev;
+ // ��ѯ����
+ struct in_addr in_addr;
+ // ��ѯ���
+ struct ether_addr ether_addr;
+ // ���������Ϣ
+ struct sk_dest_info dest_info;
+};
+
+int neigh_update(struct sk_neighbour * neigh, const struct ether_addr * lladdr,
+ uint8_t state, uint32_t flags);
+
+int neigh_event_send(struct sk_neighbour * neigh, struct rte_mbuf * mbuf);
+
+struct sk_neighbour * neigh_create(struct sk_neigh_table * tbl,
+ struct in_addr in_addr, struct sk_dev_desc * dev);
+
+struct sk_neighbour * neigh_lookup(struct sk_neigh_table * tbl,
+ const void * pkey, int hold);
+
+int neigh_tbl_init(struct sk_neigh_table * tbl, const char * symbol, unsigned int nr_entries);
+
+#ifdef __cplusplus
+}
+#endif \ No newline at end of file
diff --git a/stack/include/sk_protocol_arp.h b/stack/include/sk_protocol_arp.h
new file mode 100644
index 0000000..fd20284
--- /dev/null
+++ b/stack/include/sk_protocol_arp.h
@@ -0,0 +1,22 @@
+#pragma once
+
+int protocol_arp_init(struct mr_stack_instance * instance);
+
+int protocol_arp_deinit(struct mr_stack_instance * instance);
+
+int protocol_arp_slave_init(struct mr_stack_instance * instance,
+ struct mr_stack_slave_instance * slave_instance);
+
+int protocol_arp_slave_deinit(struct mr_stack_instance * instance,
+ struct mr_stack_slave_instance * slave_instance);
+
+int protocol_arp_dev_init(struct sk_dev_desc * dev);
+
+int protocol_arp_dev_deinit(struct sk_dev_desc * dev);
+
+int protocol_arp_slave_dev_init(struct sk_dev_desc * dev);
+
+int protocol_arp_slave_dev_deinit(struct sk_dev_desc * dev);
+
+void protocol_serv_arp_entry(struct sk_dev_desc* dev_desc,
+ thread_id_t sid, struct rte_mbuf* mbufs_in[], int nr_mbufs_in); \ No newline at end of file
diff --git a/stack/include/sk_protocol_icmp.h b/stack/include/sk_protocol_icmp.h
new file mode 100644
index 0000000..11790ca
--- /dev/null
+++ b/stack/include/sk_protocol_icmp.h
@@ -0,0 +1,6 @@
+#pragma once
+
+#include <mr_common.h>
+
+void protocol_serv_icmp_entry(struct sk_dev_desc* dev_desc, thread_id_t sid,
+ struct rte_mbuf* mbufs_in[], int nr_mbufs_in);
diff --git a/stack/include/sk_protocol_tcp.h b/stack/include/sk_protocol_tcp.h
new file mode 100644
index 0000000..fb24bb2
--- /dev/null
+++ b/stack/include/sk_protocol_tcp.h
@@ -0,0 +1,4 @@
+#pragma once
+
+void protocol_serv_tcp_entry(struct sk_dev_desc* dev_desc, thread_id_t sid,
+ struct rte_mbuf* mbufs_in[], int nr_mbufs_in); \ No newline at end of file
diff --git a/stack/include/sk_protocol_udp.h b/stack/include/sk_protocol_udp.h
new file mode 100644
index 0000000..c416278
--- /dev/null
+++ b/stack/include/sk_protocol_udp.h
@@ -0,0 +1,4 @@
+#pragma once
+
+void protocol_serv_udp_entry(struct sk_dev_desc* dev_desc,
+ thread_id_t sid, struct rte_mbuf* mbufs_in[], int nr_mbufs_in); \ No newline at end of file
diff --git a/stack/include/sk_stack.h b/stack/include/sk_stack.h
new file mode 100644
index 0000000..8297502
--- /dev/null
+++ b/stack/include/sk_stack.h
@@ -0,0 +1,48 @@
+#pragma once
+#include <sk_device.h>
+
+#ifndef MR_STACK_DEFAULT_SZ_DELIVER_RING
+#define MR_STACK_DEFAULT_SZ_DELIVER_RING 1024
+#endif
+
+#ifndef MR_STACK_DEFAULT_SZ_DELIVER_BUFFER
+#define MR_STACK_DEFAULT_SZ_DELIVER_BUFFER 128
+#endif
+
+#ifndef MR_STACK_DEFAULT_SZ_LOOP_RING
+#define MR_STACK_DEFAULT_SZ_LOOP_RING 1024
+#endif
+
+struct mr_stack_param
+{
+ // ��������
+ char servsym[MR_SYMBOL_MAX];
+ // �����߳�����������ע��Э��ջ�̡߳���Э��ջȡ���ĵ��̣߳�
+ unsigned int nr_serv_thread;
+ // �ַ����д�С
+ unsigned int sz_deliver_ring;
+ // �ַ����л�������С
+ unsigned int sz_deliver_buffer;
+ // ��ѭ�����д�С
+ unsigned int sz_loop_ring;
+};
+
+struct mr_stack_instance
+{
+ // Э��ջ���в���
+ struct mr_stack_param param;
+ // Э��ջ�豸��Ϣ
+ struct sk_dev_info_list dev_info_list;
+ // Э��ջ�豸���
+ struct sk_dev_desc_list dev_desc_list;
+};
+
+struct mr_stack_slave_instance
+{
+ // Э��ջ�豸���
+ struct sk_dev_desc_list dev_desc_list;
+};
+
+struct mr_stack_instance * mr_stack_instance_create(struct mr_stack_param * param);
+
+struct mr_stack_slave_instance * mr_stack_slave_create(); \ No newline at end of file
diff --git a/stack/src/device.c b/stack/src/device.c
new file mode 100644
index 0000000..bff5a05
--- /dev/null
+++ b/stack/src/device.c
@@ -0,0 +1,196 @@
+/* 简单数据通信用户态协议栈——设备管理器
+*
+* 本模块提供协议栈使用的设备管理功能。负责管理真实(或虚拟)设备之:
+* A. IP地址、子网掩码、默认网关等网络层信息;
+* B. MTU、VLAN等数据链路层信息。
+*
+* \author Lu Qiuwen<[email protected]>
+* \date 2016-10-18
+*/
+
+#include <sys/queue.h>
+#include <rte_ether.h>
+#include <mr_rtdev.h>
+#include <mr_rawio.h>
+#include <rte_malloc.h>
+
+#include <sk_stack.h>
+#include <sk_device.h>
+#include <assert.h>
+
+
+struct sk_dev_info * mr_stack_device_lookup(struct mr_stack_instance * instance, const char * symbol)
+{
+ return NULL;
+}
+
+int mr_stack_device_iterate(struct mr_stack_instance * instance, struct sk_dev_info ** dev_info)
+{
+ // 迭代器为空,从头开始迭代,否则查找迭代器下一个对象
+ if(*dev_info == NULL)
+ {
+ *dev_info = TAILQ_FIRST(&instance->dev_info_list);
+ return 0;
+ }
+ else
+ {
+ *dev_info = TAILQ_NEXT(*dev_info, next);
+ }
+
+ // 迭代到尾部,返回错误码
+ if (*dev_info == NULL) return -ENOENT;
+ return 0;
+}
+
+// 创建一个协议栈设备
+int mr_stack_device_create(struct mr_stack_instance * instance, struct sk_dev_param * param)
+{
+ // 检查设备是否已经存在,不允许重复创建
+ struct sk_dev_info * devinfo = mr_stack_device_lookup(instance, param->symbol);
+ if(devinfo != NULL)
+ {
+ MR_LOG(INFO, STACK, "StackCreateDevice, StackDevice %s has been created. failed. \n",
+ param->symbol);
+ return -EEXIST;
+ }
+
+ // 申请Info结构体的空间
+ devinfo = rte_zmalloc(NULL, sizeof(struct sk_dev_info), 0);
+ if(unlikely(devinfo == NULL))
+ {
+ MR_LOG(WARNING, STACK, "StackCreateDevice, Cannot alloc memory for device info.\n");
+ return -ENOMEM;
+ }
+
+ // 写参数
+ snprintf(devinfo->symbol, sizeof(devinfo->symbol), "%s", param->symbol);
+ devinfo->param = *param;
+ devinfo->instance_ = instance;
+ devinfo->in_addr = param->in_addr;
+ devinfo->in_mask = param->in_mask;
+ devinfo->mac_addr = param->mac_addr;
+ devinfo->mtu = param->mtu;
+ devinfo->promisc = 0;
+
+ // 加入到协议栈设备链表中
+ TAILQ_INSERT_TAIL(&instance->dev_info_list, devinfo, next);
+ return 0;
+}
+
+// 销毁协议栈设备
+int mr_stack_device_destory(struct sk_dev_info * devinfo)
+{
+ assert(0);
+ return 0;
+}
+
+// 设置协议栈的IP地址
+int mr_stack_device_set_inaddr(struct sk_dev_info * dev_info, struct in_addr in_addr,
+ struct in_addr in_mask)
+{
+ dev_info->in_addr = in_addr;
+ dev_info->in_mask = in_mask;
+ return 0;
+}
+
+// 读取协议栈设备的IP地址
+int mr_stack_device_get_inaddr(struct sk_dev_info * devinfo,
+ struct in_addr * in_addr, struct in_addr * in_mask)
+{
+ *in_addr = devinfo->in_addr;
+ *in_mask = devinfo->in_mask;
+ return 0;
+}
+
+// 设置协议栈设备的MTU
+int mr_stack_device_set_mtu(struct sk_dev_info * devinfo, unsigned int mtu)
+{
+ devinfo->mtu = mtu;
+ return 0;
+}
+
+// 读取协议栈设备的MTU
+int mr_stack_device_get_mtu(struct sk_dev_info * devinfo)
+{
+ return devinfo->mtu;
+}
+
+// 启动设备
+int mr_stack_device_enable(struct sk_dev_info * devinfo)
+{
+ return 0;
+}
+
+// 禁用设备
+int mr_stack_device_disable(struct sk_dev_info * devinfo)
+{
+ return 0;
+}
+
+static struct sk_dev_desc * sk_dev_desc_new(struct sk_dev_info * dev_info, unsigned int mode)
+{
+ // 申请内存空间
+ struct sk_dev_desc * dev_desc = rte_zmalloc(NULL, sizeof(struct sk_dev_desc), 0);
+ if(unlikely(dev_desc == NULL))
+ {
+ MR_LOG(WARNING, STACK, "StackDevice, StackDeviceDescCreate, "
+ "Cannot alloc memory for device %s desc. Failed. \n", dev_info->symbol);
+ return NULL;
+ }
+
+ // 各线程使用的资源放在线程初始化流程中进行,这里不进行。
+ dev_desc->dev_info = dev_info;
+ return dev_desc;
+}
+
+static void sk_dev_desc_delete(struct sk_dev_desc * dev_desc)
+{
+ // TODO:stream的释放
+
+ // 释放RX侧自循环缓冲区
+ for(int i = 0; i < RTE_DIM(dev_desc->rx_loop_buffer); i++)
+ {
+ if (dev_desc->rx_loop_buffer[i] != NULL)
+ rte_ring_free(dev_desc->rx_loop_buffer[i]);
+ }
+
+ // 释放TX侧自循环缓冲区
+ for(int i = 0; i < RTE_DIM(dev_desc->tx_loop_buffer); i++)
+ {
+ if (dev_desc->tx_loop_buffer[i] != NULL)
+ rte_ring_free(dev_desc->tx_loop_buffer[i]);
+ }
+
+ rte_free(dev_desc);
+ return;
+}
+
+/* 以下为内部初始化、注销处理流程。*/
+int stack_device_init(struct mr_stack_instance * instance)
+{
+ // 创建主应用设备句柄,插入到句柄链表中
+ struct sk_dev_info * dev_info_iter;
+ struct sk_dev_desc * dev_desc_iter;
+
+ TAILQ_FOREACH(dev_info_iter, &instance->dev_info_list, next)
+ {
+ struct sk_dev_desc * dev_desc = sk_dev_desc_new(dev_info_iter, SK_DEV_MODE_SERV);
+ if (unlikely(dev_desc == NULL)) goto errout;
+ TAILQ_INSERT_TAIL(&instance->dev_desc_list, dev_desc, next);
+ }
+
+ return 0;
+
+errout:
+ TAILQ_FOREACH(dev_desc_iter, &instance->dev_desc_list, next)
+ {
+ sk_dev_desc_delete(dev_desc_iter);
+ }
+ return -1;
+}
+
+int stack_device_slave_init(struct mr_stack_instance * instance,
+ struct mr_stack_slave_instance * slave_instance)
+{
+ return 0;
+} \ No newline at end of file
diff --git a/stack/src/neigh.c b/stack/src/neigh.c
new file mode 100644
index 0000000..ac2ef3c
--- /dev/null
+++ b/stack/src/neigh.c
@@ -0,0 +1,230 @@
+/* \brief ��Э��ջ�ھ���ϵͳ
+*
+* �����������ڽ�ͨ�ŵ��������Ϣ
+*
+* \author Lu Qiuwen<[email protected]>
+* \date 2016-10-21
+*/
+
+
+#include <rte_hash.h>
+#include <rte_rwlock.h>
+#include <rte_atomic.h>
+#include <rte_ether.h>
+#include <rte_ip.h>
+#include <rte_ip_frag.h>
+#include <rte_timer.h>
+
+#include <sk_device.h>
+#include <sk_protocol_arp.h>
+#include <sk_neigh.h>
+#include <rte_cycles.h>
+#include <rte_hash_crc.h>
+
+#define __IP_VERSION_IHL(version, len) (version << 4 | len << 0)
+#define __IP_TTL 75
+
+// �����㱨��ͷ
+static inline size_t __neigh_fill_ether_hdr(uint8_t * hdr, const struct ether_addr * src_addr,
+ const struct ether_addr * dst_addr, const uint16_t next_layer_type)
+{
+ struct ether_hdr * ether_hdr = (struct ether_hdr *)hdr;
+ ether_addr_copy(src_addr, &ether_hdr->s_addr);
+ ether_addr_copy(dst_addr, &ether_hdr->d_addr);
+ ether_hdr->ether_type = htons(next_layer_type);
+ return sizeof(struct ether_hdr);
+}
+
+// ������㱨��ͷ
+static inline size_t __neigh_fill_ipv4_hdr(uint8_t * hdr, const struct in_addr * src_addr,
+ const struct in_addr * dst_addr, uint16_t total_len, uint16_t pid, uint8_t next_proto)
+{
+ struct ipv4_hdr * ip_hdr = (struct ipv4_hdr *)hdr;
+
+ ip_hdr->version_ihl = __IP_VERSION_IHL(4, sizeof(struct ipv4_hdr) / 4);
+ ip_hdr->type_of_service = 0;
+ ip_hdr->total_length = htons(total_len);
+ ip_hdr->packet_id = htons(pid);
+ ip_hdr->fragment_offset = 0;
+ ip_hdr->time_to_live = __IP_TTL;
+ ip_hdr->next_proto_id = next_proto;
+ ip_hdr->hdr_checksum = 0;
+
+ ip_hdr->src_addr = src_addr->s_addr;
+ ip_hdr->dst_addr = dst_addr->s_addr;
+ return sizeof(struct ipv4_hdr);
+}
+
+static inline void neigh_fill_destinfo(struct sk_neighbour * neigh)
+{
+ struct sk_dest_info * dest_info = &neigh->dest_info;
+ size_t ret;
+
+ ret = __neigh_fill_ether_hdr(dest_info->hdr,
+ &neigh->dev->dev_info->mac_addr, &neigh->ether_addr,
+ ETHER_TYPE_IPv4);
+ neigh->dest_info.l2_len = ret;
+
+ ret = __neigh_fill_ipv4_hdr(dest_info->hdr + ret,
+ &neigh->dev->dev_info->in_addr,
+ &neigh->in_addr, 0, 0, 0);
+ neigh->dest_info.l3_len = ret;
+ return;
+}
+
+static void neigh_destory(struct sk_neighbour * neigh)
+{
+ return;
+}
+
+static void neigh_probe(struct sk_neighbour * neigh)
+{
+ protocol_arp_request_send(neigh->dev, neigh->in_addr);
+}
+
+static inline void neigh_hold(struct sk_neighbour * neigh)
+{
+ rte_atomic16_add(&neigh->refcnt, 1);
+ return;
+}
+
+static inline void neigh_release(struct sk_neighbour * neigh)
+{
+ if (rte_atomic16_dec_and_test(&neigh->refcnt))
+ neigh_destory(neigh);
+ return;
+}
+
+static struct sk_neighbour * neigh_alloc(struct sk_neigh_table * tbl, struct sk_dev_desc * dev)
+{
+ struct sk_neighbour * neigh = rte_zmalloc(NULL, sizeof(struct sk_neighbour), 0);
+ if (unlikely(neigh == NULL))
+ {
+ MR_LOG(INFO, STACK, "NeighSystem, NeighCreate, "
+ "Cannot alloc memory for neighbor structure. \n");
+ return NULL;
+ }
+
+ rte_rwlock_init(&neigh->rwlock);
+ rte_atomic16_init(&neigh->refcnt);
+ neigh->state = NUD_NONE;
+ neigh->dead = 1;
+ neigh->update = rte_rdtsc();
+ neigh->dev = dev;
+ return neigh;
+}
+
+
+int neigh_update(struct sk_neighbour * neigh, const struct ether_addr * lladdr,
+ uint8_t state, uint32_t flags)
+{
+ rte_rwlock_write_lock(&neigh->rwlock);
+ struct sk_dev_desc * dev = neigh->dev;
+ uint8_t old_state = neigh->state;
+
+ if((old_state & NUD_REACHABLE) && (state & NUD_REACHABLE))
+ {
+ ether_addr_copy(lladdr, &neigh->ether_addr);
+ neigh_fill_destinfo(neigh);
+ neigh->dead = 0;
+ neigh->state = state;
+ }
+
+ if((old_state & NUD_INCOMPLETE ) && (state & NUD_REACHABLE))
+ {
+ ether_addr_copy(lladdr, &neigh->ether_addr);
+ neigh_fill_destinfo(neigh);
+ neigh->dead = 0;
+ neigh->state = state;
+ }
+
+ rte_rwlock_write_unlock(&neigh->rwlock);
+ return 0;
+}
+
+int neigh_event_send(struct sk_neighbour * neigh, struct rte_mbuf * mbuf)
+{
+ rte_rwlock_write_lock(&neigh->rwlock);
+
+ if (neigh->state & (NUD_REACHABLE))
+ goto out_unblock;
+
+ if(neigh->state & NUD_NONE)
+ {
+ neigh_probe(neigh);
+ goto out_unblock;
+ }
+
+ //TODO: ����״̬������
+
+out_unblock:
+ rte_rwlock_write_unlock(&neigh->rwlock);
+ return 0;
+}
+
+struct sk_neighbour * neigh_create(struct sk_neigh_table * tbl,
+ struct in_addr in_addr, struct sk_dev_desc * dev)
+{
+ struct sk_neighbour * neigh = neigh_alloc(tbl, dev);
+ if (unlikely(neigh == NULL)) return NULL;
+
+ // Hashֵ��ΪIP��ַ������ֵ�����뵽Hash����
+ hash_t hash = in_addr.s_addr;
+ rte_rwlock_write_lock(&tbl->neigh_tbl_lock);
+ rte_hash_add_key_with_hash(tbl->neigh_tbl, &hash, hash);
+ rte_rwlock_write_unlock(&tbl->neigh_tbl_lock);
+
+ // ���������¼�������ARP����
+ neigh_event_send(neigh, NULL);
+ neigh_hold(neigh);
+ return neigh;
+}
+
+struct sk_neighbour * neigh_lookup(struct sk_neigh_table * tbl,
+ const void * pkey, int hold)
+{
+ hash_t hash = *(uint32_t *)pkey;
+ struct sk_neighbour * neigh;
+
+ rte_rwlock_read_lock(&tbl->neigh_tbl_lock);
+ rte_hash_lookup_with_hash_data(tbl->neigh_tbl, &hash, hash, (void **)&neigh);
+ rte_rwlock_read_unlock(&tbl->neigh_tbl_lock);
+
+ if (neigh == NULL) return NULL;
+
+ if (hold) neigh_hold(neigh);
+ return neigh;
+}
+
+int neigh_tbl_init(struct sk_neigh_table * tbl, const char * symbol, unsigned int nr_entries)
+{
+ char hash_tbl_symbol[MR_SYMBOL_MAX];
+ snprintf(hash_tbl_symbol, sizeof(hash_tbl_symbol), "NTB-%s", symbol);
+
+ struct rte_hash_parameters hash_params =
+ {
+ .name = hash_tbl_symbol,
+ .entries = nr_entries,
+ .key_len = sizeof(uint32_t),
+ .hash_func = rte_hash_crc,
+ .hash_func_init_val = 0,
+ };
+
+ tbl->neigh_tbl = rte_hash_create(&hash_params);
+ if (unlikely(tbl == NULL))
+ {
+ MR_LOG(WARNING, STACK, "NeighSystem, NeighTblInit, "
+ "Create hash table %s failed(for NeighTable %s): %s. \n",
+ hash_tbl_symbol, symbol, rte_strerror(rte_errno));
+ return -1;
+ }
+
+ rte_rwlock_init(&tbl->neigh_tbl_lock);
+ return 0;
+}
+
+int neigh_tbl_deinit(struct sk_neigh_table * tbl)
+{
+ rte_hash_reset(tbl->neigh_tbl);
+ return 0;
+} \ No newline at end of file
diff --git a/stack/src/protocol-arp.c b/stack/src/protocol-arp.c
new file mode 100644
index 0000000..8c4c046
--- /dev/null
+++ b/stack/src/protocol-arp.c
@@ -0,0 +1,66 @@
+/* \brief ��Э��ջARP/RARPЭ�鴦��ģ��
+*
+* ����ARP/RARPЭ�鱨������
+*
+* \author Lu Qiuwen<[email protected]>
+* \date 2016-10-21
+*/
+
+#include <mr_rtdev.h>
+#include <sk_stack.h>
+#include <sk_device.h>
+#include <rte_malloc.h>
+
+int protocol_arp_init(struct mr_stack_instance * instance)
+{
+ return 0;
+}
+
+int protocol_arp_deinit(struct mr_stack_instance * instance)
+{
+ return 0;
+}
+
+int protocol_arp_slave_init(struct mr_stack_instance * instance,
+ struct mr_stack_slave_instance * slave_instance)
+{
+ return 0;
+}
+
+int protocol_arp_slave_deinit(struct mr_stack_instance * instance,
+ struct mr_stack_slave_instance * slave_instance)
+{
+ return 0;
+}
+
+int protocol_arp_dev_init(struct sk_dev_desc * dev)
+{
+ return 0;
+}
+
+int protocol_arp_dev_deinit(struct sk_dev_desc * dev)
+{
+ return 0;
+}
+
+int protocol_arp_slave_dev_init(struct sk_dev_desc * dev)
+{
+ return 0;
+}
+
+int protocol_arp_slave_dev_deinit(struct sk_dev_desc * dev)
+{
+ return 0;
+}
+
+// ARP���Ĵ�����ں�����������̴�����
+void protocol_serv_arp_entry(struct sk_dev_desc* dev_desc,
+ thread_id_t sid, struct rte_mbuf* mbufs_in[], int nr_mbufs_in)
+{
+ return;
+}
+
+int protocol_arp_request_send(struct sk_dev_desc * dev, struct in_addr in_addr)
+{
+ return 0;
+} \ No newline at end of file
diff --git a/stack/src/protocol-icmp.c b/stack/src/protocol-icmp.c
new file mode 100644
index 0000000..e1d80ef
--- /dev/null
+++ b/stack/src/protocol-icmp.c
@@ -0,0 +1,9 @@
+
+#include <sk_device.h>
+#include <sk_stack.h>
+
+void protocol_serv_icmp_entry(struct sk_dev_desc* dev_desc, thread_id_t sid,
+ struct rte_mbuf* mbufs_in[], int nr_mbufs_in)
+{
+ return;
+} \ No newline at end of file
diff --git a/stack/src/protocol-tcp.c b/stack/src/protocol-tcp.c
new file mode 100644
index 0000000..0af46d8
--- /dev/null
+++ b/stack/src/protocol-tcp.c
@@ -0,0 +1,8 @@
+#include <mr_common.h>
+#include <sk_protocol_tcp.h>
+
+void protocol_serv_tcp_entry(struct sk_dev_desc* dev_desc,
+ thread_id_t sid, struct rte_mbuf* mbufs_in[], int nr_mbufs_in)
+{
+ return;
+}
diff --git a/stack/src/protocol-udp.c b/stack/src/protocol-udp.c
new file mode 100644
index 0000000..adf2c12
--- /dev/null
+++ b/stack/src/protocol-udp.c
@@ -0,0 +1,9 @@
+
+#include <sk_device.h>
+#include <sk_stack.h>
+
+void protocol_serv_udp_entry(struct sk_dev_desc* dev_desc,
+ thread_id_t sid, struct rte_mbuf* mbufs_in[], int nr_mbufs_in)
+{
+ return;
+} \ No newline at end of file
diff --git a/stack/src/rxtx.c b/stack/src/rxtx.c
new file mode 100644
index 0000000..92fed52
--- /dev/null
+++ b/stack/src/rxtx.c
@@ -0,0 +1,88 @@
+/* \brief ��Э��ջ���Ĵ�������
+ *
+ * ģ�鴦������������Э��ջ�����ݱ��ĺ�׼���������������ݱ���
+ *
+ * \author Lu Qiuwen<[email protected]>
+ * \date 2016-10-21
+ */
+
+#include <assert.h>
+#include <sk_device.h>
+#include <sk_stack.h>
+#include <sk_protocol_udp.h>
+#include <sk_protocol_arp.h>
+#include <sk_protocol_tcp.h>
+#include <sk_protocol_icmp.h>
+
+
+struct packet_holder
+{
+ struct rte_mbuf * packets[MR_BURST_MAX];
+ unsigned int nr_packets;
+};
+
+enum sk_packet_type
+{
+ __PACKET_TYPE_ARP = 0,
+ __PACKET_TYPE_ICMP = 1,
+ __PACKET_TYPE_TCP = 2,
+ __PACKET_TYPE_UDP = 3,
+ __PACKET_TYPE_FRAG = 4,
+ __PACKET_TYPE_ELSE = 5,
+ __PACKET_TYPE_MAX
+};
+
+static inline enum sk_packet_type __get_packet_type(struct rte_mbuf * mbuf)
+{
+ if (mbuf->packet_type & RTE_PTYPE_L2_ETHER_ARP) return __PACKET_TYPE_ARP;
+ if (mbuf->packet_type & RTE_PTYPE_L4_ICMP) return __PACKET_TYPE_ICMP;
+ if (mbuf->packet_type & RTE_PTYPE_L4_TCP) return __PACKET_TYPE_TCP;
+ if (mbuf->packet_type & RTE_PTYPE_L4_UDP) return __PACKET_TYPE_UDP;
+ if (mbuf->packet_type & RTE_PTYPE_L4_FRAG) return __PACKET_TYPE_FRAG;
+ return __PACKET_TYPE_ELSE;
+}
+
+int sk_serv_device_tx_bulk(struct sk_dev_desc * dev_desc, thread_id_t sid,
+ struct rte_mbuf * mbufs_out[], int nr_mbufs_max)
+{
+ return 0;
+}
+
+int sk_serv_device_rx_bulk(struct sk_dev_desc * dev_desc, thread_id_t sid,
+ struct rte_mbuf * mbufs_in[], struct rte_mbuf * mbufs_out[], int nr_mbufs_in, int * nr_mbufs_out)
+{
+ struct packet_holder packets[__PACKET_TYPE_MAX];
+ for (int i = 0; i < __PACKET_TYPE_MAX; i++) packets[i].nr_packets = 0;
+
+ // ���ķ��࣬���ݱ���Э���ǩ
+ for(int i = 0; i < nr_mbufs_in; i++)
+ {
+ enum sk_packet_type index = __get_packet_type(mbufs_in[i]);
+ packets[index].packets[packets[index].nr_packets++] = mbufs_in[i];
+ }
+
+ // ARP���Ĵ���
+ protocol_serv_arp_entry(dev_desc, sid, packets[__PACKET_TYPE_ARP].packets,
+ packets[__PACKET_TYPE_ARP].nr_packets);
+
+ // ICMP���Ĵ���
+ protocol_serv_icmp_entry(dev_desc, sid, packets[__PACKET_TYPE_ICMP].packets,
+ packets[__PACKET_TYPE_TCP].nr_packets);
+
+ // TCP���Ĵ���
+ protocol_serv_tcp_entry(dev_desc, sid, packets[__PACKET_TYPE_TCP].packets,
+ packets[__PACKET_TYPE_TCP].nr_packets);
+
+ // UDP���Ĵ���
+ protocol_serv_udp_entry(dev_desc, sid, packets[__PACKET_TYPE_UDP].packets,
+ packets[__PACKET_TYPE_UDP].nr_packets);
+
+ // �޷������ı��ģ����ظ��ϲ�
+ for(int i = 0; i < packets[__PACKET_TYPE_ELSE].nr_packets; i++)
+ {
+ mbufs_out[i] = packets[__PACKET_TYPE_ELSE].packets[i];
+ assert(i <= nr_mbufs_in);
+ }
+
+ return 0;
+} \ No newline at end of file
diff --git a/stack/src/stack.c b/stack/src/stack.c
new file mode 100644
index 0000000..1197167
--- /dev/null
+++ b/stack/src/stack.c
@@ -0,0 +1,33 @@
+/* 简单数据通信用户态协议栈管理器
+ *
+ * \author Lu Qiuwen<[email protected]>
+ * \date 2016-10-18
+ */
+
+#include <sk_stack.h>
+#include <rte_ip_frag.h>
+
+struct mr_stack_instance * mr_stack_instance_create(struct mr_stack_param * param)
+{
+ struct mr_stack_instance * instance;
+
+ // 分配空间
+ instance = rte_zmalloc(NULL, sizeof(struct mr_stack_instance), 0);
+ if(unlikely(instance == NULL))
+ {
+ MR_LOG(INFO, STACK, "StackInstanceCreate, "
+ "Cannot alloc memory for stack instance. \n");
+ return NULL;
+ }
+
+ // 初始化参数
+ instance->param = *param;
+ TAILQ_INIT(&instance->dev_info_list);
+ TAILQ_INIT(&instance->dev_desc_list);
+ return instance;
+}
+
+struct mr_stack_slave_instance * mr_stack_slave_create()
+{
+ return NULL;
+} \ No newline at end of file
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 4fbaa64..8cf7596 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -19,13 +19,16 @@ set(TEST_LINK_LIBRARIES ${DPDK_LIBRARY} gtest)
#target_link_libraries(TestHwInfo ${TEST_LINK_LIBRARIES} core)
# TestCase 3
-add_executable(TestVNode TestVNode.cc Unittest.cc)
-target_link_libraries(TestVNode ${TEST_LINK_LIBRARIES} core)
+# add_executable(TestVNode TestVNode.cc Unittest.cc)
+# target_link_libraries(TestVNode ${TEST_LINK_LIBRARIES} core)
# TestCase 4
-add_executable(TestMask TestMask.cc Unittest.cc)
-target_link_libraries(TestMask ${TEST_LINK_LIBRARIES} core)
+# add_executable(TestMask TestMask.cc Unittest.cc)
+# target_link_libraries(TestMask ${TEST_LINK_LIBRARIES} core)
# TestCase 5
-add_executable(TestVMan TestVMan.cc Unittest.cc)
-target_link_libraries(TestVMan ${TEST_LINK_LIBRARIES} core) \ No newline at end of file
+# add_executable(TestVMan TestVMan.cc Unittest.cc)
+# target_link_libraries(TestVMan ${TEST_LINK_LIBRARIES} core)
+
+add_executable(TestNeigh TestStackNeigh.cc Unittest.cc)
+target_link_libraries(TestNeigh ${TEST_LINK_LIBRARIES} stack) \ No newline at end of file
diff --git a/test/TestStackNeigh.cc b/test/TestStackNeigh.cc
new file mode 100644
index 0000000..36fab6d
--- /dev/null
+++ b/test/TestStackNeigh.cc
@@ -0,0 +1,30 @@
+
+#include <gtest/gtest.h>
+#include <sk_device.h>
+#include <sk_neigh.h>
+#include <netinet/in.h>
+
+class TCStackNeigh : public ::testing::Test
+{
+protected:
+ struct sk_neigh_table neigh_tbl_;
+ struct sk_dev_desc neigh_dev_desc_;
+
+ virtual void SetUp()
+ {
+ int ret = neigh_tbl_init(&neigh_tbl_, "TestNeigh", 10000);
+ neigh_dev_desc_.dev_info = new sk_dev_info;
+ ASSERT_EQ(ret, 0);
+ }
+
+ virtual void TearDown()
+ {
+ }
+};
+
+TEST_F(TCStackNeigh, TestNeighCreate)
+{
+ struct in_addr _in_addr;
+ _in_addr.s_addr = 1000000;
+ neigh_create(&neigh_tbl_, _in_addr, &neigh_dev_desc_);
+} \ No newline at end of file
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
index 3f1f275..40382d5 100644
--- a/tools/CMakeLists.txt
+++ b/tools/CMakeLists.txt
@@ -1,11 +1,13 @@
find_package(DPDK REQUIRED)
+find_package(PCAP REQUIRED)
+
include_directories(${CMAKE_SOURCE_DIR}/include)
include_directories(${CMAKE_SOURCE_DIR}/include/extern)
include_directories(${CMAKE_SOURCE_DIR}/include/internal)
include_directories(${DPDK_INCLUDE_DIR})
-
include_directories(include)
add_definitions(${DPDK_C_PREDEFINED})
+
# add_executable(dev_stat stat/dev_stat_log.c)
# target_link_libraries(dev_stat ${DPDK_LIBRARY} MESA_prof_load_static MESA_fs2)
# target_link_libraries(dev_stat rt pthread dl core)
@@ -18,8 +20,14 @@ add_executable(zcp_event_stat stat/libstat.c stat/event_stat.c)
target_link_libraries(zcp_event_stat ${DPDK_LIBRARY} MESA_prof_load_static MESA_fs2)
target_link_libraries(zcp_event_stat rt pthread dl core)
+add_executable(zcp_rx_tcpdump tcpdump/rx_tcpdump.c)
+target_include_directories(zcp_rx_tcpdump PRIVATE ${PCAP_INCLUDE_DIR})
+target_link_libraries(zcp_rx_tcpdump pag ${PCAP_LIBRARY})
+
install(TARGETS zcp_app_stat RUNTIME DESTINATION bin COMPONENT Program)
install(TARGETS zcp_event_stat RUNTIME DESTINATION bin COMPONENT Program)
+install(TARGETS zcp_rx_tcpdump RUNTIME DESTINATION bin COMPONENT Program)
+
install(FILES script/mrstart DESTINATION bin PERMISSIONS WORLD_EXECUTE COMPONENT Program)
install(FILES script/mrstop DESTINATION bin PERMISSIONS WORLD_EXECUTE COMPONENT Program)
install(FILES script/mrzcpd DESTINATION /etc/init.d/ PERMISSIONS WORLD_EXECUTE COMPONENT Program) \ No newline at end of file
diff --git a/tools/stat/app_stat.c b/tools/stat/app_stat.c
index 6732636..623169d 100644
--- a/tools/stat/app_stat.c
+++ b/tools/stat/app_stat.c
@@ -1,11 +1,12 @@
#include <mr_common.h>
-#include <mr_procman.h>
#include <mr_stat.h>
#include <stdio.h>
-#include "libstat.h"
#include <string.h>
#include <unistd.h>
+#include <mr_runtime.h>
+
+#include "libstat.h"
#define __APPST_ITEM(_ptr, _item) (_ptr->__per_app[app_id]._per_thread[sid]._item)
@@ -20,6 +21,8 @@ static void write_speed_table_leader(FILE * stream)
__WRITE_TABLE_ITEM("Rx-bps", "c", SPEED_ITEM_WIDTH);
__WRITE_TABLE_ITEM("Tx-fps", "c", SPEED_ITEM_WIDTH);
__WRITE_TABLE_ITEM("Tx-bps", "c", SPEED_ITEM_WIDTH);
+ __WRITE_TABLE_ITEM("Drop-fps", "c", SPEED_ITEM_WIDTH);
+
fprintf(stream, "%s\n", linebuf);
linecur = 0;
@@ -29,6 +32,8 @@ static void write_speed_table_leader(FILE * stream)
__WRITE_TABLE_CLINE('-', "c", SPEED_ITEM_WIDTH);
__WRITE_TABLE_CLINE('-', "c", SPEED_ITEM_WIDTH);
__WRITE_TABLE_CLINE('-', "c", SPEED_ITEM_WIDTH);
+ __WRITE_TABLE_CLINE('-', "c", SPEED_ITEM_WIDTH);
+
fprintf(stream, "%s\n", linebuf);
return;
}
@@ -44,6 +49,8 @@ static void write_total_table_leader(FILE * stream)
__WRITE_TABLE_ITEM("Rx-bits", "c", SPEED_ITEM_WIDTH);
__WRITE_TABLE_ITEM("Tx-frames", "c", SPEED_ITEM_WIDTH);
__WRITE_TABLE_ITEM("Tx-bits", "c", SPEED_ITEM_WIDTH);
+ __WRITE_TABLE_ITEM("Drop-frames", "c", SPEED_ITEM_WIDTH);
+
fprintf(stream, "%s\n", linebuf);
linecur = 0;
@@ -53,6 +60,8 @@ static void write_total_table_leader(FILE * stream)
__WRITE_TABLE_CLINE('-', "c", SPEED_ITEM_WIDTH);
__WRITE_TABLE_CLINE('-', "c", SPEED_ITEM_WIDTH);
__WRITE_TABLE_CLINE('-', "c", SPEED_ITEM_WIDTH);
+ __WRITE_TABLE_CLINE('-', "c", SPEED_ITEM_WIDTH);
+
fprintf(stream, "%s\n", linebuf);
return;
}
@@ -127,8 +136,8 @@ static void write_speed_line(FILE * stream, const char * app_sym, unsigned int a
return;
}
-static void write_count_line(FILE * stream, const char * app_sym, unsigned int app_id, unsigned int sid,
- const struct mr_app_stat * st_now, unsigned int human)
+static void write_count_line(FILE * stream, const char * app_sym,
+ unsigned int app_id, unsigned int sid, const struct mr_app_stat * st_now, unsigned int human)
{
struct mr_app_stat st_zero[1];
memset(st_zero, 0, sizeof(struct mr_app_stat));
@@ -138,14 +147,15 @@ static void write_count_line(FILE * stream, const char * app_sym, unsigned int a
static struct mr_app_stat last_app_stat;
static struct mr_app_stat now_app_stat;
-void pinfo_stat_loop(FILE * stream, struct proc_info * pinfo,
+void pinfo_stat_loop(FILE * stream, struct appinfo * pinfo,
struct mr_app_stat * st_now, struct mr_app_stat * st_last,
int speed, int delta_time, int human)
{
- const char * appsym = pinfo->symbol;
- unsigned int appid = pinfo->proc_id;
+ const char * appsym = mr_appinfo_get_symbol(pinfo);
+ unsigned int appid = mr_appinfo_get_app_id(pinfo);
+ unsigned int nr_max_thread = mr_appinfo_get_nr_max_thread(pinfo);
- for(int sid = 0; sid < pinfo->nr_max_thread; sid++)
+ for(int sid = 0; sid < nr_max_thread; sid++)
{
if (speed)
write_speed_line(stream, appsym, appid, sid,
@@ -176,9 +186,6 @@ int app_stat_output_loop(FILE * stream, int speed, int delta_time, int human)
if (delta_time != 0) sleep(delta_time);
now_app_stat = *__get_stat_handle();
- struct proc_info * pinfo[MR_APP_MAX];
- int nr_pinfo = procman_list_all(pinfo, MR_APP_MAX);
-
// д��ͷ
fprintf(stream, "\n");
write_timeinfo(stream);
@@ -188,9 +195,10 @@ int app_stat_output_loop(FILE * stream, int speed, int delta_time, int human)
else write_total_table_leader(stream);
// д������Ϣ
- for (int i = 0; i < nr_pinfo; i++)
+ struct appinfo * appinfo_iterate = NULL;
+ while(mr_app_manager_appinfo_iterate(&appinfo_iterate) >= 0)
{
- pinfo_stat_loop(stream, pinfo[i], &now_app_stat, &last_app_stat,
+ pinfo_stat_loop(stream, appinfo_iterate, &now_app_stat, &last_app_stat,
speed, delta_time, human);
}
diff --git a/tools/stat/dev_stat_log.c b/tools/stat/dev_stat.c
index b9ff0b1..b9ff0b1 100644
--- a/tools/stat/dev_stat_log.c
+++ b/tools/stat/dev_stat.c
diff --git a/tools/stat/event_stat.c b/tools/stat/event_stat.c
index 5fc0be6..1521b54 100644
--- a/tools/stat/event_stat.c
+++ b/tools/stat/event_stat.c
@@ -1,7 +1,7 @@
-#include <mr_stat.h>
-
-#include "libstat.h"
-
+#include <mr_stat.h>
+
+#include "libstat.h"
+
static void write_timeinfo(FILE * stream)
{
time_t currect;
@@ -11,70 +11,70 @@ static void write_timeinfo(FILE * stream)
libstat_strtime(str_localtime, sizeof(str_localtime), currect);
fprintf(stream, "Time: %12s\n", str_localtime);
return;
-}
-
-#define EVENT_NAME_WIDTH 25
-#define EVENT_COUNT_WIDTH 25
-
-static void write_table_header(FILE * stream)
-{
+}
+
+#define EVENT_NAME_WIDTH 25
+#define EVENT_COUNT_WIDTH 25
+
+static void write_table_header(FILE * stream)
+{
char linebuf[MR_STRING_MAX];
- unsigned int linecur = 0;
-
+ unsigned int linecur = 0;
+
__WRITE_TABLE_ITEM("EventSymbol", "c", EVENT_NAME_WIDTH);
- __WRITE_TABLE_ITEM("Count", "c", EVENT_COUNT_WIDTH);
+ __WRITE_TABLE_ITEM("Count", "c", EVENT_COUNT_WIDTH);
fprintf(stream, "%s\n", linebuf);
linecur = 0;
__WRITE_TABLE_CLINE('-', "c", EVENT_NAME_WIDTH);
__WRITE_TABLE_CLINE('-', "c", EVENT_COUNT_WIDTH);
- fprintf(stream, "%s\n", linebuf);
-}
-
-static void write_event_item(FILE * stream, const char * ev_symbol, uint64_t value)
-{
- char linebuf[MR_STRING_MAX];
+ fprintf(stream, "%s\n", linebuf);
+}
+
+static void write_event_item(FILE * stream, const char * ev_symbol, uint64_t value)
+{
+ char linebuf[MR_STRING_MAX];
char numbuf[MR_STRING_MAX];
- unsigned int linecur = 0;
-
- __WRITE_TABLE_ITEM(ev_symbol, "r", EVENT_NAME_WIDTH);
+ unsigned int linecur = 0;
+
+ __WRITE_TABLE_ITEM(ev_symbol, "r", EVENT_NAME_WIDTH);
__TRANS_DATA(value, numbuf);
- __WRITE_TABLE_ITEM(numbuf, "r", EVENT_COUNT_WIDTH);
- fprintf(stream, "%s\n", linebuf);
-}
-
-static void event_stat_loop(FILE * stream)
-{
- struct mr_event_stat * stat_handle;
- stat_handle = mr_event_stat_get();
- if(stat_handle == NULL)
- {
+ __WRITE_TABLE_ITEM(numbuf, "r", EVENT_COUNT_WIDTH);
+ fprintf(stream, "%s\n", linebuf);
+}
+
+static void event_stat_loop(FILE * stream)
+{
+ struct mr_event_stat * stat_handle;
+ stat_handle = mr_event_stat_get();
+ if(stat_handle == NULL)
+ {
fprintf(stderr, "Master(serivce) is not run or event stat "
"function is disable(handle is null).\n");
- exit(EXIT_FAILURE);
- }
-
- uint64_t total_ev_rx_dup_failed = 0;
- uint64_t total_ev_rx_entunnel_failed = 0;
-
- for(int i = 0; i < RTE_DIM(stat_handle->_per_thread); i++)
- {
- total_ev_rx_dup_failed += stat_handle->_per_thread[i].ev_rx_dup_failed;
- total_ev_rx_entunnel_failed += stat_handle->_per_thread[i].ev_rx_entunnel_failed;
- }
-
- fprintf(stream, "\n");
- write_timeinfo(stream);
- fprintf(stream, "\n");
- write_table_header(stdout);
- write_event_item(stream, "ev_rx_dup_failed", total_ev_rx_dup_failed);
- write_event_item(stream, "ev_rx_entunnel_failed", total_ev_rx_entunnel_failed);
- fprintf(stream, "\n");
- return;
-}
-
-int main(int argc, char * argv[])
-{
- libstat_init();
- event_stat_loop(stdout);
+ exit(EXIT_FAILURE);
+ }
+
+ uint64_t total_ev_rx_dup_failed = 0;
+ uint64_t total_ev_rx_entunnel_failed = 0;
+
+ for(int i = 0; i < RTE_DIM(stat_handle->_per_thread); i++)
+ {
+ total_ev_rx_dup_failed += stat_handle->_per_thread[i].ev_rx_dup_failed;
+ total_ev_rx_entunnel_failed += stat_handle->_per_thread[i].ev_rx_entunnel_failed;
+ }
+
+ fprintf(stream, "\n");
+ write_timeinfo(stream);
+ fprintf(stream, "\n");
+ write_table_header(stdout);
+ write_event_item(stream, "ev_rx_dup_failed", total_ev_rx_dup_failed);
+ write_event_item(stream, "ev_rx_entunnel_failed", total_ev_rx_entunnel_failed);
+ fprintf(stream, "\n");
+ return;
+}
+
+int main(int argc, char * argv[])
+{
+ libstat_init();
+ event_stat_loop(stdout);
} \ No newline at end of file
diff --git a/tools/stat/libstat.c b/tools/stat/libstat.c
index a9c1233..2046c2d 100644
--- a/tools/stat/libstat.c
+++ b/tools/stat/libstat.c
@@ -3,10 +3,11 @@
#include <assert.h>
#include <stdio.h>
#include <rte_log.h>
-#include "mr_ctx.h"
-#include "mr_core.h"
+#include <mr_runtime.h>
#include <string.h>
+
#include "libstat.h"
+#include "mr_core.h"
#define MR_LIB_MAX_EAL_ARGC 128
@@ -47,11 +48,11 @@ static void libstat_eal_init()
int libstat_init()
{
- int ret = 0;
libstat_eal_init();
- mr_global_ctx_slave_init();
- mr_global_cfg_slave_init();
- mr_core_stage_slaveinit();
+ mr_runtime_slave_init();
+
+ struct mr_global_ctx * g_ctx = mr_global_ctx_get();
+ mr_core_default_instance_set(g_ctx->ctx_core);
return 0;
}
@@ -135,7 +136,7 @@ int libstat_table_format_item(const char * str, const char * fmt,
int cur = 0;
int space_before = (width - len) / 2;
for (int i = 0; i < space_before; i++) _format[cur++] = ' ';
- cur += snprintf(_format + cur, sizeof(_format) - space_before, "%%s", width);
+ cur += snprintf(_format + cur, sizeof(_format) - space_before, "%%s");
for (int i = 0; i < width - space_before - len; i++) _format[cur++] = ' ';
_format[cur] = '\0';
}
diff --git a/tools/stat/libstat.h b/tools/stat/libstat.h
index d0a9aea..42fa054 100644
--- a/tools/stat/libstat.h
+++ b/tools/stat/libstat.h
@@ -1,6 +1,7 @@
#pragma once
#include <stdint.h>
+#include <inttypes.h>
#include <time.h>
int libstat_init();
@@ -60,7 +61,7 @@ do { \
static inline char * __trans_data(uint64_t data, char * buffer, size_t sz_buffer)
{
- snprintf(buffer, sz_buffer, "%llu", data);
+ snprintf(buffer, sz_buffer, "%"PRIu64, data);
return buffer;
}
diff --git a/tools/tcpdump/rx_tcpdump.c b/tools/tcpdump/rx_tcpdump.c
new file mode 100644
index 0000000..74d1454
--- /dev/null
+++ b/tools/tcpdump/rx_tcpdump.c
@@ -0,0 +1,347 @@
+/*
+*author:liujun
+*date:2016-10-09
+*func:simple tcpdump function for filtering the invalidate packets
+*diff:multi-pthread and the packets provided by libpag
+*/
+
+#include<stdio.h>
+#include<unistd.h>
+#include<string.h>
+#include<stdarg.h>
+#include<time.h>
+#include<stdlib.h>
+#include<inttypes.h>
+#include<errno.h>
+#include<fcntl.h>
+#include<arpa/inet.h>
+#include<sys/types.h>
+#include<sys/stat.h>
+#include<signal.h>
+#include<pcap.h>
+#include<pthread.h>
+#include<time.h>
+#include<libpag.h>
+
+#define atomic_inc(x) __sync_add_and_fetch((x),1)
+#define atomic_add(x,y) __sync_add_and_fetch((x),(y))
+
+#define atomic_bool_cas(compare_old_ret_new,oldval,newval) \
+ __sync_bool_compare_and_swap(compare_old_ret_new,oldval,newval)
+
+#define BPF_CODE_MAX_SIZE 100
+#define PTHREAD_MAX_NUM BPF_CODE_MAX_SIZE
+
+struct bpf_program g_fcode[BPF_CODE_MAX_SIZE];
+pthread_t g_pthd[PTHREAD_MAX_NUM];
+pcap_dumper_t *g_pdumper_write[PTHREAD_MAX_NUM];
+static long long pkt_cnt = 0; //taticstic all packets be captured
+static long long filter_pkt_cnt = 0; //statistic packets be filter
+static long long filter_pkt_total_bytes = 0; //statistic packets bytes be filter
+static long long pkt_total = 0; //set max packets will be captured by cmd [-c packet-num] . if there is not -c paramters ,set default value 0
+char *program_name;
+pcap_t *handle_dead;
+
+static volatile int keeprunning = 1; //recieve interupt sig will chang the status for ending per thread
+
+#define PATH_STR_MAX_LEN 1024
+#define FILE_BASE_NAME_MAX_LEN 1024
+#define FILE_TYPE_NAME_MAX_LEN 64
+#define INT_TO_STR_MAX_LEN 10
+
+
+void write_pcap(int pthread_num, const struct pcap_pkthdr *header, const u_char *packet)
+{
+ pcap_dump((u_char *)g_pdumper_write[pthread_num], header, packet);
+}
+
+/*
+*according the filter rule to filter mac packet
+*and write packet into pcap file
+*
+*/
+void *bpf_filter_mac_write_pcap(void *arg)
+{
+
+ uint64_t thread_id = (uint64_t)arg;
+ struct pcap_pkthdr header;
+ const u_char *packet;
+ int frame_len;
+
+ while (keeprunning == 1)
+ {
+ /*
+ *if pkt_total not equal 0, it is demonstrated that we had setted max capture packet number by used commond -c
+ *then judge the capturing packet number pkt_cnt equal pkt_total whether or not
+ */
+ if (pkt_total != 0 && atomic_bool_cas(&pkt_cnt, pkt_total, pkt_cnt))
+ break;
+ /*
+ *pag get packet and packet length
+ */
+ packet = (u_char *)pag_get_frame(thread_id);
+ if (packet == NULL)
+ continue;
+
+ frame_len = pag_get_frame_length(thread_id);
+
+ gettimeofday(&(header.ts), NULL);
+ header.caplen = (bpf_u_int32)frame_len;
+ header.len = (bpf_u_int32)frame_len;
+
+ atomic_inc(&pkt_cnt);
+ if (bpf_filter(g_fcode[thread_id].bf_insns,
+ packet, header.caplen, header.caplen) == 0 || header.caplen > 65535)
+ {
+ atomic_inc(&filter_pkt_cnt);
+ atomic_add(&filter_pkt_total_bytes, header.caplen);
+
+ }
+ else
+ write_pcap(thread_id, &header, packet);
+
+ }
+ return NULL;
+}
+
+
+void usage()
+{
+ fprintf(stderr, "%s ,with %s\n", program_name, pcap_lib_version());
+ fprintf(stderr, "Usage:%s [-write file_name] [-count packets_num] [-pthread pthread_num] [filter rules]\n", program_name);
+ fprintf(stderr, "Usage:%s [-w log.pcap] [-c 100] [-p 6] [tcp port 22]\n", program_name);
+ exit(0);
+}
+/*
+*argv[optind] pointer the bpf filter rules
+*copy all bpf filter rules regardless of blank space
+*/
+static char *copy_argv(register char **argv)
+{
+ register char **p;
+ register u_int len = 0;
+ char *buf;
+ char *src, *dst;
+ p = argv;
+ if (*p == 0)
+ return 0;
+ while (*p)
+ {
+ len += strlen(*p++) + 1;
+ }
+ buf = (char*)malloc(len);
+ if (buf == NULL)
+ perror("malloc buf err\n");
+ p = argv;
+ dst = buf;
+ while ((src = *p++) != NULL)
+ {
+ while ((*dst++ = *src++) != '\0');
+ dst[-1] = ' ';
+ }
+ dst[-1] = '\0';
+ return buf;
+}
+
+void show_capture_filter_result()
+{
+ pag_close();
+ pcap_close(handle_dead);
+ fprintf(stderr, "\n%lld packets captured \n%lld packets recived by filter \n"
+ "%lld packets, %lld bytes dropped by filter\n", pkt_cnt, pkt_cnt - filter_pkt_cnt, filter_pkt_cnt, filter_pkt_total_bytes);
+}
+
+char* string_split_last_point(char *file_name, char ch)
+{
+ char *cp;
+ if ((cp = strrchr(file_name, ch)) == NULL)
+ cp = file_name + strlen(file_name);
+ return cp;
+
+}
+
+void string_file_base_name(char *file_name, char ch, char *file_base_name)
+{
+ char *cp = string_split_last_point(file_name, ch);
+ int left_str_len = cp - file_name;
+ strncat(file_base_name, file_name, left_str_len);
+}
+
+void string_file_type_name(char *file_name, char ch, char *file_type_name)
+{
+ char *cp = string_split_last_point(file_name, ch);
+ char *end_file_str = file_name + strlen(file_name);
+ int right_str_len = end_file_str - cp;
+ char temp[] = "";
+ if (right_str_len <= 0)
+ {
+ right_str_len = 1;
+ cp = temp;
+ }
+ strncat(file_type_name, cp, right_str_len);
+}
+void int_to_str(int file_no, char *file_no_str)
+{
+ snprintf(file_no_str, INT_TO_STR_MAX_LEN, "_%d", file_no);
+ return;
+}
+
+int string_splice_length(int file_no, char *file_name)
+{
+ int str_len = strlen(file_name);
+ char file_no_str[INT_TO_STR_MAX_LEN];
+ int_to_str(file_no, file_no_str);
+ int file_no_str_len = strlen(file_no_str);
+ return str_len + file_no_str_len + 1;
+}
+
+void string_file_name_nostr_type_splice(int file_no, char *file_name, char ch, char *new_file_name)
+{
+ char file_no_str[INT_TO_STR_MAX_LEN];
+ char file_base_name[FILE_BASE_NAME_MAX_LEN];
+ char file_type_name[FILE_TYPE_NAME_MAX_LEN];
+
+ memset(file_base_name, 0, FILE_BASE_NAME_MAX_LEN);
+ memset(file_type_name, 0, FILE_TYPE_NAME_MAX_LEN);
+ memset(file_no_str, 0, INT_TO_STR_MAX_LEN);
+
+ string_file_base_name(file_name, ch, file_base_name);
+ int_to_str(file_no, file_no_str);
+ string_file_type_name(file_name, ch, file_type_name);
+
+ int len = string_splice_length(file_no, file_name);
+ snprintf(new_file_name, len, "%s%s%s", file_base_name, file_no_str, file_type_name);
+
+ return;
+}
+int per_thread_pcap_dump_open(int pth_num, char *save_file_name, char splt_ch)
+{
+ int len = string_splice_length(pth_num, save_file_name);
+ char *new_save_file_name = (char *)calloc(len, sizeof(char));
+ if (new_save_file_name != NULL)
+ {
+ string_file_name_nostr_type_splice(pth_num, save_file_name, splt_ch, new_save_file_name);
+ g_pdumper_write[pth_num] = pcap_dump_open(handle_dead, new_save_file_name);
+ free(new_save_file_name);
+ if (g_pdumper_write[pth_num] == NULL)
+ {
+ return -1;
+ }
+ return 0;
+ }
+ else
+ return -1;
+
+}
+/*
+*the interupt action such as ctrl+c will cause sig action for interuptting the thread
+*/
+void sig_interupt_handle(int signo)
+{
+ keeprunning = 0;
+}
+
+int main(int argc, char **argv)
+{
+ char ch;
+ char splt_ch = '.';
+
+ char *cp;
+ int pthread_num = 1;
+ char *bpf_filter_exp;
+ char default_save_file_name[] = "default.pcap";
+ char *save_file_name = default_save_file_name;
+ int pkt_num = 0;
+
+ if ((cp = strrchr(argv[0], '/')) != NULL)
+ program_name = cp + 1;
+ else
+ program_name = argv[0];
+
+ /*
+ *usage:./BPF_RX_TCPDUMP -c 100 -w log.pcap tcp port 22 -p 6
+ */
+ while ((ch = getopt(argc, argv, "p:w:c:")) != -1)
+ {
+ switch (ch)
+ {
+ case 'p':
+ pthread_num = atoi(optarg);
+ break;
+ case 'w':
+ save_file_name = optarg;
+ break;
+ case 'c':
+ pkt_num = atoi(optarg);
+ pkt_total = pkt_num;
+ printf("pkt_num %d\n", pkt_num);
+ break;
+ default:
+ usage();
+ }
+ }
+ //if(optind>=argc)
+ //usage();
+ //pthread_mutex_init(&p_mutex_lock,NULL);
+ signal(SIGINT, sig_interupt_handle);
+ /*
+ *default value set pkt_num,pthread_num,save_file_name,bpf_filter_exp
+ */
+ bpf_filter_exp = copy_argv(&argv[optind]);
+
+ handle_dead = pcap_open_dead(DLT_EN10MB, 65535);
+ if (handle_dead == NULL)
+ {
+ perror("pcap_open_dead() failed");
+ return -1;
+ }
+ /*
+ * multi-pthread
+ */
+ int pth_num = 0;
+ for (pth_num = 0; pth_num < pthread_num; pth_num++)
+ {
+ if (-1 == per_thread_pcap_dump_open(pth_num, save_file_name, splt_ch))
+ {
+ return -1;
+ }
+
+ if (pcap_compile(handle_dead, &g_fcode[pth_num], bpf_filter_exp, 100, 0) < 0)
+ {
+ perror(pcap_geterr(handle_dead));
+ return -1;
+ }
+ if (!bpf_validate(g_fcode[pth_num].bf_insns, g_fcode[pth_num].bf_len))
+ {
+ perror("invalidate filter rules\n");
+ return -1;
+ }
+ }
+
+ free(bpf_filter_exp);
+ if (pag_open() == -1)
+ return -1;
+
+ for (pth_num = 0; pth_num < pthread_num; pth_num++)
+ {
+ int pth_create_ret = pthread_create(&g_pthd[pth_num], NULL,
+ bpf_filter_mac_write_pcap, (void *)pth_num);
+
+ if (pth_create_ret != 0)
+ {
+ --pth_num;
+ }
+ }
+
+ for (pth_num = 0; pth_num < pthread_num; pth_num++)
+ {
+ pthread_join(g_pthd[pth_num], NULL);
+ pcap_freecode(&g_fcode[pthread_num]);
+ if (g_pdumper_write[pthread_num] != NULL)
+ pcap_dump_close(g_pdumper_write[pthread_num]);
+ }
+
+ show_capture_filter_result();
+ return 0;
+
+} \ No newline at end of file