mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-30 14:33:24 -04:00
scsi: qla2xxx: Initialize NVMe abort_work once at submission
qla_nvme_fcp_abort() and qla_nvme_ls_abort() ran INIT_WORK() on
priv->abort_work immediately before schedule_work(). INIT_WORK()
reinitializes the work_struct, resetting its list head and clearing the
pending bit. If an abort is issued more than once for the same command
(for example, concurrent transport teardown and a timeout-driven abort),
the second INIT_WORK() reinitializes a work item that is already queued,
which can corrupt the workqueue list and lead to crashes or a looping
worker.
Initialize priv->abort_work once at command submission, next to the
existing per-command spin_lock_init(&priv->cmd_lock), and leave only
schedule_work() in the abort paths. schedule_work() already does nothing
when the work item is still pending, so a repeated abort no longer
disturbs an in-flight work item. The command is not returned to the
transport until the final kref_put()/release callback runs after
abort_work has completed, so the work item is idle before priv is reused
and the single submission-time INIT_WORK() is safe.
Fixes: e473b30741 ("scsi: qla2xxx: Add FC-NVMe abort processing")
Cc: stable@vger.kernel.org
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Reviewed-by: Hannes Reinecke <hare@kernel.org>
Link: https://patch.msgid.link/20260723050413.3897522-52-njavali@marvell.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
This commit is contained in:
committed by
Martin K. Petersen (Oracle)
parent
793cedee29
commit
7e85f6dbc8
@@ -463,7 +463,6 @@ static void qla_nvme_ls_abort(struct nvme_fc_local_port *lport,
|
||||
}
|
||||
spin_unlock_irqrestore(&priv->cmd_lock, flags);
|
||||
|
||||
INIT_WORK(&priv->abort_work, qla_nvme_abort_work);
|
||||
schedule_work(&priv->abort_work);
|
||||
}
|
||||
|
||||
@@ -501,6 +500,7 @@ static int qla_nvme_ls_req(struct nvme_fc_local_port *lport,
|
||||
priv->sp = sp;
|
||||
kref_init(&sp->cmd_kref);
|
||||
spin_lock_init(&priv->cmd_lock);
|
||||
INIT_WORK(&priv->abort_work, qla_nvme_abort_work);
|
||||
nvme = &sp->u.iocb_cmd;
|
||||
priv->fd = fd;
|
||||
nvme->u.nvme.desc = fd;
|
||||
@@ -545,7 +545,6 @@ static void qla_nvme_fcp_abort(struct nvme_fc_local_port *lport,
|
||||
}
|
||||
spin_unlock_irqrestore(&priv->cmd_lock, flags);
|
||||
|
||||
INIT_WORK(&priv->abort_work, qla_nvme_abort_work);
|
||||
schedule_work(&priv->abort_work);
|
||||
}
|
||||
|
||||
@@ -877,6 +876,7 @@ static int qla_nvme_post_cmd(struct nvme_fc_local_port *lport,
|
||||
|
||||
kref_init(&sp->cmd_kref);
|
||||
spin_lock_init(&priv->cmd_lock);
|
||||
INIT_WORK(&priv->abort_work, qla_nvme_abort_work);
|
||||
sp->priv = priv;
|
||||
priv->sp = sp;
|
||||
sp->type = SRB_NVME_CMD;
|
||||
|
||||
Reference in New Issue
Block a user