|
|
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 |
|