Skip to content

Commit 560d059

Browse files
committed
Merge branch 'feature/1.26' into dev
2 parents b14e392 + d1a4dab commit 560d059

54 files changed

Lines changed: 20456 additions & 16 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,10 @@ dpdk/.travis.yml
3232
.code.yml
3333
.orange-ci.yml
3434
SMEDockerfile
35+
.gitnexus
36+
.gitnexusignore
37+
adapter/syscall/helloworld_stack
38+
adapter/syscall/helloworld_stack_epoll
39+
adapter/syscall/helloworld_stack_epoll_kernel
40+
adapter/syscall/helloworld_stack_epoll_thread_socket
41+
adapter/syscall/helloworld_stack_thread_socket

CODEBUDDY.md

Lines changed: 231 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
# CODEBUDDY.md
2+
3+
This file provides guidance to CodeBuddy Code when working with the F-Stack open source project.
4+
5+
## Project Overview
6+
7+
F-Stack is an open source high-performance network framework based on DPDK, porting the FreeBSD TCP/IP stack to user space. It achieves 10 million concurrent connections, 5 million RPS, 1 million CPS.
8+
9+
- **Primary Language:** C
10+
- **F-Stack Version:** 1.25
11+
- **DPDK Version:** 23.11.5
12+
- **Repository:** https://github.com/F-Stack/f-stack
13+
- **Local Clone:** `/data/workspace/f-stack`
14+
15+
## Build Commands
16+
17+
```bash
18+
# 1. 编译 DPDK
19+
cd /data/workspace/f-stack/dpdk
20+
meson -Denable_kmods=true build
21+
ninja -C build
22+
ninja -C build install
23+
24+
# 2. 编译 F-Stack
25+
export FF_PATH=/data/workspace/f-stack
26+
export PKG_CONFIG_PATH=/usr/lib64/pkgconfig:/usr/local/lib64/pkgconfig:/usr/lib/pkgconfig
27+
cd /data/workspace/f-stack/lib
28+
make # 编译
29+
make install # 安装(libfstack.a → /usr/local/lib,ff_*.h → /usr/local/include)
30+
31+
# 3. 清理重编
32+
cd /data/workspace/f-stack/lib && make clean && make
33+
```
34+
35+
## F-Stack Issue 分析处理标准操作流程 (SOP)
36+
37+
**适用范围:** 分析 F-Stack GitHub 仓库 (`F-Stack/f-stack`) 的 issue,判断状态并给出处理建议。
38+
39+
**环境准备:**
40+
- GitHub Token 已配置(`GH_TOKEN` 环境变量)
41+
- F-Stack 官方仓库已 clone 至 `/data/workspace/f-stack`
42+
- `gh` CLI 已安装
43+
44+
### 第一步:读 Issue 全文
45+
46+
**必须完整获取 issue 原文及全部讨论,不可仅看标题。**
47+
48+
```bash
49+
export GH_TOKEN='<token>'
50+
51+
# 获取 issue 正文
52+
gh issue view <NUMBER> -R F-Stack/f-stack
53+
54+
# 获取全部评论(API 方式,无截断)
55+
gh api repos/F-Stack/f-stack/issues/<NUMBER>/comments --jq '.[] | {user: .user.login, created_at: .created_at, body: .body}'
56+
```
57+
58+
**记录以下信息:**
59+
- 报告者(author)
60+
- F-Stack / DPDK 版本
61+
- 错误现象(crash、性能、编译失败、功能异常等)
62+
- 复现步骤或环境描述
63+
- 已有讨论结论(维护者是否回复、是否有解决方案)
64+
65+
### 第二步:查代码提交记录
66+
67+
**在本地 F-Stack 仓库中搜索相关修复。**
68+
69+
```bash
70+
cd /data/workspace/f-stack
71+
72+
# 按关键词搜索 commit message
73+
git log --all --oneline --grep='<关键词>'
74+
75+
# 按文件路径搜索变更历史
76+
git log --all --oneline -- <文件路径>
77+
78+
# 搜索修复性提交
79+
git log --all --oneline --grep='fix' --grep='<关键词>' --all-match
80+
81+
# 查看某个 commit 的详细变更
82+
git show <commit-hash>
83+
```
84+
85+
**同时检查 DPDK 上游:**
86+
```bash
87+
cd /data/workspace/f-stack/dpdk
88+
89+
# 搜索 DPDK 中的相关修复
90+
git log --all --oneline --grep='<关键词>'
91+
```
92+
93+
**关注点:**
94+
- issue 提及版本之后是否有修复性提交(Fixes/fix/patch)
95+
- 修复是否已 backport 到当前使用的分支
96+
97+
### 第三步:查关联 Issue 和 PR
98+
99+
```bash
100+
export GH_TOKEN='<token>'
101+
102+
# 搜索相关 issue(open + closed)
103+
gh search issues '<关键词>' -R F-Stack/f-stack --limit 20
104+
105+
# 搜索相关 PR(尤其是已合并的)
106+
gh search prs '<关键词>' -R F-Stack/f-stack --limit 20
107+
108+
# 查看特定 PR 详情
109+
gh pr view <NUMBER> -R F-Stack/f-stack
110+
111+
# 查看 PR 的 diff
112+
gh pr diff <NUMBER> -R F-Stack/f-stack
113+
```
114+
115+
**DPDK 上游 Patchwork(如需追踪上游 patch):**
116+
- API: `https://patches.dpdk.org/api/patches/?q=<关键词>`
117+
- 使用 `WebFetch` 工具获取
118+
119+
### 第四步:查公开资料
120+
121+
**按优先级搜索以下来源:**
122+
123+
1. **DPDK Bugzilla**: `https://bugs.dpdk.org`
124+
2. **DPDK Patchwork**: `https://patches.dpdk.org`
125+
3. **DPDK 邮件列表归档**: `https://inbox.dpdk.org`(优先用 API,避免 Anubis bot 拦截)
126+
4. **外网搜索**: Stack Overflow、CSDN、GitHub 全局搜索
127+
128+
```bash
129+
# 使用 WebSearch 搜索
130+
# 示例:搜索 F-Stack + 具体错误信息
131+
```
132+
133+
**注意:** `lore.kernel.org` 等站点可能被 Anubis bot 拦截,优先使用 API 接口或 `inbox.dpdk.org`
134+
135+
### 第五步:综合判断
136+
137+
**使用中文给出明确结论,格式如下:**
138+
139+
#### 结论模板
140+
141+
```
142+
## Issue #<NUMBER> 分析结论
143+
144+
**标题:** <issue 标题>
145+
**状态判断:** <以下之一>
146+
147+
### 情况一:已修复
148+
- 结论: 已修复
149+
- 修复 commit: <hash> (<commit message>)
150+
- 修复版本: F-Stack v<x.y> / DPDK <版本>
151+
- 是否已 backport: 是/否
152+
- 建议操作: 可关闭,回复告知用户升级到 v<x.y> 即可
153+
154+
### 情况二:有上游 patch 未合入
155+
- 结论: 有上游 patch 未合入
156+
- Patch 链接: <URL>
157+
- Patch 状态: Accepted / Under Review / Superseded
158+
- 影响版本: DPDK 22.11 / 23.11 / 24.11 各 LTS 修复状态
159+
- 建议操作: 等待合入 / 手动 cherry-pick
160+
161+
### 情况三:未修复
162+
- 结论: 未修复
163+
- 根因分析: <详细描述>
164+
- 影响范围: <哪些版本/场景受影响>
165+
- 修复方案: <建议的修复思路>
166+
- 建议操作: 需要开发修复
167+
168+
### 情况四:有 Workaround
169+
- 结论: 有 workaround
170+
- Workaround 步骤: <具体操作>
171+
- 是否需要根本修复: 是/否
172+
- 建议操作: 回复告知 workaround,保持 issue open 等待根本修复
173+
174+
### 情况五:非 Bug(使用咨询/已过时/无法复现)
175+
- 结论: 非 Bug / 已过时 / 无法复现
176+
- 理由: <详细说明>
177+
- 建议操作: 可关闭,回复说明原因
178+
```
179+
180+
### 关键注意事项
181+
182+
1. **不可自动操作 Issue**
183+
- 分析完成后,**必须人工确认无误后才可以评论或关闭 issue**
184+
- 给出建议操作,但不直接执行
185+
- 等待用户明确指令后再操作(评论、关闭、打标签等)
186+
- 回复issue的评论都使用英文
187+
188+
2. **区分问题归属**
189+
- **F-Stack 自身问题**: lib/ 目录下的代码、FreeBSD 移植层、ff_* API
190+
- **DPDK 上游问题**: dpdk/ 目录下的代码、驱动、EAL 层
191+
- **用户配置问题**: config.ini、hugepage、NIC offload、ASLR 等
192+
- **应用集成问题**: Nginx/Redis 集成、多进程架构
193+
194+
3. **DPDK 版本追踪**
195+
- F-Stack v1.25 → DPDK 23.11.5
196+
- F-Stack v1.24 → DPDK 22.11.6
197+
- F-Stack v1.22.1 → DPDK 20.11.9
198+
- F-Stack v1.21.x → DPDK 19.11.14
199+
- 涉及 DPDK 版本时,**明确 22.11 / 23.11 / 24.11 各 LTS 的修复状态**
200+
201+
4. **编译修复规则**
202+
- 修复文件后,**必须确保所有依赖该文件的其他文件也能正常编译**
203+
- 修改公共头文件后,需逐一验证所有 include 它的文件
204+
- PR 前必须执行完整 `make` 确认无 error
205+
- 编译验证命令:
206+
```bash
207+
# F-Stack lib 编译验证
208+
cd /data/workspace/f-stack/lib && make clean && make
209+
210+
# ftdns-dev src 编译验证
211+
cd /data/workspace/ftdns-dev/src && make clean && make
212+
```
213+
214+
### 批量分析流程
215+
216+
当需要批量分析多个 issue 时:
217+
218+
```bash
219+
# 1. 获取指定范围内所有 open issue
220+
gh issue list -R F-Stack/f-stack --state open --limit 500 \
221+
--json number,title,labels,createdAt,author \
222+
--jq '[.[] | select(.number >= <START> and .number <= <END>)] | sort_by(.number)'
223+
224+
# 2. 逐个执行上述五步分析流程
225+
226+
# 3. 汇总分类报告,包含:
227+
# - 总数统计
228+
# - 按类型分类(Bug / 功能请求 / 使用咨询 / 编译问题)
229+
# - 按状态分类(已修复 / 未修复 / 有 workaround / 过时)
230+
# - 建议操作清单(哪些可关闭、哪些需修复、哪些需回复)
231+
```

adapter/syscall/Makefile

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ endif
2121
# If disable it, epoll use sem_wait.
2222
#FF_PRELOAD_POLLING_MODE=1
2323

24+
# Lock-free ring IPC mode, replace sem_wait/sem_post with rte_ring.
25+
# If enable it, FF_PRELOAD_POLLING_MODE must be disabled.
26+
#FF_USE_RING_IPC=1
27+
2428
# If enable FF_KERNEL_EVENT, epoll_create/epoll_clt/epoll_wait always call f-stack and system API at the same time.
2529
# Use for some scenarios similar to Nginx.
2630
#FF_KERNEL_EVENT=1
@@ -59,6 +63,26 @@ ifdef FF_PRELOAD_POLLING_MODE
5963
CFLAGS+= -DFF_PRELOAD_POLLING_MODE
6064
endif
6165

66+
ifdef FF_USE_RING_IPC
67+
ifdef FF_PRELOAD_POLLING_MODE
68+
$(error "FF_USE_RING_IPC and FF_PRELOAD_POLLING_MODE are mutually exclusive")
69+
endif
70+
CFLAGS+= -DFF_USE_RING_IPC
71+
endif
72+
73+
# v3.3 H23 fix (D2): response path via sc->completion (same cache line as sc->result),
74+
# replacing rsp_ring enqueue. Always enabled as part of FF_USE_RING_IPC default behavior.
75+
76+
# v3.3 H19-final fix (D5): inline rte_ring_empty fast-path check before
77+
# ff_ring_process_requests, avoiding the dequeue burst function call stack
78+
# when req_ring is empty. Reuses existing ring metadata, NO new cross-core
79+
# fields. Always enabled as part of FF_USE_RING_IPC default behavior.
80+
81+
# v3.4 D6: inline dequeue burst + handler call within ff_handle_each_context,
82+
# eliminating ff_ring_process_requests() call stack and function pointer
83+
# indirection. NO new cross-core fields, only reduces local CPU.
84+
# Always enabled as part of FF_USE_RING_IPC default behavior.
85+
6286
ifdef FF_USE_THREAD_STRUCT_HANDLE
6387
CFLAGS+= -DFF_USE_THREAD_STRUCT_HANDLE
6488
endif
@@ -72,6 +96,7 @@ CFLAGS += -fPIC -Wall -Werror $(shell $(PKGCONF) --cflags libdpdk)
7296
INCLUDES= -I. -I${FF_PATH}/lib
7397

7498
LIBS+= -Wl,--no-whole-archive -lrt -lm -ldl -lcrypto -pthread -lnuma
99+
#LIBS+= -lmnl -lmlx5 -libverbs
75100
FF_LIBS= -L${FF_PATH}/lib -Wl,--whole-archive,-lfstack,--no-whole-archive
76101

77102
DPDK_LIBS+= $(shell $(PKGCONF) --static --libs libdpdk)
@@ -93,11 +118,19 @@ FSTACK_SRCS= \
93118
ff_so_zone.c \
94119
ff_socket_ops.c
95120

121+
ifdef FF_USE_RING_IPC
122+
FSTACK_SRCS += ff_ring_ipc.c
123+
endif
124+
96125
FF_SYSCALL_SRCS= \
97126
ff_so_zone.c \
98127
ff_hook_syscall.c \
99128
ff_linux_syscall.c
100129

130+
ifdef FF_USE_RING_IPC
131+
FF_SYSCALL_SRCS += ff_ring_ipc.c
132+
endif
133+
101134
FSTACK_OBJS= $(patsubst %.c,%.o,${FSTACK_SRCS})
102135

103136
FF_SYSCALL_OBJS= $(patsubst %.c,%.o,${FF_SYSCALL_SRCS})

adapter/syscall/README.md

Lines changed: 56 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# F-Stack LD_PRELOAD Beta Introduction
1+
# F-Stack LD_PRELOAD Introduction
22

33
This document mainly [Translated](https://lovelyping.com/?p=267) by ChatGPT.
44

@@ -15,11 +15,40 @@ Overall conclusion:
1515
- The new group of application instances needs to run on two CPU cores, while the standard F-Stack application process only needs to run on one CPU core. Overall, the cost-effectiveness is not high, and whether to use it depends on the specific situation of each business.
1616
- In the Nginx 600-byte body memory response test, the same number of new application instance groups in long connections is slightly higher than the standard F-Stack application process, while the same number of new application instance groups in short connections is slightly lower than the standard F-Stack application process, as shown in the Nginx access introduction section, but the CPU usage almost doubles.
1717

18-
【Note:】 Currently, the `libff_syscall.so` function is not yet complete and is only for testing purposes. All developers are welcome to work together to improve it. There are some issues as follows:
18+
## Known Limitations
1919

20-
- There are still memory leaks and easy deadlocks when the process ends.
21-
- Some interfaces (such as `sendmsg`, `readv`, `readmsg`, etc.) have not been optimized and tested because they have not been used yet, and further performance optimization and testing are needed.
22-
- Lack of longer running verification, there may be some unknown hidden problems that have not been discovered yet.
20+
`libff_syscall.so` has been continuously iterated since 2023 and many features that were originally open issues (such as `fork`, `accept4`, `__recv_chk` family, `epoll` polling mode and lock-free ring IPC) have already been implemented — see the [Feature Updates](#feature-updates-since-v122-2023-05-04--2026-05-25) section below. The following limitations are still tracked and contributions from the community are welcome:
21+
22+
- There are still potential memory leaks and risk of deadlocks when the process ends.
23+
- Some interfaces (such as `sendmsg`, `readv`, `readmsg`, etc.) have not been heavily exercised yet, and further performance optimization and testing are needed (newer additions such as `accept4`, `__recv_chk`, `__read_chk`, `__recvfrom_chk` have already been covered).
24+
- The project keeps iterating in production-like environments; long-haul stability feedback from the community is appreciated.
25+
- When multiple F-Stack instances are running, it cannot be used as a client temporarily, such as Nginx's proxy. The reference modification plan is as follows:
26+
- @铁皮大爷: I have implemented a similar logic before, but I added RSS in the hook. Delay the socket establishment (only after determining the target and source, then select which F-Stack as the worker process. It is required to set RSS symmetric hash when receiving on the network card to ensure that the output and input can be in the same F-Stack worker).
27+
- app -> `socket`: hold a socket operation, create fd (fd1), and return it to the user.
28+
- app -> `bind`: hold a bind operation, bind the bind parameters to fd1, and return it to the user.
29+
- app -> `connect`: add a connect parameter to bind on fd1, calculate according to RSS symmetric hash, select an F-Stack process (worker), and hand over the held `socket`, `bind`, and `connect` to the F-Stack process, and wait for synchronous return results.
30+
31+
## Feature Updates Since v1.22 (2023-05-04 ~ 2026-05-25)
32+
33+
The following items summarize the major changes accumulated in the `adapter/syscall/` directory since v1.22.
34+
35+
### New Features
36+
37+
- **Lock-free `rte_ring` IPC (`FF_USE_RING_IPC`)** — replaces the legacy semaphore-based shared-memory IPC with a DPDK SPSC ring, completely removing the global `ff_so_zone->lock` from the fstack main loop. Multi-core short / long connection measurements show ring performance is on par with or slightly below sem within 2–4%, with no cross-worker lock contention and natural immunity to startup-time spinlock starvation. The default behavior of the ring branch already enables the v3.4 optimizations (D2: `sc->completion` based wakeup; D5: inline `rte_ring_empty` fast empty check; D6: inline dequeue burst + dispatch). See appendix `FF_USE_RING_IPC` for the compile flag and `docs/ld_preload_ring_spec/` for the full design and benchmark.
38+
- **`epoll` polling mode** — improves latency for RTT-sensitive workloads when waiting for events.
39+
- **`fork` support** — every forked process now owns its own FreeBSD `struct thread`, behaving similarly to the Linux kernel. This removes the previous limitation of running `fork`-based applications under LD_PRELOAD.
40+
- **`accept4` with `SOCK_CLOEXEC` / `SOCK_NONBLOCK`** — adds `accept4` hook and supports `LINUX_SOCK_CLOEXEC` / `LINUX_SOCK_NONBLOCK` flags on `ff_socket`.
41+
- **Glibc `_FORTIFY_SOURCE` wrappers** — hooks `__recv_chk`, `__read_chk` and `__recvfrom_chk` so that applications compiled with `-D_FORTIFY_SOURCE` work correctly under LD_PRELOAD.
42+
43+
### Improvements & Bug Fixes
44+
45+
- **`FF_KERNEL_EVENT` kernel epoll fd leak fix**`ff_hook_close` now closes the kernel-side epoll fd when `FF_KERNEL_EVENT` is enabled, eliminating kernel fd leakage observed under long-running Nginx workloads.
46+
- **`cplen` calculation fix in `ff_hook_syscall.c`** — fixes incorrect length calculation in the hook path; the style was later aligned with `ff_hook_accept` for consistency.
47+
- **`ff_hook_recvfrom` `sh_fromlen` uninitialized fix**`sh_fromlen` is now initialized before `ff_sys_recvfrom` is invoked, fixing a `-1` return regression.
48+
- **`ioctl` conflicting types compile error fix (#942)** — resolves a function-prototype conflict that broke the build on newer toolchains.
49+
- **Ring IPC startup starvation fix** — under `FF_MULTI_SC` with `idle_sleep = 0`, an nginx worker could appear deadlocked while attaching to the second fstack instance's `ff_so_zone`; the sem path now performs a conditional `unlock → pause → lock` only when there are no in-use socket contexts, removing the starvation with zero impact on normal load.
50+
- **Ubuntu 22.04 / kernel 5.19 / gcc 11.4 build fixes** — including a pre-C99 declaration issue, references #777.
51+
- **Miscellaneous compile / log / Makefile / header polishing** — including fixes to the syscall directory build, log message cleanups and a series of small refinements across `ff_hook_syscall.c`, `ff_socket_ops.c`, `ff_socket_ops.h`, `ff_linux_syscall.c`, `ff_sysproto.h`, `ff_declare_syscalls.h` and `Makefile`.
2352

2453
## Compilation of `libff_syscall.so`
2554

@@ -337,6 +366,18 @@ In this mode, the context `sc` associated with the user application program and
337366
export FF_KERNEL_EVENT=1
338367
```
339368

369+
#### FF_USE_RING_IPC
370+
371+
Whether to switch the IPC between `libff_syscall.so` and the `fstack` instance from the legacy semaphore-based shared-memory path to a lock-free DPDK SPSC `rte_ring`. Disabled by default.
372+
373+
```
374+
export FF_USE_RING_IPC=1
375+
```
376+
377+
When this flag is enabled, the v3.4 ring-path optimizations are compiled in as the default behavior (`sc->completion`-based wakeup, inline `rte_ring_empty` fast empty check, and inline dequeue burst + dispatch); no separate sub-flags are needed.
378+
379+
Performance summary: under LD_PRELOAD + `FF_MULTI_SC` with one fstack instance per nginx worker, ring is on par with sem within 2–4% across 1 / 2 / 4 cores for both short and long connections. The ring path's main value is structural — its lock-free main loop is naturally immune to startup-time spinlock starvation and removes the need for any zone-level lock on the fstack side. For production deployments where each worker has its own dedicated fstack instance, the sem path remains the recommended configuration; the ring path is kept as a reserve for future scenarios such as multi-threaded `sc` sharing within a single process, or cross-process `sc` sharing where the worker count exceeds the fstack instance count. Full design and benchmark are in `docs/ld_preload_ring_spec/`.
380+
340381
### Running Parameters
341382

342383
You can set some parameter values required by the user application program through environment variables. If you configure them through a configuration file later, you may need to modify the original application, so temporarily use the method of setting environment variables.
@@ -385,4 +426,13 @@ Configure the process ID of the user application program, which can be used with
385426
export FF_PROC_ID=1
386427
```
387428

388-
If the user application program can configure CPU affinity, you can ignore this parameter, such as the `worker_cpu_affinity` parameter in the Nginx
429+
If the user application program can configure CPU affinity, you can ignore this parameter, such as the `worker_cpu_affinity` parameter in the Nginx configuration file.
430+
431+
## Acknowledgements
432+
433+
Special thanks to the following external contributors whose pull requests and commits since 2023-05-04 have significantly extended `libff_syscall.so`:
434+
435+
- **[liujinhui-job](https://github.com/liujinhui-job)** — contributed the largest number of commits and pull requests, including `fork` support (PR #887), `accept4` with `SOCK_CLOEXEC` / `SOCK_NONBLOCK`, the `__recv_chk` / `__read_chk` / `__recvfrom_chk` family of `_FORTIFY_SOURCE` hooks, `epoll` polling mode, the `ff_hook_recvfrom` `sh_fromlen` initialization fix (PR #872), and a series of refinements across `ff_hook_syscall.c`, `ff_socket_ops.c`, `ff_socket_ops.h`, `ff_linux_syscall.c`, `ff_sysproto.h`, `ff_declare_syscalls.h` and `Makefile`.
436+
- **[zhaozihanzzh](https://github.com/zhaozihanzzh)** — fixed the `cplen` calculation in `ff_hook_syscall.c` (and aligned the style with `ff_hook_accept`), and resolved the kernel-side epoll fd leakage in `ff_hook_close` when running under `FF_KERNEL_EVENT`.
437+
438+
Their contributions have substantially improved the completeness, correctness and Nginx-friendliness of the LD_PRELOAD path. All community pull requests are welcome.

0 commit comments

Comments
 (0)