hw/scsi/scsi-bus.c | 10 ++++++++-- include/hw/scsi/scsi.h | 1 + 2 files changed, 9 insertions(+), 2 deletions(-)
A large number of I/Os are delivered during disk capacity expansion.
Many I/Os are extracted from the Vring ring, and each one registers
reqops_unit_attention when new scsi req.
If the first registered req takes the ua, the ua is cleared
and other registered req is return 0 sense.
Let's add req_has_ua to avoid this kind of thing.
Signed-off-by: suruifeng <suruifeng@huawei.com>
Signed-off-by: Jie Wang <wangjie88@huawei.com>
---
hw/scsi/scsi-bus.c | 10 ++++++++--
include/hw/scsi/scsi.h | 1 +
2 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index 2a0a98cac9..20ec4a5f74 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -722,7 +722,13 @@ SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
* If we already have a pending unit attention condition,
* report this one before triggering another one.
*/
- !(buf[0] == REQUEST_SENSE && d->sense_is_ua))) {
+ !(buf[0] == REQUEST_SENSE && d->sense_is_ua)) &&
+ /*
+ * If we already have a req register ua ops,
+ * other req can not register.
+ */
+ !d->req_has_ua) {
+ d->req_has_ua = true;
ops = &reqops_unit_attention;
} else if (lun != d->lun ||
buf[0] == REPORT_LUNS ||
@@ -822,7 +828,7 @@ static void scsi_clear_unit_attention(SCSIRequest *req)
ua->ascq == SENSE_CODE(REPORTED_LUNS_CHANGED).ascq)) {
return;
}
-
+ req->dev->req_has_ua = false;
*ua = SENSE_CODE(NO_SENSE);
}
diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h
index 0b726bc78c..3d0cda68f6 100644
--- a/include/hw/scsi/scsi.h
+++ b/include/hw/scsi/scsi.h
@@ -74,6 +74,7 @@ struct SCSIDevice
BlockConf conf;
SCSISense unit_attention;
bool sense_is_ua;
+ bool req_has_ua;
uint8_t sense[SCSI_SENSE_BUF_SIZE];
uint32_t sense_len;
QTAILQ_HEAD(, SCSIRequest) requests;
--
2.23.0
ping.
On 2021/6/29 15:12, Jie Wang wrote:
> A large number of I/Os are delivered during disk capacity expansion.
> Many I/Os are extracted from the Vring ring, and each one registers
> reqops_unit_attention when new scsi req.
> If the first registered req takes the ua, the ua is cleared
> and other registered req is return 0 sense.
>
> Let's add req_has_ua to avoid this kind of thing.
>
> Signed-off-by: suruifeng <suruifeng@huawei.com>
> Signed-off-by: Jie Wang <wangjie88@huawei.com>
> ---
> hw/scsi/scsi-bus.c | 10 ++++++++--
> include/hw/scsi/scsi.h | 1 +
> 2 files changed, 9 insertions(+), 2 deletions(-)
>
> diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
> index 2a0a98cac9..20ec4a5f74 100644
> --- a/hw/scsi/scsi-bus.c
> +++ b/hw/scsi/scsi-bus.c
> @@ -722,7 +722,13 @@ SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
> * If we already have a pending unit attention condition,
> * report this one before triggering another one.
> */
> - !(buf[0] == REQUEST_SENSE && d->sense_is_ua))) {
> + !(buf[0] == REQUEST_SENSE && d->sense_is_ua)) &&
> + /*
> + * If we already have a req register ua ops,
> + * other req can not register.
> + */
> + !d->req_has_ua) {
> + d->req_has_ua = true;
> ops = &reqops_unit_attention;
> } else if (lun != d->lun ||
> buf[0] == REPORT_LUNS ||
> @@ -822,7 +828,7 @@ static void scsi_clear_unit_attention(SCSIRequest *req)
> ua->ascq == SENSE_CODE(REPORTED_LUNS_CHANGED).ascq)) {
> return;
> }
> -
> + req->dev->req_has_ua = false;
> *ua = SENSE_CODE(NO_SENSE);
> }
>
> diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h
> index 0b726bc78c..3d0cda68f6 100644
> --- a/include/hw/scsi/scsi.h
> +++ b/include/hw/scsi/scsi.h
> @@ -74,6 +74,7 @@ struct SCSIDevice
> BlockConf conf;
> SCSISense unit_attention;
> bool sense_is_ua;
> + bool req_has_ua;
> uint8_t sense[SCSI_SENSE_BUF_SIZE];
> uint32_t sense_len;
> QTAILQ_HEAD(, SCSIRequest) requests;
>
© 2016 - 2026 Red Hat, Inc.