arm smmu v3 队列实现机制
ARM SMMU v3 队列实现详解
1. 队列结构设计
1.1 核心数据结构
struct arm_smmu_ll_queue {union {u64 val;struct {u32 prod;u32 cons;};struct {atomic_t prod;atomic_t cons;} atomic;u8 __pad[SMP_CACHE_BYTES];} ____cacheline_aligned_in_smp;u32 max_n_shift;
};
1.2 队列宏定义
#define Q_IDX(llq, p) ((p) & ((1 << (llq)->max_n_shift) - 1)) // 队列索引计算
#define Q_WRP(llq, p) ((p) & (1 << (llq)->max_n_shift)) // 队列环绕
#define Q_OVERFLOW_FLAG (1U << 31)
#define Q_OVF(p) ((p) & Q_OVERFLOW_FLAG) // 溢出检测
#define Q_ENT(q, p) ((q)->base + \Q_IDX(&((q)->llq), p) * \(q)->ent_dwords) // 队列中某条目的地址 基地址 + 索引 × 条目大小
2. 队列类型分析
2.1 是环形队列吗?
是的,这是环形队列:
- 使用
prod
(生产者指针) 和cons
(消费者指针) - 通过
Q_IDX
宏实现环形索引:(p) & ((1 << max_n_shift) - 1)
- 队列大小是2的幂次方,便于位运算优化
2.2 支持多生产者多消费者吗?
部分支持:
多生产者:
- 使用
atomic_t
类型的prod
和cons
- 通过原子操作保证并发安全
- 支持多个CPU核心同时写入
多消费者:
- 命令队列(CMDQ):单消费者(硬件消费)
- 事件队列(EVTQ):单消费者(软件消费)
- 优先级队列(PRIQ):单消费者(软件消费)
2.3 是无锁队列吗?
不是完全无锁:
无锁部分:
- 使用原子操作进行指针更新
- 生产者使用
atomic_t
保证并发安全
有锁部分:
struct arm_smmu_cmdq {struct arm_smmu_queue q;atomic_long_t *valid_map;atomic_t owner_prod;atomic_t lock;
};
3. 队列操作机制
3.1 空间检查
static bool queue_has_space(struct arm_smmu_ll_queue *q, u32 n)
{u32 space, prod, cons;prod = Q_IDX(q, q->prod);cons = Q_IDX(q, q->cons);if (Q_WRP(q, q->prod) == Q_WRP(q, q->cons))space = (1 << q->max_n_shift) - (prod - cons);elsespace = cons - prod;return space >= n;
}
3.2 状态判断
static bool queue_full(struct arm_smmu_ll_queue *q)
{return Q_IDX(q, q->prod) == Q_IDX(q, q->cons) &&Q_WRP(q, q->prod) != Q_WRP(q, q->cons);
}static bool queue_empty(struct arm_smmu_ll_queue *q)
{return Q_IDX(q, q->prod) == Q_IDX(q, q->cons) &&Q_WRP(q, q->prod) == Q_WRP(q, q->cons);
}
4. 特殊设计特点
4.1 Wrap位机制
- 使用
Q_WRP
宏检测队列是否已环绕一圈 - 通过比较wrap位判断队列状态
- 避免队列满/空的歧义
4.2 溢出检测
- 使用
Q_OVERFLOW_FLAG
(第31位) 检测溢出 - 防止32位计数器溢出问题
4.3 缓存行对齐
u8 __pad[SMP_CACHE_BYTES];} ____cacheline_aligned_in_smp;
- 确保队列结构体按缓存行对齐
- 减少伪共享(false sharing)问题
5. 三种队列类型
5.1 命令队列(CMDQ)
- 用途:CPU向SMMU发送命令
- 特点:多生产者,单消费者(硬件)
- 同步:需要等待硬件处理完成
5.2 事件队列(EVTQ)
- 用途:SMMU向CPU报告事件
- 特点:单生产者(硬件),单消费者(软件)
- 处理:通过中断处理
5.3 优先级队列(PRIQ)
- 用途:处理页面请求
- 特点:单生产者(硬件),单消费者(软件)
- 可选:根据硬件特性决定是否启用
6. 总结
ARM SMMU v3的队列实现是一个高性能的环形队列,具有以下特点:
- 环形设计:使用位运算实现高效的环形索引
- 并发支持:支持多生产者,使用原子操作保证线程安全
- 硬件协同:与SMMU硬件紧密配合,支持硬件直接访问
- 性能优化:缓存行对齐,减少内存访问冲突
- 可靠性:包含溢出检测和wrap位机制,确保队列状态正确
这种设计既保证了高性能,又确保了在复杂硬件环境下的可靠性。