From nobody Thu Sep 24 21:18:35 2026 Received: from mail-pf1-f197.google.com (mail-pf1-f197.google.com [209.85.210.197]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 05C613546F2 for ; Sun, 20 Sep 2026 14:33:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.197 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789914806; cv=none; b=IqRPgLj36pR1NL3uzo6/ZnI73PH7JxMdyie1tm10Bf8CSMG4jn8DmSuvH+vt116Yj/dWW3BYvU2k6NsOVfPuTPF7tm5rBgG00965yvEQ+3UnUxe/33ZFKX4JnIGN5yQMIMFD3Dq28LZaqxm3m7bYtquZqf6JC+FcM+4o/csiHAs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789914806; c=relaxed/simple; bh=sJx+fGONxOD7zqOqztnWWiB8387wFQ98KF5wUeDckEk=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=Vhb+lZHc4V1XsbP51a8E72Iu/yzwZa05VCHhzg/UEbtMIrfJ0ZViUw3r6pjxLVU/BG+oa1BOscgggmr3KmOQOxDPXKl8Z/DTxrLWZHJtvV8oXdUNWRV4i2/V6RT4gRW07Qp6Vuxfd11FpxwpWKRS8EN8lH6Q9wai9ZVsAsndXHg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--stanleyjhu.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=JL97fww/; arc=none smtp.client-ip=209.85.210.197 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--stanleyjhu.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="JL97fww/" Received: by mail-pf1-f197.google.com with SMTP id d2e1a72fcca58-8663802b58fso2483309b3a.2 for ; Sun, 20 Sep 2026 07:33:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1789914803; x=1790519603; darn=vger.kernel.org; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:from:to:cc:subject:date:message-id:reply-to :content-type; bh=HQJQEJidXMPmVBcJtdQq733W8kc6T28EtDqD+r1rwkI=; b=JL97fww/e7ANb2EPJrAf/ER6si+qfDPAzBNp/c9RR2c4a1d0/eClZ+WDliKvS18gEW s/Zv5n0PhNFeTsCX90Yi5RaBHcJHvQfMzO5hKMSGwpxdqD5r0mWWZAFC+Q6Y1Qfv9f1Z TzH0kMxkv+sg2SbWE3z//Llp1JQ4ZQf/n45EsArnW+gSUh9NVHW1rUf+5laVlJy13DeW haOwfJTbfZpUOKNLdbKrVHUQcb/3NWT44/7HvMNI1569rRw9M1DjJmo00tNx9IhFz7Wu oG3wlpl1/RytilbYXnZar7FFX5Olnaf+8T7eFShJmYV4qJ9zT6x5CNEfnubs3Vx51fM6 kxuA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789914803; x=1790519603; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=HQJQEJidXMPmVBcJtdQq733W8kc6T28EtDqD+r1rwkI=; b=YCVRGl+0pkQaAHpxfccPzPcR+N6zGSyaYIFHXBHm2cYwENlR1jCGv7vOGgEMiLzv81 3PwvEpX2qa430kcdEbe88yKxzOQvI6s/xD83T3xyaXkN3HhQVGroagLCKwA1x1CelDXB 9F8MTaKaimDXbWJRpcLSyBq40cf5Sk4MixlFtoTK4tVoLAa21/tYCh0hKTo31yFTaPNZ H4fj/5kCcErcm3esY5hy/BkFuhr90+LhkRIuyJwYv8aAbHZ9yi72nt9ik0fY1nhSxomi 3DzfqfmfITuB+XdUvHM3JkK3g7xHMDYVTh2eF61CH0X14AmXKZW4gJtWI3UbpZmGHcL5 yV2g== X-Forwarded-Encrypted: i=1; AKwUvByv9bw2yAmqRBUmPmh4VtzVBBfL20P0TlAhG+bivPsM/YM4JHXlsC2iqPmuHDCh18CzyCUva1m06LypEh0=@vger.kernel.org X-Gm-Message-State: AFuF++nhsTn7320guAReIynM2xhukECmlDICuoMEd/bKlECVafaj5cI6 1dgFZlgAGDC9SEJKGVePRafYoXpBnA2upEH8L3GEhlbYURcn0Dgoej83w3YUhja9OVltyZMqixH R1L9ZJBK+XzyJ7SToI8EXjA== X-Received: from pfqy28.prod.google.com ([2002:aa7:9e1c:0:b0:873:a672:e379]) (user=stanleyjhu job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a00:9086:b0:878:34d7:69af with SMTP id d2e1a72fcca58-87834d76ccemr5134070b3a.54.1789914802966; Sun, 20 Sep 2026 07:33:22 -0700 (PDT) Date: Sun, 20 Sep 2026 22:33:18 +0800 In-Reply-To: <20260920143319.3659543-1-stanleyjhu@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260920143319.3659543-1-stanleyjhu@google.com> X-Mailer: git-send-email 2.55.0.1082.g2b9226bbc0-goog Message-ID: <20260920143319.3659543-2-stanleyjhu@google.com> Subject: [PATCH 1/2] scsi: ufs: core: Release command resources instead of force-completing From: Stanley Jhu To: Bart Van Assche , "Martin K . Petersen" , Alim Akhtar , Avri Altman Cc: "James E . J . Bottomley" , Peter Wang , Bean Huo , "Bao D . Nguyen" , Can Guo , Manivannan Sadhasivam , linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org, Stanley Jhu Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In ufshcd_host_reset_and_restore(), ufshcd_complete_requests(hba, true) couples LLD resource release (ufshcd_release_scsi_cmd()) with command completion (scsi_done()) right after ufshcd_hba_stop(): 1. EH-owned SCSI commands (SCMD_STATE_COMPLETE set): skipping scsi_done() in ufshcd_mcq_force_compl_one() also skips ufshcd_release_scsi_cmd(), leaking DMA mappings and clk_gating.active_reqs whenever ufshcd_abort() fails. 2. Non-EH SCSI commands (!SCMD_STATE_COMPLETE): calling scsi_done() right after ufshcd_hba_stop() completes them before link recovery finishes. To fix this, enforce a strict ownership boundary between LLD hardware resources and SCSI command completion: - LLD resources (DMA mappings, crypto PRDT, clk_gating.active_reqs) are tied to controller execution and must be released whenever the hardware stops executing a command, regardless of whether SCSI EH owns the command. - Command completion (scsi_done()) belongs exclusively to SCSI EH once SCMD_STATE_COMPLETE is set. However, for commands where SCMD_STATE_COMPLETE is not set, UFS cannot delegate completion to SCSI EH because UFS also performs autonomous resets (ufshcd_err_handler() on UIC/controller errors) outside of scsi_error_handler(). Since ufshcd_hba_stop() (HCE =3D 0) wipes all in-flight hardware transfers while SCSI EH is inactive, the driver itself must requeue halted non-EH commands with DID_REQUEUE after recovery finishes, or else they stall for the 30s block timeout. Implement this in three steps: 1. Track controller resource ownership with lrbp->in_flight so ufshcd_release_scsi_cmd() is idempotent across normal completion, successful task abort, and host reset teardown. 2. At controller stop (ufshcd_release_stopped_reqs()), release LLD resources for all halted commands without calling scsi_done(), clear any uncompleted reserved dev_cmd, and mark halted non-EH commands with lrbp->pending_requeue. 3. After host and link recovery finish (ufshcd_requeue_non_eh_cmds()), requeue pending commands that remain non-EH (!SCMD_STATE_COMPLETE) with DID_REQUEUE while leaving EH-owned commands on shost->eh_cmd_q. Fixes: ab248643d3d6 ("scsi: ufs: core: Add error handling for MCQ mode") Suggested-by: Bart Van Assche Signed-off-by: Stanley Jhu --- drivers/ufs/core/ufshcd.c | 183 ++++++++++++++++++++++++++++++-------- include/ufs/ufshcd.h | 6 ++ 2 files changed, 154 insertions(+), 35 deletions(-) diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index 234e18b5078f..c0772822731e 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -2432,6 +2432,7 @@ static inline void ufshcd_send_command(struct ufs_hba= *hba, lrbp->compl_time_stamp =3D ktime_set(0, 0); lrbp->compl_time_stamp_local_clock =3D 0; } + lrbp->in_flight =3D true; if (ufshcd_is_scsi_cmd(cmd)) { ufshcd_add_command_trace(hba, cmd, UFS_CMD_SEND); ufshcd_clk_scaling_start_busy(hba); @@ -3116,11 +3117,15 @@ static int ufshcd_init_cmd_priv(struct Scsi_Host *h= ost, struct scsi_cmnd *cmd) static enum scsi_qc_status ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) { + struct ufshcd_lrb *lrbp =3D scsi_cmd_priv(cmd); struct ufs_hba *hba =3D shost_priv(host); int tag =3D scsi_cmd_to_rq(cmd)->tag; int err =3D 0; struct ufs_hw_queue *hwq =3D NULL; =20 + lrbp->in_flight =3D false; + lrbp->pending_requeue =3D false; + switch (hba->ufshcd_state) { case UFSHCD_STATE_OPERATIONAL: break; @@ -3203,6 +3208,8 @@ static enum scsi_qc_status ufshcd_queue_reserved_comm= and(struct Scsi_Host *host, struct ufs_hw_queue *hwq =3D hba->mcq_enabled ? ufshcd_mcq_req_to_hwq(hba, rq) : NULL; =20 + lrbp->in_flight =3D false; + lrbp->pending_requeue =3D false; ufshcd_add_query_upiu_trace(hba, UFS_QUERY_SEND, lrbp->ucd_req_ptr); ufshcd_send_command(hba, cmd, hwq); return 0; @@ -4671,6 +4678,28 @@ int ufshcd_uic_change_pwr_mode(struct ufs_hba *hba, = u8 mode) } EXPORT_SYMBOL_GPL(ufshcd_uic_change_pwr_mode); =20 +static bool ufshcd_requeue_one_non_eh_cmd(struct request *req, void *data) +{ + struct scsi_cmnd *cmd =3D blk_mq_rq_to_pdu(req); + struct ufshcd_lrb *lrbp =3D scsi_cmd_priv(cmd); + + if (blk_mq_is_reserved_rq(req) || !lrbp->pending_requeue) + return true; + + lrbp->pending_requeue =3D false; + if (!test_bit(SCMD_STATE_COMPLETE, &cmd->state)) { + set_host_byte(cmd, DID_REQUEUE); + scsi_done(cmd); + } + return true; +} + +static void ufshcd_requeue_non_eh_cmds(struct ufs_hba *hba) +{ + blk_mq_tagset_busy_iter(&hba->host->tag_set, + ufshcd_requeue_one_non_eh_cmd, hba); +} + int ufshcd_link_recovery(struct ufs_hba *hba) { int ret; @@ -4692,6 +4721,8 @@ int ufshcd_link_recovery(struct ufs_hba *hba) ufshcd_clear_eh_in_progress(hba); spin_unlock_irqrestore(&hba->host->host_lock, flags); =20 + ufshcd_requeue_non_eh_cmds(hba); + if (ret) dev_err(hba->dev, "%s: link recovery failed, err %d", __func__, ret); @@ -5937,6 +5968,17 @@ static irqreturn_t ufshcd_uic_cmd_compl(struct ufs_h= ba *hba, u32 intr_status) /* Release the resources allocated for processing a SCSI command. */ void ufshcd_release_scsi_cmd(struct ufs_hba *hba, struct scsi_cmnd *cmd) { + struct ufshcd_lrb *lrbp =3D scsi_cmd_priv(cmd); + + lrbp->pending_requeue =3D false; + if (!lrbp->in_flight) + return; + lrbp->in_flight =3D false; + + /* Device management commands do not own any of the below. */ + if (!ufshcd_is_scsi_cmd(cmd)) + return; + scsi_dma_unmap(cmd); ufshcd_crypto_clear_prdt(hba, cmd); ufshcd_release(hba); @@ -5968,8 +6010,9 @@ void ufshcd_compl_one_cqe(struct ufs_hba *hba, int ta= sk_tag, if (unlikely(ufshcd_should_inform_monitor(hba, cmd))) ufshcd_update_monitor(hba, cmd); ufshcd_add_command_trace(hba, cmd, UFS_CMD_COMP); - cmd->result =3D ufshcd_transfer_rsp_status(hba, cmd, cqe); - ufshcd_release_scsi_cmd(hba, cmd); + if (!test_bit(SCMD_STATE_COMPLETE, &cmd->state)) + cmd->result =3D + ufshcd_transfer_rsp_status(hba, cmd, cqe); } else { if (cqe) { ocs =3D cqe->overall_status & MASK_OCS; @@ -5981,8 +6024,17 @@ void ufshcd_compl_one_cqe(struct ufs_hba *hba, int t= ask_tag, hba, ocs =3D=3D OCS_SUCCESS ? UFS_QUERY_COMP : UFS_QUERY_ERR, (struct utp_upiu_req *)lrbp->ucd_rsp_ptr); - cmd->result =3D 0; + if (!test_bit(SCMD_STATE_COMPLETE, &cmd->state)) + cmd->result =3D 0; } + ufshcd_release_scsi_cmd(hba, cmd); + /* + * Clear lrbp->pending_requeue before the tag is freed so that the + * next user of this tag is not mistaken for a command halted by + * ufshcd_hba_stop(). + */ + lrbp->pending_requeue =3D false; + /* Do not touch lrbp after scsi_done() has been called. */ scsi_done(cmd); } @@ -7912,6 +7964,8 @@ static bool ufshcd_clear_lu_cmds(struct request *req,= void *priv) struct ufs_hba *hba =3D shost_priv(shost); const u64 lun =3D *(u64 *)priv; const u32 tag =3D req->tag; + unsigned long flags; + bool outstanding; =20 if (blk_mq_is_reserved_rq(req) || sdev->lun !=3D lun) return true; @@ -7930,7 +7984,11 @@ static bool ufshcd_clear_lu_cmds(struct request *req= , void *priv) return true; } =20 - ufshcd_compl_one_cqe(hba, tag, NULL); + spin_lock_irqsave(&hba->outstanding_lock, flags); + outstanding =3D __test_and_clear_bit(tag, &hba->outstanding_reqs); + spin_unlock_irqrestore(&hba->outstanding_lock, flags); + if (outstanding) + ufshcd_compl_one_cqe(hba, tag, NULL); return true; } =20 @@ -8087,6 +8145,7 @@ static int ufshcd_abort(struct scsi_cmnd *cmd) u32 reg; =20 ufshcd_hold(hba); + lrbp->pending_requeue =3D false; =20 if (!hba->mcq_enabled) { reg =3D ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL); @@ -8153,6 +8212,16 @@ static int ufshcd_abort(struct scsi_cmnd *cmd) if (hba->mcq_enabled) { /* MCQ mode. Branch off to handle abort for mcq mode */ err =3D ufshcd_mcq_abort(cmd); + if (err =3D=3D SUCCESS) { + struct ufs_hw_queue *hwq =3D + ufshcd_mcq_req_to_hwq(hba, rq); + + if (hwq) { + spin_lock_irqsave(&hwq->cq_lock, flags); + ufshcd_release_scsi_cmd(hba, cmd); + spin_unlock_irqrestore(&hwq->cq_lock, flags); + } + } goto release; } =20 @@ -8216,6 +8285,71 @@ static void ufshcd_process_probe_result(struct ufs_h= ba *hba, hba->curr_dev_pwr_mode, hba->uic_link_state); } =20 +/* + * The caller must own @rq, either by having claimed its bit in + * hba->outstanding_reqs (legacy mode) or by holding hwq->cq_lock (MCQ mod= e). + */ +static void __ufshcd_release_stopped_req(struct ufs_hba *hba, + struct request *rq, + struct scsi_cmnd *cmd) +{ + struct ufshcd_lrb *lrbp =3D scsi_cmd_priv(cmd); + + if (!lrbp->in_flight) + return; + + ufshcd_release_scsi_cmd(hba, cmd); + if (test_bit(SCMD_STATE_COMPLETE, &cmd->state)) + return; + + if (blk_mq_is_reserved_rq(rq)) { + /* Device management commands are not requeued. */ + set_host_byte(cmd, DID_TIME_OUT); + scsi_done(cmd); + } else { + lrbp->pending_requeue =3D true; + } +} + +static bool ufshcd_release_one_stopped_req(struct request *rq, void *priv) +{ + struct scsi_cmnd *cmd =3D blk_mq_rq_to_pdu(rq); + struct ufs_hba *hba =3D priv; + unsigned long flags; + bool owned; + + if (hba->mcq_enabled) { + struct ufs_hw_queue *hwq =3D ufshcd_mcq_req_to_hwq(hba, rq); + + if (hwq) { + spin_lock_irqsave(&hwq->cq_lock, flags); + __ufshcd_release_stopped_req(hba, rq, cmd); + spin_unlock_irqrestore(&hwq->cq_lock, flags); + } + return true; + } + + /* + * Keep hba->outstanding_lock a leaf lock, as in ufshcd_poll() and + * ufshcd_abort(): clearing the bit already grants exclusive ownership. + */ + spin_lock_irqsave(&hba->outstanding_lock, flags); + owned =3D __test_and_clear_bit(rq->tag, &hba->outstanding_reqs); + spin_unlock_irqrestore(&hba->outstanding_lock, flags); + if (owned) + __ufshcd_release_stopped_req(hba, rq, cmd); + + return true; +} + +static void ufshcd_release_stopped_reqs(struct ufs_hba *hba) +{ + blk_mq_tagset_busy_iter(&hba->host->tag_set, + ufshcd_release_one_stopped_req, hba); + /* TMF sweep inherited from the replaced ufshcd_complete_requests(). */ + ufshcd_tmc_handler(hba); +} + /** * ufshcd_host_reset_and_restore - reset and restore host controller * @hba: per-adapter instance @@ -8231,13 +8365,11 @@ static int ufshcd_host_reset_and_restore(struct ufs= _hba *hba) int err; =20 /* - * Stop the host controller and complete the requests - * cleared by h/w + * Stop the host controller and release driver resources for + * requests cleared by h/w */ ufshcd_hba_stop(hba); - hba->silence_err_logs =3D true; - ufshcd_complete_requests(hba, true); - hba->silence_err_logs =3D false; + ufshcd_release_stopped_reqs(hba); =20 /* scale up clocks to max frequency before full reinitialization */ if (ufshcd_is_clkscaling_supported(hba)) @@ -8319,6 +8451,8 @@ static int ufshcd_reset_and_restore(struct ufs_hba *h= ba) } spin_unlock_irqrestore(&hba->host->host_lock, flags); =20 + ufshcd_requeue_non_eh_cmds(hba); + return err; } =20 @@ -9597,30 +9731,6 @@ static enum scsi_timeout_action ufshcd_eh_timed_out(= struct scsi_cmnd *scmd) dev_info(hba->dev, "%s() finished; outstanding_tasks =3D %#lx.\n", __func__, hba->outstanding_tasks); =20 - /* - * ufshcd_link_recovery() may already have completed @scmd, e.g. via - * the existing MCQ force-completion path. - */ - if (!test_bit(SCMD_STATE_COMPLETE, &scmd->state)) { - if (!hba->mcq_enabled) { - unsigned long flags; - struct request *rq =3D scsi_cmd_to_rq(scmd); - - spin_lock_irqsave(&hba->outstanding_lock, flags); - __clear_bit(rq->tag, &hba->outstanding_reqs); - spin_unlock_irqrestore(&hba->outstanding_lock, flags); - } - - if (ufshcd_is_scsi_cmd(scmd)) { - set_host_byte(scmd, DID_REQUEUE); - ufshcd_release_scsi_cmd(hba, scmd); - } else { - set_host_byte(scmd, DID_TIME_OUT); - } - - scsi_done(scmd); - } - return SCSI_EH_DONE; } =20 @@ -10464,15 +10574,18 @@ static int __ufshcd_wl_suspend(struct ufs_hba *hb= a, enum ufs_pm_op pm_op) ufshcd_device_reset(hba); WARN_ON(!ufshcd_is_link_off(hba)); } - if (ufshcd_is_link_hibern8(hba) && !ufshcd_uic_hibern8_exit(hba)) + if (ufshcd_is_link_hibern8(hba) && !ufshcd_uic_hibern8_exit(hba)) { ufshcd_set_link_active(hba); - else if (ufshcd_is_link_off(hba)) + } else if (ufshcd_is_link_off(hba)) { ufshcd_host_reset_and_restore(hba); + ufshcd_requeue_non_eh_cmds(hba); + } set_dev_active: /* Can also get here needing to exit DeepSleep */ if (ufshcd_is_ufs_dev_deepsleep(hba)) { ufshcd_device_reset(hba); ufshcd_host_reset_and_restore(hba); + ufshcd_requeue_non_eh_cmds(hba); } if (!ufshcd_set_dev_pwr_mode(hba, UFS_ACTIVE_PWR_MODE)) ufshcd_disable_auto_bkops(hba); diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h index dfd302f2dc7c..cd84f617f95c 100644 --- a/include/ufs/ufshcd.h +++ b/include/ufs/ufshcd.h @@ -166,6 +166,10 @@ struct ufs_pm_lvl_states { * @lun: LUN of the command * @intr_cmd: Interrupt command (doesn't participate in interrupt aggregat= ion) * @req_abort_skip: skip request abort task flag + * @in_flight: true after the command has been submitted to the controller= and + * before its resources have been released + * @pending_requeue: true if command was halted by ufshcd_hba_stop() and a= waits + * post-recovery requeue * @issue_time_stamp: time stamp for debug purposes (CLOCK_MONOTONIC) * @issue_time_stamp_local_clock: time stamp for debug purposes (local_clo= ck) * @compl_time_stamp: time stamp for statistics (CLOCK_MONOTONIC) @@ -190,6 +194,8 @@ struct ufshcd_lrb { u8 lun; /* UPIU LUN id field is only 8-bit wide */ bool intr_cmd; bool req_abort_skip; + bool in_flight; + bool pending_requeue; ktime_t issue_time_stamp; u64 issue_time_stamp_local_clock; ktime_t compl_time_stamp; --=20 2.55.0.1082.g2b9226bbc0-goog From nobody Thu Sep 24 21:18:35 2026 Received: from mail-pg1-f199.google.com (mail-pg1-f199.google.com [209.85.215.199]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E80A33546C2 for ; Sun, 20 Sep 2026 14:33:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.199 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789914808; cv=none; b=I7TYTy/Cg/Y62QorQaYCElwE+X8xPlLDhyYjH2tJQj0fLKjkckZdR/LMGPe43FCdkbCkEC9gknLO5tGuyw3vMbB9zVdkHGC8fnsdzuWWUrWaNKJGZUQlb1SuBudxTqaJPrFFPDKQcXNPAUCI/kvgKHPN15YbU0zYzkqL51NI1JU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789914808; c=relaxed/simple; bh=3pxNHbCzxSQwckjsNKHFSlhE50lIlo3WeRAKR1GUg80=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=J3lZVxsoZihjvs1r9/TWA/4qiE3e+5FVYm0cl1xj3FR0hgq553bb73bMfQ4O9awdW/LHJD4/y0EkjPynuWlcGy1VFr1+ScWlvPYy3GME57ZdeAias3PDiEFzDYsTChOoIU9uXD2VSlJyJj6knwe/bpWAWzAeywqRpuXdW5qDdtY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--stanleyjhu.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=HHw/rFAK; arc=none smtp.client-ip=209.85.215.199 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--stanleyjhu.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="HHw/rFAK" Received: by mail-pg1-f199.google.com with SMTP id 41be03b00d2f7-cc1b8088203so1951494a12.3 for ; Sun, 20 Sep 2026 07:33:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1789914805; x=1790519605; darn=vger.kernel.org; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:from:to:cc:subject:date:message-id:reply-to :content-type; bh=OqhYolaf6vUsqT3z/D8MoSBfgcWhbBjeVI+jdzmWR2U=; b=HHw/rFAKyz268dMdvKjX8AbzJddD0UbVtJn+zkhDO2Rr/FjBl9cc+7BX5AM6+wrWHY TJHCiG4EW2ofC6WcebX36WmZzlEd+qspWioTbR8U6gpU6WxFkpkOQLWZVrZRwfhP445h W8MaXu/YXKSV8/eO9sEkfdlfTnb2SoRi6ZqIyN2In30AwY3UU7+s4LYadk2WrrCoH6mT oUQZQRu2y+CNiUVe3V7O7a5PgGJ51izJmneamF8P3+kd8X+93zZQ+T59ttvq5FxtBq8h wqGcPpvfw+MMsIVPe2JML11lQ9B/fk0AH1lARz2nZA8eA6hEBs9mAs57ESsYiswvUL1h u6bg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789914805; x=1790519605; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=OqhYolaf6vUsqT3z/D8MoSBfgcWhbBjeVI+jdzmWR2U=; b=Q+7J8uiADHmMLlY7HTTY+c23Xn20BtChn3kMQNzudfGiZyZL3SWId8Sm/RCIzJAtag pz8NrnsC++PaFZ26IfOmLSaveOQ48TjeOCE32rIo1vM7fuW/3dSgqgXg7RI/Kap24+oj rELpw7pfb+c4+S5qox+2D0XSSRczaDQmlvjawDaom68DnVxp9ErEJ+E9yN5Bc+/vpG/X TY+OrGYoAJkav8fAd6fRvLU+djVjLzn8HCODNSkTyf01fIHAN0zrWkslu4YBPtz6iRyw ZgQK5EBaN/KVn4DCNz7sWHG9KrOfRvNWKBDGBEUMQ6Ul2RmVpc4ZhLsIiJDhj0zUiIBx pS6w== X-Forwarded-Encrypted: i=1; AKwUvBxiAwCKXI/oU5zy3iP1uZMPwHV/lQyF2RWf1E+8LOHGihsRquEC030OdJ2UxJgOj67SGb4fxcojh72lKnY=@vger.kernel.org X-Gm-Message-State: AFuF++ktsM645zb/lJh0s/Xu6osQ7XA0ycWzKKb3IQLwZY59gM2CTT4b uSiHaLmSbXPYA5jaGfhvVXzx+f/kAsMJWQSzS4woZz9H9TnUH39NXVNA1X7c8FNbZr7+s26apek sgQAV+qlYZDxKIT/xzcz1Sw== X-Received: from pgte19.prod.google.com ([2002:a65:6893:0:b0:cc4:bede:3dc7]) (user=stanleyjhu job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a21:1b81:b0:3cd:8bba:824f with SMTP id adf61e73a8af0-3dd8c3d3acfmr14271494637.4.1789914804832; Sun, 20 Sep 2026 07:33:24 -0700 (PDT) Date: Sun, 20 Sep 2026 22:33:19 +0800 In-Reply-To: <20260920143319.3659543-1-stanleyjhu@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260920143319.3659543-1-stanleyjhu@google.com> X-Mailer: git-send-email 2.55.0.1082.g2b9226bbc0-goog Message-ID: <20260920143319.3659543-3-stanleyjhu@google.com> Subject: [PATCH 2/2] scsi: ufs: core: Remove unused force_compl parameter and MCQ helper From: Stanley Jhu To: Bart Van Assche , "Martin K . Petersen" , Alim Akhtar , Avri Altman Cc: "James E . J . Bottomley" , Peter Wang , Bean Huo , "Bao D . Nguyen" , Can Guo , Manivannan Sadhasivam , linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org, Stanley Jhu Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" With ufshcd_host_reset_and_restore() converted to call ufshcd_release_stopped_reqs(), both remaining callers of ufshcd_complete_requests() (ufshcd_abort_all() and ufshcd_err_handler()) pass force_compl =3D false. Remove the unused force_compl parameter from ufshcd_complete_requests() and ufshcd_mcq_compl_pending_transfer(), and delete the now-unreachable ufshcd_mcq_force_compl_one() and ufshcd_mcq_compl_all_cqes_lock() helpers. No functional change intended. Suggested-by: Bart Van Assche Signed-off-by: Stanley Jhu --- drivers/ufs/core/ufs-mcq.c | 26 ----------------- drivers/ufs/core/ufshcd-priv.h | 2 -- drivers/ufs/core/ufshcd.c | 52 +++++----------------------------- 3 files changed, 7 insertions(+), 73 deletions(-) diff --git a/drivers/ufs/core/ufs-mcq.c b/drivers/ufs/core/ufs-mcq.c index 8106d55f4041..55ed72d15ada 100644 --- a/drivers/ufs/core/ufs-mcq.c +++ b/drivers/ufs/core/ufs-mcq.c @@ -328,32 +328,6 @@ static void ufshcd_mcq_process_cqe(struct ufs_hba *hba, } } =20 -/* - * This function is called from the UFS error handler with the UFS host - * controller disabled (HCE =3D 0). Reading host controller registers, e.g= . the - * CQ tail pointer (CQTPy), may not be safe with the host controller disab= led. - * Hence, iterate over all completion queue entries. This won't result in - * double completions because ufshcd_mcq_process_cqe() clears a CQE after = it - * has been processed. - */ -void ufshcd_mcq_compl_all_cqes_lock(struct ufs_hba *hba, - struct ufs_hw_queue *hwq) -{ - unsigned long flags; - u32 entries =3D hwq->max_entries; - - spin_lock_irqsave(&hwq->cq_lock, flags); - while (entries > 0) { - ufshcd_mcq_process_cqe(hba, hwq); - ufshcd_mcq_inc_cq_head_slot(hwq); - entries--; - } - - ufshcd_mcq_update_cq_tail_slot(hwq); - hwq->cq_head_slot =3D hwq->cq_tail_slot; - spin_unlock_irqrestore(&hwq->cq_lock, flags); -} - unsigned long ufshcd_mcq_poll_cqe_lock(struct ufs_hba *hba, struct ufs_hw_queue *hwq) { diff --git a/drivers/ufs/core/ufshcd-priv.h b/drivers/ufs/core/ufshcd-priv.h index e55c2a02c1f5..8ddc19143abf 100644 --- a/drivers/ufs/core/ufshcd-priv.h +++ b/drivers/ufs/core/ufshcd-priv.h @@ -73,8 +73,6 @@ int ufshcd_get_hba_mac(struct ufs_hba *hba); int ufshcd_mcq_memory_alloc(struct ufs_hba *hba); struct ufs_hw_queue *ufshcd_mcq_req_to_hwq(struct ufs_hba *hba, struct request *req); -void ufshcd_mcq_compl_all_cqes_lock(struct ufs_hba *hba, - struct ufs_hw_queue *hwq); bool ufshcd_cmd_inflight(struct scsi_cmnd *cmd); int ufshcd_mcq_sq_cleanup(struct ufs_hba *hba, int task_tag); int ufshcd_mcq_abort(struct scsi_cmnd *cmd); diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index c0772822731e..b7492a5af616 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -6109,34 +6109,6 @@ static int ufshcd_poll(struct Scsi_Host *shost, unsi= gned int queue_num) return completed_reqs !=3D 0; } =20 -static bool ufshcd_mcq_force_compl_one(struct request *rq, void *priv) -{ - struct scsi_cmnd *cmd =3D blk_mq_rq_to_pdu(rq); - struct scsi_device *sdev =3D rq->q->queuedata; - struct Scsi_Host *shost =3D sdev->host; - struct ufs_hba *hba =3D shost_priv(shost); - struct ufs_hw_queue *hwq =3D ufshcd_mcq_req_to_hwq(hba, rq); - - if (blk_mq_is_reserved_rq(rq) || !hwq) - return true; - - ufshcd_mcq_compl_all_cqes_lock(hba, hwq); - - /* - * For those cmds of which the cqes are not present in the cq, complete - * them explicitly. - */ - scoped_guard(spinlock_irqsave, &hwq->cq_lock) { - if (!test_bit(SCMD_STATE_COMPLETE, &cmd->state)) { - set_host_byte(cmd, DID_REQUEUE); - ufshcd_release_scsi_cmd(hba, cmd); - scsi_done(cmd); - } - } - - return true; -} - static bool ufshcd_mcq_compl_one(struct request *rq, void *priv) { struct scsi_device *sdev =3D rq->q->queuedata; @@ -6151,22 +6123,12 @@ static bool ufshcd_mcq_compl_one(struct request *rq= , void *priv) } =20 /** - * ufshcd_mcq_compl_pending_transfer - MCQ mode function. It is - * invoked from the error handler context or ufshcd_host_reset_and_restore= () - * to complete the pending transfers and free the resources associated with - * the scsi command. - * + * ufshcd_mcq_compl_pending_transfer - Complete pending MCQ transfers from= EH * @hba: per adapter instance - * @force_compl: This flag is set to true when invoked - * from ufshcd_host_reset_and_restore() in which case it requires special - * handling because the host controller has been reset by ufshcd_hba_stop(= ). */ -static void ufshcd_mcq_compl_pending_transfer(struct ufs_hba *hba, - bool force_compl) +static void ufshcd_mcq_compl_pending_transfer(struct ufs_hba *hba) { - blk_mq_tagset_busy_iter(&hba->host->tag_set, - force_compl ? ufshcd_mcq_force_compl_one : - ufshcd_mcq_compl_one, + blk_mq_tagset_busy_iter(&hba->host->tag_set, ufshcd_mcq_compl_one, NULL); } =20 @@ -6723,10 +6685,10 @@ static void ufshcd_exception_event_handler(struct w= ork_struct *work) } =20 /* Complete requests that have door-bell cleared */ -static void ufshcd_complete_requests(struct ufs_hba *hba, bool force_compl) +static void ufshcd_complete_requests(struct ufs_hba *hba) { if (hba->mcq_enabled) - ufshcd_mcq_compl_pending_transfer(hba, force_compl); + ufshcd_mcq_compl_pending_transfer(hba); else ufshcd_transfer_req_compl(hba); =20 @@ -7027,7 +6989,7 @@ static bool ufshcd_abort_all(struct ufs_hba *hba) =20 out: /* Complete the requests that are cleared by s/w */ - ufshcd_complete_requests(hba, false); + ufshcd_complete_requests(hba); =20 return ret !=3D 0; } @@ -7089,7 +7051,7 @@ static void ufshcd_err_handler(struct work_struct *wo= rk) spin_unlock_irqrestore(&hba->host->host_lock, flags); =20 /* Complete requests that have door-bell cleared by h/w */ - ufshcd_complete_requests(hba, false); + ufshcd_complete_requests(hba); spin_lock_irqsave(&hba->host->host_lock, flags); again: needs_restore =3D false; --=20 2.55.0.1082.g2b9226bbc0-goog