From b051b784d302cbf334803c3b1b71cc2dd55ce8a3 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 10 Nov 2026 09:11:12 -0800 Subject: [PATCH 1/3] nvme: Fix lock context annotations for nvme_passthru_{start,end}() Remove the __cond_acquires() and __cond_releases() annotations from the nvme_passthru_start() and nvme_passthru_end() declarations in nvme.h. Annotate nvme_passthru_start() and nvme_passthru_end() in core.c with __context_unsafe(/* conditional locking */). Note that nvme_passthru_start() acquires ctrl->scan_lock and ctrl->subsys->lock only when (effects & NVME_CMD_EFFECTS_CSE_MASK) is non-zero. Consider that commands frequently return non-zero effects (such as NVME_CMD_EFFECTS_CSUPP) without setting NVME_CMD_EFFECTS_CSE_MASK. Do not assume that every non-zero return value implies that locks were acquired, which is what __cond_acquires(nonzero, ...) incorrectly assumes. Observe also that nvme_passthru_end() conditionally releases locks based on the "effects" parameter rather than its return value. Acknowledge that Clang lock context analysis cannot model conditional locking based on bitmask flags. Suppress lock context imbalance warnings inside nvme_passthru_start() and nvme_passthru_end() by marking them with __context_unsafe(). Fixes: a6732bd8003a ("nvme: add context annotations for nvme_passthru_{start|stop}") Signed-off-by: Bart Van Assche --- drivers/nvme/host/core.c | 2 ++ drivers/nvme/host/nvme.h | 10 ++-------- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index f4aa02869b79..def9ac6e8b6a 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -1259,6 +1259,7 @@ u32 nvme_command_effects(struct nvme_ctrl *ctrl, struct nvme_ns *ns, u8 opcode) EXPORT_SYMBOL_NS_GPL(nvme_command_effects, "NVME_TARGET_PASSTHRU"); u32 nvme_passthru_start(struct nvme_ctrl *ctrl, struct nvme_ns *ns, u8 opcode) + __context_unsafe(/* conditional locking */) { u32 effects = nvme_command_effects(ctrl, ns, opcode); @@ -1280,6 +1281,7 @@ EXPORT_SYMBOL_NS_GPL(nvme_passthru_start, "NVME_TARGET_PASSTHRU"); u32 nvme_passthru_end(struct nvme_ctrl *ctrl, struct nvme_ns *ns, u32 effects, struct nvme_command *cmd, int status) + __context_unsafe(/* conditional locking */) { if (effects & NVME_CMD_EFFECTS_CSE_MASK) { nvme_unfreeze(ctrl); diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h index 8833a463f1c8..9c3a65657afb 100644 --- a/drivers/nvme/host/nvme.h +++ b/drivers/nvme/host/nvme.h @@ -1334,16 +1334,10 @@ static inline void nvme_auth_revoke_tls_key(struct nvme_ctrl *ctrl) {}; u32 nvme_command_effects(struct nvme_ctrl *ctrl, struct nvme_ns *ns, u8 opcode); -u32 nvme_passthru_start(struct nvme_ctrl *ctrl, struct nvme_ns *ns, u8 opcode) - __cond_acquires(nonzero, &ctrl->subsys->lock) - __cond_acquires(nonzero, &ctrl->scan_lock); - +u32 nvme_passthru_start(struct nvme_ctrl *ctrl, struct nvme_ns *ns, u8 opcode); int nvme_execute_rq(struct request *rq, bool at_head); u32 nvme_passthru_end(struct nvme_ctrl *ctrl, struct nvme_ns *ns, u32 effects, - struct nvme_command *cmd, int status) - __cond_releases(nonzero, &ctrl->scan_lock) - __cond_releases(nonzero, &ctrl->subsys->lock); - + struct nvme_command *cmd, int status); struct nvme_ctrl *nvme_ctrl_from_file(struct file *file); struct nvme_ns *nvme_find_get_ns(struct nvme_ctrl *ctrl, unsigned nsid); bool nvme_get_ns(struct nvme_ns *ns);