Storport 驱动 Win10 到 Win11 架构迁移:多线程到单线程多任务
日期: 2026-03-08
项目: Bayhub SD Host Controller Storport 驱动
背景: Windows Storport DDI 限制导致架构重构
目录
1. 背景:DDI 限制与架构挑战
1.1 Storport HwStorPortProhibitedDDI 规则
根据 Microsoft 官方文档,Storport 微型端口驱动禁止调用大量 WDM DDI 函数:
1 | 禁止的 DDI 类型: |
1.2 多线程架构的问题
原 Win10 架构使用 #ifdef MultiThread 启用的多线程模式存在以下问题:
| 问题 | 说明 |
|---|---|
| 线程同步复杂 | 需要 KeWaitForSingleObject、KeInitializeMutex 等被禁止的 DDI |
| 资源竞争 | 多线程访问共享资源需要大量锁机制 |
| Storport 不原生支持 | Storport 设计为单线程回调模型 |
| 调试困难 | 线程间 race condition 难以复现 |
1.3 迁移目标
1 | Win10: 多线程架构 (MultiThread) |
2. 架构对比
2.1 Win10 多线程架构
1 | ┌─────────────────────────────────────────────────────────────────┐ |
2.2 Win11 单线程多任务架构
1 | ┌─────────────────────────────────────────────────────────────────┐ |
2.3 关键差异
| 维度 | Win10 多线程 | Win11 单线程多任务 |
|---|---|---|
| 线程数 | 多线程 (MultiThread) | 单线程 |
| 任务调度 | Task Manager + 多事件 | switch-case 直连 |
| 同步原语 | KeWait*, ExAcquire* | StorPortWaitForSingleObject |
| 内存分配 | ExAllocatePool | StorPort* API |
| DDI 限制 | 违反 Storport DDI | 符合 Storport DDI |
3. 核心改动解析
3.1 移除 MultiThread 编译选项
Win10 代码 (thread.c):
1 |
|
Win11 代码 (移除 #ifdef MultiThread):
1 | if (card->card_type == CARD_ERROR) |
3.2 简化事件设置 API
Win10 API 签名:
1 | // 包含 taskid 参数,用于 Task Manager |
Win11 API 签名:
1 | // 直接设置事件,无需 Task Manager |
3.3 主循环重构
Win10 主循环 (Task Manager 模式):
1 | void thread_main(void * param) |
Win11 主循环 (switch-case 模式):
1 | void thread_main(void * param) |
3.4 事件等待机制
Win11 改进的事件等待:
1 | e_event_t os_wait_event(void * pdx, os_struct * os) |
4. 实现细节
4.1 事件初始化
Win11 简化的事件管理器初始化:
1 | static void win_init_event_mgr(bht_dev_ext_t* pdx, evt_mgr_t *mgr) |
Win10 移除的 Task Manager 初始化 (Win11 不再需要):
1 | // Win10 代码 - Win11 已移除 |
4.2 事件索引映射
Win11 显式的事件索引映射:
1 | static win_evt_t * win_get_evt(evt_mgr_t *mgr, e_event_t event) |
4.3 线程挂起/恢复
Win11 线程控制:
1 | bool os_pending_thread(void * pdx, bool pending) |
5. 共享任务计数器机制
5.1 问题背景
卡插拔事件 (EVENT_CARD_CHG) 可能同时包含”插入”和”拔出”两种应用场景,需要确保两种情况都被处理。
5.2 shared_task_cnt 机制
数据结构:
1 | typedef struct{ |
设置任务时递增计数:
1 | static void win_set_task(task_mgr_t *mgr, e_task_t taskid, u8 status) |
处理任务时递减计数并重入:
1 | // 处理 task 依次顺序执行,有优先级 |
5.3 机制图解
1 | 场景:卡在一次中断中被拔出又插入 |
6. 调试与问题排查
6.1 关键调试日志
1 | // 事件设置 |
6.2 常见问题
| 问题 | 可能原因 | 解决方案 |
|---|---|---|
| 事件不触发 | StorPortIssueDpc 未正确调用 |
检查 win_get_evt 返回值 |
| 事件丢失 | 同一事件快速触发两次 | 启用 shared_task_cnt |
| 线程死锁 | 在事件处理中调用 StorPortWaitForSingleObject |
避免阻塞调用 |
| CPU 100% | os_wait_event 无 os_sleep |
添加适当延迟 |
6.3 验证清单
- 确认移除了所有
#ifdef MultiThread分支 - 确认所有
os_set_event调用使用新签名 - 确认
thread_main使用 switch-case 而非 task manager - 确认
shared_task_cnt正确处理共享事件 - 确认没有调用禁止的 DDI 函数
7. 参考资料
7.1 Microsoft 官方文档
7.2 Git Commit 信息
1 | commit 906a83c5bd7ae70f0cd2e9649c377d9931e335ab |
7.3 相关文件
| 文件 | 改动说明 |
|---|---|
SDSTORDriver/sdstor/main/thread.c |
主线程事件处理重构 |
SDSTORDriver/sdstor/windows_os/winapi.c |
事件 API 简化 |
SDSTORDriver/sdstor/windows_os/winapi.h |
task 结构体修改 |
文档生成日期: 2026-03-20
版本: 1.0