mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-11-07 01:53:24 +09:00
[MG_Remote, docs] (P7): record PH-6's debts in CONTRACT-P7 and fix the stale event-ring knob text
This commit is contained in:
+11
-7
@@ -516,13 +516,17 @@ namespace MobileGL::MG_Config {
|
||||
// MOBILEGL_IPC_EVENT_WAIT_MS (PH-6, ID-P7-2): the SERVER's patience, in ms, for ONE
|
||||
// reverse-channel event that finds SEG_EVENT full under run-ahead. The apply thread
|
||||
// publishes, rings the client and parks until the client drains enough room; a client
|
||||
// that has not made room when this runs out - it stopped draining, it drains a slot at
|
||||
// a time, or it went away - FORFEITS the reverse channel: that event and every later
|
||||
// one is dropped and counted (eventDropped), and the session stops by the ordinary
|
||||
// stop path rather than by Fatal{EventRingOverflow}. It bounds the whole reservation,
|
||||
// not one park, so a trickling peer cannot stretch it. Was a 30000 ms constant spent
|
||||
// twice. Read by the server only (ServerSpawn.cpp passes it to a spawned child); the
|
||||
// lockstep arm (no kCapRunAheadApply, i.e. Magma) never waits and keeps P5C's Fatal.
|
||||
// that has not made room when this runs out - it stopped draining (NotDraining) or it
|
||||
// drains a slot at a time (TooSlow) - FORFEITS the reverse channel: that event and every
|
||||
// later one is dropped and counted (eventDropped), and the session stops by the ordinary
|
||||
// stop path rather than by Fatal{EventRingOverflow}. A peer that goes away (PeerGone) or
|
||||
// a session that is stopped (Stopped) ends the wait at once instead, so the knob may
|
||||
// exceed ServerLoop::Stop()'s 5000 ms join. It bounds the whole reservation, not one
|
||||
// park, so a trickling peer cannot stretch it - nor can a shm peer that writes the
|
||||
// (peer-writable) eventRingFull latch to 0 itself, though that one keeps the apply
|
||||
// thread spinning rather than parked until the budget runs out. Was a 30000 ms constant
|
||||
// spent twice. Read by the server only (ServerSpawn.cpp passes it to a spawned child);
|
||||
// the lockstep arm (no kCapRunAheadApply, i.e. Magma) never waits and keeps P5C's Fatal.
|
||||
Uint32 EventWaitMs = 2000;
|
||||
// MOBILEGL_IPC_PERSISTENT_BLOCK_KB: block granularity of the persistent-map push.
|
||||
// 0 IS A NEGATIVE CONTROL, NOT "unlimited": it disables the push, and
|
||||
|
||||
@@ -185,3 +185,4 @@ verify **在 wave 3 之前**只在 monolith 臂注册(`MG_IntegrationTest/CMak
|
||||
- 采样器 14:`SamplerObject::Get{BorderColor,BorderColorI,BorderColorUI,CompareMode,MagFilter,MaxAnisotropy,MaxLod,MinFilter,MinLod,MipmapMode,SamplerCompareFunc,WrapR,WrapS,WrapT}`(`VkSamplerManager` 的 `<SamplerObject>` 实例化;5 个另由 `UniformManager::ProgramSamplesOnlySingleLevelTextures`)。
|
||||
- 对象读 6:`FramebufferAttachmentObject::{GetSize,IsComplete,IsValid}`、`RenderbufferObject::IsAllocated`、`VertexArrayObject::GetIndexBufferBindingSlot`、`BufferObject::EnsureGpuResidentStorage`(monolith render pass / clear / blit / 回读 / 索引 / SSBO 与 XFB)。
|
||||
- `MGB_CTX` 访问 4:`PipeInputs::{GetTextureObject,HasOpenTransformFeedbackSpan,InvalidateCompileEnv}`、`GLImpl::CopyTextureImageToClientOrPBO_State`。
|
||||
- **PH-6 / fuzz 臂 3 的记录债(包 f2-event,ID-P7-2;细节 `~/w7/logs/f2-event/NOTE.md` §5)**:(1) **被丢事件所属的那条记录照常完成**:它仍贴 `kStatusOk` 回复并推进 `appliedSeq`(`ServerLoop.cpp` `DrainRing` 在该记录之后才停),而 `Client/` 里没有任何代码读 `eventDropped`(`EventRingConsumer::DroppedEvents()` 只有测试在读)——一个先发不等的 readback、事后才等其回复的 client,可能在看到 EOF 之前读到缺那次 writeback 的影子。只有不等待的 client 走得到(等待中的 client 在等待里就排空了)。修法候选是让触发 forfeit 的记录回复失败,或 client 在 `eventDropped != 0` 时闩 device-lost;两者都动 client 的等待 / 回复契约,未做。(2) **inproc 不被告知**:forfeit 停掉 apply 线程,同进程的 client 收不到任何信号。这不是「只有测试能到达」(初版 NOTE 的说法不对):(3) 的场景在 inproc 上同样可达,之后 client 的下一次等待在 120 s 后以 `Fatal{BarrierTimeout}` 死——诊断名字是错的,真因是 forfeit(审查指出,本包未测)。(3) **默认 2000 ms 未在设备上测过**:合法 client 停调 GL 超过旋钮(如 Android 退后台)且队里有一环以上未等待的事件(XFB writeback)会丢会话;此前是 30 s 后 Fatal。(4) **lockstep 臂不变**:无 `kCapRunAheadApply` 的 server(Magma)满环仍是 P5C 的 `Fatal{EventRingOverflow}`,不排空的对端让会话 SIGABRT(计入 `sessionsFaulted`,下一连接照常服务);fuzz 臂 3 没有 Magma 臂。(5) **对端不被告知原因**:没有 forfeit 的 wire 词,client 只见 EOF → device-lost;加 `Refuse` / `Fatal` 码会改 `wireFingerprint`。(6) **shm 的 `eventRingFull` 在对端可写的页上**:持续写 0 的对端让保留循环不 park 地自旋,直到旋钮耗尽后以 `TooSlow` forfeit 或会话被 Stop(有界,只记)。(7) **stream 面的阻塞 `sendmsg`**(`StreamLink.cpp:158`,apply 线程经 `StreamLink::Flush` 同步 `SendEvents`)**不是无界的**:数据套接字带 `TCP_USER_TIMEOUT=5000`(`SocketTransport.cpp:99-112`)。实测(临时探针,未入库):对端 SIGSTOP、旋钮 8000,stream 面 5327 ms 时链路被内核判死 → `ReverseChannelForfeit{PeerGone}`、exit 0;shm 面等满 8006 ms → `NotDraining`、exit 0。即 stream 面上一个冻住(活着但不 ACK)的对端约 5 s 被叫作 PeerGone,与旋钮无关;apply 线程恰好卡在 send 里时控制流又结束,`Stop()` 的 5000 ms join 与这 5 s 赛跑——未构造出,记录。(8) forfeit 后队列里剩下的记录不再应用(有意);`RunSession` 每会话每 250 ms 轮询一次控制套接字,且每一轮都查 apply 线程(记录,不是门)。(9) 排在 PH-6 等待后面的 surface op:server 的控制线程阻塞在 apply 线程的邮箱里(P5e 的等待谓词不含控制请求,本包未改),对端活着但只是不排空时,这个 op 要等旋钮耗尽才被回答;对端死亡则由数据 bell 报告(shm 面靠 server bell 挂在控制套接字上的死亡见证,镜像 CONTRACT-P6 D5c)。(10) **server bell 的死亡见证改变了 shm 会话的正常收尾顺序**:client 的 `ShutdownSend`(`ClientSession::Stop` 第 2 步)现在可能先让 apply 线程从 park 里以 dead bell 退出、再由控制循环读到 EOF;两条路走同一个退出块,每次 shm 会话正常收尾 server 日志多一行 INFO `the peer hung up (witness fd …, revents=0x2000)`(其措辞是为 client 侧写的)。
|
||||
|
||||
@@ -284,8 +284,9 @@ namespace MobileGL::MG_Remote::Server {
|
||||
SessionFail(MGFatalFamily::EventRingOverflow, "MGPipe: Fatal{EventRingOverflow} - %s needs %llu bytes and SEG_EVENT "
|
||||
"caps ONE record at %llu (half its capacity). Flow control cannot help: "
|
||||
"no amount of draining makes a record fit a ring that is too small for "
|
||||
"it. Raise MOBILEGL_IPC_EVENT_KB or slice the event at its producer, as "
|
||||
"the writeback path already does",
|
||||
"it. SEG_EVENT's size is fixed (SessionSegmentSizes::EventRingBytes; the "
|
||||
"MOBILEGL_IPC_EVENT_KB knob P5e proposed was never built), so slice the "
|
||||
"event at its producer, as the writeback path already does",
|
||||
eventName, static_cast<unsigned long long>(payloadBytes),
|
||||
static_cast<unsigned long long>(cap));
|
||||
}
|
||||
|
||||
@@ -653,7 +653,7 @@ CMake:
|
||||
| `MOBILEGL_IPC_RING_MB` | 8 | `SEG_CMD`;单条记录至多一半 |
|
||||
| `MOBILEGL_IPC_STAGE_MB` | 32 | `SEG_STAGE`;目标负载 profile 显式 256 |
|
||||
| `MOBILEGL_IPC_SPIN_US` | 50 | park 前自旋;P5d 三轮起自旋按一次性校准的迭代预算走、稳态不读时钟,`0` = 不自旋直接 park |
|
||||
| `MOBILEGL_IPC_EVENT_WAIT_MS` | 2000(1–600000) | PH-6(ID-P7-2),只由 server 读(`ServerSpawn.cpp` 放行给 spawn 子进程):run-ahead 下一条反向事件遇到满的 `SEG_EVENT` 时,server 等 client 腾出空间的**整笔预算**(不是每次 park 的)。到期、client 只涓流不腾够、或 client 的 bell 已死(先判死,不误报为超时)→ `ReverseChannelForfeit{NotDraining\|TooSlow\|PeerGone}`:该事件及其后全部计数丢弃(`eventDropped`),apply 循环按正常 Stop 退出,会话 exit 0,supervisor 照常欢迎下一连接。取代原先 30000 ms × 两轮后的 `Fatal{EventRingOverflow}`。lockstep 臂(无 `kCapRunAheadApply`,即 Magma)不等待,仍是 P5C 的 Fatal |
|
||||
| `MOBILEGL_IPC_EVENT_WAIT_MS` | 2000(1–600000) | PH-6(ID-P7-2),只由 server 读(`ServerSpawn.cpp` 放行给 spawn 子进程):run-ahead 下一条反向事件遇到满的 `SEG_EVENT` 时,server 等 client 腾出空间的**整笔预算**(不是每次 park 的)。到期(client 不排空 / 只涓流不腾够)→ `ReverseChannelForfeit{NotDraining\|TooSlow}`;client 已走(bell 已死——shm 上靠 server bell 挂在控制套接字上的死亡见证——或控制流 EOF)→ `{PeerGone}`、会话被 Stop(如控制流收到畸形帧)→ `{Stopped}`,这两种立即结束等待,所以旋钮可以大于 `ServerLoop::Stop()` 的 5000 ms join。之后该事件及其后全部计数丢弃(`eventDropped`),apply 循环按正常 Stop 退出,控制循环每一轮都查 apply 线程是否还在,会话 exit 0,supervisor 照常欢迎下一连接。取代原先 30000 ms × 两轮后的 `Fatal{EventRingOverflow}`。lockstep 臂(无 `kCapRunAheadApply`,即 Magma)不等待,仍是 P5C 的 Fatal |
|
||||
| `MOBILEGL_IPC_PERSISTENT_BLOCK_KB` | 64 | persistent-map 推送块粒度;`0` 是 E3(a) 阴性对照 |
|
||||
| `MOBILEGL_IPC_PERSISTENT_HASH_SUPPRESS` | 1 | 推送只发内容变了的块(追踪 buffer 走 mprotect 位图,未追踪走内容哈希);`0` 恢复全范围推送(A/B 对照) |
|
||||
| `MOBILEGL_IPC_BATCH_WAITS` | 1 | 值类记录(无 reply slot 的 kCtxState/kCtxCso/kCtxObject)发布即返回,barrier 推迟到下一个拉取类 verb;**`generate_mipmap` 例外**(它的 apply 读 `MGB_CTX->GetActiveTextureUnit()`,规则:只有 apply 不读残余填充字段的记录才可免等);`0` 恢复 R-1 逐条 barrier(`MOBILEGL_PIPE_VERIFY` 强制 0) |
|
||||
|
||||
Reference in New Issue
Block a user