Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

scsi: ufs: core: Rework ufshcd_eh_device_reset_handler()

Merge the MCQ mode and legacy mode loops into a single loop. This patch
prepares for optimizing the hot path by removing the direct hba->lrb[]
accesses from ufshcd_eh_device_reset_handler().

Reviewed-by: Avri Altman <avri.altman@sandisk.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Link: https://patch.msgid.link/20251031204029.2883185-17-bvanassche@acm.org
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

authored by

Bart Van Assche and committed by
Martin K. Petersen
f18fac1e 63a5b959

+38 -46
+38 -46
drivers/ufs/core/ufshcd.c
··· 7566 7566 return err ? : result; 7567 7567 } 7568 7568 7569 + static bool ufshcd_clear_lu_cmds(struct request *req, void *priv) 7570 + { 7571 + struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(req); 7572 + struct scsi_device *sdev = cmd->device; 7573 + struct Scsi_Host *shost = sdev->host; 7574 + struct ufs_hba *hba = shost_priv(shost); 7575 + const u64 lun = *(u64 *)priv; 7576 + const u32 tag = req->tag; 7577 + 7578 + if (sdev->lun != lun) 7579 + return true; 7580 + 7581 + if (ufshcd_clear_cmd(hba, tag) < 0) { 7582 + dev_err(hba->dev, "%s: failed to clear request %d\n", __func__, 7583 + tag); 7584 + return true; 7585 + } 7586 + 7587 + if (hba->mcq_enabled) { 7588 + struct ufs_hw_queue *hwq = ufshcd_mcq_req_to_hwq(hba, req); 7589 + 7590 + if (hwq) 7591 + ufshcd_mcq_poll_cqe_lock(hba, hwq); 7592 + return true; 7593 + } 7594 + 7595 + ufshcd_compl_one_cqe(hba, tag, NULL); 7596 + return true; 7597 + } 7598 + 7569 7599 /** 7570 7600 * ufshcd_eh_device_reset_handler() - Reset a single logical unit. 7571 7601 * @cmd: SCSI command pointer ··· 7604 7574 */ 7605 7575 static int ufshcd_eh_device_reset_handler(struct scsi_cmnd *cmd) 7606 7576 { 7607 - unsigned long flags, pending_reqs = 0, not_cleared = 0; 7608 7577 struct Scsi_Host *host; 7609 7578 struct ufs_hba *hba; 7610 - struct ufs_hw_queue *hwq; 7611 - struct ufshcd_lrb *lrbp; 7612 - u32 pos, not_cleared_mask = 0; 7613 7579 int err; 7614 7580 u8 resp = 0xF, lun; 7615 7581 ··· 7614 7588 7615 7589 lun = ufshcd_scsi_to_upiu_lun(cmd->device->lun); 7616 7590 err = ufshcd_issue_tm_cmd(hba, lun, 0, UFS_LOGICAL_RESET, &resp); 7617 - if (err || resp != UPIU_TASK_MANAGEMENT_FUNC_COMPL) { 7618 - if (!err) 7619 - err = resp; 7620 - goto out; 7591 + if (err) { 7592 + } else if (resp != UPIU_TASK_MANAGEMENT_FUNC_COMPL) { 7593 + err = resp; 7594 + } else { 7595 + /* clear the commands that were pending for corresponding LUN */ 7596 + blk_mq_tagset_busy_iter(&hba->host->tag_set, 7597 + ufshcd_clear_lu_cmds, 7598 + &cmd->device->lun); 7621 7599 } 7622 7600 7623 - if (hba->mcq_enabled) { 7624 - for (pos = 0; pos < hba->nutrs; pos++) { 7625 - lrbp = &hba->lrb[pos]; 7626 - if (ufshcd_cmd_inflight(lrbp->cmd) && 7627 - lrbp->lun == lun) { 7628 - ufshcd_clear_cmd(hba, pos); 7629 - hwq = ufshcd_mcq_req_to_hwq(hba, scsi_cmd_to_rq(lrbp->cmd)); 7630 - ufshcd_mcq_poll_cqe_lock(hba, hwq); 7631 - } 7632 - } 7633 - err = 0; 7634 - goto out; 7635 - } 7636 - 7637 - /* clear the commands that were pending for corresponding LUN */ 7638 - spin_lock_irqsave(&hba->outstanding_lock, flags); 7639 - for_each_set_bit(pos, &hba->outstanding_reqs, hba->nutrs) 7640 - if (hba->lrb[pos].lun == lun) 7641 - __set_bit(pos, &pending_reqs); 7642 - hba->outstanding_reqs &= ~pending_reqs; 7643 - spin_unlock_irqrestore(&hba->outstanding_lock, flags); 7644 - 7645 - for_each_set_bit(pos, &pending_reqs, hba->nutrs) { 7646 - if (ufshcd_clear_cmd(hba, pos) < 0) { 7647 - spin_lock_irqsave(&hba->outstanding_lock, flags); 7648 - not_cleared = 1U << pos & 7649 - ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL); 7650 - hba->outstanding_reqs |= not_cleared; 7651 - not_cleared_mask |= not_cleared; 7652 - spin_unlock_irqrestore(&hba->outstanding_lock, flags); 7653 - 7654 - dev_err(hba->dev, "%s: failed to clear request %d\n", 7655 - __func__, pos); 7656 - } 7657 - } 7658 - __ufshcd_transfer_req_compl(hba, pending_reqs & ~not_cleared_mask); 7659 - 7660 - out: 7661 7601 hba->req_abort_count = 0; 7662 7602 ufshcd_update_evt_hist(hba, UFS_EVT_DEV_RESET, (u32)err); 7663 7603 if (!err) {