Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Step:15-SP6
qemu.28166
scsi-make-io_timeout-settable.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File scsi-make-io_timeout-settable.patch of Package qemu.28166
From: Hannes Reinecke <hare@suse.de> Date: Thu, 29 Oct 2020 12:41:21 +0100 Subject: scsi: make io_timeout settable References: bsc#1178049,bsc#1194938 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: Lin Ma <lma@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 e2eb7f1b3967fecc70d05de84ace..9057fc26b37e18c7344018e86ef3 100644 --- a/hw/scsi/scsi-disk.c +++ b/hw/scsi/scsi-disk.c @@ -51,6 +51,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" @@ -2629,7 +2630,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; } @@ -2790,7 +2791,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; @@ -3108,6 +3109,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 bdc01b2ef9e5d7555b60cdbfb078..4d106a6885e2361286b4dfa3292f 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; @@ -507,7 +509,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]; @@ -522,7 +524,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) { @@ -552,7 +554,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 @@ -588,7 +590,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; } @@ -639,7 +641,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; } @@ -729,6 +731,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 09fa5c9d2a03f35f876e83f21373..b3ad910a85b656917284b36ab915 100644 --- a/include/hw/scsi/scsi.h +++ b/include/hw/scsi/scsi.h @@ -84,6 +84,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; }; @@ -188,7 +189,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); SCSIDevice *scsi_device_get(SCSIBus *bus, int channel, int target, int lun);
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