From patchwork Thu Jun 11 17:16:07 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Denis V. Lunev" X-Patchwork-Id: 1307664 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=openvz.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 49jVrm4d8Dz9sRN for ; Fri, 12 Jun 2020 03:16:40 +1000 (AEST) Received: from localhost ([::1]:45334 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jjQof-000436-70 for incoming@patchwork.ozlabs.org; Thu, 11 Jun 2020 13:16:37 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36132) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jjQoI-00040y-J3; Thu, 11 Jun 2020 13:16:14 -0400 Received: from relay.sw.ru ([185.231.240.75]:36378 helo=relay3.sw.ru) by eggs.gnu.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jjQoF-0001g0-Om; Thu, 11 Jun 2020 13:16:14 -0400 Received: from [192.168.15.81] (helo=iris.sw.ru) by relay3.sw.ru with esmtp (Exim 4.93) (envelope-from ) id 1jjQo9-0000E7-NL; Thu, 11 Jun 2020 20:16:05 +0300 From: "Denis V. Lunev" To: qemu-block@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH 1/2] block: propagate discard alignment from format drivers to the guest Date: Thu, 11 Jun 2020 20:16:07 +0300 Message-Id: <20200611171608.22052-2-den@openvz.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200611171608.22052-1-den@openvz.org> References: <20200611171608.22052-1-den@openvz.org> Received-SPF: pass client-ip=185.231.240.75; envelope-from=den@openvz.org; helo=relay3.sw.ru X-detected-operating-system: by eggs.gnu.org: First seen = 2020/06/11 13:11:47 X-ACL-Warn: Detected OS = Linux 3.11 and newer X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Fam Zheng , Eduardo Habkost , Max Reitz , Paolo Bonzini , "Denis V. Lunev" , John Snow Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Nowaday SCSI drivers in guests are able to align UNMAP requests before sending to the device. Right now QEMU provides an ability to set this via "discard_granularity" property of the block device which could be used by management layer. Though, in particular, from the point of QEMU, there is pdiscard_granularity on the format driver level, f.e. on QCOW2 or iSCSI. It would be beneficial to pass this value as a default for this property. Technically this should reduce the amount of use less UNMAP requests from the guest to the host. Basic test confirms this. Signed-off-by: Denis V. Lunev CC: Kevin Wolf CC: Max Reitz CC: Eduardo Habkost CC: Marcel Apfelbaum CC: John Snow CC: Paolo Bonzini CC: Fam Zheng --- block/block-backend.c | 11 +++++++++++ hw/core/machine.c | 15 ++++++++++++++- hw/ide/qdev.c | 3 ++- hw/scsi/scsi-disk.c | 5 ++++- include/hw/block/block.h | 2 +- include/sysemu/block-backend.h | 6 ++++++ 6 files changed, 38 insertions(+), 4 deletions(-) diff --git a/block/block-backend.c b/block/block-backend.c index 6936b25c83..9342a475cb 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -2222,6 +2222,17 @@ int blk_probe_geometry(BlockBackend *blk, HDGeometry *geo) return bdrv_probe_geometry(blk_bs(blk), geo); } +int blk_discard_granularity(BlockBackend *blk) +{ + BlockDriverState *bs = blk_bs(blk); + + if (bs == NULL) { + return DEFAULT_DISCARD_GRANULARITY; + } + + return bs->bl.pdiscard_alignment; +} + /* * Updates the BlockBackendRootState object with data from the currently * attached BlockDriverState. diff --git a/hw/core/machine.c b/hw/core/machine.c index bb3a7b18b1..08a242d606 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -28,7 +28,20 @@ #include "hw/mem/nvdimm.h" #include "migration/vmstate.h" -GlobalProperty hw_compat_5_0[] = {}; +GlobalProperty hw_compat_5_0[] = { + { "ide-cd", "discard_granularity", "0xffffffff" }, + { "ide-hd", "discard_granularity", "0xffffffff" }, + { "ide-drive", "discard_granularity", "0xffffffff" }, + { "scsi-hd", "discard_granularity", "0xffffffff" }, + { "scsi-cd", "discard_granularity", "0xffffffff" }, + { "scsi-disk", "discard_granularity", "0xffffffff" }, + { "virtio-blk-pci", "discard_granularity", "0xffffffff" }, + { "xen-block", "discard_granularity", "0xffffffff" }, + { "usb-storage", "discard_granularity", "0xffffffff" }, + { "swim-drive", "discard_granularity", "0xffffffff" }, + { "floppy", "discard_granularity", "0xffffffff" }, + { "nvme", "discard_granularity", "0xffffffff" }, +}; const size_t hw_compat_5_0_len = G_N_ELEMENTS(hw_compat_5_0); GlobalProperty hw_compat_4_2[] = { diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c index 06b11583f5..e515dbeb0e 100644 --- a/hw/ide/qdev.c +++ b/hw/ide/qdev.c @@ -179,7 +179,8 @@ static void ide_dev_initfn(IDEDevice *dev, IDEDriveKind kind, Error **errp) } } - if (dev->conf.discard_granularity == -1) { + if (dev->conf.discard_granularity == -1 || + dev->conf.discard_granularity == -2) { dev->conf.discard_granularity = 512; } else if (dev->conf.discard_granularity && dev->conf.discard_granularity != 512) { diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c index 387503e11b..6b809608e4 100644 --- a/hw/scsi/scsi-disk.c +++ b/hw/scsi/scsi-disk.c @@ -48,7 +48,6 @@ #define SCSI_MAX_INQUIRY_LEN 256 #define SCSI_MAX_MODE_LEN 256 -#define DEFAULT_DISCARD_GRANULARITY (4 * KiB) #define DEFAULT_MAX_UNMAP_SIZE (1 * GiB) #define DEFAULT_MAX_IO_SIZE INT_MAX /* 2 GB - 1 block */ @@ -2381,6 +2380,10 @@ static void scsi_realize(SCSIDevice *dev, Error **errp) if (s->qdev.conf.discard_granularity == -1) { s->qdev.conf.discard_granularity = MAX(s->qdev.conf.logical_block_size, DEFAULT_DISCARD_GRANULARITY); + } else if (s->qdev.conf.discard_granularity == -2) { + s->qdev.conf.discard_granularity = + MAX(s->qdev.conf.logical_block_size, + blk_discard_granularity(s->qdev.conf.blk)); } if (!s->version) { diff --git a/include/hw/block/block.h b/include/hw/block/block.h index d7246f3862..53d4a38044 100644 --- a/include/hw/block/block.h +++ b/include/hw/block/block.h @@ -54,7 +54,7 @@ static inline unsigned int get_physical_block_exp(BlockConf *conf) DEFINE_PROP_UINT16("min_io_size", _state, _conf.min_io_size, 0), \ DEFINE_PROP_UINT32("opt_io_size", _state, _conf.opt_io_size, 0), \ DEFINE_PROP_UINT32("discard_granularity", _state, \ - _conf.discard_granularity, -1), \ + _conf.discard_granularity, -2), \ DEFINE_PROP_ON_OFF_AUTO("write-cache", _state, _conf.wce, \ ON_OFF_AUTO_AUTO), \ DEFINE_PROP_BOOL("share-rw", _state, _conf.share_rw, false) diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h index 8203d7f6f9..241a759432 100644 --- a/include/sysemu/block-backend.h +++ b/include/sysemu/block-backend.h @@ -13,6 +13,7 @@ #ifndef BLOCK_BACKEND_H #define BLOCK_BACKEND_H +#include "qemu/units.h" #include "qemu/iov.h" #include "block/throttle-groups.h" @@ -25,6 +26,10 @@ */ #include "block/block.h" + +#define DEFAULT_DISCARD_GRANULARITY (4 * KiB) + + /* Callbacks for block device models */ typedef struct BlockDevOps { /* @@ -246,6 +251,7 @@ int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf, int blk_load_vmstate(BlockBackend *blk, uint8_t *buf, int64_t pos, int size); int blk_probe_blocksizes(BlockBackend *blk, BlockSizes *bsz); int blk_probe_geometry(BlockBackend *blk, HDGeometry *geo); +int blk_discard_granularity(BlockBackend *blk); BlockAIOCB *blk_abort_aio_request(BlockBackend *blk, BlockCompletionFunc *cb, void *opaque, int ret);