[PATCH v2] ufs: core: fix ufshcd_abort_all racing issue

Bart Van Assche bvanassche at acm.org
Thu Jun 27 13:13:22 PDT 2024


On 6/27/24 3:59 AM, Peter Wang (王信友) wrote:
> This is a chicken-and-egg problem. We need to acquire a lock to know 
> which hwq it is, but we need to know which hwq it is to acquire the
> lock. Therefore, to resolve this dilemma, perhaps we should just take
> all the hwq locks indiscriminately?
How about the (untested) patch below?

Thanks,

Bart.

diff --git a/drivers/ufs/core/ufs-mcq.c b/drivers/ufs/core/ufs-mcq.c
index aa119746ee92..c5d327ba253f 100644
--- a/drivers/ufs/core/ufs-mcq.c
+++ b/drivers/ufs/core/ufs-mcq.c
@@ -105,16 +105,15 @@ EXPORT_SYMBOL_GPL(ufshcd_mcq_config_mac);
   * @hba: per adapter instance
   * @req: pointer to the request to be issued
   *
- * Return: the hardware queue instance on which the request would
- * be queued.
+ * Return: the hardware queue instance on which the request will be or 
has been
+ * queued. %NULL if the request has already been freed.
   */
  struct ufs_hw_queue *ufshcd_mcq_req_to_hwq(struct ufs_hba *hba,
  					 struct request *req)
  {
-	u32 utag = blk_mq_unique_tag(req);
-	u32 hwq = blk_mq_unique_tag_to_hwq(utag);
+	struct blk_mq_hw_ctx *hctx = READ_ONCE(rq->mq_hctx);

-	return &hba->uhq[hwq];
+	return hctx ? &hba->uhq[hctx->queue_num] : NULL;
  }

  /**
@@ -547,6 +546,8 @@ int ufshcd_mcq_sq_cleanup(struct ufs_hba *hba, int 
task_tag)
  		if (!cmd)
  			return -EINVAL;
  		hwq = ufshcd_mcq_req_to_hwq(hba, scsi_cmd_to_rq(cmd));
+		if (!hwq)
+			return -EINVAL;
  	} else {
  		hwq = hba->dev_cmd_queue;
  	}




More information about the Linux-mediatek mailing list