Blame SOURCES/kvm-scsi-disk-add-UNMAP-limits-to-block-limits-VPD-page.patch

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