错误处理 - 🔁 Reservation Preemption 抢占行为(包括抢占并中止) (第428页)
NVME2.0协议解读 1 min read

错误处理 - 🔁 Reservation Preemption 抢占行为(包括抢占并中止) (第428页)

Blog Author

我们继续对 NVMe Express Base Specification 2.0b 第 8.19 节 Reservation 机制Preempt(抢占) 的操作行为进行中文深入解析。现在聚焦的是:


🔁 Reservation Preemption 抢占行为(包括抢占并中止)


📌 场景一:抢占 Reservation Holder

✅ 前提条件:

  • 抢占操作通过 Reservation Acquire 命令发起;
  • 设置 RACQA = 001b(抢占)或 010b(抢占并中止);
  • 提供的 CRKEY(当前注册 Key)必须是当前主机注册过的 Key;
  • PRKEY(欲抢占对象的 Reservation Key)用来定位目标 registrant 或 holder。

🧠 分支逻辑详解:

🌟 情况 1:当前 Reservation 类型 ≠ All Registrants(即不是 "所有注册者共享" 的类型)

即 Reservation 类型为: - Write Exclusive - Exclusive Access - Write Exclusive – Registrants Only - Exclusive Access – Registrants Only

🧷 PRKEY = 当前 Reservation 持有者的 Key

进行如下原子操作:

  1. 注销除当前主机外,所有使用该 PRKEY 的 registrant;
  2. 释放原 Reservation
  3. 为当前主机创建新的 Reservation,类型由 RTYPE 指定;
  4. 当前主机成为新的 Reservation 持有者。
🧷 PRKEY ≠ 当前 Reservation 持有者的 Key 且 ≠ 0h
  • 注销所有 注册了 PRKEY 值 的注册者;
  • Reservation 本身不变。
🧷 PRKEY = 0h
  • 非法,命令失败,返回 Invalid Field in Command

🌟 情况 2:Reservation 类型为 All Registrants(所有注册者共享)

即 Reservation 类型为: - Write Exclusive – All Registrants - Exclusive Access – All Registrants

🧷 PRKEY = 0h:

执行原子操作:

  1. 注销除当前主机外的所有注册者;
  2. 释放 Reservation
  3. 为当前主机重新建立 Reservation(类型由 RTYPE 指定);
  4. 当前主机成为 Reservation 持有者。
🧷 PRKEY ≠ 0h:
  • 注销所有匹配 PRKEY 值的注册者;
  • 若没有匹配的注册者 → 返回 Reservation Conflict

🌟 情况 3:Namespace 没有 Reservation 存在

  • 注销所有使用 PRKEY 注册的主机;
  • Reservation 不创建、不改变。

🌀 主机对自身 Reservation 进行“自抢占”(Self Preemption)

即当前主机是 Reservation 持有者,想换一种 Reservation 类型:

  • PRKEY = 本主机 Key
  • 会进行如下原子操作:

  • 保留当前注册状态;

  • 释放现有 Reservation
  • 建立新的 Reservation(类型为 RTYPE);
  • 当前主机为新的持有者。

🧨 Preempt and Abort(抢占并中止)RACQA = 010b

此操作 除了完成抢占流程外,还会强制中止相关命名空间中的其他命令

⚙️ 特殊行为:

  • 发生 Reservation 或 Registration 变化后,系统会通知所有受影响的控制器
  • 中止该命名空间上“正在处理中的命令”(参考 §3.4.4);
  • Reservation Acquire 命令本身将等到这些中止完成后才返回(不论是否真能中止)。

⚠️ 注:中止行为是 “尽力而为”(best effort),有些命令可能已经执行完或处于无法中止的阶段。


✅ 小结图(抢占行为决策树):

                ┌──────────────────────────┐
                 Host 发起 Preempt 操作   
                └────────────┬─────────────┘
                             
         ┌─────────────────────────────────────┐
          Reservation Type  All Registrants?
         └────────────┬─────────────┬──────────┘
                      │否           │是
                                   
        PRKEY == 当前 Reservation     PRKEY == 0h
             持有者的 Key            
         ┌──────┬─────────────┐       └─是→ 执行抢占并重建Reservation
         │否    │是                   
                                   │否
     Unregister  PRKEY匹配            
     注册者        重建           PRKEY 匹配谁?
                 Reservation         ├─ 匹配  Unregister
                                      └─ 不匹配  Reservation Conflict

如果你希望我继续绘制 Reservation 状态转换图(State Diagram) 或讲解实际命令结构(Register, Acquire 等的 Command Dword Layout),我可以接着补充。需要我继续吗?