scsi: ufs: core: Fix task management completion
Subsystems (2)
PATCH 1/1 scsi: ufs: core: Fix task management completion
commit f5ef336fd2e4c36dedae4e7ca66cf5349d6fda62 upstream.
The UFS driver uses blk_mq_tagset_busy_iter() when identifying task management requests to complete, however blk_mq_tagset_busy_iter() doesn't work.
blk_mq_tagset_busy_iter() only iterates requests dispatched by the block layer. That appears as if it might have started since commit 37f4a24c2469 ("blk-mq: centralise related handling into blk_mq_get_driver_tag") which removed 'data->hctx->tags->rqs[rq->tag] = rq' from blk_mq_rq_ctx_init() which gets called:
blk_get_request
blk_mq_alloc_request
__blk_mq_alloc_request
blk_mq_rq_ctx_init
Since UFS task management requests are not dispatched by the block layer, hctx->tags->rqs[rq->tag] remains NULL, and since blk_mq_tagset_busy_iter() relies on finding requests using hctx->tags->rqs[rq->tag], UFS task management requests are never found by blk_mq_tagset_busy_iter().
By using blk_mq_tagset_busy_iter(), the UFS driver was relying on internal details of the block layer, which was fragile and subsequently got broken. Fix by removing the use of blk_mq_tagset_busy_iter() and having the driver keep track of task management requests.
--- drivers/scsi/ufs/ufshcd.c | 54 ++++++++++++++++++--------------------- drivers/scsi/ufs/ufshcd.h | 1 + 2 files changed, 26 insertions(+), 29 deletions(-)
drivers/scsi/ufs/ufshcd.c +25 -29
@@ -6105,27 +6105,6 @@ static irqreturn_t ufshcd_check_errors(struct ufs_hba *hba)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
@@ -6136,14 +6115,24 @@ static bool ufshcd_compl_tm(struct request *req, void *priv, bool reserved)*/ static irqreturn_t ufshcd_tmc_handler (struct ufs_hba *hba) { -struct request_queue *q = hba->tmf_queue; -struct ctm_info ci = { - .hba = hba, - .pending =ufshcd_readl (hba,REG_UTP_TASK_REQ_DOOR_BELL ), - }; +unsigned long flags, pending, issued; +irqreturn_t ret =IRQ_NONE ; +int tag; -blk_mq_tagset_busy_iter (q->tag_set, ufshcd_compl_tm, &ci); -return ci.ncpl ?IRQ_HANDLED :IRQ_NONE ; + pending =ufshcd_readl (hba,REG_UTP_TASK_REQ_DOOR_BELL ); + +spin_lock_irqsave (hba->host->host_lock, flags); + 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 ret; }/**
@@ -6273,9 +6262,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->req_header.dword_0 |=cpu_to_be32 (task_tag);memcpy (hba->utmrdl_base_addr + task_tag, treq,sizeof (*treq));
@@ -6319,6 +6308,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);
@@ -9246,6 +9236,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_vops_device_reset (hba);
drivers/scsi/ufs/ufshcd.h +1 -0
@@ -731,6 +731,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;
Signature · 1 line
2.25.1
Quoted 2 lines · Adrian Hunter
commit
f5ef336fd2e4c36dedae4e7ca66cf5349d6fda62upstream.
Now queued up, thanks.
greg k-h