Record networking and DMA development progress
Add the current OS source tree, build scripts, system image layout, and development notes covering DMA page allocation, e1000 bring-up, net API dispatch, and DHCP work in progress.
This commit is contained in:
+504
@@ -0,0 +1,504 @@
|
||||
# UTSM 算法记录
|
||||
|
||||
```text
|
||||
UTSM = UUID-Tuned Sealed Memory
|
||||
中文名:UUID 调谐封缄内存
|
||||
```
|
||||
|
||||
本文记录 UTSM v1 的核心算法。
|
||||
|
||||
---
|
||||
|
||||
## 1. 段创建算法
|
||||
|
||||
目标:为任务创建一个只存密文的连续内存段,并返回 capability。
|
||||
|
||||
```text
|
||||
utsm_create_segment(process, size, flags)
|
||||
1. size 按 64B / 4KB 对齐。
|
||||
2. 从 buddy/slab 分配 cipher data pages。
|
||||
3. 从 DMP pool 分配 DMP。
|
||||
4. 生成 segment_uuid。
|
||||
5. key_epoch = process.crypto_epoch。
|
||||
6. tweak_seed = hash(process_uuid, segment_uuid, key_epoch)。
|
||||
7. 初始化 dirty_bitmap。
|
||||
8. 初始化 mac_table。
|
||||
9. 填写 utsm_segment_desc。
|
||||
10. 填写 utsm_dmp。
|
||||
11. generation++。
|
||||
12. 生成 utsm_capability。
|
||||
13. 将 capability 写入任务 capability table。
|
||||
14. 返回 capability。
|
||||
```
|
||||
|
||||
复杂度:
|
||||
|
||||
```text
|
||||
段元数据初始化:O(1)
|
||||
数据页分配:O(page_count)
|
||||
热路径访问定位:O(1)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. 密钥派生算法
|
||||
|
||||
UUID 不作为明文密钥,而是作为调谐因子。
|
||||
|
||||
```text
|
||||
segment_key = KDF(
|
||||
DRR_root_key,
|
||||
process_uuid,
|
||||
segment_uuid,
|
||||
key_epoch
|
||||
)
|
||||
```
|
||||
|
||||
每 64B cache line 生成 tweak:
|
||||
|
||||
```text
|
||||
line_index = offset / 64
|
||||
tweak = hash(tweak_seed, line_index, key_epoch)
|
||||
```
|
||||
|
||||
加密和解密对称:
|
||||
|
||||
```text
|
||||
ciphertext = plaintext XOR stream(segment_key, tweak)
|
||||
plaintext = ciphertext XOR stream(segment_key, tweak)
|
||||
```
|
||||
|
||||
设计理由:
|
||||
|
||||
```text
|
||||
1. 避免十进制 UUID 解析。
|
||||
2. 避免 UUID 孔洞破坏连续内存。
|
||||
3. 以 64B cache line 为单位,适合 CPU cache 和 SIMD。
|
||||
4. key_epoch 可用于快速作废旧段。
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. UTRW Fast Read 算法
|
||||
|
||||
```text
|
||||
UTRW_READ_FAST(cap, offset, len, dst)
|
||||
1. desc = SEGMENT_TABLE[cap.segment_slot]。
|
||||
2. 检查 desc.generation == cap.generation。
|
||||
3. 检查 cap.rights 包含 READ。
|
||||
4. 检查 cap.epoch == desc.key_epoch。
|
||||
5. 检查 offset + len <= desc.cipher_length。
|
||||
6. 检查 desc.state == ACTIVE。
|
||||
7. key = PCKC_LOOKUP(desc.segment_slot, desc.key_epoch)。
|
||||
8. 如果 key miss,进入 slow path。
|
||||
9. 读取 writer_seq_before。
|
||||
10. 如果 writer_seq_before 为奇数,重试或 slow path。
|
||||
11. 对访问范围涉及的每个 64B line:
|
||||
a. 计算 line_index。
|
||||
b. 生成 tweak。
|
||||
c. 读取密文 line。
|
||||
d. 解密成明文 line。
|
||||
e. 拷贝目标字节到 dst。
|
||||
12. 读取 writer_seq_after。
|
||||
13. 如果 before != after,重试。
|
||||
14. 返回 OK。
|
||||
```
|
||||
|
||||
复杂度:
|
||||
|
||||
```text
|
||||
段定位:O(1)
|
||||
读写长度 n:O(n / 64)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. UTRW Fast Write 算法
|
||||
|
||||
```text
|
||||
UTRW_WRITE_FAST(cap, offset, len, src)
|
||||
1. desc = SEGMENT_TABLE[cap.segment_slot]。
|
||||
2. 检查 desc.generation == cap.generation。
|
||||
3. 检查 cap.rights 包含 WRITE。
|
||||
4. 检查 cap.epoch == desc.key_epoch。
|
||||
5. 检查 offset + len <= desc.cipher_length。
|
||||
6. 检查 desc.state == ACTIVE。
|
||||
7. key = PCKC_LOOKUP(desc.segment_slot, desc.key_epoch)。
|
||||
8. 如果 key miss,进入 slow path。
|
||||
9. 如果是强恢复段,写 WRITE_INTENT log。
|
||||
10. writer_seq++,进入奇数写入状态。
|
||||
11. 对访问范围涉及的每个 64B line:
|
||||
a. 计算 line_index。
|
||||
b. 生成 tweak。
|
||||
c. 如果覆盖完整 line,直接使用 src 明文。
|
||||
d. 如果部分覆盖 line,读取旧密文,解密旧明文,合并新明文。
|
||||
e. 加密成新密文。
|
||||
f. 写回 cipher data。
|
||||
12. 标记 dirty_bitmap。
|
||||
13. writer_seq++,回到偶数稳定状态。
|
||||
14. 如果是强恢复段,写 WRITE_COMMIT log。
|
||||
15. 返回 OK。
|
||||
```
|
||||
|
||||
部分写规则:
|
||||
|
||||
```text
|
||||
UTSM 的加密单位是 64B line。
|
||||
如果只写 line 的一部分,必须读旧密文、解密、合并、重新加密整条 line。
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. UTRW Slow Path 算法
|
||||
|
||||
Slow Path 触发条件:
|
||||
|
||||
```text
|
||||
PCKC key miss
|
||||
generation mismatch
|
||||
epoch mismatch
|
||||
state != ACTIVE
|
||||
checkpoint busy
|
||||
recovery busy
|
||||
MAC failed
|
||||
segment poisoned
|
||||
out of bounds
|
||||
access denied
|
||||
```
|
||||
|
||||
处理策略:
|
||||
|
||||
```text
|
||||
KEY_MISS
|
||||
-> 派生 segment_key
|
||||
-> 生成 key_schedule
|
||||
-> 写入 PCKC
|
||||
-> 回到 fast path
|
||||
|
||||
STALE_CAPABILITY
|
||||
-> 尝试从 capability table 刷新
|
||||
-> 失败则返回错误
|
||||
|
||||
EPOCH_EXPIRED
|
||||
-> 刷新 cap.epoch 和 auth_tag
|
||||
-> 清除旧 PCKC key
|
||||
-> 回到 fast path
|
||||
|
||||
CHECKPOINT_BUSY
|
||||
-> 短暂等待或写 side log
|
||||
|
||||
RECOVERING
|
||||
-> 阻塞任务,等待 DRR 完成恢复
|
||||
|
||||
MAC_FAILED
|
||||
-> 标记 suspicious page
|
||||
-> 通知 DRR
|
||||
-> 尝试 page rollback
|
||||
|
||||
SEGMENT_POISONED
|
||||
-> 拒绝访问
|
||||
-> 交给 DRR 决定回滚、重建或 kill task
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. PCKC 查找算法
|
||||
|
||||
每 CPU 保存少量热段 key。
|
||||
|
||||
```text
|
||||
PCKC_LOOKUP(slot, epoch)
|
||||
1. 检查 current hot slot。
|
||||
2. 检查 hot_segment_slot[0..N]。
|
||||
3. 如果 slot 和 epoch 均匹配,返回 key_schedule。
|
||||
4. 否则返回 MISS。
|
||||
```
|
||||
|
||||
替换策略:
|
||||
|
||||
```text
|
||||
第一版使用小型 LRU 或替换最冷 slot。
|
||||
```
|
||||
|
||||
建议槽数:
|
||||
|
||||
```text
|
||||
8 个 key slot 起步。
|
||||
高并发或服务型任务可扩展到 16 个。
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Checkpoint 算法
|
||||
|
||||
### 7.1 Dirty Shard 标记算法
|
||||
|
||||
Dirty Bitmap 分片为 Dirty Shard,避免 checkpoint 扫描整块大 bitmap。
|
||||
|
||||
```text
|
||||
UTSM_MARK_DIRTY(desc, page_index)
|
||||
1. shard = desc.dirty_shards[page_index / PAGES_PER_SHARD]。
|
||||
2. bit = page_index % PAGES_PER_SHARD。
|
||||
3. 如果 bit 原来是 0:
|
||||
a. 设置 bitmap bit。
|
||||
b. shard.dirty_count++。
|
||||
c. 如果 shard.dirty_count 从 0 变为 1,加入 per-cpu dirty_shard_list。
|
||||
4. 返回。
|
||||
```
|
||||
|
||||
复杂度:
|
||||
|
||||
```text
|
||||
Dirty 标记:O(1)
|
||||
Checkpoint 扫描:O(number_of_dirty_shards + number_of_dirty_pages)
|
||||
```
|
||||
|
||||
### 7.2 A/B Checkpoint Metadata 提交算法
|
||||
|
||||
```text
|
||||
CHECKPOINT_METADATA_COMMIT(gen)
|
||||
1. active = checkpoint.active_slot。
|
||||
2. inactive = opposite(active)。
|
||||
3. 清理 inactive slot 的临时状态。
|
||||
4. 写 inactive.metadata_header。
|
||||
5. 写 segment desc snapshot。
|
||||
6. 写 DMP snapshot。
|
||||
7. 写 dirty shard summary。
|
||||
8. 写 MAC root。
|
||||
9. 写 generation。
|
||||
10. 计算并写 CRC。
|
||||
11. flush inactive slot。
|
||||
12. 原子切换 checkpoint.active_slot = inactive。
|
||||
13. 写 CHECKPOINT_COMMIT log。
|
||||
```
|
||||
|
||||
恢复时:
|
||||
|
||||
```text
|
||||
1. 读取 active slot。
|
||||
2. 校验 generation 和 CRC。
|
||||
3. 如果 active 有效,使用 active。
|
||||
4. 如果 active 无效,校验 fallback slot。
|
||||
5. 如果 fallback 有效,使用 fallback。
|
||||
6. 如果双槽都无效,进入 system rollback。
|
||||
```
|
||||
|
||||
### 7.3 Dirty Page Checkpoint 算法
|
||||
|
||||
```text
|
||||
DRR_CHECKPOINT()
|
||||
1. checkpoint_generation++。
|
||||
2. 写 CHECKPOINT_BEGIN log。
|
||||
3. inactive_slot = opposite(active_slot)。
|
||||
4. 遍历 per-cpu dirty_shard_list。
|
||||
5. 跳过 dirty_count == 0 的 shard。
|
||||
6. 对每个 dirty shard:
|
||||
a. 找到关联 segment。
|
||||
b. desc.state = CHECKPOINTING。
|
||||
c. 冻结 writer。
|
||||
d. flush PWC / per-CPU dirty buffer。
|
||||
e. 只扫描 shard 内 dirty bit。
|
||||
f. 复制 dirty ciphertext page 到 checkpoint region。
|
||||
g. 计算 page MAC。
|
||||
h. 写 dirty shard summary。
|
||||
i. 清 shard bitmap。
|
||||
j. shard.dirty_count = 0。
|
||||
k. desc.state = ACTIVE。
|
||||
7. 写 segment desc snapshot。
|
||||
8. 写 DMP snapshot。
|
||||
9. CHECKPOINT_METADATA_COMMIT(checkpoint_generation)。
|
||||
```
|
||||
|
||||
提交规则:
|
||||
|
||||
```text
|
||||
只有存在 CHECKPOINT_COMMIT 且 CRC 正确的 checkpoint 才是稳定点。
|
||||
中途崩溃的 checkpoint 直接丢弃。
|
||||
A/B metadata 至少保留一个旧稳定点。
|
||||
```
|
||||
|
||||
### 7.4 DRR Emergency Pool 分配算法
|
||||
|
||||
DRR Recovery 路径不能依赖普通 allocator。
|
||||
|
||||
```text
|
||||
DRR_EMERGENCY_ALLOC(size, class)
|
||||
1. 从 DRR emergency pool 的 class freelist 取对象。
|
||||
2. 如果 freelist 非空,返回对象。
|
||||
3. 如果 freelist 为空,从 emergency pages 切分。
|
||||
4. 如果 emergency pages 不足:
|
||||
a. 写 EMERGENCY_POOL_EXHAUSTED。
|
||||
b. 进入 system rollback。
|
||||
```
|
||||
|
||||
Emergency Pool 包含:
|
||||
|
||||
```text
|
||||
DRR private stack
|
||||
recovery log buffer
|
||||
checkpoint metadata buffer
|
||||
crash buffer
|
||||
metadata slab
|
||||
emergency pages
|
||||
```
|
||||
|
||||
规则:
|
||||
|
||||
```text
|
||||
普通 allocator 不可使用 Emergency Pool。
|
||||
Emergency Pool 不参与普通内存回收。
|
||||
DRR OOM 直接视为不可恢复故障。
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Rollback 算法
|
||||
|
||||
分三级。
|
||||
|
||||
### 8.1 Page Rollback
|
||||
|
||||
```text
|
||||
1. 定位最近稳定 checkpoint。
|
||||
2. 校验 checkpoint page MAC。
|
||||
3. 将旧密文页复制回 cipher data。
|
||||
4. 恢复 page MAC。
|
||||
5. 清 dirty bit。
|
||||
6. 段保持 ACTIVE。
|
||||
```
|
||||
|
||||
### 8.2 Segment Rollback
|
||||
|
||||
```text
|
||||
1. desc.state = RECOVERING。
|
||||
2. 恢复 segment desc snapshot。
|
||||
3. 恢复 DMP snapshot。
|
||||
4. 恢复 key_epoch。
|
||||
5. 恢复 dirty bitmap。
|
||||
6. 恢复 mac_table。
|
||||
7. 清除对应 PCKC key。
|
||||
8. desc.state = ACTIVE。
|
||||
```
|
||||
|
||||
### 8.3 System Rollback
|
||||
|
||||
```text
|
||||
1. DRR 写 crash reason。
|
||||
2. 标记 boot attempt failed。
|
||||
3. 触发 reboot。
|
||||
4. bootloader 读取 BCB。
|
||||
5. 如果失败次数超限,切换 last_good_slot。
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. 任务创建算法
|
||||
|
||||
```text
|
||||
task_create(entry, priority, flags)
|
||||
1. 分配 TCB。
|
||||
2. 生成 tid。
|
||||
3. 生成 process_uuid。
|
||||
4. 创建 utsm_process_context。
|
||||
5. 创建 stack segment。
|
||||
6. 创建 heap segment。
|
||||
7. 可选创建 ipc segment。
|
||||
8. 初始化 capability table。
|
||||
9. cap[0] = stack。
|
||||
10. cap[1] = heap。
|
||||
11. 初始化 CPU context。
|
||||
12. 通过 UTRW_WRITE 写入 task_start_packet。
|
||||
13. hot_segment_hint = stack.segment_slot。
|
||||
14. state = READY。
|
||||
15. enqueue_task(current_cpu)。
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. 调度切换算法
|
||||
|
||||
```text
|
||||
schedule()
|
||||
1. old = current。
|
||||
2. utsm_switch_out(old)。
|
||||
3. next = pick_next_task()。
|
||||
4. utsm_switch_in(next)。
|
||||
5. context_switch(old, next)。
|
||||
```
|
||||
|
||||
`utsm_switch_out`:
|
||||
|
||||
```text
|
||||
1. 如果 old 有 PWC dirty,登记 flush pending。
|
||||
2. 保存 old.hot_segment_hint。
|
||||
3. 更新 old.recovery_generation。
|
||||
4. 更新 heartbeat。
|
||||
```
|
||||
|
||||
`utsm_switch_in`:
|
||||
|
||||
```text
|
||||
1. 如果 next.state == RECOVERING,跳过。
|
||||
2. PCKC.current_process_uuid = next.crypto.process_uuid。
|
||||
3. PCKC.current_crypto_epoch = next.crypto.crypto_epoch。
|
||||
4. 预热 next.hot_segment_hint。
|
||||
```
|
||||
|
||||
调度路径禁止:
|
||||
|
||||
```text
|
||||
扫描段
|
||||
扫描 capability table
|
||||
计算 MAC
|
||||
写 checkpoint
|
||||
重加密整段
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 11. 任务异常处理算法
|
||||
|
||||
```text
|
||||
UTRW_DETECT_FAULT(task, segment, error)
|
||||
1. task.fault_segment_slot = segment.slot。
|
||||
2. task.state = FAULTED。
|
||||
3. 从 runqueue 移除。
|
||||
4. 写 DRR fault event。
|
||||
5. DRR 判断:
|
||||
a. 刷新 capability。
|
||||
b. page rollback。
|
||||
c. segment rollback。
|
||||
d. kill task。
|
||||
e. system rollback。
|
||||
```
|
||||
|
||||
任务 kill:
|
||||
|
||||
```text
|
||||
task_kill(task)
|
||||
1. task.state = ZOMBIE。
|
||||
2. 从 runqueue 移除。
|
||||
3. revoke capability table。
|
||||
4. owned segment key_epoch++。
|
||||
5. desc.state = DESTROYED。
|
||||
6. 加入 deferred free。
|
||||
7. 写 TASK_KILL recovery log。
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 12. 复杂度总结
|
||||
|
||||
```text
|
||||
段定位:O(1)
|
||||
UTRW 读写:O(n / 64)
|
||||
PCKC 命中:O(1)
|
||||
PCKC miss:O(KDF + key schedule)
|
||||
Dirty 标记:O(1)
|
||||
Checkpoint:O(number_of_dirty_shards + number_of_dirty_pages)
|
||||
A/B metadata 切换:O(1)
|
||||
DRR emergency alloc:O(1)
|
||||
Page rollback:O(1 page)
|
||||
Segment rollback:O(segment_dirty_pages + metadata)
|
||||
调度切换额外成本:O(1)
|
||||
```
|
||||
Reference in New Issue
Block a user