linux kernel version: 5.15.x
关键结构体
nvme_dev
字段 | 说明 |
---|---|
unsigned int nr_write_queues | Number of queues to use for writes. If not set, reads and writes will share a queue set. 可以通过nvme.ko加载参数指定,默认为0 |
unsigned int nr_poll_queues | Number of queues to use for polled IO 可以通过nvme.ko加载参数指定,默认为0 |
unsigned int nr_allocated_queues | num_possible_cpus() + nr_write_queues + nr_poll_queues + 1 |
struct nvme_queue* queues | 保存nvme_dev中的所有的sq和cq的队列信息的数组,index为0保存的时admin QP的信息 数组中的元素为struct nvme_queue结构体 数组的个数为nr_allocated_queues |
unsigned online_queues | 有效的队列数 |
unsigned long bar_mapped_size | bar空间ioremap的大小 |
void __iomem* bar | bar空间地址,内容为映射的ctrl的寄存器数据 |
void __iomem* dbs | 队列的门铃寄存器的基地址,为bar空间地址+0x1000偏移地址 |
struct dma_pool* prp_page_pool | prp page页面管理结构体数组,元素为4K大小,地址要求4K对齐 |
struct dma_pool* prp_small_pool | prp small管理结构体数组,元素为256bytes大小,地址要求256bytes对齐 |
mempool_t* iod_mempool |
nvme_ctrl
nvme_queue
nvme_queue结构体对应一个QP(SQ + CQ)。
字段 | 说明 |
---|---|
u16 qid | 队列id,admin的队列id为0 |
u32 q_depth | 队列深度,admin队列为32,io队列的值等于nvme_dev->q_depth,通常情况下,SQ和CQ的深度时一样的 驱动会将该信息同步到ctrl的AQA寄存器 |
u32 __iomem* q_db | 队列对应doorbell的地址,按照顺序分别存放SQ Tail Doorbell和CQ Head Doorbell,均为4bytes大小 nvme_dev->dbs[qid 2 nvme_dev->db_stride] |
u8 sqes | 提交队列中命令(sqe)结构体的大小 admin的SQ队列为6,io的SQ队列的值等于nvme_dev->sqes(通常也是6),实际大小为2^6=64 bytes |
void* sq_cmds | sqe的数组,保存了q_depth个sqes大小的元素 采用dma_alloc_coherent函数申请资源 |
dma_addr_t sq_dma_addr | sq的dma地址,,驱动会将该地址信息同步给ctrl的ASQ寄存器 |
u16 sq_tail | sq队列的尾指针位置 |
u16 last_sq_tail | |
struct nvme_completion* cqes | cqe的数组,保存了q_depth个nvme_completion结构体 使用dma_alloc_coherent函数申请资源 |
dma_addr_t cq_dma_addr | cq的dma地址,驱动会将该地址信息同步给ctrl的ACQ寄存器 |
u16 cq_head | cq队列的头指针位置 |
u8 cq_phase | 通过该字段与cqe中的phase bit进行对比来判定当前cqe是否时有效的cqe |
u16 cq_vector | 队列对应的中断向量号 |