Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5ff924f3 authored by Nitin Rawat's avatar Nitin Rawat
Browse files

scsi: ufs: Add states to debug host_blocked in ufs driver



In UFS based targets, sometimes we are seeing ufs driver
return SCSI_MLQUEUE_HOST_BUSY error to scsi mid layer
while processing scsi request. This change is to add
contexts in driver while returning this error to scsi
which will help to debug such issues further.

Change-Id: I6bfb7a7c326dc12fbe08922d55104df87beb069b
Signed-off-by: default avatarNitin Rawat <nitirawa@codeaurora.org>
parent 82e0a0f5
Loading
Loading
Loading
Loading
+15 −1
Original line number Diff line number Diff line
@@ -3702,8 +3702,11 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
			cmd->scsi_done(cmd);
			return 0;
		}
		if (err == -EAGAIN)
		if (err == -EAGAIN) {
			hba->ufs_stats.scsi_blk_reqs.ts = ktime_get();
			hba->ufs_stats.scsi_blk_reqs.busy_ctx = SCALING_BUSY;
			return SCSI_MLQUEUE_HOST_BUSY;
		}
	} else if (err == 1) {
		has_read_lock = true;
	}
@@ -3719,6 +3722,8 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
	/* if error handling is in progress, return host busy */
	if (ufshcd_eh_in_progress(hba)) {
		err = SCSI_MLQUEUE_HOST_BUSY;
		hba->ufs_stats.scsi_blk_reqs.ts = ktime_get();
		hba->ufs_stats.scsi_blk_reqs.busy_ctx = EH_IN_PROGRESS;
		goto out_unlock;
	}

@@ -3728,6 +3733,9 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
	case UFSHCD_STATE_EH_SCHEDULED:
	case UFSHCD_STATE_RESET:
		err = SCSI_MLQUEUE_HOST_BUSY;
		hba->ufs_stats.scsi_blk_reqs.ts = ktime_get();
		hba->ufs_stats.scsi_blk_reqs.busy_ctx =
			UFS_RESET_OR_EH_SCHEDULED;
		goto out_unlock;
	case UFSHCD_STATE_ERROR:
		set_host_byte(cmd, DID_ERROR);
@@ -3753,6 +3761,8 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
		 * completion.
		 */
		err = SCSI_MLQUEUE_HOST_BUSY;
		hba->ufs_stats.scsi_blk_reqs.ts = ktime_get();
		hba->ufs_stats.scsi_blk_reqs.busy_ctx = LRB_IN_USE;
		goto out;
	}

@@ -3760,6 +3770,8 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
	err = ufshcd_hold(hba, true);
	if (err) {
		err = SCSI_MLQUEUE_HOST_BUSY;
		hba->ufs_stats.scsi_blk_reqs.ts = ktime_get();
		hba->ufs_stats.scsi_blk_reqs.busy_ctx = UFSHCD_HOLD;
		clear_bit_unlock(tag, &hba->lrb_in_use);
		goto out;
	}
@@ -3770,6 +3782,8 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
	if (err) {
		clear_bit_unlock(tag, &hba->lrb_in_use);
		err = SCSI_MLQUEUE_HOST_BUSY;
		hba->ufs_stats.scsi_blk_reqs.ts = ktime_get();
		hba->ufs_stats.scsi_blk_reqs.busy_ctx = UFSHCD_HIBERN8_HOLD;
		hba->ufs_stats.clk_rel.ctx = QUEUE_CMD;
		ufshcd_release(hba, true);
		goto out;
+15 −0
Original line number Diff line number Diff line
@@ -627,6 +627,20 @@ struct ufshcd_clk_ctx {
	enum ufshcd_ctx ctx;
};

enum ufshcd_scsi_host_busy_ctxt {
	SCALING_BUSY,
	EH_IN_PROGRESS,
	UFS_RESET_OR_EH_SCHEDULED,
	LRB_IN_USE,
	UFSHCD_HOLD,
	UFSHCD_HIBERN8_HOLD,
};

struct ufshcd_blk_ctx {
	ktime_t ts;
	enum ufshcd_scsi_host_busy_ctxt busy_ctx;
};

/**
 * struct ufs_stats - keeps usage/err statistics
 * @enabled: enable tag stats for debugfs
@@ -659,6 +673,7 @@ struct ufs_stats {
	ktime_t last_intr_ts;
	struct ufshcd_clk_ctx clk_hold;
	struct ufshcd_clk_ctx clk_rel;
	struct ufshcd_blk_ctx scsi_blk_reqs;
	u32 hibern8_exit_cnt;
	ktime_t last_hibern8_exit_tstamp;
	u32 power_mode_change_cnt;