yeahuh / rpms / qemu-kvm

Forked from rpms/qemu-kvm 2 years ago
Clone
9ae3a8
From de979b1f256be8488f49a78646dee1ded06251ef Mon Sep 17 00:00:00 2001
9ae3a8
From: Paolo Bonzini <pbonzini@redhat.com>
9ae3a8
Date: Mon, 20 Jan 2014 12:49:40 +0100
9ae3a8
Subject: [PATCH 2/4] scsi-disk: add UNMAP limits to block limits VPD page
9ae3a8
9ae3a8
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
9ae3a8
Message-id: <1390222180-24891-1-git-send-email-pbonzini@redhat.com>
9ae3a8
Patchwork-id: 56831
9ae3a8
O-Subject: [RHEL 7.0 qemu-kvm PATCH] scsi-disk: add UNMAP limits to block limits VPD page
9ae3a8
Bugzilla: 1037503
9ae3a8
RH-Acked-by: Orit Wasserman <owasserm@redhat.com>
9ae3a8
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
9ae3a8
RH-Acked-by: Fam Zheng <famz@redhat.com>
9ae3a8
9ae3a8
Bugzilla: 1037503
9ae3a8
9ae3a8
Brew build: 6896455
9ae3a8
9ae3a8
Linux prefers WRITE SAME to UNMAP if the limits are zero, and WRITE
9ae3a8
SAME does not discard anything unless the device can guarantee that
9ae3a8
the resulting block is zero.
9ae3a8
9ae3a8
Setting the maximum unmap block and descriptor counts to non-zero
9ae3a8
makes Linux choose UNMAP and fixes thin provisioning on glusterfs.
9ae3a8
9ae3a8
While the maximum unmap block count can have some effect on performance,
9ae3a8
the (suggested) maximum number of descriptors is not particularly
9ae3a8
important so I didn't add a customization option.  SCSI drivers are
9ae3a8
used to online firmware updates so I'm not yet adding versioning support
9ae3a8
for SCSI, but we're probably getting close to the point when it's worth
9ae3a8
thinking about it.
9ae3a8
9ae3a8
Reported-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
9ae3a8
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
9ae3a8
(cherry picked from commit 8a1bd2973ed5f99a3c37c9afdff823c4a22152b1)
9ae3a8
---
9ae3a8
 hw/scsi/scsi-disk.c | 20 ++++++++++++++++++++
9ae3a8
 1 file changed, 20 insertions(+)
9ae3a8
9ae3a8
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
9ae3a8
---
9ae3a8
 hw/scsi/scsi-disk.c |   20 ++++++++++++++++++++
9ae3a8
 1 files changed, 20 insertions(+), 0 deletions(-)
9ae3a8
9ae3a8
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
9ae3a8
index 7653411..bce617c 100644
9ae3a8
--- a/hw/scsi/scsi-disk.c
9ae3a8
+++ b/hw/scsi/scsi-disk.c
9ae3a8
@@ -47,6 +47,7 @@ do { printf("scsi-disk: " fmt , ## __VA_ARGS__); } while (0)
9ae3a8
 #define SCSI_MAX_MODE_LEN           256
9ae3a8
 
9ae3a8
 #define DEFAULT_DISCARD_GRANULARITY 4096
9ae3a8
+#define DEFAULT_MAX_UNMAP_SIZE      (1 << 30)   /* 1 GB */
9ae3a8
 
9ae3a8
 typedef struct SCSIDiskState SCSIDiskState;
9ae3a8
 
9ae3a8
@@ -74,6 +75,7 @@ struct SCSIDiskState
9ae3a8
     bool media_event;
9ae3a8
     bool eject_request;
9ae3a8
     uint64_t wwn;
9ae3a8
+    uint64_t max_unmap_size;
9ae3a8
     QEMUBH *bh;
9ae3a8
     char *version;
9ae3a8
     char *serial;
9ae3a8
@@ -625,6 +627,8 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
9ae3a8
                     s->qdev.conf.min_io_size / s->qdev.blocksize;
9ae3a8
             unsigned int opt_io_size =
9ae3a8
                     s->qdev.conf.opt_io_size / s->qdev.blocksize;
9ae3a8
+            unsigned int max_unmap_sectors =
9ae3a8
+                    s->max_unmap_size / s->qdev.blocksize;
9ae3a8
 
9ae3a8
             if (s->qdev.type == TYPE_ROM) {
9ae3a8
                 DPRINTF("Inquiry (EVPD[%02X] not supported for CDROM\n",
9ae3a8
@@ -647,6 +651,18 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
9ae3a8
             outbuf[14] = (opt_io_size >> 8) & 0xff;
9ae3a8
             outbuf[15] = opt_io_size & 0xff;
9ae3a8
 
9ae3a8
+            /* max unmap LBA count, default is 1GB */
9ae3a8
+            outbuf[20] = (max_unmap_sectors >> 24) & 0xff;
9ae3a8
+            outbuf[21] = (max_unmap_sectors >> 16) & 0xff;
9ae3a8
+            outbuf[22] = (max_unmap_sectors >> 8) & 0xff;
9ae3a8
+            outbuf[23] = max_unmap_sectors & 0xff;
9ae3a8
+
9ae3a8
+            /* max unmap descriptors, 255 fit in 4 kb with an 8-byte header.  */
9ae3a8
+            outbuf[24] = 0;
9ae3a8
+            outbuf[25] = 0;
9ae3a8
+            outbuf[26] = 0;
9ae3a8
+            outbuf[27] = 255;
9ae3a8
+
9ae3a8
             /* optimal unmap granularity */
9ae3a8
             outbuf[28] = (unmap_sectors >> 24) & 0xff;
9ae3a8
             outbuf[29] = (unmap_sectors >> 16) & 0xff;
9ae3a8
@@ -2519,6 +2535,8 @@ static Property scsi_hd_properties[] = {
9ae3a8
     DEFINE_PROP_BIT("dpofua", SCSIDiskState, features,
9ae3a8
                     SCSI_DISK_F_DPOFUA, false),
9ae3a8
     DEFINE_PROP_HEX64("wwn", SCSIDiskState, wwn, 0),
9ae3a8
+    DEFINE_PROP_UINT64("max_unmap_size", SCSIDiskState, max_unmap_size,
9ae3a8
+                       DEFAULT_MAX_UNMAP_SIZE),
9ae3a8
     DEFINE_BLOCK_CHS_PROPERTIES(SCSIDiskState, qdev.conf),
9ae3a8
     DEFINE_PROP_END_OF_LIST(),
9ae3a8
 };
9ae3a8
@@ -2628,6 +2646,8 @@ static Property scsi_disk_properties[] = {
9ae3a8
     DEFINE_PROP_BIT("dpofua", SCSIDiskState, features,
9ae3a8
                     SCSI_DISK_F_DPOFUA, false),
9ae3a8
     DEFINE_PROP_HEX64("wwn", SCSIDiskState, wwn, 0),
9ae3a8
+    DEFINE_PROP_UINT64("max_unmap_size", SCSIDiskState, max_unmap_size,
9ae3a8
+                       DEFAULT_MAX_UNMAP_SIZE),
9ae3a8
     DEFINE_PROP_END_OF_LIST(),
9ae3a8
 };
9ae3a8
 
9ae3a8
-- 
9ae3a8
1.7.1
9ae3a8