Skip to content

Commit 3821080

Browse files
keithbuschChristoph Hellwig
authored andcommitted
Revert "nvme-pci: remove last_sq_tail"
Multiple CPUs may be mapped to the same hctx, allowing mulitple submission contexts to attempt commit_rqs(). We need to verify we're not writing the same doorbell value multiple times since that's a spec violation. Revert commit 54b2fce. Link: https://bugzilla.redhat.com/show_bug.cgi?id=1878596 Reported-by: "B.L. Jones" <brandon.gustav@googlemail.com> Signed-off-by: Keith Busch <kbusch@kernel.org>
1 parent 65ff5cd commit 3821080

1 file changed

Lines changed: 19 additions & 4 deletions

File tree

drivers/nvme/host/pci.c

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ struct nvme_queue {
198198
u32 q_depth;
199199
u16 cq_vector;
200200
u16 sq_tail;
201+
u16 last_sq_tail;
201202
u16 cq_head;
202203
u16 qid;
203204
u8 cq_phase;
@@ -455,11 +456,24 @@ static int nvme_pci_map_queues(struct blk_mq_tag_set *set)
455456
return 0;
456457
}
457458

458-
static inline void nvme_write_sq_db(struct nvme_queue *nvmeq)
459+
/*
460+
* Write sq tail if we are asked to, or if the next command would wrap.
461+
*/
462+
static inline void nvme_write_sq_db(struct nvme_queue *nvmeq, bool write_sq)
459463
{
464+
if (!write_sq) {
465+
u16 next_tail = nvmeq->sq_tail + 1;
466+
467+
if (next_tail == nvmeq->q_depth)
468+
next_tail = 0;
469+
if (next_tail != nvmeq->last_sq_tail)
470+
return;
471+
}
472+
460473
if (nvme_dbbuf_update_and_check_event(nvmeq->sq_tail,
461474
nvmeq->dbbuf_sq_db, nvmeq->dbbuf_sq_ei))
462475
writel(nvmeq->sq_tail, nvmeq->q_db);
476+
nvmeq->last_sq_tail = nvmeq->sq_tail;
463477
}
464478

465479
/**
@@ -476,8 +490,7 @@ static void nvme_submit_cmd(struct nvme_queue *nvmeq, struct nvme_command *cmd,
476490
cmd, sizeof(*cmd));
477491
if (++nvmeq->sq_tail == nvmeq->q_depth)
478492
nvmeq->sq_tail = 0;
479-
if (write_sq)
480-
nvme_write_sq_db(nvmeq);
493+
nvme_write_sq_db(nvmeq, write_sq);
481494
spin_unlock(&nvmeq->sq_lock);
482495
}
483496

@@ -486,7 +499,8 @@ static void nvme_commit_rqs(struct blk_mq_hw_ctx *hctx)
486499
struct nvme_queue *nvmeq = hctx->driver_data;
487500

488501
spin_lock(&nvmeq->sq_lock);
489-
nvme_write_sq_db(nvmeq);
502+
if (nvmeq->sq_tail != nvmeq->last_sq_tail)
503+
nvme_write_sq_db(nvmeq, true);
490504
spin_unlock(&nvmeq->sq_lock);
491505
}
492506

@@ -1496,6 +1510,7 @@ static void nvme_init_queue(struct nvme_queue *nvmeq, u16 qid)
14961510
struct nvme_dev *dev = nvmeq->dev;
14971511

14981512
nvmeq->sq_tail = 0;
1513+
nvmeq->last_sq_tail = 0;
14991514
nvmeq->cq_head = 0;
15001515
nvmeq->cq_phase = 1;
15011516
nvmeq->q_db = &dev->dbs[qid * 2 * dev->db_stride];

0 commit comments

Comments
 (0)