在 linux-5.4/drivers/nvme/host/pci.c 中,我创建了一个并希望使用以下行nvme_command
将此命令写入:nvmeq->sq_cmds[nvmeq->sq_tail]
memcpy(&nvmeq->sq_cmds[nvmeq->sq_tail], &cmd, sizeof(cmd));
但是当printk
我nvmeq->sq_cmds[nvmeq->sq_tail]
. (3次有正确数据,但大部分时间没有数据)
首先,因为我绕过了块层,所以我创建了PER_CPU
变量并得到了nvme_queue
执行的时间nvme_alloc_queue()
。我曾经怀疑原因是
nvme_queue
没有成功获取到,但是我可以printk
每个队列的nvmeq->qid
和nvmeq->q_depth
。所以我排除了这个原因。
以下是我的代码:
DEFINE_PER_CPU(struct nvme_queue *, nvme_irq_queues);
......
static int nvme_alloc_queue(struct nvme_dev *dev, int qid, int depth) {
......
if (qid > 0) {
struct nvme_queue **per_cpu_queue = &per_cpu(nvme_irq_queues, qid - 1);
*per_cpu_queue = nvmeq;
printk(KERN_ERR "[EBIO %s] NVMe interrupt queue: %p cpu: %d qid: %d depth: %d\n", __func__, nvmeq, qid - 1, qid, depth);
}
......
}
int nvme_fine_granu_read(struct ebio *ebio) {
struct nvme_queue *nvmeq = get_cpu_var(nvme_irq_queues);
struct nvme_command cmd;
union CSD_cmd_u csd_cmd;
struct nvme_ns *ns = list_entry(nvmeq->dev->ctrl.namespaces.next, struct nvme_ns, list);
memset(&cmd, 0, sizeof(cmd));
csd_cmd.recordRead.header.opCode = E_CSD_CMD_OPCODE_RECORD_READ;
csd_cmd.recordRead.strLbn = nvme_block_nr(ns, ebio->block);
csd_cmd.recordRead.recordInfoAdrOfs = 0;
cmd.common.opcode = 0xd0;
cmd.common.command_id = ebio_tag(ebio) | NVME_FINE_GRANU;
cmd.common.nsid = cpu_to_le32(ns->head->ns_id);
cmd.common.cdw12 = cpu_to_le32(csd_cmd.data[0]);
cmd.common.cdw13 = cpu_to_le32(csd_cmd.data[1]);
cmd.common.cdw14 = cpu_to_le32(csd_cmd.data[2]);
cmd.common.cdw15 = cpu_to_le32(csd_cmd.data[3]);
spin_lock_irq(&nvmeq->sq_lock);
memcpy(&nvmeq->sq_cmds[nvmeq->sq_tail], &cmd, sizeof(cmd));
if (++nvmeq->sq_tail == nvmeq->q_depth)
nvmeq->sq_tail = 0;
if (nvme_dbbuf_update_and_check_event(nvmeq->sq_tail, nvmeq->dbbuf_sq_db, nvmeq->dbbuf_sq_ei))
writel(nvmeq->sq_tail, nvmeq->q_db);
nvmeq->last_sq_tail = nvmeq->sq_tail;
spin_unlock_irq(&nvmeq->sq_lock);
put_cpu_var(nvme_irq_queues);
return 0;
}
printk
的每个成员我都可以cmd
,所以写的nvme_command
是正确的,但是memcpy
操作memcpy(&nvmeq->sq_cmds[nvmeq->sq_tail], &cmd, sizeof(cmd));
失败了。