docs(storage): #45 复核结论——卷锁无第二写者,全序列卷锁项关闭(销项) #86
+2
-4
@@ -20,8 +20,7 @@
|
||||
|
||||
| # | 事项 | 发现 | 证据与现状 | 出处 |
|
||||
|---|---|---|---|---|
|
||||
| dhara 重试自旋残留 | **dhara 重试自旋残留**——`try_recover()` 的 `DHARA_MAX_RETRIES`(8) 自旋在坏块密集时仍可能长时间占用 defaultTask(喂狗点) | 2026-10-02 | 低优先:现有 `vol_lock` + 喂狗节奏缓解;若台架再出"存储侧喂狗饥饿"再排期 | `Lib/dhara/map.c` |
|
||||
| 可选全序列卷锁 | **可选全序列卷锁**——现卷锁仅覆盖 `syslog` / `cfg` / `lftpd` 三条路径(`vol_lock_wait(0)` try 语义),其它潜在访问点(如 UI 读日志)未纳入。⚠ 原本挂在本题下的「dhara 失败类快照(C4)」待还项**已于 2026-11-04 由问题 #79 还清**(`nand_ftl_fault_get/clear` + 探针按类分流,见 `../架构设计/STM32F4-Base存储架构说明.md` §10.4 已闭环段)——本题现只剩**卷锁覆盖面**本身,不再被 C4 阻塞 | 2026-10-02;C4 拆分 2026-11-04 | 待评估:先确认是否真有第二写者;无则关闭本项 | `App/fs/vol_lock.{c,h}` |
|
||||
| dhara 重试自旋残留 | **dhara 重试自旋残留**——`try_recover()` 的 `DHARA_MAX_RETRIES`(8) 自旋在坏块密集时仍可能长时间占用 defaultTask(喂狗点) | 2026-10-02;2026-11-05 复核未复发 | 低优先:现有 `vol_lock` + 喂狗节奏缓解,自旋另有 FTL 入口直接喂狗兜底(`../架构设计/STM32F4-Base存储架构说明.md` §10.5);若台架再出"存储侧喂狗饥饿"再排期 | `Lib/dhara/map.c` |
|
||||
|
||||
## 3. 硬件(V0.1 缺陷 → V0.2 改版项)
|
||||
|
||||
@@ -53,8 +52,7 @@
|
||||
|---|---|---|---|
|
||||
| 1 | **net 层跨上下文收口** | 同批处理两件事:裸指针收口为状态查询 API;对时 reconcile/relisten 突发导致 uiTask 800 ms 以上连续缺席,评估优先级矩阵与突发分片让路 | 同类台架负载下不再出现目标饿死签名;网络与 UI 回归通过;证据写入网络与看门狗模块文档 |
|
||||
| 2 | **网络性能资源建议簇** | 分别评估 PASV 重复建监听、PHY 强制 100M 无回退、`NET_MAX_SOCKETS` 与单连接语义不一致;DE 项随 RS-485,不在本项做。机理见 `../网络/Net层阻塞模型架构设计.md` 与 `Drivers/BSP/NET/README.md` | 每项形成“修改并验证”或“有理由不做”的结论;不为了清清单做无收益重构 |
|
||||
| 3 | **dhara 重试自旋与卷锁评估** | 先确认是否仍出现存储侧喂狗饥饿、是否确有第二写者,再决定是否修改 | 有新证据才排修改;无第二写者则关闭全序列卷锁项 |
|
||||
| 4 | **uvprojx 空 TU 观察** | 201 个 LVGL `.c` 中 127 个在 `.map` 零产出,但当前增量构建仅 4~5 秒;有全量构建耗时痛点时先补计时基线,再用 Keil 原生 `<IncludeInBuild>0</IncludeInBuild>` 可逆排除 | 有实测收益才保留改动;否则继续观察 |
|
||||
| 3 | **uvprojx 空 TU 观察** | 201 个 LVGL `.c` 中 127 个在 `.map` 零产出,但当前增量构建仅 4~5 秒;有全量构建耗时痛点时先补计时基线,再用 Keil 原生 `<IncludeInBuild>0</IncludeInBuild>` 可逆排除 | 有实测收益才保留改动;否则继续观察 |
|
||||
|
||||
> RS-485 白名单随 `暂缓-RS485.md` 整簇处理,不列为 UI 后的独立编码任务。
|
||||
> 并行写域、工作树与合并纪律统一见 `docs/环境与部署/并行任务工作树方案.md`。
|
||||
|
||||
@@ -728,3 +728,44 @@ LPN 与原始码的位置**就地分类并打印(`ftl_err_name()` 给可读名
|
||||
`[CFG] load: file missing, factory template generated`,0 条 flush FAIL。
|
||||
⚠ 动作 A 语义 = 卷内容全失(旧卷随 map clear 作废),本次台架卷为可弃数据。
|
||||
|
||||
### 10.5 卷锁覆盖面审计与 dhara 重试自旋复核(2026-11-05,问题 #45 评估结论)
|
||||
|
||||
**结论先行:卷锁之外没有第二写者,登记簿「可选全序列卷锁」项就此关闭;
|
||||
「存储侧喂狗饥饿」无 2026-10-02 之后的新证据,dhara 重试自旋保留为长期观察。**
|
||||
判据 = 对 master `c487ce4` 的调用点枚举(判据:`App/` 与 `Drivers/BSP/` 下全部带
|
||||
`FA_WRITE` 的 `f_open` 与 `f_unlink`/`f_rename`/`f_mkdir`/`f_opendir` 调用点)
|
||||
+ 2026-11-05 之前的全部台架留档。评估过程与逐条证据见 Gitea 问题 #45。
|
||||
|
||||
**覆盖面清单(生产构建的全部卷访问序列):**
|
||||
|
||||
| 访问道 | 任务上下文 | 串行化纪律 |
|
||||
|---|---|---|
|
||||
| `/log` 七本 + `wdev.log`(追加写 / 清除 / `f_mkdir /log`) | defaultTask | `vol_lock_wait(0)` try,锁跨 open…close 完整序列(`App/log/sys_log_mcu.c`) |
|
||||
| `/log/soe.log` | defaultTask | 同上(`App/log/soe_store.c`) |
|
||||
| `/config.ini` 原子写 tmp+rename / unlink;`/prot_set.bin` 同后端 | defaultTask | 同上,store 后端四函数全覆盖(`App/cfg/cfg_file_store_mcu.c` v1.3;`App/cfg/prot_set_store.c` 走 `cfg_store_read`/`cfg_store_write_atomic`,无独立盘触点) |
|
||||
| `/wave` 录波段(mkdir / 追加写 ≤21×`f_write` / unlink) | defaultTask | 同上,锁跨完整序列(`App/task/default_task.c` 录波段) |
|
||||
| FTP RETR/STOR/LIST/DELE/MKD | ftpTask | 100 ms 分片阻塞 + 每片 `lftpd_task_wd_beat()`,锁跨 open…close / opendir…closedir 全程(`Drivers/BSP/NET/lftpd/lftpd_io.c`) |
|
||||
| 回放页段表/段窗读、UI 记录页读 | uiTask | try(0) 锁跨完整序列(`App/task/ui_task.c`、`App/log/sys_log_mcu.c` 读径) |
|
||||
| 空闲 flush 兜底(`CTRL_SYNC`) | defaultTask | try(0) 闸门,卷忙跳过(§5.5;`App/fs/vol_idle_sync.c`) |
|
||||
| `f_mount`/`f_mkfs`/`/fschk.tmp` 探针/`nand_ftl_format` | defaultTask 启动段 | **就绪屏障门控**:`STORAGE_READY` 在 `storage_bring_up()` 末尾才置位,netTask/ftpTask/uiTask 的卷入口全部等屏障(`App/task/default_task.c` 卷锁创建处注释),启动期卷写无并发使用者 |
|
||||
|
||||
LVGL 的 FatFs 驱动桥(`Lib/lvgl/src/libs/fsdrv/lv_fs_fatfs.c`)`LV_USE_FS_FATFS`
|
||||
默认关闭、本仓未接线,不是卷使用者;`test/board/` 的存储测试任务仅存在于互斥测试
|
||||
构建(`test-suite-switch` 门禁),不在产品镜像。**登记簿原口径「卷锁仅覆盖
|
||||
syslog/cfg/lftpd 三条路径」是 2026-10-02 建档快照,已被本表取代**——SOE、录波段写、
|
||||
`/prot_set.bin`、UI 读径与空闲 sync 随后都进了同一把锁。
|
||||
|
||||
**dhara 重试自旋**:`try_recover()` 的自旋有界——`DHARA_MAX_RETRIES`(8) 次 restart
|
||||
后以 `DHARA_E_TOO_BAD` 定案(`Lib/dhara/map.c:270-306`),journal 层六处重试环同为
|
||||
有界;且 NAND 长操作在驱动入口与 `gd5f_wait_busy` 每 100 ms 经 `nand_ftl_wd_feed()`
|
||||
**直接喂 IWDG**(`Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c`)——自旋即便落在
|
||||
defaultTask(喂狗点)内也不饿狗,残留形态收敛为「有界时长的存储服务延迟」。
|
||||
真 NAND 卡死 = 持续喂狗、设备存活但存储冻结,属已声明边界
|
||||
(`../子系统设计/看门狗设计说明.md` §9 R4;要改成"NAND 死也复位"需给
|
||||
`nand_ftl_wd_feed()` 加上限,非本单判据)。**复发复核**:「存储侧喂狗饥饿」唯一
|
||||
实证 = 2026-10-02 台架轮(并发 FTL 写 → journal 竞争,另有同日 IWDG 超时被配成
|
||||
复位默认值的 P0 修复,见 `../子系统设计/看门狗设计说明.md` 变更记录),此后
|
||||
2026-10-25 F2/F3 探针轮、2026-11-02 录波枚举台架轮(卷锁 try 超时 0 次)、
|
||||
2026-11-05 PR #82 补验 soak(STOR 密集)均无该签名。重开判据不变:**台架再出
|
||||
存储侧喂狗饥饿才排期**;观察行留登记簿 §2。
|
||||
|
||||
|
||||
+1
-1
@@ -320,7 +320,7 @@ STM32F4-Base/
|
||||
│ │ console_log(UART5 控制台单写者)、soe_rec(64B SOE 纯编解码)+ soe_store(投递/落盘胶水)
|
||||
│ ├── cfg/ 配置引擎:cfg_file(静态态单任务收敛于 defaultTask)、store(MCU=FreeRTOS 堆)、
|
||||
│ │ prot_set_store(/prot_set.bin 原子写,保护定值持久化)
|
||||
│ ├── fs/ 卷锁 vol_lock(syslog / cfg / lftpd 三条路径 try 语义)、vol_idle_sync
|
||||
│ ├── fs/ 卷锁 vol_lock(全卷访问点串行化:写者/读者 try、lftpd 分片阻塞)、vol_idle_sync
|
||||
│ ├── sync/ time_sync(timeSyncTask 载体)、time_sntp(SNTP 校时客户端,UDP)
|
||||
│ └── util/ sys_clock(墙钟)、task_watchdog(IWDG 判定状态机)、boot_stats、sha256、task_prof
|
||||
├── Drivers/BSP/ 纯手工驱动/服务(不受 CubeMX 保护)
|
||||
|
||||
Reference in New Issue
Block a user