[PATCH v6 1/4] scsi: target: Do not re-enable interrupts in compare_and_write_post()

From: Laurence Oberman

Date: Tue Oct 27 2026 - 08:34:35 EST


target_complete_cmd() may be called by a backend driver from interrupt
context, as the comment above target_complete_cmd_with_sense() says. For a
command that has been aborted it calls target_cmd_interrupted(), which
invokes cmd->transport_complete_callback(). Once the WRITE phase of a
COMPARE AND WRITE has been set up that callback is
compare_and_write_post(), which takes t_state_lock with spin_lock_irq()
and drops it with spin_unlock_irq(), unconditionally enabling interrupts
in a caller that had them disabled.

Use spin_lock_irqsave() / spin_unlock_irqrestore() instead.

compare_and_write_callback() has the same pattern, but its
spin_lock_irq() is on the path taken after a successful compare, which is
reached only from target_complete_ok_work() in process context; the
success == false path returns long before it. It is left alone.

Signed-off-by: Laurence Oberman <loberman@xxxxxxxxxx>
---

Notes:
Pre-existing, and not needed by the rest of the series, but
compare_and_write_post() is modified by patch 2 and the mismatch between
its spin_lock_irq() and the spin_lock_irqsave() a few lines below would be
confusing to leave in place.

No Fixes: tag -- the pattern predates target_cmd_interrupted().

drivers/target/target_core_sbc.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c
index 21f5cb8..8c52e1e 100644
--- a/drivers/target/target_core_sbc.c
+++ b/drivers/target/target_core_sbc.c
@@ -352,15 +352,16 @@ static sense_reason_t compare_and_write_post(struct se_cmd *cmd, bool success,
{
struct se_device *dev = cmd->se_dev;
sense_reason_t ret = TCM_NO_SENSE;
+ unsigned long flags;

- spin_lock_irq(&cmd->t_state_lock);
+ spin_lock_irqsave(&cmd->t_state_lock, flags);
if (success) {
*post_ret = 1;

if (cmd->scsi_status == SAM_STAT_CHECK_CONDITION)
ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
}
- spin_unlock_irq(&cmd->t_state_lock);
+ spin_unlock_irqrestore(&cmd->t_state_lock, flags);

/*
* Unlock ->caw_sem originally obtained during sbc_compare_and_write()
--
2.43.0