2 Star 0 Fork 32

我们17走/gazelle

forked from src-openEuler/gazelle 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
0139-diff-udp-and-tcp-read-from-stack.patch 8.69 KB
一键复制 编辑 原始数据 按行查看 历史
From 472e2f00b3fda7dad4396704fd94715d91be4642 Mon Sep 17 00:00:00 2001
From: jiangheng <jiangheng14@huawei.com>
Date: Wed, 21 Feb 2024 04:25:43 +0800
Subject: [PATCH] diff udp and tcp read from stack
---
src/lstack/core/lstack_lwip.c | 211 +++++++++++++++++++++++-----------
1 file changed, 146 insertions(+), 65 deletions(-)
diff --git a/src/lstack/core/lstack_lwip.c b/src/lstack/core/lstack_lwip.c
index 50a3389..0b339fe 100644
--- a/src/lstack/core/lstack_lwip.c
+++ b/src/lstack/core/lstack_lwip.c
@@ -831,74 +831,96 @@ static struct pbuf *pbuf_free_partial(struct pbuf *pbuf, uint16_t free_len)
return pbuf;
}
-ssize_t do_lwip_read_from_stack(int32_t fd, void *buf, size_t len, int32_t flags,
- struct sockaddr *addr, socklen_t *addrlen)
+static bool recv_break_for_err(struct lwip_sock *sock)
{
- size_t recv_left = len;
- struct pbuf *pbuf = NULL;
- ssize_t recvd = 0;
- uint32_t copy_len;
- struct lwip_sock *sock = get_socket_by_fd(fd);
- bool latency_enable = get_protocol_stack_group()->latency_start;
-
- if (sock->errevent > 0 && !NETCONN_IS_DATAIN(sock)) {
- errno = err_to_errno(netconn_err(sock->conn));
- return -1;
- }
+ bool break_wait = (sock->errevent > 0) && (!NETCONN_IS_DATAIN(sock));
+ errno = err_to_errno(netconn_err(sock->conn));
+ return break_wait;
+}
- thread_bind_stack(sock);
+static void recv_block_wait(struct lwip_sock *sock)
+{
+ lstack_block_wait(sock->wakeup);
+}
- if (sock->same_node_rx_ring != NULL) {
- return gazelle_same_node_ring_recv(sock, buf, len, flags);
+/*
+ * return 0 on success, -1 on error
+ * pbuf maybe NULL(tcp fin packet)
+ */
+static int recv_ring_get_one(struct lwip_sock *sock, bool noblock, struct pbuf **pbuf)
+{
+ if (sock->recv_lastdata != NULL) {
+ *pbuf = sock->recv_lastdata;
+ sock->recv_lastdata = NULL;
+ return 0;
}
- while (recv_left > 0) {
- if (sock->recv_lastdata) {
- pbuf = sock->recv_lastdata;
- sock->recv_lastdata = NULL;
+ if (noblock) {
+ if (gazelle_ring_read(sock->recv_ring, (void **)pbuf, 1) != 1) {
+ errno = EAGAIN;
+ return -1;
} else {
- if (netconn_is_nonblocking(sock->conn)) {
- if (gazelle_ring_read(sock->recv_ring, (void **)&pbuf, 1) != 1) {
- break;
- }
- } else {
- while (gazelle_ring_read(sock->recv_ring, (void **)&pbuf, 1) != 1 && recvd == 0) {
- /* if the connection is disconnected, recv return 0 */
- if (sock->errevent > 0 && !NETCONN_IS_DATAIN(sock)) {
- errno = err_to_errno(netconn_err(sock->conn));
- return -1;
- }
-
- lstack_block_wait(sock->wakeup);
- }
+ return 0;
+ }
+ } else {
+ while (gazelle_ring_read(sock->recv_ring, (void **)pbuf, 1) != 1) {
+ if (recv_break_for_err(sock)) {
+ return -1;
}
+ recv_block_wait(sock);
}
+ return 0;
+ }
+}
- /* if udp recv a packet whose len is 0, return 0 */
- if (NETCONN_IS_UDP(sock) && pbuf->tot_len == 0) {
- return 0;
+/* return true: fin is read to user, false: pend fin */
+static bool recv_ring_handle_fin(struct lwip_sock *sock, struct pbuf *pbuf, ssize_t recvd)
+{
+ if (pbuf == NULL) {
+ if (recvd > 0) {
+ /* handle data first, then handle fin */
+ sock->recv_lastdata = (void *)&fin_packet;
+ gazelle_ring_read_over(sock->recv_ring);
+ return false;
}
+ gazelle_ring_read_over(sock->recv_ring);
+ return true;
+ }
+ /* pending fin */
+ if (pbuf == (void *)&fin_packet) {
+ return true;
+ }
- /* fin */
- if (unlikely(pbuf == NULL)) {
- if (recvd > 0) {
- /* read data first, then read fin */
- sock->recv_lastdata = (void *)&fin_packet;
- gazelle_ring_read_over(sock->recv_ring);
- break;
- }
- gazelle_ring_read_over(sock->recv_ring);
- return 0;
+ return false;
+}
+
+static ssize_t recv_ring_tcp_read(struct lwip_sock *sock, void *buf, size_t len, bool noblock)
+{
+ ssize_t recvd = 0;
+ size_t recv_left = len;
+ uint32_t copy_len;
+ struct pbuf *pbuf = NULL;
+
+ if (len == 0) {
+ return 0;
+ }
+
+ while (recv_left > 0) {
+ if (recv_ring_get_one(sock, noblock, &pbuf) != 0) {
+ break;
}
- /* pending fin */
- if (unlikely(pbuf == (void *)&fin_packet)) {
- return 0;
+ if (unlikely((pbuf == NULL) || (pbuf == (void *)&fin_packet))) {
+ if (recv_ring_handle_fin(sock, pbuf, recvd)) {
+ return 0;
+ } else {
+ break; /* recvd > 0, pending fin, handle data */
+ }
}
copy_len = (recv_left > pbuf->tot_len) ? pbuf->tot_len : recv_left;
if (copy_len > UINT16_MAX) {
- copy_len = UINT16_MAX;
+ copy_len = UINT16_MAX; /* it's impossible to get here */
}
pbuf_copy_partial(pbuf, (char *)buf + recvd, copy_len, 0);
@@ -907,39 +929,98 @@ ssize_t do_lwip_read_from_stack(int32_t fd, void *buf, size_t len, int32_t flags
if (pbuf->tot_len > copy_len) {
sock->recv_lastdata = pbuf_free_partial(pbuf, copy_len);
- break;
} else {
if (sock->wakeup) {
sock->wakeup->stat.app_read_cnt += 1;
}
- if (latency_enable) {
+
+ if (get_protocol_stack_group()->latency_start) {
calculate_lstack_latency(&sock->stack->latency, pbuf, GAZELLE_LATENCY_READ_LSTACK);
}
- gazelle_ring_read_over(sock->recv_ring);
- /* in udp, if pbuf remaining len less than copy_len, discard these packets */
- if (recvd > 0 && NETCONN_IS_UDP(sock)) {
- sock->stack->stats.sock_rx_drop++;
- break;
- }
+ gazelle_ring_read_over(sock->recv_ring);
}
}
- /* rte_ring_count reduce lock */
- if (sock->wakeup && sock->wakeup->type == WAKEUP_EPOLL && (sock->events & EPOLLIN)
- && (!NETCONN_IS_DATAIN(sock))) {
- del_sock_event(sock, EPOLLIN);
+ if (recvd > 0) {
+ errno = 0;
+ } else {
+ recvd = -1;
}
+ return recvd;
+}
+
+static ssize_t recv_ring_udp_read(struct lwip_sock *sock, void *buf, size_t len, bool noblock,
+ struct sockaddr *addr, socklen_t *addrlen)
+{
+ size_t recv_left = len;
+ struct pbuf *pbuf = NULL;
+ uint32_t copy_len;
+
+ sock->recv_lastdata = NULL;
+
+ if (recv_ring_get_one(sock, noblock, &pbuf) != 0) {
+ /* errno have set */
+ return -1;
+ }
+
+ copy_len = (recv_left > pbuf->tot_len) ? pbuf->tot_len : recv_left;
+ pbuf_copy_partial(pbuf, (char *)buf, copy_len, 0);
+ /* drop remaining data if have */
+ gazelle_ring_read_over(sock->recv_ring);
+
if (pbuf && addr && addrlen) {
lwip_sock_make_addr(sock->conn, &(pbuf->addr), pbuf->port, addr, addrlen);
}
- if (recvd == 0) {
+ if (copy_len < pbuf->tot_len) {
+ sock->stack->stats.sock_rx_drop++;
+ }
+
+ if (sock->wakeup) {
+ sock->wakeup->stat.app_read_cnt++;
+ }
+ if (get_protocol_stack_group()->latency_start) {
+ calculate_lstack_latency(&sock->stack->latency, pbuf, GAZELLE_LATENCY_READ_LSTACK);
+ }
+
+ return copy_len;
+}
+
+ssize_t do_lwip_read_from_stack(int32_t fd, void *buf, size_t len, int32_t flags,
+ struct sockaddr *addr, socklen_t *addrlen)
+{
+ ssize_t recvd = 0;
+ struct lwip_sock *sock = get_socket_by_fd(fd);
+
+ if (recv_break_for_err(sock)) {
+ return -1;
+ }
+
+ thread_bind_stack(sock);
+
+ if (sock->same_node_rx_ring != NULL) {
+ return gazelle_same_node_ring_recv(sock, buf, len, flags);
+ }
+
+ if (NETCONN_IS_UDP(sock)) {
+ recvd = recv_ring_udp_read(sock, buf, len, netconn_is_nonblocking(sock->conn), addr, addrlen);
+ } else {
+ recvd = recv_ring_tcp_read(sock, buf, len, netconn_is_nonblocking(sock->conn));
+ }
+
+ /* rte_ring_count reduce lock */
+ if (sock->wakeup && sock->wakeup->type == WAKEUP_EPOLL && (sock->events & EPOLLIN)
+ && (!NETCONN_IS_DATAIN(sock))) {
+ del_sock_event(sock, EPOLLIN);
+ }
+
+ if (recvd < 0) {
if (sock->wakeup) {
sock->wakeup->stat.read_null++;
}
- GAZELLE_RETURN(EAGAIN);
+ return -1;
}
return recvd;
}
--
2.27.0
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/together17/gazelle.git
git@gitee.com:together17/gazelle.git
together17
gazelle
gazelle
master

搜索帮助

0d507c66 1850385 C8b1a773 1850385