Commit 18305320 authored by Mike Christie's avatar Mike Christie Committed by Martin K. Petersen
Browse files

scsi: sd: Have midlayer retry sd_sync_cache() errors



This has sd_sync_cache() have the SCSI midlayer retry errors instead of
driving them itself.

There is one behavior change where we no longer retry when
scsi_execute_cmd() returns < 0, but we should be ok. We don't need to retry
for failures like the queue being removed, and for the case where there are
no tags/reqs the block layer waits/retries for us. For possible memory
allocation failures from blk_rq_map_kern() we use GFP_NOIO, so retrying
will probably not help.

Signed-off-by: default avatarMike Christie <michael.christie@oracle.com>
Link: https://lore.kernel.org/r/20240123002220.129141-10-michael.christie@oracle.com


Acked-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 5dbf1047
Loading
Loading
Loading
Loading
+17 −18
Original line number Diff line number Diff line
@@ -1645,36 +1645,35 @@ static unsigned int sd_check_events(struct gendisk *disk, unsigned int clearing)

static int sd_sync_cache(struct scsi_disk *sdkp)
{
	int retries, res;
	int res;
	struct scsi_device *sdp = sdkp->device;
	const int timeout = sdp->request_queue->rq_timeout
		* SD_FLUSH_TIMEOUT_MULTIPLIER;
	/* Leave the rest of the command zero to indicate flush everything. */
	const unsigned char cmd[16] = { sdp->use_16_for_sync ?
				SYNCHRONIZE_CACHE_16 : SYNCHRONIZE_CACHE };
	struct scsi_sense_hdr sshdr;
	struct scsi_failure failure_defs[] = {
		{
			.allowed = 3,
			.result = SCMD_FAILURE_RESULT_ANY,
		},
		{}
	};
	struct scsi_failures failures = {
		.failure_definitions = failure_defs,
	};
	const struct scsi_exec_args exec_args = {
		.req_flags = BLK_MQ_REQ_PM,
		.sshdr = &sshdr,
		.failures = &failures,
	};

	if (!scsi_device_online(sdp))
		return -ENODEV;

	for (retries = 3; retries > 0; --retries) {
		unsigned char cmd[16] = { 0 };

		if (sdp->use_16_for_sync)
			cmd[0] = SYNCHRONIZE_CACHE_16;
		else
			cmd[0] = SYNCHRONIZE_CACHE;
		/*
		 * Leave the rest of the command zero to indicate
		 * flush everything.
		 */
		res = scsi_execute_cmd(sdp, cmd, REQ_OP_DRV_IN, NULL, 0,
				       timeout, sdkp->max_retries, &exec_args);
		if (res == 0)
			break;
	}

	res = scsi_execute_cmd(sdp, cmd, REQ_OP_DRV_IN, NULL, 0, timeout,
			       sdkp->max_retries, &exec_args);
	if (res) {
		sd_print_result(sdkp, "Synchronize Cache(10) failed", res);