On Thu, 22 Oct 2026 15:45:07 +0800, Stanley Jhu wrote:
> +    if (tm_func == UFS_QUERY_TASK) {
> +        if (u->fault_inject_mode == UFS_FAULT_INJECT_IN_TRANSITION) {
> +            u->held_req = NULL;
> +            u->active_fault_inject_tag = UFS_FAULT_INJECT_TAG_NONE;
> +            u->params.fault_inject_tag = UFS_FAULT_INJECT_TAG_NONE;
> +            *tm_resp = UFS_UPIU_TASK_MANAGEMENT_FUNC_COMPL;
> +            ufs_fault_inject_complete_held_req(hreq);

Which host path is in-transition meant to reach? In Linux, QUERY TASK
is sent only by ufshcd_try_to_abort_task(). When it runs from
ufshcd_abort() after a SCSI timeout, scsi_timeout() has already set
SCMD_STATE_COMPLETE (drivers/scsi/scsi_error.c:391), so scsi_done()
drops the completion posted here (drivers/scsi/scsi_lib.c:1772). The
request stays MQ_RQ_IN_FLIGHT, ufshcd_cmd_inflight() stays true, and
the loop returns -EBUSY after 100 "not pending" replies
(drivers/ufs/core/ufshcd.c:7993-8026). The "completed" branch is never
taken, and recovery ends in a host reset, as with abort-failed. I got
this with O_DIRECT writes on mainline 7.3-rc7 (MCQ and legacy) and on
ACK android17-6.18 (MCQ).

If the target is a path where the host does take this completion, for
example ufshcd_abort_all() from the error handler, the host would see a
WRITE succeed although no data reached the LU.

> +        } else {
> +            /* UFS_FAULT_INJECT_ABORT_SUCCESS or default */
> +            u->held_req = NULL;
> +            if (ufs_mcq_req(hreq)) {
[...]
> +            *tm_resp = UFS_UPIU_TASK_MANAGEMENT_FUNC_COMPL;
> +        }

This repeats the generic ABORT TASK code in ufs_process_tmr(). The held
request is in UFS_REQUEST_RUNNING, so ufs_find_req_by_tag() finds it,
and releasing the hold and returning false gives the same result. The
same is true for the QUERY TASK SUCCEEDED branch above. With both
changed (17 deletions, 4 insertions), the UFS qtests pass 29/29.

Daejun

Reply via email to