From nobody Thu May 9 02:27:22 2024 Delivered-To: importer@patchew.org Received-SPF: temperror (zoho.com: Error in retrieving data from DNS) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=temperror (zoho.com: Error in retrieving data from DNS) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=intel.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1547450402070857.3372376862254; Sun, 13 Jan 2019 23:20:02 -0800 (PST) Received: from localhost ([127.0.0.1]:45819 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1giwXO-0000d5-NP for importer@patchew.org; Mon, 14 Jan 2019 02:19:58 -0500 Received: from eggs.gnu.org ([209.51.188.92]:39123) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1giwVl-0008Hj-AN for qemu-devel@nongnu.org; Mon, 14 Jan 2019 02:18:18 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1giwVj-0002T5-T2 for qemu-devel@nongnu.org; Mon, 14 Jan 2019 02:18:17 -0500 Received: from mga12.intel.com ([192.55.52.136]:16363) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1giwVj-0002I3-Jo for qemu-devel@nongnu.org; Mon, 14 Jan 2019 02:18:15 -0500 Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga106.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 13 Jan 2019 23:18:07 -0800 Received: from fedora.sh.intel.com ([10.67.114.176]) by fmsmga008.fm.intel.com with ESMTP; 13 Jan 2019 23:18:05 -0800 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.56,476,1539673200"; d="scan'208";a="116551685" From: Changpeng Liu To: qemu-devel@nongnu.org Date: Mon, 14 Jan 2019 15:35:17 +0800 Message-Id: <1547451317-21375-1-git-send-email-changpeng.liu@intel.com> X-Mailer: git-send-email 1.9.3 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 192.55.52.136 Subject: [Qemu-devel] [PATCH] vhost-user-blk: enable discard/write zeroes features X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: changpeng.liu@intel.com, stefanha@redhat.com, mst@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Linux commit 1f23816b8 "virtio_blk: add discard and write zeroes support" added the support in the Guest kernel, while here enable the feature bits support with vhost-user-blk driver. Also enable the test example utility with DISCARD command support. Signed-off-by: Changpeng Liu --- contrib/vhost-user-blk/vhost-user-blk.c | 107 +++++++++++++++++++-----= ---- hw/block/vhost-user-blk.c | 4 ++ include/standard-headers/linux/virtio_blk.h | 54 ++++++++++++++ 3 files changed, 132 insertions(+), 33 deletions(-) diff --git a/contrib/vhost-user-blk/vhost-user-blk.c b/contrib/vhost-user-b= lk/vhost-user-blk.c index 858221a..fe6302c 100644 --- a/contrib/vhost-user-blk/vhost-user-blk.c +++ b/contrib/vhost-user-blk/vhost-user-blk.c @@ -20,6 +20,10 @@ #include "contrib/libvhost-user/libvhost-user-glib.h" #include "contrib/libvhost-user/libvhost-user.h" =20 +#if defined(__linux__) +#include +#include +#endif =20 struct virtio_blk_inhdr { unsigned char status; @@ -157,6 +161,29 @@ vub_writev(VubReq *req, struct iovec *iov, uint32_t io= vcnt) return rc; } =20 +static int +vub_discard(VubReq *req, struct iovec *iov, uint32_t iovcnt) +{ + if (iovcnt !=3D 1) { + fprintf(stderr, "Invalid Discard IOV count\n"); + return -1; + } + + #if defined(__linux__) && defined(BLKDISCARD) + VubDev *vdev_blk =3D req->vdev_blk; + struct virtio_blk_discard_write_zeroes *desc =3D + (struct virtio_blk_discard_write_zeroes *)iov->iov_= base; + uint64_t range[2] =3D { le64toh(desc->sector) << 9, + le32toh(desc->num_sectors) << 9 }; + if (ioctl(vdev_blk->blk_fd, BLKDISCARD, range) =3D=3D 0) { + return 0; + } + return -1; + #endif + + return -1; +} + static void vub_flush(VubReq *req) { @@ -212,44 +239,54 @@ static int vub_virtio_process_req(VubDev *vdev_blk, in_num--; =20 type =3D le32toh(req->out->type); - switch (type & ~(VIRTIO_BLK_T_OUT | VIRTIO_BLK_T_BARRIER)) { - case VIRTIO_BLK_T_IN: { - ssize_t ret =3D 0; - bool is_write =3D type & VIRTIO_BLK_T_OUT; - req->sector_num =3D le64toh(req->out->sector); - if (is_write) { - ret =3D vub_writev(req, &elem->out_sg[1], out_num); - } else { - ret =3D vub_readv(req, &elem->in_sg[0], in_num); - } - if (ret >=3D 0) { - req->in->status =3D VIRTIO_BLK_S_OK; - } else { - req->in->status =3D VIRTIO_BLK_S_IOERR; - } - vub_req_complete(req); - break; + switch (type & ~VIRTIO_BLK_T_BARRIER) { + case VIRTIO_BLK_T_IN: + case VIRTIO_BLK_T_OUT: { + ssize_t ret =3D 0; + bool is_write =3D type & VIRTIO_BLK_T_OUT; + req->sector_num =3D le64toh(req->out->sector); + if (is_write) { + ret =3D vub_writev(req, &elem->out_sg[1], out_num); + } else { + ret =3D vub_readv(req, &elem->in_sg[0], in_num); } - case VIRTIO_BLK_T_FLUSH: { - vub_flush(req); + if (ret >=3D 0) { req->in->status =3D VIRTIO_BLK_S_OK; - vub_req_complete(req); - break; + } else { + req->in->status =3D VIRTIO_BLK_S_IOERR; } - case VIRTIO_BLK_T_GET_ID: { - size_t size =3D MIN(vub_iov_size(&elem->in_sg[0], in_num), - VIRTIO_BLK_ID_BYTES); - snprintf(elem->in_sg[0].iov_base, size, "%s", "vhost_user_blk"= ); + vub_req_complete(req); + break; + } + case VIRTIO_BLK_T_FLUSH: + vub_flush(req); + req->in->status =3D VIRTIO_BLK_S_OK; + vub_req_complete(req); + break; + case VIRTIO_BLK_T_GET_ID: { + size_t size =3D MIN(vub_iov_size(&elem->in_sg[0], in_num), + VIRTIO_BLK_ID_BYTES); + snprintf(elem->in_sg[0].iov_base, size, "%s", "vhost_user_blk"); + req->in->status =3D VIRTIO_BLK_S_OK; + req->size =3D elem->in_sg[0].iov_len; + vub_req_complete(req); + break; + } + case VIRTIO_BLK_T_DISCARD: { + int rc; + rc =3D vub_discard(req, &elem->out_sg[1], out_num); + if (rc =3D=3D 0) { req->in->status =3D VIRTIO_BLK_S_OK; - req->size =3D elem->in_sg[0].iov_len; - vub_req_complete(req); - break; - } - default: { + } else { req->in->status =3D VIRTIO_BLK_S_UNSUPP; - vub_req_complete(req); - break; } + vub_req_complete(req); + break; + } + default: + req->in->status =3D VIRTIO_BLK_S_UNSUPP; + vub_req_complete(req); + break; } =20 return 0; @@ -313,6 +350,7 @@ vub_get_features(VuDev *dev) 1ull << VIRTIO_BLK_F_TOPOLOGY | 1ull << VIRTIO_BLK_F_BLK_SIZE | 1ull << VIRTIO_BLK_F_FLUSH | + 1ull << VIRTIO_BLK_F_DISCARD | 1ull << VIRTIO_BLK_F_CONFIG_WCE | 1ull << VIRTIO_F_VERSION_1 | 1ull << VHOST_USER_F_PROTOCOL_FEATURES; @@ -454,7 +492,7 @@ vub_get_blocksize(int fd) =20 #if defined(__linux__) && defined(BLKSSZGET) if (ioctl(fd, BLKSSZGET, &blocksize) =3D=3D 0) { - return blocklen; + return blocksize; } #endif =20 @@ -474,6 +512,9 @@ vub_initialize_config(int fd, struct virtio_blk_config = *config) config->min_io_size =3D 1; config->opt_io_size =3D 1; config->num_queues =3D 1; + config->max_discard_sectors =3D 32768; + config->max_discard_seg =3D 1; + config->discard_sector_alignment =3D config->blk_size >> 9; } =20 static VubDev * diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c index 1451940..5fe1810 100644 --- a/hw/block/vhost-user-blk.c +++ b/hw/block/vhost-user-blk.c @@ -38,6 +38,8 @@ static const int user_feature_bits[] =3D { VIRTIO_BLK_F_RO, VIRTIO_BLK_F_FLUSH, VIRTIO_BLK_F_CONFIG_WCE, + VIRTIO_BLK_F_DISCARD, + VIRTIO_BLK_F_WRITE_ZEROES, VIRTIO_F_VERSION_1, VIRTIO_RING_F_INDIRECT_DESC, VIRTIO_RING_F_EVENT_IDX, @@ -204,6 +206,8 @@ static uint64_t vhost_user_blk_get_features(VirtIODevic= e *vdev, virtio_add_feature(&features, VIRTIO_BLK_F_BLK_SIZE); virtio_add_feature(&features, VIRTIO_BLK_F_FLUSH); virtio_add_feature(&features, VIRTIO_BLK_F_RO); + virtio_add_feature(&features, VIRTIO_BLK_F_DISCARD); + virtio_add_feature(&features, VIRTIO_BLK_F_WRITE_ZEROES); =20 if (s->config_wce) { virtio_add_feature(&features, VIRTIO_BLK_F_CONFIG_WCE); diff --git a/include/standard-headers/linux/virtio_blk.h b/include/standard= -headers/linux/virtio_blk.h index ab16ec5..666dc2e 100644 --- a/include/standard-headers/linux/virtio_blk.h +++ b/include/standard-headers/linux/virtio_blk.h @@ -38,6 +38,8 @@ #define VIRTIO_BLK_F_BLK_SIZE 6 /* Block size of disk is available*/ #define VIRTIO_BLK_F_TOPOLOGY 10 /* Topology information is available */ #define VIRTIO_BLK_F_MQ 12 /* support more than one vq */ +#define VIRTIO_BLK_F_DISCARD 13 /* DISCARD is supported */ +#define VIRTIO_BLK_F_WRITE_ZEROES 14 /* WRITE ZEROES is supported */ =20 /* Legacy feature bits */ #ifndef VIRTIO_BLK_NO_LEGACY @@ -84,6 +86,39 @@ struct virtio_blk_config { =20 /* number of vqs, only available when VIRTIO_BLK_F_MQ is set */ uint16_t num_queues; + + /* the next 3 entries are guarded by VIRTIO_BLK_F_DISCARD */ + /* + * The maximum discard sectors (in 512-byte sectors) for + * one segment. + */ + uint32_t max_discard_sectors; + /* + * The maximum number of discard segments in a + * discard command. + */ + uint32_t max_discard_seg; + /* Discard commands must be aligned to this number of sectors. */ + uint32_t discard_sector_alignment; + + /* the next 3 entries are guarded by VIRTIO_BLK_F_WRITE_ZEROES */ + /* + * The maximum number of write zeroes sectors (in 512-byte sectors) in + * one segment. + */ + uint32_t max_write_zeroes_sectors; + /* + * The maximum number of segments in a write zeroes + * command. + */ + uint32_t max_write_zeroes_seg; + /* + * Set if a VIRTIO_BLK_T_WRITE_ZEROES request may result in the + * deallocation of one or more of the sectors. + */ + uint8_t write_zeroes_may_unmap; + + uint8_t unused1[3]; } QEMU_PACKED; =20 /* @@ -112,6 +147,12 @@ struct virtio_blk_config { /* Get device ID command */ #define VIRTIO_BLK_T_GET_ID 8 =20 +/* Discard command */ +#define VIRTIO_BLK_T_DISCARD 11 + +/* Write zeroes command */ +#define VIRTIO_BLK_T_WRITE_ZEROES 13 + #ifndef VIRTIO_BLK_NO_LEGACY /* Barrier before this op. */ #define VIRTIO_BLK_T_BARRIER 0x80000000 @@ -131,6 +172,19 @@ struct virtio_blk_outhdr { __virtio64 sector; }; =20 +/* Unmap this range (only valid for write zeroes command) */ +#define VIRTIO_BLK_WRITE_ZEROES_FLAG_UNMAP 0x00000001 + +/* Discard/write zeroes range for each request. */ +struct virtio_blk_discard_write_zeroes { + /* discard/write zeroes start sector */ + uint64_t sector; + /* number of discard/write zeroes sectors */ + uint32_t num_sectors; + /* flags for this range */ + uint32_t flags; +}; + #ifndef VIRTIO_BLK_NO_LEGACY struct virtio_scsi_inhdr { __virtio32 errors; --=20 1.9.3