Skip to content

Commit

Permalink
Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/g…
Browse files Browse the repository at this point in the history
…it/jejb/scsi

Pull SCSI fixes from James Bottomley:
 "Five fixes, all in drivers.

  The big change is the UFS task management rework, with lpfc next and
  the rest being fairly minor and obvious fixes"

* tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi:
  scsi: iscsi: Fix iscsi_task use after free
  scsi: lpfc: Fix memory overwrite during FC-GS I/O abort handling
  scsi: elx: efct: Delete stray unlock statement
  scsi: ufs: core: Fix task management completion
  scsi: acornscsi: Remove scsi_cmd_to_tag() reference
  • Loading branch information
Linus Torvalds committed Oct 9, 2021
2 parents 50eb0a0 + 258aad7 commit 0950fcb
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 43 deletions.
2 changes: 1 addition & 1 deletion drivers/scsi/arm/acornscsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -1776,7 +1776,7 @@ int acornscsi_reconnect_finish(AS_Host *host)
host->scsi.disconnectable = 0;
if (host->SCpnt->device->id == host->scsi.reconnected.target &&
host->SCpnt->device->lun == host->scsi.reconnected.lun &&
scsi_cmd_to_tag(host->SCpnt) == host->scsi.reconnected.tag) {
scsi_cmd_to_rq(host->SCpnt)->tag == host->scsi.reconnected.tag) {
#if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON))
DBG(host->SCpnt, printk("scsi%d.%c: reconnected",
host->host->host_no, acornscsi_target(host)));
Expand Down
3 changes: 1 addition & 2 deletions drivers/scsi/elx/efct/efct_scsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ efct_scsi_io_alloc(struct efct_node *node)
struct efct *efct;
struct efct_xport *xport;
struct efct_io *io;
unsigned long flags = 0;
unsigned long flags;

efct = node->efct;

Expand All @@ -44,7 +44,6 @@ efct_scsi_io_alloc(struct efct_node *node)
if (!io) {
efc_log_err(efct, "IO alloc Failed\n");
atomic_add_return(1, &xport->io_alloc_failed_count);
spin_unlock_irqrestore(&node->active_ios_lock, flags);
return NULL;
}

Expand Down
15 changes: 9 additions & 6 deletions drivers/scsi/libiscsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -2281,20 +2281,23 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
return FAILED;
}

conn = session->leadconn;
iscsi_get_conn(conn->cls_conn);
conn->eh_abort_cnt++;
age = session->age;

spin_lock(&session->back_lock);
task = (struct iscsi_task *)sc->SCp.ptr;
if (!task || !task->sc) {
/* task completed before time out */
ISCSI_DBG_EH(session, "sc completed while abort in progress\n");

spin_unlock(&session->back_lock);
goto success;
spin_unlock_bh(&session->frwd_lock);
mutex_unlock(&session->eh_mutex);
return SUCCESS;
}

conn = session->leadconn;
iscsi_get_conn(conn->cls_conn);
conn->eh_abort_cnt++;
age = session->age;

ISCSI_DBG_EH(session, "aborting [sc %p itt 0x%x]\n", sc, task->itt);
__iscsi_get_task(task);
spin_unlock(&session->back_lock);
Expand Down
11 changes: 7 additions & 4 deletions drivers/scsi/lpfc/lpfc_sli.c
Original file line number Diff line number Diff line change
Expand Up @@ -12292,23 +12292,26 @@ void
lpfc_ignore_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
struct lpfc_iocbq *rspiocb)
{
struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
struct lpfc_nodelist *ndlp = NULL;
IOCB_t *irsp = &rspiocb->iocb;

/* ELS cmd tag <ulpIoTag> completes */
lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
"0139 Ignoring ELS cmd tag x%x completion Data: "
"0139 Ignoring ELS cmd code x%x completion Data: "
"x%x x%x x%x\n",
irsp->ulpIoTag, irsp->ulpStatus,
irsp->un.ulpWord[4], irsp->ulpTimeout);
/*
* Deref the ndlp after free_iocb. sli_release_iocb will access the ndlp
* if exchange is busy.
*/
if (cmdiocb->iocb.ulpCommand == CMD_GEN_REQUEST64_CR)
if (cmdiocb->iocb.ulpCommand == CMD_GEN_REQUEST64_CR) {
ndlp = cmdiocb->context_un.ndlp;
lpfc_ct_free_iocb(phba, cmdiocb);
else
} else {
ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
lpfc_els_free_iocb(phba, cmdiocb);
}

lpfc_nlp_put(ndlp);
}
Expand Down
52 changes: 22 additions & 30 deletions drivers/scsi/ufs/ufshcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -6377,27 +6377,6 @@ static irqreturn_t ufshcd_check_errors(struct ufs_hba *hba, u32 intr_status)
return retval;
}

struct ctm_info {
struct ufs_hba *hba;
unsigned long pending;
unsigned int ncpl;
};

static bool ufshcd_compl_tm(struct request *req, void *priv, bool reserved)
{
struct ctm_info *const ci = priv;
struct completion *c;

WARN_ON_ONCE(reserved);
if (test_bit(req->tag, &ci->pending))
return true;
ci->ncpl++;
c = req->end_io_data;
if (c)
complete(c);
return true;
}

/**
* ufshcd_tmc_handler - handle task management function completion
* @hba: per adapter instance
Expand All @@ -6408,18 +6387,24 @@ static bool ufshcd_compl_tm(struct request *req, void *priv, bool reserved)
*/
static irqreturn_t ufshcd_tmc_handler(struct ufs_hba *hba)
{
unsigned long flags;
struct request_queue *q = hba->tmf_queue;
struct ctm_info ci = {
.hba = hba,
};
unsigned long flags, pending, issued;
irqreturn_t ret = IRQ_NONE;
int tag;

pending = ufshcd_readl(hba, REG_UTP_TASK_REQ_DOOR_BELL);

spin_lock_irqsave(hba->host->host_lock, flags);
ci.pending = ufshcd_readl(hba, REG_UTP_TASK_REQ_DOOR_BELL);
blk_mq_tagset_busy_iter(q->tag_set, ufshcd_compl_tm, &ci);
issued = hba->outstanding_tasks & ~pending;
for_each_set_bit(tag, &issued, hba->nutmrs) {
struct request *req = hba->tmf_rqs[tag];
struct completion *c = req->end_io_data;

complete(c);
ret = IRQ_HANDLED;
}
spin_unlock_irqrestore(hba->host->host_lock, flags);

return ci.ncpl ? IRQ_HANDLED : IRQ_NONE;
return ret;
}

/**
Expand Down Expand Up @@ -6542,9 +6527,9 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba,
ufshcd_hold(hba, false);

spin_lock_irqsave(host->host_lock, flags);
blk_mq_start_request(req);

task_tag = req->tag;
hba->tmf_rqs[req->tag] = req;
treq->upiu_req.req_header.dword_0 |= cpu_to_be32(task_tag);

memcpy(hba->utmrdl_base_addr + task_tag, treq, sizeof(*treq));
Expand Down Expand Up @@ -6585,6 +6570,7 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba,
}

spin_lock_irqsave(hba->host->host_lock, flags);
hba->tmf_rqs[req->tag] = NULL;
__clear_bit(task_tag, &hba->outstanding_tasks);
spin_unlock_irqrestore(hba->host->host_lock, flags);

Expand Down Expand Up @@ -9635,6 +9621,12 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
err = PTR_ERR(hba->tmf_queue);
goto free_tmf_tag_set;
}
hba->tmf_rqs = devm_kcalloc(hba->dev, hba->nutmrs,
sizeof(*hba->tmf_rqs), GFP_KERNEL);
if (!hba->tmf_rqs) {
err = -ENOMEM;
goto free_tmf_queue;
}

/* Reset the attached device */
ufshcd_device_reset(hba);
Expand Down
1 change: 1 addition & 0 deletions drivers/scsi/ufs/ufshcd.h
Original file line number Diff line number Diff line change
Expand Up @@ -828,6 +828,7 @@ struct ufs_hba {

struct blk_mq_tag_set tmf_tag_set;
struct request_queue *tmf_queue;
struct request **tmf_rqs;

struct uic_command *active_uic_cmd;
struct mutex uic_cmd_mutex;
Expand Down

0 comments on commit 0950fcb

Please sign in to comment.