fengbojiang 2018-11-13 22:04:23 +08:00
commit 4d6c56c565
15 changed files with 201 additions and 68 deletions

View File

@ -22,7 +22,7 @@ extern int is_fstack_fd(int sockfd);
static ngx_inline int
ngx_ff_skip_listening_socket(ngx_cycle_t *cycle, const ngx_listening_t *ls, int *type)
{
if (ngx_process <= NGX_PROCESS_MASTER) {
if (ngx_ff_process == NGX_FF_PROCESS_NONE) {
/* process master, kernel network stack*/
if (!ls->belong_to_host) {
@ -32,7 +32,7 @@ ngx_ff_skip_listening_socket(ngx_cycle_t *cycle, const ngx_listening_t *ls, int
return 1;
}
}
} else if (NGX_PROCESS_WORKER == ngx_process) {
} else {
/* process worker, fstack */
if (ls->belong_to_host) {
return 1;
@ -45,11 +45,6 @@ ngx_ff_skip_listening_socket(ngx_cycle_t *cycle, const ngx_listening_t *ls, int
if(type) {
*type |= SOCK_FSTACK;
}
} else {
ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
"unexpected process type: %d, ignored",
ngx_process);
exit(1);
}
return 0;

View File

@ -117,12 +117,13 @@ ngx_ff_epoll_init(ngx_cycle_t *cycle, ngx_msec_t timer)
ngx_free(event_list);
}
event_list = ngx_alloc(sizeof(struct epoll_event), cycle->log);
nevents = 64;
event_list = ngx_alloc(sizeof(struct epoll_event) * nevents, cycle->log);
if (event_list == NULL) {
return NGX_ERROR;
}
nevents = 8;
return NGX_OK;
}

View File

@ -128,7 +128,7 @@ ngx_kqueue_init(ngx_cycle_t *cycle, ngx_msec_t timer)
#endif
#if (NGX_HAVE_FSTACK)
if(ngx_process != NGX_PROCESS_WORKER) {
if(ngx_ff_process == NGX_FF_PROCESS_NONE) {
return NGX_OK;
}
#endif

View File

@ -252,10 +252,10 @@ ngx_process_events_and_timers(ngx_cycle_t *cycle)
#if (NGX_HAVE_FSTACK)
/*
* NGX_PROCESS_WORKERs run on both fstack and kernel,
* NGX_FF_PROCESS_*s run on both fstack and kernel,
* others ( e.g. cache manager/loader ) only run on kernel.
*/
if(ngx_process == NGX_PROCESS_WORKER) {
if(!!ngx_ff_process) {
(void) ngx_process_events(cycle, timer, flags);
/*

View File

@ -360,25 +360,28 @@ ngx_event_connect_set_transparent(ngx_peer_connection_t *pc, ngx_socket_t s)
case AF_INET:
#if defined(IP_TRANSPARENT)
if (setsockopt(s, IPPROTO_IP, IP_TRANSPARENT,
(const void *) &value, sizeof(int)) == -1)
#if defined(NGX_HAVE_FSTACK)
/****
FreeBSD define IP_BINDANY in freebsd/netinet/in.h
Fstack should only support IP_BINDANY.
****/
#define IP_BINDANY 24
if (setsockopt(s, IPPROTO_IP, IP_BINDANY,
(const void *) &value, sizeof(int)) == -1)
{
ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,
"setsockopt(IP_TRANSPARENT) failed");
return NGX_ERROR;
}
#elif defined(IP_BINDANY)
if (setsockopt(s, IPPROTO_IP, IP_BINDANY,
(const void *) &value, sizeof(int)) == -1)
{
ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,
"setsockopt(IP_BINDANY) failed");
"setsockopt(IP_BINDANY) failed");
return NGX_ERROR;
}
#elif defined(IP_TRANSPARENT)
if (setsockopt(s, IPPROTO_IP, IP_TRANSPARENT,
(const void *) &value, sizeof(int)) == -1)
{
ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,
"setsockopt(IP_TRANSPARENT) failed");
return NGX_ERROR;
}
#endif

View File

@ -29,6 +29,7 @@ static void ngx_cache_loader_process_handler(ngx_event_t *ev);
#if (NGX_HAVE_FSTACK)
extern int ff_mod_init(const char *conf, int proc_id, int proc_type);
ngx_int_t ngx_ff_process;
#endif
ngx_uint_t ngx_process;
@ -72,7 +73,6 @@ static ngx_log_t ngx_exit_log;
static ngx_open_file_t ngx_exit_log_file;
#if (NGX_HAVE_FSTACK)
static ngx_int_t ngx_ff_primary;
static sem_t *ngx_ff_worker_sem;
#endif
@ -312,6 +312,51 @@ ngx_master_process_cycle(ngx_cycle_t *cycle)
}
}
#if (NGX_HAVE_FSTACK)
static int
ngx_single_process_cycle_loop(void *arg)
{
ngx_uint_t i;
ngx_cycle_t *cycle = (ngx_cycle_t *)arg;
//ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "worker cycle");
ngx_process_events_and_timers(cycle);
if (ngx_terminate || ngx_quit) {
for (i = 0; cycle->modules[i]; i++) {
if (cycle->modules[i]->exit_process) {
cycle->modules[i]->exit_process(cycle);
}
}
ngx_master_process_exit(cycle);
}
if (ngx_reconfigure) {
ngx_reconfigure = 0;
ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reconfiguring");
cycle = ngx_init_cycle(cycle);
if (cycle == NULL) {
cycle = (ngx_cycle_t *) ngx_cycle;
return 0;
}
ngx_cycle = cycle;
}
if (ngx_reopen) {
ngx_reopen = 0;
ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reopening logs");
ngx_reopen_files(cycle, (ngx_uid_t) -1);
}
return 0;
}
#endif
void
ngx_single_process_cycle(ngx_cycle_t *cycle)
{
@ -322,6 +367,36 @@ ngx_single_process_cycle(ngx_cycle_t *cycle)
exit(2);
}
#if (NGX_HAVE_FSTACK)
ngx_core_conf_t *ccf;
ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
if (ccf->fstack_conf.len == 0) {
ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
"fstack_conf null");
exit(2);
}
ngx_ff_process = NGX_FF_PROCESS_PRIMARY;
if (ff_mod_init((const char *)ccf->fstack_conf.data, 0,
ngx_ff_process == NGX_FF_PROCESS_PRIMARY)) {
ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
"ff_mod_init failed");
exit(2);
}
if (ngx_open_listening_sockets(cycle) != NGX_OK) {
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
"ngx_open_listening_sockets failed");
exit(2);
}
if (!ngx_test_config) {
ngx_configure_listening_sockets(cycle);
}
#endif
for (i = 0; cycle->modules[i]; i++) {
if (cycle->modules[i]->init_process) {
if (cycle->modules[i]->init_process(cycle) == NGX_ERROR) {
@ -331,6 +406,9 @@ ngx_single_process_cycle(ngx_cycle_t *cycle)
}
}
#if (NGX_HAVE_FSTACK)
ff_run(ngx_single_process_cycle_loop, (void *)cycle);
#else
for ( ;; ) {
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "worker cycle");
@ -366,6 +444,7 @@ ngx_single_process_cycle(ngx_cycle_t *cycle)
ngx_reopen_files(cycle, (ngx_uid_t) -1);
}
}
#endif
}
@ -1045,11 +1124,13 @@ ngx_worker_process_init(ngx_cycle_t *cycle, ngx_int_t worker)
}
if (worker == 0) {
ngx_ff_primary = 1;
ngx_ff_process = NGX_FF_PROCESS_PRIMARY;
} else {
ngx_ff_process = NGX_FF_PROCESS_SECONDARY;
}
if (ff_mod_init((const char *)ccf->fstack_conf.data, worker,
ngx_ff_primary)) {
ngx_ff_process == NGX_FF_PROCESS_PRIMARY)) {
ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
"ff_mod_init failed");
exit(2);
@ -1186,7 +1267,7 @@ ngx_worker_process_exit(ngx_cycle_t *cycle)
ngx_log_error(NGX_LOG_NOTICE, ngx_cycle->log, 0, "exit");
#if (NGX_HAVE_FSTACK)
if (ngx_ff_primary) {
if (ngx_ff_process == NGX_FF_PROCESS_PRIMARY) {
// wait for secondary worker processes to exit.
ngx_msleep(500);
}

View File

@ -37,6 +37,12 @@ typedef struct {
void ngx_master_process_cycle(ngx_cycle_t *cycle);
void ngx_single_process_cycle(ngx_cycle_t *cycle);
#if (NGX_HAVE_FSTACK)
#define NGX_FF_PROCESS_NONE 0
#define NGX_FF_PROCESS_PRIMARY 1
#define NGX_FF_PROCESS_SECONDARY 2
extern ngx_int_t ngx_ff_process;
#endif
extern ngx_uint_t ngx_process;
extern ngx_uint_t ngx_worker;

View File

@ -39,10 +39,10 @@ port_list=0
# Port config section
# Correspond to dpdk.port_list's index: port0, port1...
[port0]
addr=192.168.1.2
netmask=255.255.255.0
broadcast=192.168.1.255
gateway=192.168.1.1
addr=10.139.144.123
netmask=255.255.224.0
broadcast=10.139.159.255
gateway=10.139.128.1
# lcore list used to handle this port
# the format is same as port_list
@ -55,12 +55,21 @@ gateway=192.168.1.1
# 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.
<<<<<<< HEAD
#[kni]
#enable=1
#method=reject
# The format is same as port_list
#tcp_port=80,443
#udp_port=53
=======
[kni]
enable=1
method=reject
# The format is same as port_list
tcp_port=80,443
udp_port=53
>>>>>>> 387425b16df2b02c99c1583c2f9c376c1fb05ca4
# FreeBSD network performance tuning configurations.
# Most native FreeBSD configurations are supported.

View File

@ -1,14 +1,14 @@
# F-Stack API Reference
F-Stack is a high performance network framework based on DPDK.
F-Stack (FF) is a high-performance network framework based on DPDK.
FF API provides standard Kqueue/Epoll interface, and a micro threading framework (SPP).
FF API provides the standard Kqueue/Epoll interface, and a micro threading framework (SPP).
In order to facilitate a variety of services can use F-Stack simpler and faster, F-Stack has integrated Nginx and Redis。
In order to facilitate a variety of services to use F-Stack simpler and faster, F-Stack has been integrated with Nginx and Redis。
## FF API
The header file ff_api.h defines the following API, which should be used to replace the system called when using the F-Sstack.
The header file ff_api.h defines the following API, which should be used to replace the system calls when using F-Stack.
### Initialize
@ -18,12 +18,12 @@ In order to facilitate a variety of services can use F-Stack simpler and faster,
conf:Profile path
argv-c <coremask>,the coremask parameters can cover the coremask in configuration file
Initialize F-Stackinclude DPDK/FreeBSD network stack, etc.
Initialize F-Stackincluding DPDK/FreeBSD network stack, etc.
#### ff_run
void ff_run(loop_func_t loop, void *arg);
loop is a callbask functionthe service logic is implemented by the user, and be called by each poll of F-Stack .
loop is a callbask functionthe service logic is implemented by the user, and called by each poll of F-Stack .
### Control API
@ -32,7 +32,7 @@ loop is a callbask functionthe service logic is implemented by the user, and
int ff_fcntl(int fd, int cmd, ...);
fcntl() performs one of the operations described below on the open file descriptor fd. The operation is determined by cmd.
more info see man fcntl
more info see man fcntl.
#### ff_sysctl
@ -40,14 +40,14 @@ more info see man fcntl
const void *newp, size_t newlen);
ff_sysctl is used to modify kernel parameters at runtime.
However, it is currently only supported before F-Stack is started.
However, it is supported only before F-Stack is started.
#### ff_ioctl
int ff_ioctl(int fd, unsigned long request, ...);
The ioctl() function manipulates the underlying device parameters of special files.
more info see man ioctl
more info see man ioctl.
### Network API
@ -55,8 +55,8 @@ However, it is currently only supported before F-Stack is started.
int ff_socket(int domain, int type, int protocol);
creates an endpoint for communication and returns a file descriptor that refers to that endpoint.
more info see man socket
ff_socket creates an endpoint for communication and returns a file descriptor that refers to that endpoint.
more info see man socket.
#### ff_setsockopt & ff_getsockopt
@ -65,15 +65,15 @@ However, it is currently only supported before F-Stack is started.
int ff_setsockopt(int s, int level, int optname, const void *optval,
socklen_t optlen);
getsockopt() and setsockopt() manipulate options for the socket referred to by the file descriptor sockfd.
getsockopt() and setsockopt() manipulate options for the socket denoted by the file descriptor sockfd.
more info see man getsockopt and man setsockopt.
#### ff_socketpair
int ff_socketpair(int domain, int type, int protocol, int *sv);
The socketpair() call creates an unnamed pair of connected sockets in the specified domain, of the specified type, and using the optionally specified protocol.
more info see man socketpair
The socketpair() call creates an unnamed pair of connected sockets in the given domain in the specified type, and uses the optionally given protocol.
more info see man socketpair.
#### Socket operation function
@ -123,7 +123,7 @@ However, it is currently only supported before F-Stack is started.
ssize_t ff_sendto(int s, const void *buf, size_t len, int flags, const struct linux_sockaddr *to, socklen_t tolen);
ssize_t ff_sendmsg(int s, const struct msghdr *msg, int flags);
send a message on a socket.
Functions to send a message on a socket.
more info see man send.
#### ff\_recv & ff\_recvfrom & ff\_recvmsg
@ -132,7 +132,7 @@ However, it is currently only supported before F-Stack is started.
ssize_t ff_recvfrom(int s, void *buf, size_t len, int flags, struct linux_sockaddr *from, socklen_t *fromlen);
ssize_t ff_recvmsg(int s, struct msghdr *msg, int flags);
receive a message from a socket.
Functions to receive a message from a socket.
more info see man recv.
#### ff_select
@ -146,7 +146,7 @@ However, it is currently only supported before F-Stack is started.
int ff_poll(struct pollfd fds[], nfds_t nfds, int timeout);
wait for some event on a file descriptor.
ff_poll waits for events on a file descriptor.
more info see man poll.
### Kqueue API
@ -156,7 +156,7 @@ However, it is currently only supported before F-Stack is started.
int ff_kqueue(void);
int ff_kevent(int kq, const struct kevent *changelist, int nchanges, struct kevent *eventlist, int nevents, const struct timespec *timeout);
The kqueue() system call provides a generic method of notifying the user when an event happens or a condition holds, based on the results of small pieces of kernel code termed filters.
The kqueue() system call provides a generic method of notifying the user when an event occurs or a condition holds, based on the results of small pieces of kernel code termed filters.
more info see man kqueue on FreeBSD System Calls Manual.
### Epoll API
@ -172,12 +172,12 @@ However, it is currently only supported before F-Stack is started.
int ff_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
This system call performs control operations on the epoll(7) instance referred to by the file descriptor epfd.
This system call performs control operations on the epoll(7) instance referred by the file descriptor epfd.
more info see man epoll_ctl.
### Micro Thread API `micro_thread/mt_api.h`
In order to develop asynchronous program convenient without complex asynchronous logic processing, reference [SPP's micro thread framework](https://github.com/Tencent/MSEC/tree/master/spp_rpc) F-Stack provides a micro thread framework, synchronous programming can be achieved using the asynchronous call.
In order to develop asynchronous program convenient without complex asynchronous logic processing (reference [SPP's micro thread framework](https://github.com/Tencent/MSEC/tree/master/spp_rpc)), F-Stack provides a micro thread framework so that synchronous programming can be achieved using asynchronous calls.
#### UDP send/recv interface
@ -204,7 +204,7 @@ However, it is currently only supported before F-Stack is started.
int mt_tcpsendrcv_ex(struct sockaddr_in* dst, void* pkg, int len, void* rcv_buf, int* buf_size, int timeout, MtFuncTcpMsgLen func, MT_TCP_CONN_TYPE type = MT_TCP_LONG);
Tcp send and recv interface, you can choose if the connection is keep-alive or close.The parameter of buf can't use `static`.
TCP send and recv interface, you can choose if the connection is keep-alive or close.The parameter of buf can't use `static`.
int mt_tcpsendrcv_ex(struct sockaddr_in* dst, void* pkg, int len, void*& rcv_buf, int& recv_pkg_size, int timeout, MtFuncTcpMsgChecker check_func, void* msg_ctx=NULL, MT_TCP_CONN_TYPE type = MT_TCP_LONG, bool keep_rcv_buf=false);
@ -217,6 +217,6 @@ However, it is currently only supported before F-Stack is started.
Use connection pool to send and recv tcp packet, keep-alive default are 10 mintues. The parameter of buf can't use `static`.
#### Socet API of micro thread
#### Socket API for micro threads
see `micro_thread/mt_api.h`.

View File

@ -64,6 +64,7 @@ get_curthread(void)
}
#define curthread get_curthread()
#undef curthread
#define PCPU_GET(member) (get_pcpu()->pc_ ## member)
#define PCPU_ADD(member, value) (get_pcpu()->pc_ ## member += (value))

View File

@ -1114,6 +1114,7 @@ in_pcbconnect_setup(struct inpcb *inp, struct sockaddr *nam,
return (error);
}
#else
if (lport == 0)
{
struct ifaddr *ifa;
struct ifnet *ifp;

View File

@ -19,13 +19,27 @@ HOST_OS:=$(shell uname -s)
#DEBUG=-O0 -gdwarf-2 -g3 -Wno-format-truncation
#FF_KNI=1
FF_KNI=1
#FF_NETGRAPH=1
#FF_IPFW=1
include ${TOPDIR}/mk/kern.pre.mk
ifeq ($(FF_DPDK),)
ifeq (${MACHINE_CPUARCH},aarch64)
FF_DPDK=${TOPDIR}/dpdk/build
else
FF_DPDK=${TOPDIR}/dpdk/x86_64-native-linuxapp-gcc
endif
endif
ifdef RTE_SDK
ifeq (${MACHINE_CPUARCH},aarch64)
FF_DPDK=${RTE_SDK}/build
else
FF_DPDK=${RTE_SDK}/x86_64-native-linuxapp-gcc
endif
endif
DPDK_CFLAGS= -Wall -Werror -include ${FF_DPDK}/include/rte_config.h
DPDK_CFLAGS+= -march=native -DRTE_MACHINE_CPUFLAG_SSE -DRTE_MACHINE_CPUFLAG_SSE2 -DRTE_MACHINE_CPUFLAG_SSE3
@ -33,8 +47,6 @@ DPDK_CFLAGS+= -DRTE_MACHINE_CPUFLAG_SSSE3 -DRTE_MACHINE_CPUFLAG_SSE4_1 -DRTE_MAC
DPDK_CFLAGS+= -DRTE_COMPILE_TIME_CPUFLAGS=RTE_CPUFLAG_SSE,RTE_CPUFLAG_SSE2,RTE_CPUFLAG_SSE3,RTE_CPUFLAG_SSSE3,RTE_CPUFLAG_SSE4_1,RTE_CPUFLAG_SSE4_2
DPDK_CFLAGS+= -I${FF_DPDK}/include
include ${TOPDIR}/mk/kern.pre.mk
KERNPREINCLUDES:= ${INCLUDES}
INCLUDES= -I${OVERRIDE_INCLUDES_ROOT} ${KERNPREINCLUDES}
INCLUDES+= -I./machine_include
@ -88,6 +100,13 @@ endif
endif
#
# fix the MACHINE_CPUARCH to match the FreeBSD directory name
#
ifeq (${MACHINE_CPUARCH},aarch64)
MACHINE_CPUARCH=arm64
endif
#
# Distilled from FreeBSD src/sys/conf/Makefile.i386
@ -258,7 +277,7 @@ KERN_MHEADERS+= \
KERN_MSRCS+= \
linker_if.m
ifeq (${MACHINE_CPUARCH},arm64)
LIBKERN_SRCS+= \
bcd.c \
crc32.c \
@ -266,7 +285,19 @@ LIBKERN_SRCS+= \
jenkins_hash.c \
strlcpy.c \
strnlen.c \
zlib.c
zlib.c \
fls.c \
flsl.c
else
LIBKERN_SRCS+= \
bcd.c \
crc32.c \
inet_ntoa.c \
jenkins_hash.c \
strlcpy.c \
strnlen.c \
zlib.c
endif
MACHINE_SRCS+= \

View File

@ -1342,6 +1342,12 @@ ff_dpdk_if_send(struct ff_dpdk_if_context *ctx, void *m,
}
}
if (prev != NULL) {
prev->next = cur;
}
head->nb_segs++;
prev = cur;
void *data = rte_pktmbuf_mtod(cur, void*);
int len = total > RTE_MBUF_DEFAULT_DATAROOM ? RTE_MBUF_DEFAULT_DATAROOM : total;
int ret = ff_mbuf_copydata(m, data, off, len);
@ -1351,15 +1357,10 @@ ff_dpdk_if_send(struct ff_dpdk_if_context *ctx, void *m,
return -1;
}
if (prev != NULL) {
prev->next = cur;
}
prev = cur;
cur->data_len = len;
off += len;
total -= len;
head->nb_segs++;
cur = NULL;
}

View File

@ -4,7 +4,7 @@
ifndef COMPILER_TYPE
ifeq ($(patsubst gcc%,gcc,$(notdir ${CC})),gcc)
COMPILER_TYPE:= gcc
COMPILER_TYPE:= gcc
else ifeq ($(notdir ${CC}), clang)
COMPILER_TYPE:= clang
else

View File

@ -101,6 +101,10 @@ CFLAGS+=
INLINE_LIMIT?= 8000
endif
ifeq (${MACHINE_CPUARCH},arm64)
INLINE_LIMIT?= 15000
endif
#
# GCC SSP support
#