169b9a
From 04ab93423b97ab5bc175032e0e4e1da288840805 Mon Sep 17 00:00:00 2001
169b9a
From: John Snow <jsnow@redhat.com>
169b9a
Date: Thu, 2 Aug 2018 15:53:34 +0200
169b9a
Subject: [PATCH 1/4] scsi-disk: support reporting of rotation rate
169b9a
169b9a
RH-Author: John Snow <jsnow@redhat.com>
169b9a
Message-id: <20180802155336.10347-2-jsnow@redhat.com>
169b9a
Patchwork-id: 81613
169b9a
O-Subject: [RHEL-7.6 qemu-kvm PATCH 1/3] scsi-disk: support reporting of rotation rate
169b9a
Bugzilla: 1583807
169b9a
RH-Acked-by: Daniel P. Berrange <berrange@redhat.com>
169b9a
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
169b9a
RH-Acked-by: Thomas Huth <thuth@redhat.com>
169b9a
169b9a
From: "Daniel P. Berrange" <berrange@redhat.com>
169b9a
169b9a
The Linux kernel will query the SCSI "Block device characteristics"
169b9a
VPD to determine the rotations per minute of the disk. If this has
169b9a
the value 1, it is taken to be an SSD and so Linux sets the
169b9a
'rotational' flag to 0 for the I/O queue and will stop using that
169b9a
disk as a source of random entropy. Other operating systems may
169b9a
also take into account rotation rate when setting up default
169b9a
behaviour.
169b9a
169b9a
Mgmt apps should be able to set the rotation rate for virtualized
169b9a
block devices, based on characteristics of the host storage in use,
169b9a
so that the guest OS gets sensible behaviour out of the box. This
169b9a
patch thus adds a 'rotation-rate' parameter for 'scsi-hd' and
169b9a
'scsi-block' device types. For the latter, this parameter will be
169b9a
ignored unless the host device has TYPE_DISK.
169b9a
169b9a
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
169b9a
Message-Id: <20171004114008.14849-2-berrange@redhat.com>
169b9a
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
169b9a
(cherry picked from commit 070f80095ad5b1143b50d2faffd2b1a84292e00d)
169b9a
Signed-off-by: John Snow <jsnow@redhat.com>
169b9a
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
169b9a
---
169b9a
 hw/scsi/scsi-disk.c | 20 ++++++++++++++++++++
169b9a
 1 file changed, 20 insertions(+)
169b9a
169b9a
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
169b9a
index 8a8b0ab..911c7b7 100644
169b9a
--- a/hw/scsi/scsi-disk.c
169b9a
+++ b/hw/scsi/scsi-disk.c
169b9a
@@ -83,6 +83,14 @@ struct SCSIDiskState
169b9a
     char *product;
169b9a
     bool tray_open;
169b9a
     bool tray_locked;
169b9a
+    /*
169b9a
+     * 0x0000        - rotation rate not reported
169b9a
+     * 0x0001        - non-rotating medium (SSD)
169b9a
+     * 0x0002-0x0400 - reserved
169b9a
+     * 0x0401-0xffe  - rotations per minute
169b9a
+     * 0xffff        - reserved
169b9a
+     */
169b9a
+    uint16_t rotation_rate;
169b9a
 };
169b9a
 
169b9a
 static int scsi_handle_rw_error(SCSIDiskReq *r, int error);
169b9a
@@ -565,6 +573,7 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
169b9a
             outbuf[buflen++] = 0x83; // device identification
169b9a
             if (s->qdev.type == TYPE_DISK) {
169b9a
                 outbuf[buflen++] = 0xb0; // block limits
169b9a
+                outbuf[buflen++] = 0xb1; /* block device characteristics */
169b9a
                 outbuf[buflen++] = 0xb2; // thin provisioning
169b9a
             }
169b9a
             break;
169b9a
@@ -670,6 +679,15 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
169b9a
             outbuf[31] = unmap_sectors & 0xff;
169b9a
             break;
169b9a
         }
169b9a
+        case 0xb1: /* block device characteristics */
169b9a
+        {
169b9a
+            buflen = 8;
169b9a
+            outbuf[4] = (s->rotation_rate >> 8) & 0xff;
169b9a
+            outbuf[5] = s->rotation_rate & 0xff;
169b9a
+            outbuf[6] = 0;
169b9a
+            outbuf[7] = 0;
169b9a
+            break;
169b9a
+        }
169b9a
         case 0xb2: /* thin provisioning */
169b9a
         {
169b9a
             buflen = 8;
169b9a
@@ -2543,6 +2561,7 @@ static Property scsi_hd_properties[] = {
169b9a
     DEFINE_PROP_HEX64("wwn", SCSIDiskState, wwn, 0),
169b9a
     DEFINE_PROP_UINT64("max_unmap_size", SCSIDiskState, max_unmap_size,
169b9a
                        DEFAULT_MAX_UNMAP_SIZE),
169b9a
+    DEFINE_PROP_UINT16("rotation_rate", SCSIDiskState, rotation_rate, 0),
169b9a
     DEFINE_BLOCK_CHS_PROPERTIES(SCSIDiskState, qdev.conf),
169b9a
     DEFINE_PROP_END_OF_LIST(),
169b9a
 };
169b9a
@@ -2619,6 +2638,7 @@ static const TypeInfo scsi_cd_info = {
169b9a
 static Property scsi_block_properties[] = {
169b9a
     DEFINE_PROP_DRIVE("drive", SCSIDiskState, qdev.conf.bs),
169b9a
     DEFINE_PROP_INT32("bootindex", SCSIDiskState, qdev.conf.bootindex, -1),
169b9a
+    DEFINE_PROP_UINT16("rotation_rate", SCSIDiskState, rotation_rate, 0),
169b9a
     DEFINE_PROP_END_OF_LIST(),
169b9a
 };
169b9a
 
169b9a
-- 
169b9a
1.8.3.1
169b9a