mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-03 15:53:54 -06:00
scsi: make io_timeout configurable
The current code sets an infinite timeout on SG_IO requests, causing the guest to stall if the host experiences a frame loss. This patch adds an 'io_timeout' parameter for SCSIDevice to make the SG_IO timeout configurable, and also shortens the default timeout to 30 seconds to avoid infinite stalls. Signed-off-by: Hannes Reinecke <hare@suse.de> Message-Id: <20201116183114.55703-3-hare@suse.de> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
106ad1f9c5
commit
c9b6609b69
3 changed files with 18 additions and 9 deletions
|
@ -115,6 +115,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;
|
||||
|
@ -123,7 +125,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 * 1000;
|
||||
r->io_header.usr_ptr = r;
|
||||
r->io_header.flags |= SG_FLAG_DIRECT_IO;
|
||||
|
||||
|
@ -506,7 +508,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];
|
||||
|
@ -521,7 +523,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 * 1000;
|
||||
|
||||
ret = blk_ioctl(blk, SG_IO, &io_header);
|
||||
if (ret < 0 || io_header.driver_status || io_header.host_status) {
|
||||
|
@ -551,7 +553,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
|
||||
|
@ -587,7 +589,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;
|
||||
}
|
||||
|
@ -638,7 +640,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), 6);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -728,6 +730,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 = DEFAULT_IO_TIMEOUT;
|
||||
scsi_generic_read_device_inquiry(s);
|
||||
}
|
||||
|
||||
|
@ -751,6 +754,8 @@ static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
|
|||
static Property scsi_generic_properties[] = {
|
||||
DEFINE_PROP_DRIVE("drive", SCSIDevice, conf.blk),
|
||||
DEFINE_PROP_BOOL("share-rw", SCSIDevice, conf.share_rw, false),
|
||||
DEFINE_PROP_UINT32("io_timeout", SCSIDevice, io_timeout,
|
||||
DEFAULT_IO_TIMEOUT),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue