[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Stable-7.2.15 08/33] scsi: fetch unit attention when creating the reque
From: |
Michael Tokarev |
Subject: |
[Stable-7.2.15 08/33] scsi: fetch unit attention when creating the request |
Date: |
Sat, 9 Nov 2024 09:38:34 +0300 |
From: Stefano Garzarella <sgarzare@redhat.com>
Commit 1880ad4f4e ("virtio-scsi: Batched prepare for cmd reqs") split
calls to scsi_req_new() and scsi_req_enqueue() in the virtio-scsi device.
No ill effects were observed until commit 8cc5583abe ("virtio-scsi: Send
"REPORTED LUNS CHANGED" sense data upon disk hotplug events") added a
unit attention that was easy to trigger with device hotplug and
hot-unplug.
Because the two calls were separated, all requests in the batch were
prepared calling scsi_req_new() to report a sense. The first one
submitted would report the right sense and reset it to NO_SENSE, while
the others reported CHECK_CONDITION with no sense data. This caused
SCSI errors in Linux.
To solve this issue, let's fetch the unit attention as early as possible
when we prepare the request, so that only the first request in the batch
will use the unit attention SCSIReqOps and the others will not report
CHECK CONDITION.
Fixes: 1880ad4f4e ("virtio-scsi: Batched prepare for cmd reqs")
Fixes: 8cc5583abe ("virtio-scsi: Send "REPORTED LUNS CHANGED" sense data upon
disk hotplug events")
Reported-by: Thomas Huth <thuth@redhat.com>
Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=2176702
Co-developed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
Message-ID: <20230712134352.118655-2-sgarzare@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 9472083e642bfb9bc836b38662baddd9bc964ebc)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index e5c9f7a53d..e76bfbd47b 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -413,19 +413,35 @@ static const struct SCSIReqOps reqops_invalid_opcode = {
/* SCSIReqOps implementation for unit attention conditions. */
-static int32_t scsi_unit_attention(SCSIRequest *req, uint8_t *buf)
+static void scsi_fetch_unit_attention_sense(SCSIRequest *req)
{
+ SCSISense *ua = NULL;
+
if (req->dev->unit_attention.key == UNIT_ATTENTION) {
- scsi_req_build_sense(req, req->dev->unit_attention);
+ ua = &req->dev->unit_attention;
} else if (req->bus->unit_attention.key == UNIT_ATTENTION) {
- scsi_req_build_sense(req, req->bus->unit_attention);
+ ua = &req->bus->unit_attention;
}
+
+ /*
+ * Fetch the unit attention sense immediately so that another
+ * scsi_req_new does not use reqops_unit_attention.
+ */
+ if (ua) {
+ scsi_req_build_sense(req, *ua);
+ *ua = SENSE_CODE(NO_SENSE);
+ }
+}
+
+static int32_t scsi_unit_attention(SCSIRequest *req, uint8_t *buf)
+{
scsi_req_complete(req, CHECK_CONDITION);
return 0;
}
static const struct SCSIReqOps reqops_unit_attention = {
.size = sizeof(SCSIRequest),
+ .init_req = scsi_fetch_unit_attention_sense,
.send_command = scsi_unit_attention
};
@@ -699,6 +715,11 @@ SCSIRequest *scsi_req_alloc(const SCSIReqOps *reqops,
SCSIDevice *d,
object_ref(OBJECT(d));
object_ref(OBJECT(qbus->parent));
notifier_list_init(&req->cancel_notifiers);
+
+ if (reqops->init_req) {
+ reqops->init_req(req);
+ }
+
trace_scsi_req_alloc(req->dev->id, req->lun, req->tag);
return req;
}
@@ -798,6 +819,15 @@ uint8_t *scsi_req_get_buf(SCSIRequest *req)
static void scsi_clear_unit_attention(SCSIRequest *req)
{
SCSISense *ua;
+
+ /*
+ * scsi_fetch_unit_attention_sense() already cleaned the unit attention
+ * in this case.
+ */
+ if (req->ops == &reqops_unit_attention) {
+ return;
+ }
+
if (req->dev->unit_attention.key != UNIT_ATTENTION &&
req->bus->unit_attention.key != UNIT_ATTENTION) {
return;
diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h
index 6ea4b64fe7..60bc32da32 100644
--- a/include/hw/scsi/scsi.h
+++ b/include/hw/scsi/scsi.h
@@ -108,6 +108,7 @@ int cdrom_read_toc_raw(int nb_sectors, uint8_t *buf, int
msf, int session_num);
/* scsi-bus.c */
struct SCSIReqOps {
size_t size;
+ void (*init_req)(SCSIRequest *req);
void (*free_req)(SCSIRequest *req);
int32_t (*send_command)(SCSIRequest *req, uint8_t *buf);
void (*read_data)(SCSIRequest *req);
--
2.39.5
- [Stable-7.2.15 v1 00/33] Patch Round-up for stable 7.2.15, freeze on 2024-11-18, Michael Tokarev, 2024/11/09
- [Stable-7.2.15 01/33] softmmu/physmem.c: Keep transaction attribute in address_space_map(), Michael Tokarev, 2024/11/09
- [Stable-7.2.15 04/33] fuzz: disable leak-detection for oss-fuzz builds, Michael Tokarev, 2024/11/09
- [Stable-7.2.15 03/33] block/reqlist: allow adding overlapping requests, Michael Tokarev, 2024/11/09
- [Stable-7.2.15 02/33] target/ppc: Fix lxvx/stxvx facility check, Michael Tokarev, 2024/11/09
- [Stable-7.2.15 05/33] tracetool: avoid invalid escape in Python string, Michael Tokarev, 2024/11/09
- [Stable-7.2.15 06/33] linux-user/flatload: Take mmap_lock in load_flt_binary(), Michael Tokarev, 2024/11/09
- [Stable-7.2.15 08/33] scsi: fetch unit attention when creating the request,
Michael Tokarev <=
- [Stable-7.2.15 10/33] hw/audio/hda: free timer on exit, Michael Tokarev, 2024/11/09
- [Stable-7.2.15 09/33] hw/intc/arm_gicv3_cpuif: Add cast to match the documentation, Michael Tokarev, 2024/11/09
- [Stable-7.2.15 07/33] linux-user: Fix parse_elf_properties GNU0_MAGIC check, Michael Tokarev, 2024/11/09
- [Stable-7.2.15 11/33] KVM: Dynamic sized kvm memslots array, Michael Tokarev, 2024/11/09
- [Stable-7.2.15 14/33] raw-format: Fix error message for invalid offset/size, Michael Tokarev, 2024/11/09
- [Stable-7.2.15 13/33] tests: Wait for migration completion on destination QEMU to avoid failures, Michael Tokarev, 2024/11/09
- [Stable-7.2.15 12/33] accel/kvm: check for KVM_CAP_READONLY_MEM on VM, Michael Tokarev, 2024/11/09
- [Stable-7.2.15 16/33] target/i386: Avoid unreachable variable declaration in mmu_translate(), Michael Tokarev, 2024/11/09
- [Stable-7.2.15 15/33] tcg: Reset data_gen_ptr correctly, Michael Tokarev, 2024/11/09
- [Stable-7.2.15 17/33] target/i386: Walk NPT in guest real mode, Michael Tokarev, 2024/11/09