Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15-SP7:GA
qemu.21548
scsi-make-io_timeout-settable.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File scsi-make-io_timeout-settable.patch of Package qemu.21548
From: Hannes Reinecke <hare@suse.de> Date: Thu, 29 Oct 2020 12:41:21 +0100 Subject: scsi: make io_timeout settable References: bsc#1178049 Add an 'io_timeout' parameter for SCSIDevice to allow SG_IO ioctls to pass in a timeout, avoiding infinite guest stalls if the host needs to abort a command. Signed-off-by: Hannes Reinecke <hare@suse.de> Signed-off-by: Bruce Rogers <brogers@suse.com> --- hw/scsi/scsi-disk.c | 7 +++++-- hw/scsi/scsi-generic.c | 15 +++++++++------ include/hw/scsi/scsi.h | 3 ++- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c index e44c61eeb46f72989a7bc42bb8fa..29eb2e6629297342f34bac5d98bd 100644 --- a/hw/scsi/scsi-disk.c +++ b/hw/scsi/scsi-disk.c @@ -50,6 +50,7 @@ #define DEFAULT_DISCARD_GRANULARITY (4 * KiB) #define DEFAULT_MAX_UNMAP_SIZE (1 * GiB) +#define DEFAULT_IO_TIMEOUT UINT_MAX /* Infinity */ #define DEFAULT_MAX_IO_SIZE INT_MAX /* 2 GB - 1 block */ #define TYPE_SCSI_DISK_BASE "scsi-disk-base" @@ -2610,7 +2611,7 @@ static int get_device_type(SCSIDiskState *s) cmd[4] = sizeof(buf); ret = scsi_SG_IO_FROM_DEV(s->qdev.conf.blk, cmd, sizeof(cmd), - buf, sizeof(buf)); + buf, sizeof(buf), s->qdev.io_timeout); if (ret < 0) { return -1; } @@ -2771,7 +2772,7 @@ static BlockAIOCB *scsi_block_do_sgio(SCSIBlockReq *req, /* The rest is as in scsi-generic.c. */ io_header->mx_sb_len = sizeof(r->req.sense); io_header->sbp = r->req.sense; - io_header->timeout = UINT_MAX; + io_header->timeout = s->qdev.io_timeout; io_header->usr_ptr = r; io_header->flags |= SG_FLAG_DIRECT_IO; @@ -3089,6 +3090,8 @@ static Property scsi_block_properties[] = { DEFAULT_MAX_IO_SIZE), DEFINE_PROP_INT32("scsi_version", SCSIDiskState, qdev.default_scsi_version, -1), + DEFINE_PROP_UINT32("io_timeout", SCSIDiskState, qdev.io_timeout, + DEFAULT_IO_TIMEOUT), DEFINE_PROP_END_OF_LIST(), }; diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c index e7798ebcd0d41f13b4cf28f9a40f..3027885538ad20f8cddbad8c4026 100644 --- a/hw/scsi/scsi-generic.c +++ b/hw/scsi/scsi-generic.c @@ -114,6 +114,8 @@ static int execute_command(BlockBackend *blk, SCSIGenericReq *r, int direction, BlockCompletionFunc *complete) { + SCSIDevice *s = r->req.dev; + r->io_header.interface_id = 'S'; r->io_header.dxfer_direction = direction; r->io_header.dxferp = r->buf; @@ -122,7 +124,7 @@ static int execute_command(BlockBackend *blk, r->io_header.cmd_len = r->req.cmd.len; r->io_header.mx_sb_len = sizeof(r->req.sense); r->io_header.sbp = r->req.sense; - r->io_header.timeout = MAX_UINT; + r->io_header.timeout = s->io_timeout; r->io_header.usr_ptr = r; r->io_header.flags |= SG_FLAG_DIRECT_IO; @@ -503,7 +505,7 @@ static int read_naa_id(const uint8_t *p, uint64_t *p_wwn) } int scsi_SG_IO_FROM_DEV(BlockBackend *blk, uint8_t *cmd, uint8_t cmd_size, - uint8_t *buf, uint8_t buf_size) + uint8_t *buf, uint8_t buf_size, uint32_t timeout) { sg_io_hdr_t io_header; uint8_t sensebuf[8]; @@ -518,7 +520,7 @@ int scsi_SG_IO_FROM_DEV(BlockBackend *blk, uint8_t *cmd, uint8_t cmd_size, io_header.cmd_len = cmd_size; io_header.mx_sb_len = sizeof(sensebuf); io_header.sbp = sensebuf; - io_header.timeout = 6000; /* XXX */ + io_header.timeout = timeout; ret = blk_ioctl(blk, SG_IO, &io_header); if (ret < 0 || io_header.driver_status || io_header.host_status) { @@ -548,7 +550,7 @@ static void scsi_generic_set_vpd_bl_emulation(SCSIDevice *s) cmd[4] = sizeof(buf); ret = scsi_SG_IO_FROM_DEV(s->conf.blk, cmd, sizeof(cmd), - buf, sizeof(buf)); + buf, sizeof(buf), s->io_timeout); if (ret < 0) { /* * Do not assume anything if we can't retrieve the @@ -584,7 +586,7 @@ static void scsi_generic_read_device_identification(SCSIDevice *s) cmd[4] = sizeof(buf); ret = scsi_SG_IO_FROM_DEV(s->conf.blk, cmd, sizeof(cmd), - buf, sizeof(buf)); + buf, sizeof(buf), s->io_timeout); if (ret < 0) { return; } @@ -635,7 +637,7 @@ static int get_stream_blocksize(BlockBackend *blk) cmd[0] = MODE_SENSE; cmd[4] = sizeof(buf); - ret = scsi_SG_IO_FROM_DEV(blk, cmd, sizeof(cmd), buf, sizeof(buf)); + ret = scsi_SG_IO_FROM_DEV(blk, cmd, sizeof(cmd), buf, sizeof(buf), 60); if (ret < 0) { return -1; } @@ -725,6 +727,7 @@ static void scsi_generic_realize(SCSIDevice *s, Error **errp) /* Only used by scsi-block, but initialize it nevertheless to be clean. */ s->default_scsi_version = -1; + s->io_timeout = 30000; scsi_generic_read_device_inquiry(s); } diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h index 332ef602f41385fbab533143dbbc..ead723690114f847d0d3638c3c2e 100644 --- a/include/hw/scsi/scsi.h +++ b/include/hw/scsi/scsi.h @@ -88,6 +88,7 @@ struct SCSIDevice uint64_t port_wwn; int scsi_version; int default_scsi_version; + uint32_t io_timeout; bool needs_vpd_bl_emulation; bool hba_supports_iothread; }; @@ -192,7 +193,7 @@ void scsi_device_unit_attention_reported(SCSIDevice *dev); void scsi_generic_read_device_inquiry(SCSIDevice *dev); int scsi_device_get_sense(SCSIDevice *dev, uint8_t *buf, int len, bool fixed); int scsi_SG_IO_FROM_DEV(BlockBackend *blk, uint8_t *cmd, uint8_t cmd_size, - uint8_t *buf, uint8_t buf_size); + uint8_t *buf, uint8_t buf_size, uint32_t timeout); SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int target, int lun); /* scsi-generic.c. */
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor