diff options
| author | Qiuwen Lu <[email protected]> | 2016-10-28 10:42:16 +0800 |
|---|---|---|
| committer | Qiuwen Lu <[email protected]> | 2016-10-28 10:42:16 +0800 |
| commit | b88cf32a2d358882b9734fece1067ecaca3533d6 (patch) | |
| tree | c0d473e25dde0ea8ce039faa9cd0c363ca2cfe00 | |
| parent | f274e8a4d27e56d8e1600a7a3181017a4b538574 (diff) | |
| parent | a6a6c0630d71df0ed391966a859d77833d785e2a (diff) | |
Merge branch 'dev-4.X.X' into rel-4.X.Xv4.0.3-20161028
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(¶m->usr_ether_addr)) + { + rte_eth_dev_default_mac_addr_set(dev->port_id, ¶m->usr_ether_addr); + ether_addr_copy(¶m->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, ð_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, ðer_hdr->s_addr); + ether_addr_copy(dst_addr, ðer_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 |
