From b72fcd6421f599422d76a969795a7f523c405684 Mon Sep 17 00:00:00 2001 From: jiangheng12 Date: Fri, 10 Mar 2023 19:54:47 +0800 Subject: [PATCH] when send ring full whether dynamic alloc mbuf is configurable reduce cpu usage when send ring full --- src/common/gazelle_opt.h | 3 +++ src/lstack/core/lstack_cfg.c | 7 +++++ src/lstack/core/lstack_lwip.c | 46 +++++++++++++++++++++++++++++---- src/lstack/include/lstack_cfg.h | 1 + src/lstack/lstack.conf | 4 +++ 5 files changed, 56 insertions(+), 5 deletions(-) diff --git a/src/common/gazelle_opt.h b/src/common/gazelle_opt.h index 76b89ce..745fdd8 100644 --- a/src/common/gazelle_opt.h +++ b/src/common/gazelle_opt.h @@ -87,4 +87,7 @@ #define GAZELLE_RUN_DIR "/var/run/gazelle/" #define GAZELLE_FILE_PERMISSION 0700 +#define SEND_TIME_WAIT_NS 20000 +#define SECOND_NSECOND 1000000000 + #endif /* _GAZELLE_OPT_H_ */ diff --git a/src/lstack/core/lstack_cfg.c b/src/lstack/core/lstack_cfg.c index 1f7dda1..86d0f14 100644 --- a/src/lstack/core/lstack_cfg.c +++ b/src/lstack/core/lstack_cfg.c @@ -65,6 +65,7 @@ static int32_t parse_nic_read_number(void); static int32_t parse_tcp_conn_count(void); static int32_t parse_mbuf_count_per_conn(void); static int32_t parse_send_ring_size(void); +static int32_t parse_expand_send_ring(void); static inline int32_t parse_int(void *arg, char * arg_string, int32_t default_val, int32_t min_val, int32_t max_val) @@ -112,6 +113,7 @@ static struct config_vector_t g_config_tbl[] = { { "rpc_number", parse_rpc_number }, { "nic_read_number", parse_nic_read_number }, { "send_ring_size", parse_send_ring_size }, + { "expand_send_ring", parse_expand_send_ring }, { NULL, NULL } }; @@ -721,6 +723,11 @@ static int32_t parse_send_ring_size(void) return parse_int(&g_config_params.send_ring_size, "send_ring_size", 32, 1, SOCK_SEND_RING_SIZE_MAX); } +static int32_t parse_expand_send_ring(void) +{ + return parse_int(&g_config_params.expand_send_ring, "expand_send_ring", 0, 0, 1); +} + static int32_t parse_mbuf_count_per_conn(void) { return parse_int(&g_config_params.mbuf_count_per_conn, "mbuf_count_per_conn", diff --git a/src/lstack/core/lstack_lwip.c b/src/lstack/core/lstack_lwip.c index b9f97e0..dcd7e05 100644 --- a/src/lstack/core/lstack_lwip.c +++ b/src/lstack/core/lstack_lwip.c @@ -126,10 +126,12 @@ static struct pbuf *init_mbuf_to_pbuf(struct rte_mbuf *mbuf, pbuf_layer layer, u } /* true: need replenish again */ -static bool replenish_send_idlembuf(struct protocol_stack *stack, struct rte_ring *ring) +static bool replenish_send_idlembuf(struct protocol_stack *stack, struct lwip_sock *sock) { void *pbuf[SOCK_SEND_RING_SIZE_MAX]; + struct rte_ring *ring = sock->send_ring; + uint32_t replenish_cnt = gazelle_ring_free_count(ring); if (replenish_cnt == 0) { return false; @@ -152,6 +154,10 @@ static bool replenish_send_idlembuf(struct protocol_stack *stack, struct rte_rin pbuf_free(pbuf[i]); } + if (!get_global_cfg_params()->expand_send_ring) { + sem_post(&sock->snd_ring_sem); + } + return false; } @@ -181,7 +187,7 @@ void gazelle_init_sock(int32_t fd) LSTACK_LOG(ERR, LSTACK, "sock_send create failed. errno: %d.\n", rte_errno); return; } - (void)replenish_send_idlembuf(stack, sock->send_ring); + (void)replenish_send_idlembuf(stack, sock); sock->stack = stack; sock->stack->conn_num++; @@ -490,6 +496,17 @@ static inline size_t merge_data_lastpbuf(struct lwip_sock *sock, void *buf, size return send_len; } +int sem_timedwait_nsecs(sem_t *sem) +{ + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + long long wait_nsec = ts.tv_nsec + SEND_TIME_WAIT_NS; + ts.tv_nsec = wait_nsec % SECOND_NSECOND; + long add = wait_nsec / SECOND_NSECOND; + ts.tv_sec += add; + return sem_timedwait(sem, &ts); +} + ssize_t write_stack_data(struct lwip_sock *sock, const void *buf, size_t len) { if (sock->errevent > 0) { @@ -518,6 +535,16 @@ ssize_t write_stack_data(struct lwip_sock *sock, const void *buf, size_t len) /* send_ring is full, data attach last pbuf */ if (write_avail == 0) { + if (!get_global_cfg_params()->expand_send_ring) { + sem_timedwait_nsecs(&sock->snd_ring_sem); + if (likely(sock->send_ring != NULL)) { + write_avail = gazelle_ring_readable_count(sock->send_ring); + } + goto END; + } + if (unlikely(sock->send_ring == NULL)) { + goto END; + } struct pbuf *last_pbuf = gazelle_ring_readlast(sock->send_ring); if (last_pbuf) { send_len += app_direct_attach(stack, last_pbuf, (char *)buf + send_len, len - send_len, write_num); @@ -536,8 +563,17 @@ ssize_t write_stack_data(struct lwip_sock *sock, const void *buf, size_t len) } /* send_ring have idle */ - send_len += (write_num <= write_avail) ? app_buff_write(sock, (char *)buf + send_len, len - send_len, write_num) : - app_direct_write(stack, sock, (char *)buf + send_len, len - send_len, write_num); + if (get_global_cfg_params()->expand_send_ring) { + send_len += (write_num <= write_avail) ? app_buff_write(sock, (char *)buf + send_len, len - send_len, write_num) : + app_direct_write(stack, sock, (char *)buf + send_len, len - send_len, write_num); + } else { + if (write_num > write_avail) { + write_num = write_avail; + len = write_num * MBUF_MAX_DATA_LEN; + } + send_len += app_buff_write(sock, (char *)buf + send_len, len - send_len, write_num); + } + if (wakeup) { wakeup->stat.app_write_cnt += write_num; } @@ -558,7 +594,7 @@ static inline bool replenish_send_ring(struct protocol_stack *stack, struct lwip { bool replenish_again = false; - replenish_again = replenish_send_idlembuf(stack, sock->send_ring); + replenish_again = replenish_send_idlembuf(stack, sock); if ((sock->epoll_events & EPOLLOUT) && NETCONN_IS_OUTIDLE(sock)) { add_sock_event(sock, EPOLLOUT); diff --git a/src/lstack/include/lstack_cfg.h b/src/lstack/include/lstack_cfg.h index 6af081d..5f16c19 100644 --- a/src/lstack/include/lstack_cfg.h +++ b/src/lstack/include/lstack_cfg.h @@ -90,6 +90,7 @@ struct cfg_params { struct secondary_attach_arg sec_attach_arg; char unix_socket_filename[NAME_MAX]; uint16_t send_ring_size; + bool expand_send_ring; }; struct cfg_params *get_global_cfg_params(void); diff --git a/src/lstack/lstack.conf b/src/lstack/lstack.conf index fb68c32..a4571ff 100644 --- a/src/lstack/lstack.conf +++ b/src/lstack/lstack.conf @@ -22,6 +22,10 @@ mbuf_count_per_conn = 170 # send ring size, default is 32, max is 2048 send_ring_size = 256 + +# 0: when send ring full, send return +# 1: when send ring full, alloc mbuf from mempool to send data +expand_send_ring = 0 #protocol stack thread per loop params #send connect to nic -- 2.33.0