Merge tag 'for-upstream' of https://repo.or.cz/qemu/kevin into staging
Block layer patches - SCSI passthrough: Fix errors on temporarily suspended dm-multipath # -----BEGIN PGP SIGNATURE----- # # iQJFBAABCgAvFiEE3D3rFZqa+V09dFb+fwmycsiPL9YFAmkxxnERHGt3b2xmQHJl # ZGhhdC5jb20ACgkQfwmycsiPL9YH0Q//QWDBVYFM+3+OW2cXXj9BmWS1xEUmq4L2 # DVkOOOHx2U7SxRvSlCo+4l9Lo4P3+tHimm+ApqEgWES4MOGZG1qCE1gnfA6tvNaR # qkq67DoZ9VShiP5FQwyhXkAUm4cPHFFb8ZIpqc8sH1LGxcoA7hq7bI32RzGsiE3U # pyOD+11z4ARQYqU/YRF8fKqTqwudhgVSIJInBcUCYzuIaUjxl4ZjHxvjRdFMQc2F # OIhJVNAOJ4cpvPspmAmTrwKFU81xjX6ymIqHenjX+ZJ3QtSLtuPaDDYJdGmXu8F9 # Me9OMnZfP4lu4I6L5kO2JpVAnzHppUSUsJcescs1q+dsqhGCR+tPgPUsYCmMlro5 # yoMIxCdAX7aAWI2wjg4TjYrYNI3FRB9+IL2qqHvW2cthkA6C6Ef+/26EIEkMGzsN # rAqyjHa8Bo64JPdW8PUyeg+N27qf9ZwSut8KFR/++hM+sHbm2SImSgqJ+WepgYKx # gIzsXGOOeVQUdbCGXfwzhnzGbOLZMg4nUZDTSnHVvNF/JfdJsgxkm//zFll6PJcH # 3vF7XiA+RoBSea5WiWBaBPWDvDaxsRrkOE/j1GQ/GM8vt6ZK+qplPMBMihXOyfE2 # KS9RwNzhgOAl0XrRpmTVLTLPvZocd9g7XTFiicxIFqJNoMrPNWBSmKEibDMbD5jP # eo87nHrXS0s= # =H7YD # -----END PGP SIGNATURE----- # gpg: Signature made Thu 04 Dec 2025 11:35:45 AM CST # gpg: using RSA key DC3DEB159A9AF95D3D7456FE7F09B272C88F2FD6 # gpg: issuer "kwolf@redhat.com" # gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>" [unknown] # gpg: WARNING: The key's User ID is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: DC3D EB15 9A9A F95D 3D74 56FE 7F09 B272 C88F 2FD6 * tag 'for-upstream' of https://repo.or.cz/qemu/kevin: file-posix: Handle suspended dm-multipath better for SG_IO Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
@@ -4288,25 +4288,8 @@ hdev_open_Mac_error:
|
||||
static bool coroutine_fn sgio_path_error(int ret, sg_io_hdr_t *io_hdr)
|
||||
{
|
||||
if (ret < 0) {
|
||||
switch (ret) {
|
||||
case -ENODEV:
|
||||
return true;
|
||||
case -EAGAIN:
|
||||
/*
|
||||
* The device is probably suspended. This happens while the dm table
|
||||
* is reloaded, e.g. because a path is added or removed. This is an
|
||||
* operation that should complete within 1ms, so just wait a bit and
|
||||
* retry.
|
||||
*
|
||||
* If the device was suspended for another reason, we'll wait and
|
||||
* retry SG_IO_MAX_RETRIES times. This is a tolerable delay before
|
||||
* we return an error and potentially stop the VM.
|
||||
*/
|
||||
qemu_co_sleep_ns(QEMU_CLOCK_REALTIME, 1000000);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
/* Path errors sometimes result in -ENODEV */
|
||||
return ret == -ENODEV;
|
||||
}
|
||||
|
||||
if (io_hdr->host_status != SCSI_HOST_OK) {
|
||||
@@ -4375,6 +4358,7 @@ hdev_co_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
|
||||
{
|
||||
BDRVRawState *s = bs->opaque;
|
||||
RawPosixAIOData acb;
|
||||
uint64_t eagain_sleep_ns = 1 * SCALE_MS;
|
||||
int retries = SG_IO_MAX_RETRIES;
|
||||
int ret;
|
||||
|
||||
@@ -4403,9 +4387,37 @@ hdev_co_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
|
||||
},
|
||||
};
|
||||
|
||||
do {
|
||||
ret = raw_thread_pool_submit(handle_aiocb_ioctl, &acb);
|
||||
} while (req == SG_IO && retries-- && hdev_co_ioctl_sgio_retry(&acb, ret));
|
||||
retry:
|
||||
ret = raw_thread_pool_submit(handle_aiocb_ioctl, &acb);
|
||||
if (req == SG_IO && s->use_mpath) {
|
||||
if (ret == -EAGAIN && eagain_sleep_ns < NANOSECONDS_PER_SECOND) {
|
||||
/*
|
||||
* If this is a multipath device, it is probably suspended.
|
||||
*
|
||||
* This can happen while the dm table is reloaded, e.g. because a
|
||||
* path is added or removed. This is an operation that should
|
||||
* complete within 1ms, so just wait a bit and retry.
|
||||
*
|
||||
* There are also some cases in which libmpathpersist must recover
|
||||
* from path failure during its operation, which can leave the
|
||||
* device suspended for a bit longer while the library brings back
|
||||
* reservations into the expected state.
|
||||
*
|
||||
* Use increasing delays to cover both cases without waiting
|
||||
* excessively, and stop after a bit more than a second (1023 ms).
|
||||
* This is a tolerable delay before we return an error and
|
||||
* potentially stop the VM.
|
||||
*/
|
||||
qemu_co_sleep_ns(QEMU_CLOCK_REALTIME, eagain_sleep_ns);
|
||||
eagain_sleep_ns *= 2;
|
||||
goto retry;
|
||||
}
|
||||
|
||||
/* Even for ret == 0, the SG_IO header can contain an error */
|
||||
if (retries-- && hdev_co_ioctl_sgio_retry(&acb, ret)) {
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user