Repository navigation
fix: 分配中途从根回收导致对象重叠;box 池 >4GiB 时指针溢出 - #14
Open
carsontung666 wants to merge 2 commits into
Open
carsontung666 wants to merge 2 commits into
carsontung666 wants to merge 2 commits into
Conversation
sbo_find_alloc 在 meta 块不足时调用 sbo_reclaim_empty(root)。若当前所在 box(或其祖先)整棵子树为空,会被这次回收 blocks_free 掉;随后 blocks_alloc 往往把同一块再分出来,新对象落在已脱离树的 box 里,而父层 认为该 slot 空闲,之后的分配与之重叠,且该块永久泄漏。 - sbo_find_alloc:只回收当前 box 自己的空子 box;块不足直接失败。 - sbo_alloc:find 失败且确有块被回收时,在顶层重试一次(不再误报 OOM)。 - sbo_mask_contmax:m32 非 0 时 best 应为 32 而不是 33(只会高估,hint 精度问题)。 - sbo_find_alloc 新建子 box 后补 sbo_propagate,父链缓存不再过期高估。 - sbo_box_at:id * stride 改用 size_t,避免单 shard 池 >= 4GiB 时溢出。 18_model_check 新增 G(3 块池定向复现:重叠 + 泄漏)与 H(5 块池随机 churn)两个阶段;旧代码下二者均 FAIL。
两者只影响 hint 精度(高估容量,不会分错也不会误报 OOM),且 contmax 修正在 churn 基准上有约 2.5% 的未解释开销。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
只修两个会破坏数据的 bug,不含优化。
1. 分配中途从根回收,导致对象重叠
sbo_find_alloc在 meta 块不足(max_blocks - used_blocks < need_blk)时调用sbo_reclaim_empty(root)。如果当前所在的 box(或它的祖先)整棵子树为空,这次回收会把它blocks_free掉。紧接着blocks_alloc往往把同一块再分出来,新对象落在一个已经脱离树的 box 里;父层认为该 slot 空闲,后续分配就和它重叠,那个块也永久泄漏。最小复现(2MB 数据、单 shard、池里正好 3 个 box):
kvspace-c 只在池"完全满"时才扩容(
sbo_pool_full只看还能否再放 1 块),剩 1–2 块、请求又需要建多层 box 时同样会走到这条路径。修复:
sbo_find_alloc不再从 root 回收,只回收当前 box 自己的空子 box(不会释放当前 box),块不足直接失败;sbo_alloc在 find 失败且 root 回收确实释放了块时,在顶层重试一次,不会因此误报 OOM。2. box 池超过 4 GiB 时
sbo_box_at32 位溢出(uint32_t)id * c->stride是 32 位乘法。单 shard 的 box 池超过 4 GiB(约 880 万个 box)后,box 指针回绕,指向池开头的旧 box。kvspace-c 用单 shard,head 池可以原地扩到 256 GiB(REGION_RESERVE),所以大库会走到这里。复现:8 GiB 数据、4.5 GiB box 池、单 shard,连续分配 504B(每次新建一个 L1 box),直到超过回绕点 20 万个 box。之后检查最早的 1000 个对象:main 上有 669 个
sbo_allocated_size出错,本分支 0 个。这个测试要 4.5 GiB 内存,没有放进 ctest。修复: 改成
size_t乘法。测试
18_model_check新增两个阶段:性能
Xeon w7-3455,gcc 13.2
-O3 -DNDEBUG,单线程绑一个物理核。main、本分支、main 副本(A/A)交替运行 30 次取中位数。工作负载是随机尺寸 churn(8B–200KB,4096 个存活对象)。正常路径没有可测的开销。8 块池那一行 main 更"快",是因为 200 万次操作里有 56 万次分配直接失败:僵尸 box 不断吃掉块,失败路径返回得很早。
review 中发现的另外两处(
sbo_mask_contmax在 m32 非 0 时高估 1、新建子 box 后父链缓存不更新)只影响 hint 精度,不会分错也不会误报 OOM,按"只修大问题"的原则从本 PR 里去掉了。