@@ -2814,58 +2814,72 @@ void fnic_exch_mgr_reset(struct fc_lport *lp, u32 sid, u32 did)
}
-/*
- * fnic_is_abts_pending() is a helper function that
- * walks through tag map to check if there is any IOs pending,if there is one,
- * then it returns 1 (true), otherwise 0 (false)
- * if @lr_sc is non NULL, then it checks IOs specific to particular LUN,
- * otherwise, it checks for all IOs.
- */
-int fnic_is_abts_pending(struct fnic *fnic, struct scsi_cmnd *lr_sc)
+struct fnic_is_abts_pending_data {
+ struct scsi_cmnd *lr_sc;
+ int ret;
+};
+
+static bool __fnic_is_abts_pending(struct request *req, void *data,
+ bool reserved)
{
- int tag;
+ struct fnic_is_abts_pending_data *pdata = data;
struct fnic_io_req *io_req;
spinlock_t *io_lock;
unsigned long flags;
- int ret = 0;
- struct scsi_cmnd *sc;
struct scsi_device *lun_dev = NULL;
+ struct scsi_cmnd *sc = blk_mq_rq_to_pdu(req);
+ struct fc_lport *lp = shost_priv(sc->device->host);
+ struct fnic *fnic = lport_priv(lp);
- if (lr_sc)
- lun_dev = lr_sc->device;
+ if (pdata->lr_sc)
+ lun_dev = pdata->lr_sc->device;
- /* walk again to check, if IOs are still pending in fw */
- for (tag = 0; tag < fnic->fnic_max_tag_id; tag++) {
- sc = scsi_host_find_tag(fnic->lport->host, tag);
- /*
- * ignore this lun reset cmd or cmds that do not belong to
- * this lun
- */
- if (!sc || (lr_sc && (sc->device != lun_dev || sc == lr_sc)))
- continue;
+ /*
+ * ignore this lun reset cmd or cmds that do not belong to
+ * this lun
+ */
+ if (!sc || (pdata->lr_sc && (sc->device != lun_dev ||
+ sc == pdata->lr_sc)))
+ return true;
- io_lock = fnic_io_lock_hash(fnic, sc);
- spin_lock_irqsave(io_lock, flags);
+ io_lock = fnic_io_lock_hash(fnic, sc);
+ spin_lock_irqsave(io_lock, flags);
- io_req = (struct fnic_io_req *)CMD_SP(sc);
+ io_req = (struct fnic_io_req *)CMD_SP(sc);
- if (!io_req || sc->device != lun_dev) {
- spin_unlock_irqrestore(io_lock, flags);
- continue;
- }
+ if (!io_req || sc->device != lun_dev)
+ goto unlock;
- /*
- * Found IO that is still pending with firmware and
- * belongs to the LUN that we are resetting
- */
- FNIC_SCSI_DBG(KERN_INFO, fnic->lport->host,
- "Found IO in %s on lun\n",
- fnic_ioreq_state_to_str(CMD_STATE(sc)));
+ /*
+ * Found IO that is still pending with firmware and
+ * belongs to the LUN that we are resetting
+ */
+ FNIC_SCSI_DBG(KERN_INFO, fnic->lport->host,
+ "Found IO in %s on lun\n",
+ fnic_ioreq_state_to_str(CMD_STATE(sc)));
- if (CMD_STATE(sc) == FNIC_IOREQ_ABTS_PENDING)
- ret = 1;
- spin_unlock_irqrestore(io_lock, flags);
- }
+ if (CMD_STATE(sc) == FNIC_IOREQ_ABTS_PENDING)
+ pdata->ret = 1;
+ unlock:
+ spin_unlock_irqrestore(io_lock, flags);
+ return true;
+}
- return ret;
+/*
+ * fnic_is_abts_pending() is a helper function that
+ * walks through tag map to check if there is any IOs pending,if there is one,
+ * then it returns 1 (true), otherwise 0 (false)
+ * if @lr_sc is non NULL, then it checks IOs specific to particular LUN,
+ * otherwise, it checks for all IOs.
+ */
+int fnic_is_abts_pending(struct fnic *fnic, struct scsi_cmnd *lr_sc)
+{
+ struct fnic_is_abts_pending_data data = {
+ .lr_sc = lr_sc,
+ .ret = 0,
+ };
+
+ blk_mq_tagset_busy_iter(&fnic->lport->host->tag_set,
+ __fnic_is_abts_pending, &data);
+ return data.ret;
}
So far, scsi_host_find_tag() is supposed to use in fast path and the passed tag should be active. Convert the scsi command walking into blk_mq_tagset_busy_iter(), which has been one common pattern for handling failure. Cc: Satish Kharat <satishkh@cisco.com> Cc: Karan Tilak Kumar <kartilak@cisco.com> Cc: David Jeffery <djeffery@redhat.com> Signed-off-by: Ming Lei <ming.lei@redhat.com> --- drivers/scsi/fnic/fnic_scsi.c | 96 ++++++++++++++++++++--------------- 1 file changed, 55 insertions(+), 41 deletions(-)