From a02c88d651a5ba8d1710f448238a12b2904dcd60 Mon Sep 17 00:00:00 2001 From: logwang Date: Tue, 8 Aug 2017 22:36:49 +0800 Subject: [PATCH] Simplify startup arguments and add ff_fdisused. Changes: 1.Simplify f-stack startup arguments:"--conf, --proc-type, --proc-id". 2.add a function `ff_fdisused` to check if fd is used in f-stack. --- app/micro_thread/Makefile | 6 +- app/micro_thread/echo.cpp | 2 +- app/micro_thread/f-stack.pc | 7 - app/micro_thread/ff_hook.cpp | 90 +---- app/micro_thread/ff_hook.h | 8 - app/micro_thread/kqueue_proxy.cpp | 8 +- app/micro_thread/mt_api.cpp | 6 +- app/micro_thread/mt_api.h | 2 +- app/micro_thread/mt_self_echo.cpp | 2 +- app/micro_thread/mt_sys_hook.cpp | 62 ++-- .../src/event/modules/ngx_ff_module.c | 257 +++++++++----- .../src/event/modules/ngx_kqueue_module.c | 15 - .../src/event/modules/ngx_select_module.c | 26 -- app/redis-3.2.8/src/ae.c | 14 - app/redis-3.2.8/src/ae_ff_kqueue.c | 4 - app/redis-3.2.8/src/anet_ff.c | 330 ++++++++++++------ app/redis-3.2.8/src/config.ini | 68 ---- app/redis-3.2.8/src/server.c | 24 +- app/redis-3.2.8/src/start.sh | 67 ---- config.ini | 5 + example/main.c | 9 +- example/main_epoll.c | 11 +- freebsd/kern/kern_descrip.c | 26 ++ lib/ff_api.h | 5 +- lib/ff_api.symlist | 1 + lib/ff_config.c | 176 ++++++++-- lib/ff_config.h | 9 +- lib/ff_dpdk_if.c | 102 +----- lib/ff_freebsd_init.c | 2 + lib/ff_init.c | 4 +- lib/include/sys/filedesc.h | 36 ++ start.sh | 28 +- 32 files changed, 714 insertions(+), 698 deletions(-) delete mode 100644 app/micro_thread/f-stack.pc delete mode 100644 app/redis-3.2.8/src/config.ini delete mode 100644 app/redis-3.2.8/src/start.sh create mode 100644 lib/include/sys/filedesc.h diff --git a/app/micro_thread/Makefile b/app/micro_thread/Makefile index a0f49d1fe..a91e6cf5c 100644 --- a/app/micro_thread/Makefile +++ b/app/micro_thread/Makefile @@ -26,7 +26,11 @@ endif DEBUG= -g BINARY = libmt.a FF_LIB=$(FF_PATH)/libfstack.a -DPDK_LIBS = $(shell pkg-config --define-variable=TOPDIR=${FF_PATH} --libs f-stack.pc) +DPDK_LIBS+= -L${FF_PATH}/lib -L${FF_DPDK}/lib -Wl,--whole-archive,-lfstack,--no-whole-archive +DPDK_LIBS+= -Wl,--whole-archive -lrte_pmd_vmxnet3_uio -lrte_pmd_i40e -lrte_pmd_ixgbe -lrte_pmd_e1000 -lrte_pmd_ring +DPDK_LIBS+= -Wl,--whole-archive -lrte_hash -lrte_kvargs -Wl,-lrte_mbuf -lethdev -lrte_eal -Wl,-lrte_mempool +DPDK_LIBS+= -lrte_ring -lrte_cmdline -lrte_cfgfile -lrte_kni -lrte_timer -Wl,-lrte_pmd_virtio +DPDK_LIBS+= -Wl,--no-whole-archive -lrt -lm -ldl -lcrypto -pthread # Comment the following line if you are not using the gnu c compiler #C_ARGS = -Wall -g -fPIC -D_DEBUG diff --git a/app/micro_thread/echo.cpp b/app/micro_thread/echo.cpp index c5eef1e49..0d67b16d7 100644 --- a/app/micro_thread/echo.cpp +++ b/app/micro_thread/echo.cpp @@ -97,6 +97,6 @@ int echo_server() int main(int argc, char *argv[]) { - mt_init_frame("./config.ini", argc, argv); + mt_init_frame(argc, argv); echo_server(); } diff --git a/app/micro_thread/f-stack.pc b/app/micro_thread/f-stack.pc deleted file mode 100644 index 8b119a50b..000000000 --- a/app/micro_thread/f-stack.pc +++ /dev/null @@ -1,7 +0,0 @@ -DPDK = ${TOPDIR}/dpdk/x86_64-native-linuxapp-gcc - -Name: F-Stack -Description: F-Stack pkg-config pc -Version: 1.0 -Libs: -L${TOPDIR}/lib -Wl,--whole-archive,-lfstack,--no-whole-archive -Wl,--no-as-needed -fvisibility=default -pthread -lm -lrt -L${DPDK}/lib -Wl,--whole-archive -lrte_pmd_vmxnet3_uio -lrte_pmd_i40e -lrte_pmd_ixgbe -lrte_pmd_e1000 -lrte_pmd_ring -Wl,--whole-archive -lrte_hash -lrte_kvargs -Wl,-lrte_mbuf -lethdev -lrte_eal -Wl,-lrte_mempool -lrte_ring -lrte_cmdline -lrte_cfgfile -lrte_kni -lrte_timer -Wl,-lrte_pmd_virtio -Wl,--no-whole-archive -lrt -lm -ldl -lcrypto -Cflags: -Wall -Werror -include ${DPDK}/include/rte_config.h -I${DPDK}/include -march=native -DRTE_MACHINE_CPUFLAG_SSE -DRTE_MACHINE_CPUFLAG_SSE2 -DRTE_MACHINE_CPUFLAG_SSE3 -DRTE_MACHINE_CPUFLAG_SSSE3 -DRTE_MACHINE_CPUFLAG_SSE4_1 -DRTE_MACHINE_CPUFLAG_SSE4_2 -DRTE_COMPILE_TIME_CPUFLAGS=RTE_CPUFLAG_SSE,RTE_CPUFLAG_SSE2,RTE_CPUFLAG_SSE3,RTE_CPUFLAG_SSSE3,RTE_CPUFLAG_SSE4_1,RTE_CPUFLAG_SSE4_2 diff --git a/app/micro_thread/ff_hook.cpp b/app/micro_thread/ff_hook.cpp index 1bc277252..bd6e78afa 100644 --- a/app/micro_thread/ff_hook.cpp +++ b/app/micro_thread/ff_hook.cpp @@ -34,55 +34,17 @@ #include "mt_sys_hook.h" #include "ff_hook.h" - - - -/* -void ff_hook_new_fd(int fd) -{ - if (fd < 0 || fd >= ff_HOOK_MAX_FD) { - return; - } - g_ff_hook_fd_tab[fd] = 1; -} - -bool ff_hook_find_fd(int fd) { - if (fd < 0 || fd >= ff_HOOK_MAX_FD) { - return false; - } - - if (g_ff_hook_fd_tab[fd] == 1) { - return true; - } else { - return false; - } -} - -void ff_hook_free_fd(int fd) -{ - if (fd < 0 || fd >= ff_HOOK_MAX_FD) { - return; - } - g_ff_hook_fd_tab[fd] = 0; -} -*/ - int ff_hook_socket(int domain, int type, int protocol) { - if (!ff_hook_active() || (AF_INET != domain) || (SOCK_STREAM != type && SOCK_DGRAM != type)) { + if ((AF_INET != domain) || (SOCK_STREAM != type && SOCK_DGRAM != type)) { return mt_real_func(socket)(domain, type, protocol); } - int fd = ff_socket(domain, type, protocol); - if (fd >= 0) { - fd |= 1 << FF_FD_BITS; - } - return fd; + return ff_socket(domain, type, protocol); } int ff_hook_close(int fd) { - if (CHK_FD_BIT(fd)) { - fd = CLR_FD_BIT(fd); + if (ff_fdisused(fd)) { return ff_close(fd); } else { return mt_real_func(close)(fd); @@ -91,8 +53,7 @@ int ff_hook_close(int fd) int ff_hook_connect(int fd, const struct sockaddr *address, socklen_t addrlen_len) { - if (CHK_FD_BIT(fd)) { - fd = CLR_FD_BIT(fd); + if (ff_fdisused(fd)) { return ff_connect(fd, (struct linux_sockaddr *)address, addrlen_len); } else { return mt_real_func(connect)(fd, address, addrlen_len); @@ -101,8 +62,7 @@ int ff_hook_connect(int fd, const struct sockaddr *address, socklen_t addrlen_le ssize_t ff_hook_read(int fd, void *buf, size_t nbyte) { - if (CHK_FD_BIT(fd)) { - fd = CLR_FD_BIT(fd); + if (ff_fdisused(fd)) { return ff_read(fd, buf, nbyte); } else { return mt_real_func(read)(fd, buf, nbyte); @@ -111,8 +71,7 @@ ssize_t ff_hook_read(int fd, void *buf, size_t nbyte) ssize_t ff_hook_write(int fd, const void *buf, size_t nbyte) { - if (CHK_FD_BIT(fd)) { - fd = CLR_FD_BIT(fd); + if (ff_fdisused(fd)) { return ff_write(fd, buf, nbyte); } else { return mt_real_func(write)(fd, buf, nbyte); @@ -121,8 +80,7 @@ ssize_t ff_hook_write(int fd, const void *buf, size_t nbyte) ssize_t ff_hook_sendto(int fd, const void *message, size_t length, int flags, const struct sockaddr *dest_addr, socklen_t dest_len) { - if (CHK_FD_BIT(fd)) { - fd = CLR_FD_BIT(fd); + if (ff_fdisused(fd)) { return ff_sendto(fd, message, length, flags, (struct linux_sockaddr *)dest_addr, dest_len); } else { return mt_real_func(sendto)(fd, message, length, flags, dest_addr, dest_len); @@ -131,8 +89,7 @@ ssize_t ff_hook_sendto(int fd, const void *message, size_t length, int flags, ssize_t ff_hook_recvfrom(int fd, void *buffer, size_t length, int flags, struct sockaddr *address, socklen_t *address_len) { - if (CHK_FD_BIT(fd)) { - fd = CLR_FD_BIT(fd); + if (ff_fdisused(fd)) { return ff_recvfrom(fd, buffer, length, flags, (struct linux_sockaddr *)address, address_len); } else { return mt_real_func(recvfrom)(fd, buffer, length, flags, address, address_len); @@ -140,8 +97,7 @@ ssize_t ff_hook_recvfrom(int fd, void *buffer, size_t length, int flags, } ssize_t ff_hook_recv(int fd, void *buffer, size_t length, int flags) { - if (CHK_FD_BIT(fd)) { - fd = CLR_FD_BIT(fd); + if (ff_fdisused(fd)) { return ff_recv(fd, buffer, length, flags); } else { return mt_real_func(recv)(fd, buffer, length, flags); @@ -149,8 +105,7 @@ ssize_t ff_hook_recv(int fd, void *buffer, size_t length, int flags) } ssize_t ff_hook_send(int fd, const void *buf, size_t nbyte, int flags) { - if (CHK_FD_BIT(fd)) { - fd = CLR_FD_BIT(fd); + if (ff_fdisused(fd)) { return ff_send(fd, buf, nbyte, flags); } else { return mt_real_func(send)(fd, buf, nbyte, flags); @@ -159,8 +114,7 @@ ssize_t ff_hook_send(int fd, const void *buf, size_t nbyte, int flags) } int ff_hook_setsockopt(int fd, int level, int option_name, const void *option_value, socklen_t option_len) { - if (CHK_FD_BIT(fd)) { - fd = CLR_FD_BIT(fd); + if (ff_fdisused(fd)) { return ff_setsockopt(fd, level, option_name, option_value, option_len); } else { return mt_real_func(setsockopt)(fd, level, option_name, option_value, option_len); @@ -169,8 +123,7 @@ int ff_hook_setsockopt(int fd, int level, int option_name, const void *option_va int ff_hook_ioctl(int fd, int cmd, void *arg) { - if (CHK_FD_BIT(fd)) { - fd = CLR_FD_BIT(fd); + if (ff_fdisused(fd)) { return ff_ioctl(fd, cmd, arg); } else { return mt_real_func(ioctl)(fd, cmd, arg); @@ -179,8 +132,7 @@ int ff_hook_ioctl(int fd, int cmd, void *arg) int ff_hook_fcntl(int fd, int cmd, void *arg) { - if (CHK_FD_BIT(fd)) { - fd = CLR_FD_BIT(fd); + if (ff_fdisused(fd)) { return ff_fcntl(fd, cmd, arg); } else { return mt_real_func(fcntl)(fd, cmd, arg); @@ -189,8 +141,7 @@ int ff_hook_fcntl(int fd, int cmd, void *arg) int ff_hook_listen(int fd, int backlog) { - if (CHK_FD_BIT(fd)) { - fd = CLR_FD_BIT(fd); + if (ff_fdisused(fd)) { return ff_listen(fd, backlog); } else { return mt_real_func(listen)(fd, backlog); @@ -199,8 +150,7 @@ int ff_hook_listen(int fd, int backlog) int ff_hook_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) { - if (CHK_FD_BIT(fd)) { - fd = CLR_FD_BIT(fd); + if (ff_fdisused(fd)) { return ff_bind(fd, (struct linux_sockaddr *)addr, addrlen); } else { return mt_real_func(bind)(fd, addr, addrlen); @@ -208,14 +158,8 @@ int ff_hook_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) } int ff_hook_accept(int fd, struct sockaddr *addr, socklen_t *addrlen) { - if (CHK_FD_BIT(fd)) { - fd = CLR_FD_BIT(fd); - int c = ff_accept(fd, (struct linux_sockaddr *)addr, addrlen); - if (c < 0) { - return c; - } - c |= 1 << FF_FD_BITS; - return c; + if (ff_fdisused(fd)) { + return ff_accept(fd, (struct linux_sockaddr *)addr, addrlen); } else { return mt_real_func(accept)(fd, addr, addrlen); } diff --git a/app/micro_thread/ff_hook.h b/app/micro_thread/ff_hook.h index 92edf7b15..8fb6ae678 100644 --- a/app/micro_thread/ff_hook.h +++ b/app/micro_thread/ff_hook.h @@ -22,14 +22,6 @@ #include -#define FF_FD_BITS 16 -#define CHK_FD_BIT(fd) (fd & (1 << FF_FD_BITS)) -#define CLR_FD_BIT(fd) (fd & ~(1 << FF_FD_BITS)) - -void ff_hook_new_fd(int fd); -bool ff_hook_find_fd(int fd); - -void ff_hook_free_fd(int fd); int ff_hook_socket(int domain, int type, int protocol); int ff_hook_close(int fd); diff --git a/app/micro_thread/kqueue_proxy.cpp b/app/micro_thread/kqueue_proxy.cpp index 796723e20..edf578ee6 100644 --- a/app/micro_thread/kqueue_proxy.cpp +++ b/app/micro_thread/kqueue_proxy.cpp @@ -187,9 +187,6 @@ bool KqueueProxy::KqueueCtrlAdd(int fd, int events) KqEvent ke; int ret; - if (CHK_FD_BIT(fd)) { - fd = CLR_FD_BIT(fd); - } if (old_events & KQ_EVENT_WRITE) { EV_SET(&ke, fd, EVFILT_WRITE, EV_DELETE, 0, 0, NULL); ret = ff_kevent(_kqfd, &ke, 1, NULL, 0, NULL); @@ -274,9 +271,6 @@ bool KqueueProxy::KqueueCtrlDelRef(int fd, int events, bool use_ref) } KqEvent ke; int ret; - if (CHK_FD_BIT(fd)) { - fd = CLR_FD_BIT(fd); - } if (old_events & KQ_EVENT_WRITE) { EV_SET(&ke, fd, EVFILT_WRITE, EV_DELETE, 0, 0, NULL); ret = ff_kevent(_kqfd, &ke, 1, NULL, 0, NULL); @@ -380,7 +374,7 @@ void KqueueProxy::KqueueRcvEventList(int evtfdnum) for (int i = 0; i < evtfdnum; i++) { - osfd = _evtlist[i].ident |= 1 << FF_FD_BITS; + osfd = _evtlist[i].ident; item = KqFdRefGet(osfd); if (item == NULL) diff --git a/app/micro_thread/mt_api.cpp b/app/micro_thread/mt_api.cpp index 288dd486b..59c03cc90 100644 --- a/app/micro_thread/mt_api.cpp +++ b/app/micro_thread/mt_api.cpp @@ -716,10 +716,10 @@ void* mt_get_msg_private() * @info 业务不使用spp,裸用微线程,需要调用该初始化函数 * @return false:初始化失败 true:初始化成功 */ -bool mt_init_frame(const char *conf, int argc, char * const argv[]) +bool mt_init_frame(int argc, char * const argv[]) { - if (conf && argc) { - ff_init(conf, argc, argv); + if (argc) { + ff_init(argc, argv); ff_set_hook_flag(); } memset(&g_mt_syscall_tab, 0, sizeof(g_mt_syscall_tab)); diff --git a/app/micro_thread/mt_api.h b/app/micro_thread/mt_api.h index c10a16454..cdf61c794 100644 --- a/app/micro_thread/mt_api.h +++ b/app/micro_thread/mt_api.h @@ -296,7 +296,7 @@ void* mt_get_msg_private(); * 使用spp,直接调用SyncFrame的框架初始化函数即可 * @return false:初始化失败 true:初始化成功 */ -bool mt_init_frame(const char *conf=NULL, int argc=0, char * const argv[]=NULL); +bool mt_init_frame(int argc=0, char * const argv[]=NULL); /** * @brief 设置微线程独立栈空间大小 diff --git a/app/micro_thread/mt_self_echo.cpp b/app/micro_thread/mt_self_echo.cpp index fbe9ffb7c..b8ae08059 100644 --- a/app/micro_thread/mt_self_echo.cpp +++ b/app/micro_thread/mt_self_echo.cpp @@ -239,7 +239,7 @@ int main(int argc, char* argv[]) addr.sin_addr.s_addr = inet_addr("112.90.143.29"); addr.sin_port = htons(19999); - mt_init_frame("./config.ini", argc, argv); + mt_init_frame(argc, argv); mt_start_thread((void*)server,NULL); diff --git a/app/micro_thread/mt_sys_hook.cpp b/app/micro_thread/mt_sys_hook.cpp index 63e11052a..dd70f4109 100644 --- a/app/micro_thread/mt_sys_hook.cpp +++ b/app/micro_thread/mt_sys_hook.cpp @@ -122,7 +122,7 @@ int ioctl(int fd, unsigned long cmd, ...) mt_hook_syscall(ioctl); MtHookFd* hook_fd = mt_hook_find_fd(fd); - if (!mt_hook_active() || !hook_fd) + if (!mt_hook_active() || !hook_fd || !ff_hook_active()) { return ff_hook_ioctl(fd, cmd, arg); } @@ -145,9 +145,9 @@ int socket(int domain, int type, int protocol) { mt_hook_syscall(socket); - if (!mt_hook_active()) + if (!ff_hook_active()) { - return ff_hook_socket(domain, type, protocol); + return mt_real_func(socket)(domain, type, protocol); } int fd = ff_hook_socket(domain, type, protocol); @@ -158,7 +158,6 @@ int socket(int domain, int type, int protocol) mt_hook_new_fd(fd); - mt_hook_syscall(ioctl); int nb = 1; ff_hook_ioctl(fd, FIONBIO, &nb); @@ -172,9 +171,9 @@ int socket(int domain, int type, int protocol) int close(int fd) { mt_hook_syscall(close); - if (!mt_hook_active()) + if (!ff_hook_active()) { - return ff_hook_close(fd); + return mt_real_func(close)(fd); } mt_hook_free_fd(fd); @@ -189,9 +188,9 @@ int connect(int fd, const struct sockaddr *address, socklen_t address_len) { mt_hook_syscall(connect); MtHookFd* hook_fd = mt_hook_find_fd(fd); - if (!mt_hook_active() || !hook_fd) + if (!mt_hook_active() || !hook_fd || !ff_hook_active()) { - return ff_hook_connect(fd, address, address_len); + return mt_real_func(connect)(fd, address, address_len); } if (hook_fd->sock_flag & MT_FD_FLG_UNBLOCK) @@ -209,9 +208,9 @@ ssize_t read(int fd, void *buf, size_t nbyte) { mt_hook_syscall(read); MtHookFd* hook_fd = mt_hook_find_fd(fd); - if (!mt_hook_active() || !hook_fd) + if (!mt_hook_active() || !hook_fd || !ff_hook_active()) { - return ff_hook_read(fd, buf, nbyte); + return mt_real_func(read)(fd, buf, nbyte); } if (hook_fd->sock_flag & MT_FD_FLG_UNBLOCK) @@ -229,9 +228,9 @@ ssize_t write(int fd, const void *buf, size_t nbyte) { mt_hook_syscall(write); MtHookFd* hook_fd = mt_hook_find_fd(fd); - if (!mt_hook_active() || !hook_fd) + if (!mt_hook_active() || !hook_fd || !ff_hook_active()) { - return ff_hook_write(fd, buf, nbyte); + return mt_real_func(write)(fd, buf, nbyte); } if (hook_fd->sock_flag & MT_FD_FLG_UNBLOCK) @@ -250,9 +249,9 @@ ssize_t sendto(int fd, const void *message, size_t length, int flags, { mt_hook_syscall(sendto); MtHookFd* hook_fd = mt_hook_find_fd(fd); - if (!mt_hook_active() || !hook_fd) + if (!mt_hook_active() || !hook_fd || !ff_hook_active()) { - return ff_hook_sendto(fd, message, length, flags, dest_addr, dest_len); + return mt_real_func(sendto)(fd, message, length, flags, dest_addr, dest_len); } if (hook_fd->sock_flag & MT_FD_FLG_UNBLOCK) @@ -272,9 +271,9 @@ ssize_t recvfrom(int fd, void *buffer, size_t length, int flags, { mt_hook_syscall(recvfrom); MtHookFd* hook_fd = mt_hook_find_fd(fd); - if (!mt_hook_active() || !hook_fd) + if (!mt_hook_active() || !hook_fd || !ff_hook_active()) { - return ff_hook_recvfrom(fd, buffer, length, flags, address, address_len); + return mt_real_func(recvfrom)(fd, buffer, length, flags, address, address_len); } if (hook_fd->sock_flag & MT_FD_FLG_UNBLOCK) @@ -293,9 +292,9 @@ ssize_t recv(int fd, void *buffer, size_t length, int flags) { mt_hook_syscall(recv); MtHookFd* hook_fd = mt_hook_find_fd(fd); - if (!mt_hook_active() || !hook_fd) + if (!mt_hook_active() || !hook_fd || !ff_hook_active()) { - return ff_hook_recv(fd, buffer, length, flags); + return mt_real_func(recv)(fd, buffer, length, flags); } if (hook_fd->sock_flag & MT_FD_FLG_UNBLOCK) @@ -313,9 +312,9 @@ ssize_t send(int fd, const void *buf, size_t nbyte, int flags) { mt_hook_syscall(send); MtHookFd* hook_fd = mt_hook_find_fd(fd); - if (!mt_hook_active() || !hook_fd) + if (!mt_hook_active() || !hook_fd || !ff_hook_active()) { - return ff_hook_send(fd, buf, nbyte, flags); + return mt_real_func(send)(fd, buf, nbyte, flags); } if (hook_fd->sock_flag & MT_FD_FLG_UNBLOCK) @@ -334,9 +333,9 @@ int setsockopt(int fd, int level, int option_name, const void *option_value, soc { mt_hook_syscall(setsockopt); MtHookFd* hook_fd = mt_hook_find_fd(fd); - if (!mt_hook_active() || !hook_fd) + if (!mt_hook_active() || !hook_fd || !ff_hook_active()) { - return ff_hook_setsockopt(fd, level, option_name, option_value, option_len); + return mt_real_func(setsockopt)(fd, level, option_name, option_value, option_len); } if (SOL_SOCKET == level) @@ -369,9 +368,9 @@ int fcntl(int fd, int cmd, ...) mt_hook_syscall(fcntl); MtHookFd* hook_fd = mt_hook_find_fd(fd); - if (!mt_hook_active() || !hook_fd) + if (!mt_hook_active() || !hook_fd || !ff_hook_active()) { - return ff_hook_fcntl(fd, cmd, arg); + return mt_real_func(fcntl)(fd, cmd, arg); } if (cmd == F_SETFL) @@ -393,18 +392,33 @@ int fcntl(int fd, int cmd, ...) int listen(int sockfd, int backlog) { mt_hook_syscall(listen); + if (!ff_hook_active()) + { + return mt_real_func(listen)(sockfd, backlog); + } + return ff_hook_listen(sockfd, backlog); } int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) { mt_hook_syscall(bind); + if (!ff_hook_active()) + { + return mt_real_func(bind)(sockfd, addr, addrlen); + } + return ff_hook_bind(sockfd, addr, addrlen); } int accept(int fd, struct sockaddr *addr, socklen_t *addrlen) { mt_hook_syscall(accept); + if (!ff_hook_active()) + { + return mt_real_func(accept)(fd, addr, addrlen); + } + return ff_hook_accept(fd, addr, addrlen); } diff --git a/app/nginx-1.11.10/src/event/modules/ngx_ff_module.c b/app/nginx-1.11.10/src/event/modules/ngx_ff_module.c index 0dcf12a3b..52f4a758d 100644 --- a/app/nginx-1.11.10/src/event/modules/ngx_ff_module.c +++ b/app/nginx-1.11.10/src/event/modules/ngx_ff_module.c @@ -1,40 +1,62 @@ /* - * Inspired by nginx_ofp's ngx_ofp_module.c. - * https://github.com/OpenFastPath/nginx_ofp. - * But According to #42, nginx_ofp's ngx_ofp_module.c may be derived from https://github.com/opendp/dpdk-nginx/blob/master/src/event/modules/ans_module.c, - * so add a license of opendp/dpdk-nginx. + * Inspired by opendp/dpdk-nginx's ans_module.c. + * License of opendp: + * + BSD LICENSE + Copyright(c) 2015-2017 Ansyun anssupport@163.com. All rights reserved. + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + Neither the name of Ansyun anssupport@163.com nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + Author: JiaKai (jiakai1000@gmail.com) and Bluestar (anssupport@163.com) */ -/*- -BSD LICENSE -Copyright(c) 2015-2017 Ansyun anssupport@163.com. All rights reserved. -All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. -Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in -the documentation and/or other materials provided with the -distribution. -Neither the name of Ansyun anssupport@163.com nor the names of its -contributors may be used to endorse or promote products derived -from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -Author: JiaKai (jiakai1000@gmail.com) and Bluestar (anssupport@163.com) -*/ +/* + * Copyright (C) 2017 THL A29 Limited, a Tencent company. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ #include #include @@ -64,9 +86,17 @@ Author: JiaKai (jiakai1000@gmail.com) and Bluestar (anssupport@163.com) #include #include -#define FF_FD_BITS 16 -#define CHK_FD_BIT(fd) (fd & (1 << FF_FD_BITS)) -#define CLR_FD_BIT(fd) (fd & ~(1 << FF_FD_BITS)) +#ifndef likely +#define likely(x) __builtin_expect((x),1) +#endif + +#ifndef unlikely +#define unlikely(x) __builtin_expect((x),0) +#endif + +#define INIT_FUNCTION(func) \ + real_##func = dlsym(RTLD_NEXT, #func); \ + assert(real_##func) static int (*real_close)(int); static int (*real_socket)(int, int, int); @@ -89,14 +119,12 @@ static int (*real_ioctl)(int, int, void *); static int (*real_select) (int, fd_set *, fd_set *, fd_set *, struct timeval *); +static int inited; + void ff_mod_init(int argc, char * const *argv) { int rc; -#define INIT_FUNCTION(func) \ - real_##func = dlsym(RTLD_NEXT, #func); \ - assert(real_##func) - INIT_FUNCTION(socket); INIT_FUNCTION(bind); INIT_FUNCTION(connect); @@ -115,12 +143,10 @@ ff_mod_init(int argc, char * const *argv) { INIT_FUNCTION(ioctl); INIT_FUNCTION(select); -#undef INIT_FUNCTION - - assert(argc >= 2); - - rc = ff_init(argv[1], argc, argv); + rc = ff_init(argc, argv); assert(0 == rc); + + inited = 1; } int @@ -128,14 +154,17 @@ socket(int domain, int type, int protocol) { int rc; + if (unlikely(inited == 0)) { + INIT_FUNCTION(socket); + return real_socket(domain, type, protocol); + } + if ((AF_INET != domain) || (SOCK_STREAM != type && SOCK_DGRAM != type)) { rc = real_socket(domain, type, protocol); return rc; } rc = ff_socket(domain, type, protocol); - if(rc >= 0) - rc |= 1 << FF_FD_BITS; return rc; } @@ -143,8 +172,12 @@ socket(int domain, int type, int protocol) int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) { - if (CHK_FD_BIT(sockfd)) { - sockfd = CLR_FD_BIT(sockfd); + if (unlikely(inited == 0)) { + INIT_FUNCTION(bind); + return real_bind(sockfd, addr, addrlen); + } + + if (ff_fdisused(sockfd)) { return ff_bind(sockfd, (struct linux_sockaddr *)addr, addrlen); } else { return real_bind(sockfd, addr, addrlen); @@ -154,8 +187,12 @@ bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) { - if (CHK_FD_BIT(sockfd)) { - sockfd = CLR_FD_BIT(sockfd); + if (unlikely(inited == 0)) { + INIT_FUNCTION(connect); + return real_connect(sockfd, addr, addrlen); + } + + if (ff_fdisused(sockfd)) { return ff_connect(sockfd, (struct linux_sockaddr *)addr, addrlen); } else { return real_connect(sockfd, addr, addrlen); @@ -165,8 +202,12 @@ connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) ssize_t send(int sockfd, const void *buf, size_t len, int flags) { - if (CHK_FD_BIT(sockfd)) { - sockfd = CLR_FD_BIT(sockfd); + if (unlikely(inited == 0)) { + INIT_FUNCTION(send); + return real_send(sockfd, buf, len, flags); + } + + if (ff_fdisused(sockfd)) { return ff_send(sockfd, buf, len, flags); } else { return real_send(sockfd, buf, len, flags); @@ -177,10 +218,14 @@ ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen) { - if (CHK_FD_BIT(sockfd)) { - sockfd = CLR_FD_BIT(sockfd); + if (unlikely(inited == 0)) { + INIT_FUNCTION(sendto); + return real_sendto(sockfd, buf, len, flags, dest_addr, addrlen); + } + + if (ff_fdisused(sockfd)) { return ff_sendto(sockfd, buf, len, flags, - (struct linux_sockaddr *)dest_addr, addrlen); + (struct linux_sockaddr *)dest_addr, addrlen); } else { return real_sendto(sockfd, buf, len, flags, dest_addr, addrlen); } @@ -189,8 +234,12 @@ sendto(int sockfd, const void *buf, size_t len, int flags, ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags) { - if (CHK_FD_BIT(sockfd)) { - sockfd = CLR_FD_BIT(sockfd); + if (unlikely(inited == 0)) { + INIT_FUNCTION(sendmsg); + return real_sendmsg(sockfd, msg, flags); + } + + if (ff_fdisused(sockfd)) { return ff_sendmsg(sockfd, msg, flags); } else { return real_sendmsg(sockfd, msg, flags); @@ -200,8 +249,12 @@ sendmsg(int sockfd, const struct msghdr *msg, int flags) ssize_t recv(int sockfd, void *buf, size_t len, int flags) { - if (CHK_FD_BIT(sockfd)) { - sockfd = CLR_FD_BIT(sockfd); + if (unlikely(inited == 0)) { + INIT_FUNCTION(recv); + return real_recv(sockfd, buf, len, flags); + } + + if (ff_fdisused(sockfd)) { return ff_recv(sockfd, buf, len, flags); } else { return real_recv(sockfd, buf, len, flags); @@ -211,8 +264,12 @@ recv(int sockfd, void *buf, size_t len, int flags) int listen(int sockfd, int backlog) { - if (CHK_FD_BIT(sockfd)) { - sockfd = CLR_FD_BIT(sockfd); + if (unlikely(inited == 0)) { + INIT_FUNCTION(listen); + return real_listen(sockfd, backlog); + } + + if (ff_fdisused(sockfd)) { return ff_listen(sockfd, backlog); } else { return real_listen(sockfd, backlog); @@ -223,8 +280,12 @@ int setsockopt (int sockfd, int level, int optname, const void *optval, socklen_t optlen) { - if (CHK_FD_BIT(sockfd)) { - sockfd = CLR_FD_BIT(sockfd); + if (unlikely(inited == 0)) { + INIT_FUNCTION(setsockopt); + return real_setsockopt(sockfd, level, optname, optval, optlen); + } + + if (ff_fdisused(sockfd)) { return ff_setsockopt(sockfd, level, optname, optval, optlen); } else { return real_setsockopt(sockfd, level, optname, optval, optlen); @@ -234,14 +295,13 @@ setsockopt (int sockfd, int level, int optname, int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) { - if (CHK_FD_BIT(sockfd)) { - sockfd = CLR_FD_BIT(sockfd); - int fd = ff_accept(sockfd, (struct linux_sockaddr *)addr, addrlen); - if (fd < 0) { - return fd; - } - fd |= 1 << FF_FD_BITS; - return fd; + if (unlikely(inited == 0)) { + INIT_FUNCTION(accept); + return real_accept(sockfd, addr, addrlen); + } + + if (ff_fdisused(sockfd)) { + return ff_accept(sockfd, (struct linux_sockaddr *)addr, addrlen); } else { return real_accept(sockfd, addr, addrlen); } @@ -250,8 +310,12 @@ accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) int accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags) { - if (CHK_FD_BIT(sockfd)) { - sockfd = CLR_FD_BIT(sockfd); + if (unlikely(inited == 0)) { + INIT_FUNCTION(accept4); + return real_accept4(sockfd, addr, addrlen, flags); + } + + if (ff_fdisused(sockfd)) { return ff_accept(sockfd, (struct linux_sockaddr *)addr, addrlen); } else { return real_accept4(sockfd, addr, addrlen, flags); @@ -261,13 +325,14 @@ accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags) int close(int sockfd) { - if (CHK_FD_BIT(sockfd)) { - sockfd = CLR_FD_BIT(sockfd); + if (unlikely(inited == 0)) { + INIT_FUNCTION(close); + return real_close(sockfd); + } + + if (ff_fdisused(sockfd)) { return ff_close(sockfd); } else { - if (__builtin_expect(!!(real_close == NULL), 0)) { - real_close = dlsym(RTLD_NEXT, "close"); - } return real_close(sockfd); } } @@ -275,8 +340,12 @@ close(int sockfd) ssize_t writev(int sockfd, const struct iovec *iov, int iovcnt) { - if (CHK_FD_BIT(sockfd)) { - sockfd = CLR_FD_BIT(sockfd); + if (unlikely(inited == 0)) { + INIT_FUNCTION(writev); + return real_writev(sockfd, iov, iovcnt); + } + + if (ff_fdisused(sockfd)) { return ff_writev(sockfd, iov, iovcnt); } else { return real_writev(sockfd, iov, iovcnt); @@ -286,8 +355,12 @@ writev(int sockfd, const struct iovec *iov, int iovcnt) ssize_t readv(int sockfd, const struct iovec *iov, int iovcnt) { - if (CHK_FD_BIT(sockfd)) { - sockfd = CLR_FD_BIT(sockfd); + if (unlikely(inited == 0)) { + INIT_FUNCTION(readv); + return real_readv(sockfd, iov, iovcnt); + } + + if (ff_fdisused(sockfd)) { return ff_readv(sockfd, iov, iovcnt); } else { return real_readv(sockfd, iov, iovcnt); @@ -297,8 +370,12 @@ readv(int sockfd, const struct iovec *iov, int iovcnt) int ioctl(int sockfd, int request, void *p) { - if (CHK_FD_BIT(sockfd)) { - sockfd = CLR_FD_BIT(sockfd); + if (unlikely(inited == 0)) { + INIT_FUNCTION(ioctl); + return real_ioctl(sockfd, request, p); + } + + if (ff_fdisused(sockfd)) { return ff_ioctl(sockfd, request, p); } else { return real_ioctl(sockfd, request, p); @@ -309,8 +386,12 @@ int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) { - if (CHK_FD_BIT(nfds)) { - nfds = CLR_FD_BIT(nfds); + if (unlikely(inited == 0)) { + INIT_FUNCTION(select); + return real_select(nfds, readfds, writefds, exceptfds, timeout); + } + + if (ff_fdisused(nfds)) { struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 0; diff --git a/app/nginx-1.11.10/src/event/modules/ngx_kqueue_module.c b/app/nginx-1.11.10/src/event/modules/ngx_kqueue_module.c index a2175bb6a..dc529782a 100644 --- a/app/nginx-1.11.10/src/event/modules/ngx_kqueue_module.c +++ b/app/nginx-1.11.10/src/event/modules/ngx_kqueue_module.c @@ -51,10 +51,6 @@ static struct kevent notify_kev; #endif #if (NGX_HAVE_FSTACK) -#define FF_FD_BITS 16 -#define CHK_FD_BIT(fd) (fd & (1 << FF_FD_BITS)) -#define CLR_FD_BIT(fd) (fd & ~(1 << FF_FD_BITS)) - extern int kqueue(void); extern int kevent(int kq, const struct kevent *changelist, int nchanges, struct kevent *eventlist, int nevents, const struct timespec *timeout); @@ -430,15 +426,7 @@ ngx_kqueue_set_event(ngx_event_t *ev, ngx_int_t filter, ngx_uint_t flags) kev = &change_list[nchanges]; -#if (NGX_HAVE_FSTACK) - ngx_socket_t fd = c->fd; - if (CHK_FD_BIT(fd)) - fd = CLR_FD_BIT(fd); - - kev->ident = fd; -#else kev->ident = c->fd; -#endif kev->filter = (short) filter; kev->flags = (u_short) flags; kev->udata = NGX_KQUEUE_UDATA_T ((uintptr_t) ev | ev->instance); @@ -593,9 +581,6 @@ ngx_kqueue_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, } for (i = 0; i < events; i++) { -#if (NGX_HAVE_FSTACK) - event_list[i].ident |= 1 << FF_FD_BITS; -#endif ngx_kqueue_dump_event(cycle->log, &event_list[i]); if (event_list[i].flags & EV_ERROR) { diff --git a/app/nginx-1.11.10/src/event/modules/ngx_select_module.c b/app/nginx-1.11.10/src/event/modules/ngx_select_module.c index 7d63e1d37..0b036ccb9 100644 --- a/app/nginx-1.11.10/src/event/modules/ngx_select_module.c +++ b/app/nginx-1.11.10/src/event/modules/ngx_select_module.c @@ -72,12 +72,6 @@ ngx_module_t ngx_select_module = { NGX_MODULE_V1_PADDING }; -#if (NGX_HAVE_FSTACK) -#define FF_FD_BITS 16 -#define CHK_FD_BIT(fd) (fd & (1 << FF_FD_BITS)) -#define CLR_FD_BIT(fd) (fd & ~(1 << FF_FD_BITS)) -#endif - static ngx_int_t ngx_select_init(ngx_cycle_t *cycle, ngx_msec_t timer) { @@ -154,20 +148,10 @@ ngx_select_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags) } if (event == NGX_READ_EVENT) { -#if (NGX_HAVE_FSTACK) - if (CHK_FD_BIT(c->fd)) - FD_SET(CLR_FD_BIT(c->fd), &master_read_fd_set); -#else FD_SET(c->fd, &master_read_fd_set); -#endif } else if (event == NGX_WRITE_EVENT) { -#if (NGX_HAVE_FSTACK) - if (CHK_FD_BIT(c->fd)) - FD_SET(CLR_FD_BIT(c->fd), &master_write_fd_set); -#else FD_SET(c->fd, &master_write_fd_set); -#endif } if (max_fd != -1 && max_fd < c->fd) { @@ -202,20 +186,10 @@ ngx_select_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags) "select del event fd:%d ev:%i", c->fd, event); if (event == NGX_READ_EVENT) { -#if (NGX_HAVE_FSTACK) - if (CHK_FD_BIT(c->fd)) - FD_CLR(CLR_FD_BIT(c->fd), &master_read_fd_set); -#else FD_CLR(c->fd, &master_read_fd_set); -#endif } else if (event == NGX_WRITE_EVENT) { -#if (NGX_HAVE_FSTACK) - if (CHK_FD_BIT(c->fd)) - FD_CLR(CLR_FD_BIT(c->fd), &master_write_fd_set); -#else FD_CLR(c->fd, &master_write_fd_set); -#endif } if (max_fd == c->fd) { diff --git a/app/redis-3.2.8/src/ae.c b/app/redis-3.2.8/src/ae.c index 3f015dc7e..585149433 100644 --- a/app/redis-3.2.8/src/ae.c +++ b/app/redis-3.2.8/src/ae.c @@ -139,11 +139,6 @@ void aeStop(aeEventLoop *eventLoop) { int aeCreateFileEvent(aeEventLoop *eventLoop, int fd, int mask, aeFileProc *proc, void *clientData) { -#ifdef HAVE_FF_KQUEUE - if (CHK_FD_BIT(fd)) { - fd = CLR_FD_BIT(fd); - } -#endif if (fd >= eventLoop->setsize) { errno = ERANGE; return AE_ERR; @@ -163,11 +158,6 @@ int aeCreateFileEvent(aeEventLoop *eventLoop, int fd, int mask, void aeDeleteFileEvent(aeEventLoop *eventLoop, int fd, int mask) { -#ifdef HAVE_FF_KQUEUE - if (CHK_FD_BIT(fd)) { - fd = CLR_FD_BIT(fd); - } -#endif if (fd >= eventLoop->setsize) return; aeFileEvent *fe = &eventLoop->events[fd]; if (fe->mask == AE_NONE) return; @@ -415,11 +405,7 @@ int aeProcessEvents(aeEventLoop *eventLoop, int flags) for (j = 0; j < numevents; j++) { aeFileEvent *fe = &eventLoop->events[eventLoop->fired[j].fd]; int mask = eventLoop->fired[j].mask; -#ifdef HAVE_FF_KQUEUE - int fd = eventLoop->fired[j].fd | (1 << FF_FD_BITS); -#else int fd = eventLoop->fired[j].fd; -#endif int rfired = 0; /* note the fe->mask & mask & ... code: maybe an already processed diff --git a/app/redis-3.2.8/src/ae_ff_kqueue.c b/app/redis-3.2.8/src/ae_ff_kqueue.c index 462c52920..907f52d21 100644 --- a/app/redis-3.2.8/src/ae_ff_kqueue.c +++ b/app/redis-3.2.8/src/ae_ff_kqueue.c @@ -35,10 +35,6 @@ typedef unsigned short u_short; typedef unsigned int u_int; #include "ff_api.h" -#define FF_FD_BITS 16 -#define CHK_FD_BIT(fd) (fd & (1 << FF_FD_BITS)) -#define CLR_FD_BIT(fd) (fd & ~(1 << FF_FD_BITS)) - typedef struct aeApiState { int kqfd; struct kevent *events; diff --git a/app/redis-3.2.8/src/anet_ff.c b/app/redis-3.2.8/src/anet_ff.c index 0f40aa4be..9321760fe 100644 --- a/app/redis-3.2.8/src/anet_ff.c +++ b/app/redis-3.2.8/src/anet_ff.c @@ -1,39 +1,62 @@ /* - * Inspired by nginx_ofp's ngx_ofp_module.c. - * https://github.com/OpenFastPath/nginx_ofp. - * Related #42. + * Inspired by opendp/dpdk-nginx's ans_module.c. + * License of opendp: + * + BSD LICENSE + Copyright(c) 2015-2017 Ansyun anssupport@163.com. All rights reserved. + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + Neither the name of Ansyun anssupport@163.com nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + Author: JiaKai (jiakai1000@gmail.com) and Bluestar (anssupport@163.com) */ -/*- -BSD LICENSE -Copyright(c) 2015-2017 Ansyun anssupport@163.com. All rights reserved. -All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. -Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in -the documentation and/or other materials provided with the -distribution. -Neither the name of Ansyun anssupport@163.com nor the names of its -contributors may be used to endorse or promote products derived -from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -Author: JiaKai (jiakai1000@gmail.com) and Bluestar (anssupport@163.com) -*/ +/* + * Copyright (C) 2017 THL A29 Limited, a Tencent company. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ #include #include @@ -64,9 +87,20 @@ typedef unsigned int u_int; #include #include -#define FF_FD_BITS 16 -#define CHK_FD_BIT(fd) (fd & (1 << FF_FD_BITS)) -#define CLR_FD_BIT(fd) (fd & ~(1 << FF_FD_BITS)) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpedantic" + +#ifndef likely +#define likely(x) __builtin_expect((x),1) +#endif + +#ifndef unlikely +#define unlikely(x) __builtin_expect((x),0) +#endif + +#define INIT_FUNCTION(func) \ + real_##func = dlsym(RTLD_NEXT, #func); \ + assert(real_##func) static int inited = 0; @@ -94,14 +128,6 @@ static int (*real_select) (int, fd_set *, fd_set *, fd_set *, struct timeval *); void ff_mod_init() { -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wpedantic" - //int rc; - - #define INIT_FUNCTION(func) \ - real_##func = dlsym(RTLD_NEXT, #func); \ - assert(real_##func) - INIT_FUNCTION(socket); INIT_FUNCTION(bind); INIT_FUNCTION(connect); @@ -121,169 +147,232 @@ void ff_mod_init() { INIT_FUNCTION(fcntl); INIT_FUNCTION(select); -#undef INIT_FUNCTION - inited = 1; -#pragma GCC diagnostic pop } -int socket(int domain, int type, int protocol) +int +socket(int domain, int type, int protocol) { int rc; - if ((inited == 0) || (AF_INET != domain) || (SOCK_STREAM != type && SOCK_DGRAM != type)) - { + if (unlikely(inited == 0)) { + INIT_FUNCTION(socket); + return real_socket(domain, type, protocol); + } + + if ((AF_INET != domain) || (SOCK_STREAM != type && SOCK_DGRAM != type)) { rc = real_socket(domain, type, protocol); return rc; } rc = ff_socket(domain, type, protocol); - if(rc >= 0) - rc |= 1 << FF_FD_BITS; return rc; } -int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) +int +bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) { - if (CHK_FD_BIT(sockfd)) { - sockfd = CLR_FD_BIT(sockfd); + if (unlikely(inited == 0)) { + INIT_FUNCTION(bind); + return real_bind(sockfd, addr, addrlen); + } + + if (ff_fdisused(sockfd)) { return ff_bind(sockfd, (struct linux_sockaddr *)addr, addrlen); } else { return real_bind(sockfd, addr, addrlen); } } -int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) +int +connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) { - if (CHK_FD_BIT(sockfd)) { - sockfd = CLR_FD_BIT(sockfd); + if (unlikely(inited == 0)) { + INIT_FUNCTION(connect); + return real_connect(sockfd, addr, addrlen); + } + + if (ff_fdisused(sockfd)) { return ff_connect(sockfd, (struct linux_sockaddr *)addr, addrlen); } else { return real_connect(sockfd, addr, addrlen); } } -ssize_t send(int sockfd, const void *buf, size_t len, int flags) +ssize_t +send(int sockfd, const void *buf, size_t len, int flags) { - if (CHK_FD_BIT(sockfd)) { - sockfd = CLR_FD_BIT(sockfd); + if (unlikely(inited == 0)) { + INIT_FUNCTION(send); + return real_send(sockfd, buf, len, flags); + } + + if (ff_fdisused(sockfd)) { return ff_send(sockfd, buf, len, flags); } else { return real_send(sockfd, buf, len, flags); } } -ssize_t write(int sockfd, const void *buf, size_t count) +ssize_t +recv(int sockfd, void *buf, size_t len, int flags) { - if (CHK_FD_BIT(sockfd)) { - sockfd = CLR_FD_BIT(sockfd); - return ff_write(sockfd, buf, count); - } else { - return real_write(sockfd, buf, count); + if (unlikely(inited == 0)) { + INIT_FUNCTION(recv); + return real_recv(sockfd, buf, len, flags); } -} -ssize_t recv(int sockfd, void *buf, size_t len, int flags) -{ - if (CHK_FD_BIT(sockfd)) { - sockfd = CLR_FD_BIT(sockfd); + if (ff_fdisused(sockfd)) { return ff_recv(sockfd, buf, len, flags); } else { return real_recv(sockfd, buf, len, flags); } } -ssize_t read(int sockfd, void *buf, size_t count) +int +listen(int sockfd, int backlog) { - if (CHK_FD_BIT(sockfd)) { - sockfd = CLR_FD_BIT(sockfd); - return ff_read(sockfd, buf, count); - } else { - return real_read(sockfd, buf, count); + if (unlikely(inited == 0)) { + INIT_FUNCTION(listen); + return real_listen(sockfd, backlog); } -} -int listen(int sockfd, int backlog) -{ - if (CHK_FD_BIT(sockfd)) { - sockfd = CLR_FD_BIT(sockfd); + if (ff_fdisused(sockfd)) { return ff_listen(sockfd, backlog); } else { return real_listen(sockfd, backlog); } } -int setsockopt (int sockfd, int level, int optname, +int +setsockopt (int sockfd, int level, int optname, const void *optval, socklen_t optlen) { - if (CHK_FD_BIT(sockfd)) { - sockfd = CLR_FD_BIT(sockfd); + if (unlikely(inited == 0)) { + INIT_FUNCTION(setsockopt); + return real_setsockopt(sockfd, level, optname, optval, optlen); + } + + if (ff_fdisused(sockfd)) { return ff_setsockopt(sockfd, level, optname, optval, optlen); } else { return real_setsockopt(sockfd, level, optname, optval, optlen); } } -int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) +int +accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) { - if (CHK_FD_BIT(sockfd)) { - sockfd = CLR_FD_BIT(sockfd); - int fd = ff_accept(sockfd, (struct linux_sockaddr *)addr, addrlen); - if (fd < 0) { - return fd; - } - fd |= 1 << FF_FD_BITS; - return fd; + if (unlikely(inited == 0)) { + INIT_FUNCTION(accept); + return real_accept(sockfd, addr, addrlen); + } + + if (ff_fdisused(sockfd)) { + return ff_accept(sockfd, (struct linux_sockaddr *)addr, addrlen); } else { return real_accept(sockfd, addr, addrlen); } } -int accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags) +int +accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags) { - if (CHK_FD_BIT(sockfd)) { - sockfd = CLR_FD_BIT(sockfd); + if (unlikely(inited == 0)) { + INIT_FUNCTION(accept4); + return real_accept4(sockfd, addr, addrlen, flags); + } + + if (ff_fdisused(sockfd)) { return ff_accept(sockfd, (struct linux_sockaddr *)addr, addrlen); } else { return real_accept4(sockfd, addr, addrlen, flags); } } -int close(int sockfd) +int +close(int sockfd) { - if (CHK_FD_BIT(sockfd)) { - sockfd = CLR_FD_BIT(sockfd); + if (unlikely(inited == 0)) { + INIT_FUNCTION(close); + return real_close(sockfd); + } + + if (ff_fdisused(sockfd)) { return ff_close(sockfd); } else { return real_close(sockfd); } } -ssize_t writev(int sockfd, const struct iovec *iov, int iovcnt) +ssize_t write(int sockfd, const void *buf, size_t count) { - if (CHK_FD_BIT(sockfd)) { - sockfd = CLR_FD_BIT(sockfd); + if (unlikely(inited == 0)) { + INIT_FUNCTION(write); + return real_write(sockfd, buf, count); + } + + if (ff_fdisused(sockfd)) { + return ff_write(sockfd, buf, count); + } else { + return real_write(sockfd, buf, count); + } +} + +ssize_t +writev(int sockfd, const struct iovec *iov, int iovcnt) +{ + if (unlikely(inited == 0)) { + INIT_FUNCTION(writev); + return real_writev(sockfd, iov, iovcnt); + } + + if (ff_fdisused(sockfd)) { return ff_writev(sockfd, iov, iovcnt); } else { return real_writev(sockfd, iov, iovcnt); } } -ssize_t readv(int sockfd, const struct iovec *iov, int iovcnt) +ssize_t read(int sockfd, void *buf, size_t count) { - if (CHK_FD_BIT(sockfd)) { - sockfd = CLR_FD_BIT(sockfd); + if (unlikely(inited == 0)) { + INIT_FUNCTION(read); + return real_read(sockfd, buf, count); + } + + if (ff_fdisused(sockfd)) { + return ff_read(sockfd, buf, count); + } else { + return real_read(sockfd, buf, count); + } +} + +ssize_t +readv(int sockfd, const struct iovec *iov, int iovcnt) +{ + if (unlikely(inited == 0)) { + INIT_FUNCTION(readv); + return real_readv(sockfd, iov, iovcnt); + } + + if (ff_fdisused(sockfd)) { return ff_readv(sockfd, iov, iovcnt); } else { return real_readv(sockfd, iov, iovcnt); } } -int ioctl(int sockfd, int request, void *p) +int +ioctl(int sockfd, int request, void *p) { - if (CHK_FD_BIT(sockfd)) { - sockfd = CLR_FD_BIT(sockfd); + if (unlikely(inited == 0)) { + INIT_FUNCTION(ioctl); + return real_ioctl(sockfd, request, p); + } + + if (ff_fdisused(sockfd)) { return ff_ioctl(sockfd, request, p); } else { return real_ioctl(sockfd, request, p); @@ -292,19 +381,28 @@ int ioctl(int sockfd, int request, void *p) int fcntl(int sockfd, int cmd, void *p) { - if (CHK_FD_BIT(sockfd)) { - sockfd = CLR_FD_BIT(sockfd); + if (unlikely(inited == 0)) { + INIT_FUNCTION(fcntl); + return real_fcntl(sockfd, cmd, p); + } + + if (ff_fdisused(sockfd)) { return ff_fcntl(sockfd, cmd, p); } else { return real_fcntl(sockfd, cmd, p); } } -int select(int nfds, fd_set *readfds, fd_set *writefds, +int +select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) { - if (CHK_FD_BIT(nfds)) { - nfds = CLR_FD_BIT(nfds); + if (unlikely(inited == 0)) { + INIT_FUNCTION(select); + return real_select(nfds, readfds, writefds, exceptfds, timeout); + } + + if (ff_fdisused(nfds)) { struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 0; @@ -314,3 +412,5 @@ int select(int nfds, fd_set *readfds, fd_set *writefds, } } +#pragma GCC diagnostic pop + diff --git a/app/redis-3.2.8/src/config.ini b/app/redis-3.2.8/src/config.ini deleted file mode 100644 index 5f12a7907..000000000 --- a/app/redis-3.2.8/src/config.ini +++ /dev/null @@ -1,68 +0,0 @@ -[dpdk] -lcore_mask=1 -# set lcore_mask=1, use only one processor (https://redis.io/topics/faq#redis-is-single-threaded-how-can-i-exploit-multiple-cpu--cores) -## Port mask, enable and disable ports. -## Default: all ports are enabled. -#port_mask=1 -channel=4 -nb_ports=1 -promiscuous=1 -numa_on=1 - -[port0] -addr=192.168.1.2 -netmask=255.255.255.0 -broadcast=192.168.1.255 -gateway=192.168.1.1 -## Packet capture path, this will hurt performance -#pcap=./a.pcap - -## Kni config: if enabled and method=reject, -## all packets that do not belong to the following tcp_port and udp_port -## will transmit to kernel; if method=accept, all packets that belong to -## the following tcp_port and udp_port will transmit to kernel. -#[kni] -#enable=1 -#method=reject -#tcp_port=80 -#udp_port=53 - -[log] -level=1 -dir=/var/log - -## FreeBSD network performance tuning configurations. -## Most native FreeBSD configurations are supported. -[freebsd.boot] -hz=100 - -kern.ipc.maxsockets=262144 - -net.inet.tcp.syncache.hashsize=4096 -net.inet.tcp.syncache.bucketlimit=100 - -net.inet.tcp.tcbhashsize=65536 - -[freebsd.sysctl] -kern.ipc.somaxconn=32768 -kern.ipc.maxsockbuf=16777216 - -net.inet.tcp.fast_finwait2_recycle=1 -net.inet.tcp.sendspace=16384 -net.inet.tcp.recvspace=8192 -net.inet.tcp.nolocaltimewait=1 -net.inet.tcp.cc.algorithm=htcp -net.inet.tcp.sendbuf_max=16777216 -net.inet.tcp.recvbuf_max=16777216 -net.inet.tcp.sendbuf_auto=1 -net.inet.tcp.recvbuf_auto=1 -net.inet.tcp.sendbuf_inc=16384 -net.inet.tcp.recvbuf_inc=524288 -net.inet.tcp.inflight.enable=0 -net.inet.tcp.sack=1 -net.inet.tcp.blackhole=1 -net.inet.tcp.msl=2000 -net.inet.tcp.delayed_ack=0 - -net.inet.udp.blackhole=1 -net.inet.ip.redirect=0 diff --git a/app/redis-3.2.8/src/server.c b/app/redis-3.2.8/src/server.c index fe9c781cf..5b962a6f0 100644 --- a/app/redis-3.2.8/src/server.c +++ b/app/redis-3.2.8/src/server.c @@ -3954,18 +3954,22 @@ int main(int argc, char **argv) { int j; #ifdef HAVE_FF_KQUEUE - ff_mod_init(); - int rc = ff_init(argv[1], argc, argv); + int rc = ff_init(argc, argv); assert(0 == rc); - // TODO - char **tmp_argv = zmalloc(sizeof(char *) * (argc - 6)); + ff_mod_init(); + //split fstack arguments. + int new_argc = argc - 3; + if (new_argc <= 0) { + new_argc = 1; + } + char **new_argv = zmalloc(sizeof(char *) * new_argc); + new_argv[0] = argv[0]; int i; - for (i = 0; i < argc; i++) { - tmp_argv[i] = argv[i + 6]; + for (i = 1; i < new_argc; i++) { + new_argv[i] = argv[i + 3]; } - tmp_argv[0] = argv[0]; - argv = tmp_argv; - argc -= 6; + argv = new_argv; + argc = new_argc; #endif #ifdef REDIS_TEST @@ -4139,7 +4143,7 @@ int main(int argc, char **argv) { ff_run(loop, server.el); aeDeleteEventLoop(server.el); #ifdef HAVE_FF_KQUEUE - zfree(tmp_argv); + zfree(new_argv); #endif return 0; } diff --git a/app/redis-3.2.8/src/start.sh b/app/redis-3.2.8/src/start.sh deleted file mode 100644 index fcfe6a26f..000000000 --- a/app/redis-3.2.8/src/start.sh +++ /dev/null @@ -1,67 +0,0 @@ -#!/bin/bash - -function usage() { - echo "F-Stack app start tool" - echo "Options:" - echo " -c [conf] Path of config file" - echo " -b [N] Path of binary" - echo " -h show this help" - exit -} - -conf=./config.ini -bin=./redis-server - -while getopts "c:b:h" args -do - case $args in - c) - conf=$OPTARG - ;; - b) - bin=$OPTARG - ;; - h) - usage - exit 0 - ;; - esac -done - -allcmask0x=`cat ${conf}|grep lcore_mask|awk -F '=' '{print $2}'` -((allcmask=16#$allcmask0x)) - -num_procs=0 -PROCESSOR=$(grep 'processor' /proc/cpuinfo |sort |uniq |wc -l) -for((i=0;i<${PROCESSOR};++i)) -do - mask=`echo "2^$i"|bc` - ((result=${allcmask} & ${mask})) - if [ ${result} != 0 ] - then - ((num_procs++)); - cpuinfo[$i]=1 - else - cpuinfo[$i]=0 - fi -done - -proc_id=0 -for((i=0;i<${PROCESSOR};++i)) -do - if ((cpuinfo[$i] == 1)) - then - cmask=`echo "2^$i"|bc` - cmask=`echo "obase=16;${cmask}"|bc` - if ((proc_id == 0)) - then - echo "${bin} ${conf} -c $cmask --proc-type=primary --num-procs=${num_procs} --proc-id=${proc_id}" - ${bin} ${conf} -c ${cmask} --proc-type=primary --num-procs=${num_procs} --proc-id=${proc_id} ../redis.conf & - sleep 5 - else - echo "${bin} ${conf} -c $cmask --proc-type=secondary --num-procs=${num_procs} --proc-id=${proc_id}" - ${bin} ${conf} -c $cmask --proc-type=secondary --num-procs=${num_procs} --proc-id=${proc_id} ../redis.conf & - fi - ((proc_id++)) - fi -done diff --git a/config.ini b/config.ini index d030042d4..96fcfd122 100644 --- a/config.ini +++ b/config.ini @@ -37,6 +37,11 @@ gateway=192.168.1.1 [freebsd.boot] hz=100 +## Block out a range of descriptors to avoid overlap +## with the kernel's descriptor space. +## You can increase this value according to your app. +fd_reserve=1024 + kern.ipc.maxsockets=262144 net.inet.tcp.syncache.hashsize=4096 diff --git a/example/main.c b/example/main.c index d0e232902..0e2fcd053 100644 --- a/example/main.c +++ b/example/main.c @@ -103,14 +103,7 @@ int loop(void *arg) int main(int argc, char * argv[]) { - char *conf; - if (argc < 2) { - conf = "./config.ini"; - } else { - conf = argv[1]; - } - - ff_init(conf, argc, argv); + ff_init(argc, argv); int sockfd = ff_socket(AF_INET, SOCK_STREAM, 0); printf("sockfd:%d\n", sockfd); diff --git a/example/main_epoll.c b/example/main_epoll.c index 5842f3d1f..de8f3889b 100644 --- a/example/main_epoll.c +++ b/example/main_epoll.c @@ -18,9 +18,7 @@ #define MAX_EVENTS 512 struct epoll_event ev; - struct epoll_event events[MAX_EVENTS]; -struct kevent kqevents[MAX_EVENTS]; int epfd; int sockfd; @@ -100,14 +98,7 @@ int loop(void *arg) int main(int argc, char * argv[]) { - char *conf; - if (argc < 2) { - conf = "./config.ini"; - } else { - conf = argv[1]; - } - - ff_init(conf, argc, argv); + ff_init(argc, argv); sockfd = ff_socket(AF_INET, SOCK_STREAM, 0); printf("sockfd:%d\n", sockfd); diff --git a/freebsd/kern/kern_descrip.c b/freebsd/kern/kern_descrip.c index d4ee583d1..6326867ed 100644 --- a/freebsd/kern/kern_descrip.c +++ b/freebsd/kern/kern_descrip.c @@ -4105,4 +4105,30 @@ fildesc_drvinit(void *unused) SYSINIT(fildescdev, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, fildesc_drvinit, NULL); +#else + +int +ff_fdisused(int fd) +{ + struct thread *td = curthread; + + return (fd < td->td_proc->p_fd->fd_nfiles && + fdisused(td->td_proc->p_fd, fd) && + td->td_proc->p_fd->fd_ofiles[fd].fde_file != NULL); +} + +/* + * block out a range of descriptors to avoid overlap with + * the kernel's descriptor space + */ +void +ff_fdused_range(struct filedesc *fdp, int max) +{ + int i; + + for (i = 0; i < max; i++) + fdused(fdp, i); +} + #endif + diff --git a/lib/ff_api.h b/lib/ff_api.h index 5ca680b8f..0c7758d77 100644 --- a/lib/ff_api.h +++ b/lib/ff_api.h @@ -46,7 +46,7 @@ struct linux_sockaddr { typedef int (*loop_func_t)(void *arg); -int ff_init(const char *conf, int argc, char * const argv[]); +int ff_init(int argc, char * const argv[]); void ff_run(loop_func_t loop, void *arg); @@ -109,6 +109,9 @@ int ff_kevent_do_each(int kq, const struct kevent *changelist, int nchanges, int ff_gettimeofday(struct timeval *tv, struct timezone *tz); +extern int ff_fdisused(int fd); + + /* route api begin */ enum FF_ROUTE_CTL { FF_ROUTE_ADD, diff --git a/lib/ff_api.symlist b/lib/ff_api.symlist index 88199d408..555e0b0bb 100644 --- a/lib/ff_api.symlist +++ b/lib/ff_api.symlist @@ -41,3 +41,4 @@ ff_mbuf_tx_offload ff_route_ctl ff_rtioctl ff_gettimeofday +ff_fdisused diff --git a/lib/ff_config.c b/lib/ff_config.c index c35c0ab83..4ac57bbec 100644 --- a/lib/ff_config.c +++ b/lib/ff_config.c @@ -29,24 +29,109 @@ #include #include #include +#include +#include + #include "ff_config.h" #include "ff_ini_parser.h" +#define DEFAULT_CONFIG_FILE "config.ini" + +#define BITS_PER_HEX 4 + struct ff_config ff_global_cfg; int dpdk_argc; char *dpdk_argv[DPDK_CONFIG_NUM + 1]; -int dpdk_argc_arg; -char *dpdk_argv_arg[DPDK_CONFIG_NUM + 1]; - -char* const short_options = "c:"; -struct option long_options[] = { - { "proc-type", 1, NULL, 0 }, - { "num-procs", 1, NULL, 0 }, - { "proc-id", 1, NULL, 0 }, - { 0, 0, 0, 0}, +char* const short_options = "c:t:p:"; +struct option long_options[] = { + { "conf", 1, NULL, 'c'}, + { "proc-type", 1, NULL, 't'}, + { "proc-id", 1, NULL, 'p'}, + { 0, 0, 0, 0}, }; +static int +xdigit2val(unsigned char c) +{ + int val; + + if (isdigit(c)) + val = c - '0'; + else if (isupper(c)) + val = c - 'A' + 10; + else + val = c - 'a' + 10; + return val; +} + +static int +parse_lcore_mask(struct ff_config *cfg, const char *coremask) +{ + int i, j, idx = 0; + unsigned count = 0; + char c; + int val; + uint16_t *proc_lcore; + char buf[RTE_MAX_LCORE] = {0}; + + if (coremask == NULL) + return 0; + + cfg->dpdk.proc_lcore = (uint16_t *)calloc(RTE_MAX_LCORE, sizeof(uint16_t)); + if (cfg->dpdk.proc_lcore == NULL) { + fprintf(stderr, "parse_lcore_mask malloc failed\n"); + return 0; + } + proc_lcore = cfg->dpdk.proc_lcore; + + /* + * Remove all blank characters ahead and after. + * Remove 0x/0X if exists. + */ + while (isblank(*coremask)) + coremask++; + if (coremask[0] == '0' && ((coremask[1] == 'x') + || (coremask[1] == 'X'))) + coremask += 2; + + i = strlen(coremask); + while ((i > 0) && isblank(coremask[i - 1])) + i--; + + if (i == 0) + return 0; + + for (i = i - 1; i >= 0 && idx < RTE_MAX_LCORE; i--) { + c = coremask[i]; + if (isxdigit(c) == 0) { + return 0; + } + val = xdigit2val(c); + for (j = 0; j < BITS_PER_HEX && idx < RTE_MAX_LCORE; j++, idx++) { + if ((1 << j) & val) { + proc_lcore[count] = idx; + if (cfg->dpdk.proc_id == count) { + sprintf(buf, "%x", 1<dpdk.proc_mask = strdup(buf); + } + count++; + } + } + } + + for (; i >= 0; i--) + if (coremask[i] != '0') + return 0; + + if (cfg->dpdk.proc_id >= count) + return 0; + + cfg->dpdk.nb_procs = count; + + return 1; +} + static int is_integer(const char *s) { @@ -160,10 +245,10 @@ port_cfg_handler(struct ff_config *cfg, const char *section, } static int -handler(void* user, const char* section, const char* name, +ini_parse_handler(void* user, const char* section, const char* name, const char* value) { - struct ff_config* pconfig = (struct ff_config*)user; + struct ff_config *pconfig = (struct ff_config*)user; printf("[%s]: %s=%s\n", section, name, value); @@ -176,6 +261,7 @@ handler(void* user, const char* section, const char* name, pconfig->dpdk.no_huge = atoi(value); } else if (MATCH("dpdk", "lcore_mask")) { pconfig->dpdk.lcore_mask = strdup(value); + return parse_lcore_mask(pconfig, pconfig->dpdk.lcore_mask); } else if (MATCH("dpdk", "port_mask")) { pconfig->dpdk.port_mask = atoi(value); } else if (MATCH("dpdk", "nb_ports")) { @@ -212,7 +298,7 @@ handler(void* user, const char* section, const char* name, } static int -dpdk_argc_argv_setup(struct ff_config *cfg) +dpdk_args_setup(struct ff_config *cfg) { int n = 0, i; dpdk_argv[n++] = strdup("f-stack"); @@ -233,9 +319,9 @@ dpdk_argc_argv_setup(struct ff_config *cfg) sprintf(temp, "-m%d", cfg->dpdk.memory); dpdk_argv[n++] = strdup(temp); } - - for(i = 0; i < dpdk_argc_arg; ++i) { - dpdk_argv[n++] = dpdk_argv_arg[i]; + if (cfg->dpdk.proc_type) { + sprintf(temp, "--proc-type=%s", cfg->dpdk.proc_type); + dpdk_argv[n++] = strdup(temp); } dpdk_argc = n; @@ -243,33 +329,40 @@ dpdk_argc_argv_setup(struct ff_config *cfg) return n; } -static void -ff_load_arg(struct ff_config *cfg, int argc, char *const argv[]) +static int +ff_parse_args(struct ff_config *cfg, int argc, char *const argv[]) { - dpdk_argc_arg = 0; int c; int index = 0; while((c = getopt_long(argc, argv, short_options, long_options, &index)) != -1) { switch (c) { case 'c': - cfg->dpdk.proc_mask = strdup(optarg); + cfg->filename = strdup(optarg); break; - case 0: - if (0 == strcmp(long_options[index].name, "num-procs")) { - cfg->dpdk.nb_procs = atoi(optarg); - } else if(0 == strcmp(long_options[index].name, "proc-id")) { - cfg->dpdk.proc_id = atoi(optarg); - } else if(0 == strcmp(long_options[index].name, "proc-type")) { - char temp[DPDK_CONFIG_MAXLEN] = {0}; - sprintf(temp, "--proc-type=%s",optarg); - dpdk_argv_arg[dpdk_argc_arg++] = strdup(temp); - } + case 'p': + cfg->dpdk.proc_id = atoi(optarg); + break; + case 't': + cfg->dpdk.proc_type = strdup(optarg); break; default: - break; + return -1; } } - return; + + if (cfg->dpdk.proc_type == NULL || + (strcmp(cfg->dpdk.proc_type, "primary") && + strcmp(cfg->dpdk.proc_type, "secondary"))) { + printf("invalid proc-type\n"); + return -1; + } + + if ((uint16_t)cfg->dpdk.proc_id > RTE_MAX_LCORE) { + printf("proc_id:%d is too large\n", cfg->dpdk.proc_id); + return -1; + } + + return 0; } static int @@ -315,21 +408,31 @@ ff_default_config(struct ff_config *cfg) { memset(cfg, 0, sizeof(struct ff_config)); + cfg->filename = DEFAULT_CONFIG_FILE; + + cfg->dpdk.proc_id = -1; cfg->dpdk.numa_on = 1; cfg->dpdk.promiscuous = 1; cfg->freebsd.hz = 100; cfg->freebsd.physmem = 1048576*256; + cfg->freebsd.fd_reserve = 0; } int -ff_load_config(const char *conf, int argc, char * const argv[]) +ff_load_config(int argc, char *const argv[]) { ff_default_config(&ff_global_cfg); - - int ret = ini_parse(conf, handler, &ff_global_cfg); + + int ret = ff_parse_args(&ff_global_cfg, argc, argv); + if (ret < 0) { + return ret; + } + + ret = ini_parse(ff_global_cfg.filename, ini_parse_handler, + &ff_global_cfg); if (ret != 0) { - printf("parse %s failed on line %d\n", conf, ret); + printf("parse %s failed on line %d\n", ff_global_cfg.filename, ret); return -1; } @@ -337,8 +440,7 @@ ff_load_config(const char *conf, int argc, char * const argv[]) return -1; } - ff_load_arg(&ff_global_cfg, argc, argv); - if (dpdk_argc_argv_setup(&ff_global_cfg) <= 0) { + if (dpdk_args_setup(&ff_global_cfg) <= 0) { return -1; } diff --git a/lib/ff_config.h b/lib/ff_config.h index 08cac0d25..a37a0f430 100644 --- a/lib/ff_config.h +++ b/lib/ff_config.h @@ -63,7 +63,9 @@ struct ff_freebsd_cfg { }; struct ff_config { - struct { + char *filename; + struct { + char *proc_type; /* mask of enabled lcores */ char *lcore_mask; /* mask of current proc on all lcores */ @@ -81,6 +83,8 @@ struct ff_config { int promiscuous; int numa_on; int tso; + /* list of proc-lcore */ + uint16_t *proc_lcore; struct ff_port_cfg *port_cfgs; } dpdk; @@ -101,11 +105,12 @@ struct ff_config { struct ff_freebsd_cfg *sysctl; long physmem; int hz; + int fd_reserve; } freebsd; }; extern struct ff_config ff_global_cfg; -int ff_load_config(const char *conf, int argc, char * const argv[]); +int ff_load_config(int argc, char * const argv[]); #endif /* ifndef __FSTACK_CONFIG_H */ diff --git a/lib/ff_dpdk_if.c b/lib/ff_dpdk_if.c index cedc58ba0..9e22ae048 100644 --- a/lib/ff_dpdk_if.c +++ b/lib/ff_dpdk_if.c @@ -87,8 +87,6 @@ #define MAX_TX_QUEUE_PER_PORT RTE_MAX_ETHPORTS #define MAX_RX_QUEUE_PER_PORT 128 -#define BITS_PER_HEX 4 - #define KNI_MBUF_MAX 2048 #define KNI_QUEUE_SIZE 2048 @@ -147,7 +145,7 @@ struct lcore_conf { uint16_t nb_procs; uint16_t socket_id; uint16_t nb_rx_queue; - uint16_t *lcore_proc; + uint16_t *proc_lcore; struct lcore_rx_queue rx_queue_list[MAX_RX_QUEUE_PER_LCORE]; uint16_t tx_queue_id[RTE_MAX_ETHPORTS]; struct mbuf_table tx_mbufs[RTE_MAX_ETHPORTS]; @@ -270,77 +268,6 @@ check_all_ports_link_status(void) } } -static int -xdigit2val(unsigned char c) -{ - int val; - - if (isdigit(c)) - val = c - '0'; - else if (isupper(c)) - val = c - 'A' + 10; - else - val = c - 'a' + 10; - return val; -} - -static int -parse_lcore_mask(const char *coremask, uint16_t *lcore_proc, - uint16_t nb_procs) -{ - int i, j, idx = 0; - unsigned count = 0; - char c; - int val; - - if (coremask == NULL) - return -1; - - /* Remove all blank characters ahead and after. - * Remove 0x/0X if exists. - */ - while (isblank(*coremask)) - coremask++; - if (coremask[0] == '0' && ((coremask[1] == 'x') - || (coremask[1] == 'X'))) - coremask += 2; - - i = strlen(coremask); - while ((i > 0) && isblank(coremask[i - 1])) - i--; - - if (i == 0) - return -1; - - for (i = i - 1; i >= 0 && idx < RTE_MAX_LCORE && count < nb_procs; i--) { - c = coremask[i]; - if (isxdigit(c) == 0) { - return -1; - } - val = xdigit2val(c); - for (j = 0; j < BITS_PER_HEX && idx < RTE_MAX_LCORE && count < nb_procs; - j++, idx++) { - if ((1 << j) & val) { - if (!lcore_config[idx].detected) { - RTE_LOG(ERR, EAL, "lcore %u unavailable\n", idx); - return -1; - } - lcore_proc[count] = idx; - count++; - } - } - } - - for (; i >= 0; i--) - if (coremask[i] != '0') - return -1; - - if (count < nb_procs) - return -1; - - return 0; -} - static int init_lcore_conf(void) { @@ -351,17 +278,20 @@ init_lcore_conf(void) lcore_conf.proc_id = ff_global_cfg.dpdk.proc_id; lcore_conf.nb_procs = ff_global_cfg.dpdk.nb_procs; - lcore_conf.lcore_proc = rte_zmalloc(NULL, - sizeof(uint16_t)*lcore_conf.nb_procs, 0); - if (lcore_conf.lcore_proc == NULL) { - rte_exit(EXIT_FAILURE, "rte_zmalloc lcore_proc failed\n"); - } - int ret = parse_lcore_mask(ff_global_cfg.dpdk.lcore_mask, - lcore_conf.lcore_proc, lcore_conf.nb_procs); - if (ret < 0) { - rte_exit(EXIT_FAILURE, "parse_lcore_mask failed:%s\n", - ff_global_cfg.dpdk.lcore_mask); + lcore_conf.proc_lcore = rte_zmalloc(NULL, + sizeof(uint16_t) * lcore_conf.nb_procs, 0); + if (lcore_conf.proc_lcore == NULL) { + rte_exit(EXIT_FAILURE, "rte_zmalloc proc_lcore failed\n"); + } + rte_memcpy(lcore_conf.proc_lcore, ff_global_cfg.dpdk.proc_lcore, + sizeof(uint16_t) * lcore_conf.nb_procs); + uint16_t proc_id; + for (proc_id = 0; proc_id < lcore_conf.nb_procs; proc_id++) { + uint16_t lcore_id = lcore_conf.proc_lcore[proc_id]; + if (!lcore_config[lcore_id].detected) { + rte_exit(EXIT_FAILURE, "lcore %u unavailable\n", lcore_id); + } } uint16_t socket_id = 0; @@ -427,7 +357,7 @@ init_mem_pool(void) int numa_on = ff_global_cfg.dpdk.numa_on; for (i = 0; i < lcore_conf.nb_procs; i++) { - lcore_id = lcore_conf.lcore_proc[i]; + lcore_id = lcore_conf.proc_lcore[i]; if (numa_on) { socketid = rte_lcore_to_socket_id(lcore_id); } @@ -932,7 +862,7 @@ process_packets(uint8_t port_id, uint16_t queue_id, struct rte_mbuf **bufs, if(i == queue_id) continue; - mbuf_pool = pktmbuf_pool[rte_lcore_to_socket_id(qconf->lcore_proc[i])]; + mbuf_pool = pktmbuf_pool[rte_lcore_to_socket_id(qconf->proc_lcore[i])]; mbuf_clone = rte_pktmbuf_clone(rtem, mbuf_pool); if(mbuf_clone) { int ret = rte_ring_enqueue(arp_ring[i][port_id], mbuf_clone); diff --git a/lib/ff_freebsd_init.c b/lib/ff_freebsd_init.c index 4697f52ca..7d9fd021e 100644 --- a/lib/ff_freebsd_init.c +++ b/lib/ff_freebsd_init.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -111,6 +112,7 @@ ff_freebsd_init(void) mutex_init(); mi_startup(); sx_init(&proctree_lock, "proctree"); + ff_fdused_range(curthread->td_proc->p_fd, ff_global_cfg.freebsd.fd_reserve); cur = ff_global_cfg.freebsd.sysctl; while (cur) { diff --git a/lib/ff_init.c b/lib/ff_init.c index 5922cd8d2..0659202f1 100644 --- a/lib/ff_init.c +++ b/lib/ff_init.c @@ -33,10 +33,10 @@ extern int ff_freebsd_init(); int -ff_init(const char *conf, int argc, char * const argv[]) +ff_init(int argc, char * const argv[]) { int ret; - ret = ff_load_config(conf, argc, argv); + ret = ff_load_config(argc, argv); if (ret < 0) exit(1); diff --git a/lib/include/sys/filedesc.h b/lib/include/sys/filedesc.h new file mode 100644 index 000000000..db07bcef0 --- /dev/null +++ b/lib/include/sys/filedesc.h @@ -0,0 +1,36 @@ +/*- + * Copyright (c) 2010 Kip Macy + * Copyright (C) 2017 THL A29 Limited, a Tencent company. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSTACK_SYS_FILEDESC_H_ +#define _FSTACK_SYS_FILEDESC_H_ + +#include_next + +void ff_fdused_range(struct filedesc *fdp, int max); +int ff_fdisused(int fd); + +#endif /* _FSTACK_SYS_FILEDESC_H_ */ diff --git a/start.sh b/start.sh index 83231f0c1..c8f78f6f2 100755 --- a/start.sh +++ b/start.sh @@ -40,28 +40,18 @@ do if [ ${result} != 0 ] then ((num_procs++)); - cpuinfo[$i]=1 - else - cpuinfo[$i]=0 fi done -proc_id=0 -for((i=0;i<${PROCESSOR};++i)) +for((proc_id=0; proc_id<${num_procs}; ++proc_id)) do - if ((cpuinfo[$i] == 1)) + if ((proc_id == 0)) then - cmask=`echo "2^$i"|bc` - cmask=`echo "obase=16;${cmask}"|bc` - if ((proc_id == 0)) - then - echo "${bin} ${conf} -c $cmask --proc-type=primary --num-procs=${num_procs} --proc-id=${proc_id}" - ${bin} ${conf} -c ${cmask} --proc-type=primary --num-procs=${num_procs} --proc-id=${proc_id} & - sleep 5 - else - echo "${bin} ${conf} -c $cmask --proc-type=secondary --num-procs=${num_procs} --proc-id=${proc_id}" - ${bin} ${conf} -c $cmask --proc-type=secondary --num-procs=${num_procs} --proc-id=${proc_id} & - fi - ((proc_id++)) - fi + echo "${bin} --conf ${conf} --proc-type=primary --proc-id=${proc_id}" + ${bin} --conf ${conf} --proc-type=primary --proc-id=${proc_id} & + sleep 5 + else + echo "${bin} --conf ${conf} --proc-type=secondary --proc-id=${proc_id}" + ${bin} --conf ${conf} --proc-type=secondary --proc-id=${proc_id} & + fi done