Conversation
| let (source_allocation, source_base, source_addr, response_ssd_stage_len) = | ||
| if local_direct_read { | ||
| let target_capacity = target_allocation.capcity(); | ||
| if target_capacity < ssd_stage_len { |
There was a problem hiding this comment.
[P1] 允许未对齐容量走 scratch 读取
这里把本地 SSD 回填强制要求为 target_capacity >= align(len, 512),但 KvSsdStorage::load_into_addr 已经会在容量不满足 direct I/O 时选择 scratch,并且最终只复制真实的 len。当前 buddy allocator 对 100 B 请求只会给 128 B capacity,因此这类小 value 的内存副本被驱逐后,本地 SSD GET 会在这里直接失败,尽管 target 足以容纳 payload。这里应只要求 target_capacity >= len,并把实际 capacity 传下去,让存储层自行选择 direct/scratch。
| self.submit_ctx(ctx, &mut read_inflight, &mut write_inflight); | ||
| continue; | ||
| } | ||
| if let Err(err) = self.uring.submit_and_wait(1) { |
There was a problem hiding this comment.
[P1] 不要因可重试的 io_uring 错误退出 worker
submit_and_wait 可能瞬时返回 EINTR,CQ overflow 时也可能返回 EBUSY。当前分支只处理已经出现在 CQ 中的项就直接退出;仍在内核中的 SQE 对应的 IoCtx 只剩 user_data 裸指针,其 oneshot 不会完成,随后该 ring 上的读写会挂住或因 receiver 关闭持续失败。请对 EINTR 重试、对 EBUSY drain 后重试;若确实是致命错误,也需要显式完成/取消全部 outstanding context 后再终止 worker。
| avformat_close_input(&fmt_ctx); | ||
| } | ||
| if (avio_ctx != NULL) { | ||
| avio_context_free(&avio_ctx); |
There was a problem hiding this comment.
[P1] 释放 AVIOContext 使用的 buffer
成功调用 avio_alloc_context 后,上面的局部 avio_buffer 被置为 NULL;而 FFmpeg 的 avio_context_free 只释放 context 本身(实现中仅调用 av_freep(ps)),不会释放 avio_ctx->buffer。因此每次 read_frames_numpy 都会泄漏这里分配的 64 KiB。应在 avio_context_free 前调用 av_freep(&avio_ctx->buffer)。
| detail: "kv ssd storage has no active device".to_string(), | ||
| })); | ||
| } | ||
| let idx = self.next_write_device.fetch_add(1, Ordering::Relaxed) % self.devices.len(); |
There was a problem hiding this comment.
[P2] 按 entry 大小选择可承载的 device
这里在不知道 entry_len 的情况下直接 round-robin 到单个 device,而该 device 的 writer 之后只会在自己的 shard_ids 中分配。配置不同大小的多个 root 时,一个只放得进大盘 shard 的 value 若轮询到小盘会直接返回 InvalidArgument,即使其他 device 有足够空间也不会重试,导致 SSD persist 是否成功取决于计数器奇偶。建议先按 aligned length 过滤可承载的 device,并在候选 device 间做 fallback。
No description provided.