diff --git a/patches.kabi/scsi_disk-kABI-add-back-members.patch b/patches.kabi/scsi_disk-kABI-add-back-members.patch new file mode 100644 index 0000000..aa7698a --- /dev/null +++ b/patches.kabi/scsi_disk-kABI-add-back-members.patch @@ -0,0 +1,43 @@ +From: Lee Duncan +Date: Fri 10 Mar 2023 09:42:11 AM PST +Subject: [PATCH] scsi_disk kABI: add back members +Patch-mainline: never (kABI patch) +References: bsc#1209092 + +Add back 4 members removed from the scsi_disk structure +by patch scsi-sd-Revert-Rework-asynchronous-resume-support, +but add them with different names to ensure they don't +get used, or if they do we will know. +--- + drivers/scsi/sd.h | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +--- a/drivers/scsi/sd.h ++++ b/drivers/scsi/sd.h +@@ -150,6 +150,26 @@ struct scsi_disk { + unsigned urswrz : 1; + unsigned security : 1; + unsigned ignore_medium_access_errors : 1; ++ ++ /* ++ * these 4 fields have been removed when commit ++ * 785538bfdd682c8e was backported, but are being ++ * added back in for (1) kABI checking, and ++ * (2) so that the struct doesn't change size, but ++ * they are added with name changes, in case some ++ * module tries to use them. ++ */ ++#ifdef __GENKSYMS__ ++ int start_result; ++ u32 start_sense_len; ++ u8 start_sense_buffer[SCSI_SENSE_BUFFERSIZE]; ++ struct work_struct start_done_work; ++#else ++ int start_result_not_used; ++ u32 start_sense_len_not_used; ++ u8 start_sense_buffer_not_used[SCSI_SENSE_BUFFERSIZE]; ++ struct work_struct start_done_work_not_used; ++#endif + }; + #define to_scsi_disk(obj) container_of(obj, struct scsi_disk, disk_dev) + diff --git a/patches.suse/scsi-sd-Revert-Rework-asynchronous-resume-support.patch b/patches.suse/scsi-sd-Revert-Rework-asynchronous-resume-support.patch new file mode 100644 index 0000000..761fd9d --- /dev/null +++ b/patches.suse/scsi-sd-Revert-Rework-asynchronous-resume-support.patch @@ -0,0 +1,199 @@ +From: Bart Van Assche +Date: Tue, 16 Aug 2022 10:26:38 -0700 +Subject: scsi: sd: Revert "Rework asynchronous resume support" +Git-commit: 785538bfdd682c8e962341d585f9b88262a0475e +Patch-mainline: v6.0-rc3 +References: bsc#1209092 + +Although commit 88f1669019bd ("scsi: sd: Rework asynchronous resume support") +eliminates a delay for some ATA disks after resume, it causes resume of ATA +disks to fail on other setups. See also: + + * "Resume process hangs for 5-6 seconds starting sometime in 5.16" + (https://bugzilla.kernel.org/show_bug.cgi?id=215880). + + * Geert's regression report + (https://lore.kernel.org/linux-scsi/alpine.DEB.2.22.394.2207191125130.1006766@ramsan.of.borg/). + +This is what I understand about this issue: + + * During resume, ata_port_pm_resume() starts the SCSI error handler. This + changes the SCSI host state into SHOST_RECOVERY and causes + scsi_queue_rq() to return BLK_STS_RESOURCE. + + * sd_resume() calls sd_start_stop_device() for ATA devices. That function + in turn calls sd_submit_start() which tries to submit a START STOP UNIT + command. That command can only be submitted after the SCSI error handler + has changed the SCSI host state back to SHOST_RUNNING. + + * The SCSI error handler runs on its own thread and calls + schedule_work(&(ap->scsi_rescan_task)). That causes + ata_scsi_dev_rescan() to be called from the context of a kernel + workqueue. That call hangs in blk_mq_get_tag(). I'm not sure why - maybe + because all available tags have been allocated by sd_submit_start() + calls (this is a guess). + +Link: https://lore.kernel.org/r/20220816172638.538734-1-bvanassche@acm.org +Fixes: 88f1669019bd ("scsi: sd: Rework asynchronous resume support") +Cc: Damien Le Moal +Cc: Hannes Reinecke +Cc: Geert Uytterhoeven +Cc: gzhqyz@gmail.com +Reported-by: Geert Uytterhoeven +Reported-by: gzhqyz@gmail.com +Reported-and-tested-by: Vlastimil Babka +Tested-by: John Garry +Tested-by: Hans de Goede +Signed-off-by: Bart Van Assche +Signed-off-by: Martin K. Petersen +Acked-by: Lee Duncan +--- + drivers/scsi/sd.c | 84 ++++++++++++------------------------------------------- + drivers/scsi/sd.h | 5 ---- + 2 files changed, 18 insertions(+), 71 deletions(-) + +diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c +index 8f79fa6318fe..eb76ba055021 100644 +--- a/drivers/scsi/sd.c ++++ b/drivers/scsi/sd.c +@@ -103,7 +103,6 @@ static void sd_config_discard(struct scsi_disk *, unsigned int); + static void sd_config_write_same(struct scsi_disk *); + static int sd_revalidate_disk(struct gendisk *); + static void sd_unlock_native_capacity(struct gendisk *disk); +-static void sd_start_done_work(struct work_struct *work); + static int sd_probe(struct device *); + static int sd_remove(struct device *); + static void sd_shutdown(struct device *); +@@ -3471,7 +3470,6 @@ static int sd_probe(struct device *dev) + sdkp->max_retries = SD_MAX_RETRIES; + atomic_set(&sdkp->openers, 0); + atomic_set(&sdkp->device->ioerr_cnt, 0); +- INIT_WORK(&sdkp->start_done_work, sd_start_done_work); + + if (!sdp->request_queue->rq_timeout) { + if (sdp->type != TYPE_MOD) +@@ -3594,69 +3592,12 @@ static void scsi_disk_release(struct device *dev) + kfree(sdkp); + } + +-/* Process sense data after a START command finished. */ +-static void sd_start_done_work(struct work_struct *work) +-{ +- struct scsi_disk *sdkp = container_of(work, typeof(*sdkp), +- start_done_work); +- struct scsi_sense_hdr sshdr; +- int res = sdkp->start_result; +- +- if (res == 0) +- return; +- +- sd_print_result(sdkp, "Start/Stop Unit failed", res); +- +- if (res < 0) +- return; +- +- if (scsi_normalize_sense(sdkp->start_sense_buffer, +- sdkp->start_sense_len, &sshdr)) +- sd_print_sense_hdr(sdkp, &sshdr); +-} +- +-/* A START command finished. May be called from interrupt context. */ +-static void sd_start_done(struct request *req, blk_status_t status) +-{ +- const struct scsi_cmnd *scmd = blk_mq_rq_to_pdu(req); +- struct scsi_disk *sdkp = scsi_disk(req->q->disk); +- +- sdkp->start_result = scmd->result; +- WARN_ON_ONCE(scmd->sense_len > SCSI_SENSE_BUFFERSIZE); +- sdkp->start_sense_len = scmd->sense_len; +- memcpy(sdkp->start_sense_buffer, scmd->sense_buffer, +- ARRAY_SIZE(sdkp->start_sense_buffer)); +- WARN_ON_ONCE(!schedule_work(&sdkp->start_done_work)); +-} +- +-/* Submit a START command asynchronously. */ +-static int sd_submit_start(struct scsi_disk *sdkp, u8 cmd[], u8 cmd_len) +-{ +- struct scsi_device *sdev = sdkp->device; +- struct request_queue *q = sdev->request_queue; +- struct request *req; +- struct scsi_cmnd *scmd; +- +- req = scsi_alloc_request(q, REQ_OP_DRV_IN, BLK_MQ_REQ_PM); +- if (IS_ERR(req)) +- return PTR_ERR(req); +- +- scmd = blk_mq_rq_to_pdu(req); +- scmd->cmd_len = cmd_len; +- memcpy(scmd->cmnd, cmd, cmd_len); +- scmd->allowed = sdkp->max_retries; +- req->timeout = SD_TIMEOUT; +- req->rq_flags |= RQF_PM | RQF_QUIET; +- req->end_io = sd_start_done; +- blk_execute_rq_nowait(req, /*at_head=*/true); +- +- return 0; +-} +- + static int sd_start_stop_device(struct scsi_disk *sdkp, int start) + { + unsigned char cmd[6] = { START_STOP }; /* START_VALID */ ++ struct scsi_sense_hdr sshdr; + struct scsi_device *sdp = sdkp->device; ++ int res; + + if (start) + cmd[4] |= 1; /* START */ +@@ -3667,10 +3608,23 @@ static int sd_start_stop_device(struct scsi_disk *sdkp, int start) + if (!scsi_device_online(sdp)) + return -ENODEV; + +- /* Wait until processing of sense data has finished. */ +- flush_work(&sdkp->start_done_work); ++ res = scsi_execute(sdp, cmd, DMA_NONE, NULL, 0, NULL, &sshdr, ++ SD_TIMEOUT, sdkp->max_retries, 0, RQF_PM, NULL); ++ if (res) { ++ sd_print_result(sdkp, "Start/Stop Unit failed", res); ++ if (res > 0 && scsi_sense_valid(&sshdr)) { ++ sd_print_sense_hdr(sdkp, &sshdr); ++ /* 0x3a is medium not present */ ++ if (sshdr.asc == 0x3a) ++ res = 0; ++ } ++ } + +- return sd_submit_start(sdkp, cmd, sizeof(cmd)); ++ /* SCSI error codes must not go to the generic layer */ ++ if (res) ++ return -EIO; ++ ++ return 0; + } + + /* +@@ -3697,8 +3651,6 @@ static void sd_shutdown(struct device *dev) + sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n"); + sd_start_stop_device(sdkp, 0); + } +- +- flush_work(&sdkp->start_done_work); + } + + static int sd_suspend_common(struct device *dev, bool ignore_stop_errors) +diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h +index b89187761d61..5eea762f84d1 100644 +--- a/drivers/scsi/sd.h ++++ b/drivers/scsi/sd.h +@@ -150,11 +150,6 @@ struct scsi_disk { + unsigned urswrz : 1; + unsigned security : 1; + unsigned ignore_medium_access_errors : 1; +- +- int start_result; +- u32 start_sense_len; +- u8 start_sense_buffer[SCSI_SENSE_BUFFERSIZE]; +- struct work_struct start_done_work; + }; + #define to_scsi_disk(obj) container_of(obj, struct scsi_disk, disk_dev) + + diff --git a/series.conf b/series.conf index 3af04f3..46f3aac 100644 --- a/series.conf +++ b/series.conf @@ -33015,6 +33015,7 @@ patches.suse/scsi-megaraid_sas-Remove-unnecessary-kfree.patch patches.suse/msft-hv-2639-scsi-storvsc-Remove-WQ_MEM_RECLAIM-from-storvsc_erro.patch patches.suse/scsi-core-Fix-passthrough-retry-counter-handling.patch + patches.suse/scsi-sd-Revert-Rework-asynchronous-resume-support.patch patches.suse/0009-blk-mq-fix-io-hung-due-to-missing-commit_rqs.patch patches.suse/loop-Check-for-overflow-while-configuring-loop.patch patches.suse/0249-md-Flush-workqueue-md_rdev_misc_wq-in-md_alloc.patch @@ -37408,6 +37409,7 @@ ######################################################## patches.rpmify/BTF-Don-t-break-ABI-when-debuginfo-is-disabled.patch patches.kabi/fb_deferred_io-kABI-workaround.patch + patches.kabi/scsi_disk-kABI-add-back-members.patch ######################################################## # SLE15-SP3 OOT performance patches evaluated but left