191 lines
7.0 KiB
Diff
191 lines
7.0 KiB
Diff
From b72fcd6421f599422d76a969795a7f523c405684 Mon Sep 17 00:00:00 2001
|
|
From: jiangheng12 <jiangheng14@huawei.com>
|
|
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
|
|
|