All of lore.kernel.org
 help / color / mirror / Atom feed
From: Nilay Shroff <nilay@linux.ibm.com>
To: linux-nvme@lists.infradead.org, linux-kernel@vger.kernel.org
Cc: hch@lst.de, kbusch@kernel.org, sagi@grimberg.me, axboe@fb.com,
	bvanassche@acm.org, elver@google.com, gjoyce@linux.ibm.com,
	Nilay Shroff <nilay@linux.ibm.com>
Subject: [PATCH 12/15] nvme: add Clang context annotations for nvme_queue::cq_poll_lock
Date: Wed, 10 Jun 2026 19:57:32 +0530	[thread overview]
Message-ID: <20260610142743.115898-13-nilay@linux.ibm.com> (raw)
In-Reply-To: <20260610142743.115898-1-nilay@linux.ibm.com>

nvme_queue::cqes, nvme_queue::cq_head, and nvme_queue::cq_phase are
protected by nvme_queue::cq_poll_lock. Annotate these fields with
__guarded_by(&cq_poll_lock) and annotate helpers accessing them with
__must_hold(&cq_poll_lock) so that Clang's context analysis can
validate the locking requirements.

IRQ-based queues do not use cq_poll_lock and instead rely on interrupt
serialization. Annotate nvme_irq() and nvme_irq_check() with
__context_unsafe() to suppress the corresponding context analysis
warnings.

After annotating the completion queue state and helper functions,
Clang's context analysis reports that nvme_poll() invokes
nvme_cqe_pending() without holding nvme_queue::cq_poll_lock:

drivers/nvme/host/pci.c:1683:7: warning: calling function 'nvme_cqe_pending' requires holding spinlock 'hctx->driver_data->cq_poll_lock'
      exclusively [-Wthread-safety-analysis]
 1683 |             !nvme_cqe_pending(nvmeq))

Fix the warning by acquiring nvme_queue::cq_poll_lock before invoking
nvme_cqe_pending() in nvme_poll().

Signed-off-by: Nilay Shroff <nilay@linux.ibm.com>
---
 drivers/nvme/host/pci.c | 21 ++++++++++++++++-----
 1 file changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index c464570cffd0..343860584b31 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -369,17 +369,17 @@ struct nvme_queue {
 	void *sq_cmds;
 	 /* only used for poll queues: */
 	spinlock_t cq_poll_lock ____cacheline_aligned_in_smp;
-	struct nvme_completion *cqes;
+	struct nvme_completion *cqes __guarded_by(&cq_poll_lock);
 	dma_addr_t sq_dma_addr;
 	dma_addr_t cq_dma_addr;
 	u32 __iomem *q_db;
 	u32 q_depth;
 	u16 cq_vector;
-	u16 cq_head;
+	u16 cq_head __guarded_by(&cq_poll_lock);
 	u16 sq_tail __guarded_by(&sq_lock);
 	u16 last_sq_tail __guarded_by(&sq_lock);
 	u16 qid;
-	u8 cq_phase;
+	u8 cq_phase __guarded_by(&cq_poll_lock);
 	u8 sqes;
 	unsigned long flags;
 #define NVMEQ_ENABLED		0
@@ -1534,6 +1534,7 @@ static void nvme_pci_complete_batch(struct io_comp_batch *iob)
 
 /* We read the CQE phase first to check if the rest of the entry is valid */
 static inline bool nvme_cqe_pending(struct nvme_queue *nvmeq)
+	__must_hold(nvmeq->cq_poll_lock)
 {
 	struct nvme_completion *hcqe = &nvmeq->cqes[nvmeq->cq_head];
 
@@ -1541,6 +1542,7 @@ static inline bool nvme_cqe_pending(struct nvme_queue *nvmeq)
 }
 
 static inline void nvme_ring_cq_doorbell(struct nvme_queue *nvmeq)
+	__must_hold(nvmeq->cq_poll_lock)
 {
 	u16 head = nvmeq->cq_head;
 
@@ -1558,6 +1560,7 @@ static inline struct blk_mq_tags *nvme_queue_tagset(struct nvme_queue *nvmeq)
 
 static inline void nvme_handle_cqe(struct nvme_queue *nvmeq,
 				   struct io_comp_batch *iob, u16 idx)
+	__must_hold(nvmeq->cq_poll_lock)
 {
 	struct nvme_completion *cqe = &nvmeq->cqes[idx];
 	__u16 command_id = READ_ONCE(cqe->command_id);
@@ -1595,6 +1598,7 @@ static inline void nvme_handle_cqe(struct nvme_queue *nvmeq,
 }
 
 static inline void nvme_update_cq_head(struct nvme_queue *nvmeq)
+	__must_hold(nvmeq->cq_poll_lock)
 {
 	u32 tmp = nvmeq->cq_head + 1;
 
@@ -1608,6 +1612,7 @@ static inline void nvme_update_cq_head(struct nvme_queue *nvmeq)
 
 static inline bool nvme_poll_cq(struct nvme_queue *nvmeq,
 			        struct io_comp_batch *iob)
+	__must_hold(nvmeq->cq_poll_lock)
 {
 	bool found = false;
 
@@ -1628,6 +1633,7 @@ static inline bool nvme_poll_cq(struct nvme_queue *nvmeq,
 }
 
 static irqreturn_t nvme_irq(int irq, void *data)
+	__context_unsafe(/* IRQ queues do not use cq_poll_lock  */)
 {
 	struct nvme_queue *nvmeq = data;
 	DEFINE_IO_COMP_BATCH(iob);
@@ -1641,6 +1647,7 @@ static irqreturn_t nvme_irq(int irq, void *data)
 }
 
 static irqreturn_t nvme_irq_check(int irq, void *data)
+	__context_unsafe(/* IRQ queues do not use cq_poll_lock */)
 {
 	struct nvme_queue *nvmeq = data;
 
@@ -1673,11 +1680,14 @@ static int nvme_poll(struct blk_mq_hw_ctx *hctx, struct io_comp_batch *iob)
 	struct nvme_queue *nvmeq = hctx->driver_data;
 	bool found;
 
-	if (!test_bit(NVMEQ_POLLED, &nvmeq->flags) ||
-	    !nvme_cqe_pending(nvmeq))
+	if (!test_bit(NVMEQ_POLLED, &nvmeq->flags))
 		return 0;
 
 	spin_lock(&nvmeq->cq_poll_lock);
+	if (!nvme_cqe_pending(nvmeq)) {
+		spin_unlock(&nvmeq->cq_poll_lock);
+		return 0;
+	}
 	found = nvme_poll_cq(nvmeq, iob);
 	spin_unlock(&nvmeq->cq_poll_lock);
 
@@ -2133,6 +2143,7 @@ static int nvme_alloc_sq_cmds(struct nvme_dev *dev, struct nvme_queue *nvmeq,
 }
 
 static int nvme_alloc_queue(struct nvme_dev *dev, int qid, int depth)
+	__context_unsafe(/* safe to allocate queue without any protection */)
 {
 	struct nvme_queue *nvmeq = &dev->queues[qid];
 
-- 
2.53.0



  parent reply	other threads:[~2026-06-10 14:28 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-10 14:27 [PATCH 00/15] Support Clang context analysis for NVMe host drivers Nilay Shroff
2026-06-10 14:27 ` [PATCH 01/15] nvme: update nvme_passthru_end() signature Nilay Shroff
2026-06-10 14:27 ` [PATCH 02/15] nvme: add Clang context annotations for nvme_passthru_{start|stop} Nilay Shroff
2026-06-10 14:27 ` [PATCH 03/15] nvme: add Clang context annotations for nvme_ns_head::srcu Nilay Shroff
2026-06-10 14:27 ` [PATCH 04/15] nvme: add Clang context annotations for nvme_ns_head::requeue_list Nilay Shroff
2026-06-10 16:25   ` Bart Van Assche
2026-06-11  4:18     ` Nilay Shroff
2026-06-10 14:27 ` [PATCH 05/15] nvme: add Clang context annotations for nvme_ns_head::current_path Nilay Shroff
2026-06-10 14:27 ` [PATCH 06/15] nvme: add Clang context annotations for nvme_dev::shutdown_lock Nilay Shroff
2026-06-10 14:27 ` [PATCH 07/15] nvme: add Clang context annotations for nvme_subsystem::lock Nilay Shroff
2026-06-10 16:28   ` Bart Van Assche
2026-06-11  4:34     ` Nilay Shroff
2026-06-10 14:27 ` [PATCH 08/15] nvme: add Clang context annotations for nvme_ctrl::ana_lock Nilay Shroff
2026-06-10 14:27 ` [PATCH 09/15] nvme: add Clang context annotations for nvme_subsystems_lock Nilay Shroff
2026-06-10 16:30   ` Bart Van Assche
2026-06-11  4:39     ` Nilay Shroff
2026-06-10 14:27 ` [PATCH 10/15] nvme: add Clang context annotations in fabric.c Nilay Shroff
2026-06-10 14:27 ` [PATCH 11/15] nvme: add Clang context annotations for nvme_queue::sq_lock Nilay Shroff
2026-06-10 16:33   ` Bart Van Assche
2026-06-11  4:52     ` Nilay Shroff
2026-06-10 14:27 ` Nilay Shroff [this message]
2026-06-10 16:35   ` [PATCH 12/15] nvme: add Clang context annotations for nvme_queue::cq_poll_lock Bart Van Assche
2026-06-11  4:52     ` Nilay Shroff
2026-06-10 16:46   ` Keith Busch
2026-06-11  4:54     ` Nilay Shroff
2026-06-10 14:27 ` [PATCH 13/15] nvme: add Clang context annotations in rdma.c Nilay Shroff
2026-06-10 14:27 ` [PATCH 14/15] nvme: add Clang context annotations in tcp.c Nilay Shroff
2026-06-10 14:27 ` [PATCH 15/15] nvme: enable Clang context analysis support for nvme host driver Nilay Shroff

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260610142743.115898-13-nilay@linux.ibm.com \
    --to=nilay@linux.ibm.com \
    --cc=axboe@fb.com \
    --cc=bvanassche@acm.org \
    --cc=elver@google.com \
    --cc=gjoyce@linux.ibm.com \
    --cc=hch@lst.de \
    --cc=kbusch@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-nvme@lists.infradead.org \
    --cc=sagi@grimberg.me \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.