All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stefano Garzarella <sgarzare@redhat.com>
To: qemu-devel@nongnu.org
Cc: Laurent Vivier <lvivier@redhat.com>,
	"Michael S. Tsirkin" <mst@redhat.com>,
	Stefan Hajnoczi <stefanha@redhat.com>,
	Max Reitz <mreitz@redhat.com>, Thomas Huth <thuth@redhat.com>,
	Paolo Bonzini <pbonzini@redhat.com>,
	Kevin Wolf <kwolf@redhat.com>,
	qemu-block@nongnu.org
Subject: [Qemu-devel] [PATCH RFC 1/2] virtio-blk: add DISCARD and WRITE ZEROES features
Date: Thu, 24 Jan 2019 18:23:22 +0100	[thread overview]
Message-ID: <20190124172323.230296-2-sgarzare@redhat.com> (raw)
In-Reply-To: <20190124172323.230296-1-sgarzare@redhat.com>

This patch adds the support of DISCARD and WRITE ZEROES commands,
that have been introduced in the virtio-blk protocol to have
better performance when using SSD backend.

Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
---
 hw/block/virtio-blk.c | 79 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 79 insertions(+)

diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index f208c6ddb9..8850957751 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -145,6 +145,25 @@ out:
     aio_context_release(blk_get_aio_context(s->conf.conf.blk));
 }
 
+static void virtio_blk_discard_wzeroes_complete(void *opaque, int ret)
+{
+    VirtIOBlockReq *req = opaque;
+    VirtIOBlock *s = req->dev;
+
+    aio_context_acquire(blk_get_aio_context(s->conf.conf.blk));
+    if (ret) {
+        if (virtio_blk_handle_rw_error(req, -ret, 0)) {
+            goto out;
+        }
+    }
+
+    virtio_blk_req_complete(req, VIRTIO_BLK_S_OK);
+    virtio_blk_free_request(req);
+
+out:
+    aio_context_release(blk_get_aio_context(s->conf.conf.blk));
+}
+
 #ifdef __linux__
 
 typedef struct {
@@ -584,6 +603,56 @@ static int virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb)
         virtio_blk_free_request(req);
         break;
     }
+    /*
+     * VIRTIO_BLK_T_DISCARD and VIRTIO_BLK_T_WRITE_ZEROES are defined with
+     * VIRTIO_BLK_T_OUT flag set. We masked this flag in the switch statement,
+     * so we must mask it for these requests, then we will check the type.
+     */
+    case VIRTIO_BLK_T_DISCARD & ~VIRTIO_BLK_T_OUT:
+    case VIRTIO_BLK_T_WRITE_ZEROES & ~VIRTIO_BLK_T_OUT:
+    {
+        struct virtio_blk_discard_write_zeroes dwz_hdr;
+        uint64_t sector;
+        int bytes;
+
+        if (unlikely(iov_to_buf(out_iov, out_num, 0, &dwz_hdr,
+                                sizeof(dwz_hdr)) != sizeof(dwz_hdr))) {
+            virtio_error(vdev, "virtio-blk discard/wzeroes header too short");
+            return -1;
+        }
+
+        sector = virtio_ldq_p(VIRTIO_DEVICE(req->dev), &dwz_hdr.sector);
+        bytes = virtio_ldl_p(VIRTIO_DEVICE(req->dev),
+                             &dwz_hdr.num_sectors) << BDRV_SECTOR_BITS;
+
+        if (!virtio_blk_sect_range_ok(req->dev, sector, bytes)) {
+            virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR);
+            virtio_blk_free_request(req);
+            return 0;
+        }
+
+        if ((type & ~(VIRTIO_BLK_T_BARRIER)) == VIRTIO_BLK_T_DISCARD) {
+            blk_aio_pdiscard(req->dev->blk, sector << BDRV_SECTOR_BITS, bytes,
+                             virtio_blk_discard_wzeroes_complete, req);
+        } else if ((type & ~(VIRTIO_BLK_T_BARRIER)) ==
+                   VIRTIO_BLK_T_WRITE_ZEROES) {
+            int flags = 0;
+
+            if (virtio_ldl_p(VIRTIO_DEVICE(req->dev), &dwz_hdr.flags) &
+                VIRTIO_BLK_WRITE_ZEROES_FLAG_UNMAP) {
+                flags |= BDRV_REQ_MAY_UNMAP;
+            }
+
+            blk_aio_pwrite_zeroes(req->dev->blk, sector << BDRV_SECTOR_BITS,
+                                  bytes, flags,
+                                  virtio_blk_discard_wzeroes_complete, req);
+        } else { /* Unsupported if VIRTIO_BLK_T_OUT is not set */
+            virtio_blk_req_complete(req, VIRTIO_BLK_S_UNSUPP);
+            virtio_blk_free_request(req);
+        }
+
+        break;
+    }
     default:
         virtio_blk_req_complete(req, VIRTIO_BLK_S_UNSUPP);
         virtio_blk_free_request(req);
@@ -763,6 +832,14 @@ static void virtio_blk_update_config(VirtIODevice *vdev, uint8_t *config)
     blkcfg.alignment_offset = 0;
     blkcfg.wce = blk_enable_write_cache(s->blk);
     virtio_stw_p(vdev, &blkcfg.num_queues, s->conf.num_queues);
+    virtio_stl_p(vdev, &blkcfg.max_discard_sectors, BDRV_REQUEST_MAX_SECTORS);
+    virtio_stl_p(vdev, &blkcfg.max_discard_seg, 1);
+    virtio_stl_p(vdev, &blkcfg.discard_sector_alignment,
+                 blk_size >> BDRV_SECTOR_BITS);
+    virtio_stl_p(vdev, &blkcfg.max_write_zeroes_sectors,
+                 BDRV_REQUEST_MAX_SECTORS);
+    virtio_stl_p(vdev, &blkcfg.max_write_zeroes_seg, 1);
+    blkcfg.write_zeroes_may_unmap = 1;
     memcpy(config, &blkcfg, sizeof(struct virtio_blk_config));
 }
 
@@ -787,6 +864,8 @@ static uint64_t virtio_blk_get_features(VirtIODevice *vdev, uint64_t features,
     virtio_add_feature(&features, VIRTIO_BLK_F_GEOMETRY);
     virtio_add_feature(&features, VIRTIO_BLK_F_TOPOLOGY);
     virtio_add_feature(&features, VIRTIO_BLK_F_BLK_SIZE);
+    virtio_add_feature(&features, VIRTIO_BLK_F_DISCARD);
+    virtio_add_feature(&features, VIRTIO_BLK_F_WRITE_ZEROES);
     if (virtio_has_feature(features, VIRTIO_F_VERSION_1)) {
         if (s->conf.scsi) {
             error_setg(errp, "Please set scsi=off for virtio-blk devices in order to use virtio 1.0");
-- 
2.20.1

  reply	other threads:[~2019-01-24 17:23 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-01-24 17:23 [Qemu-devel] [PATCH RFC 0/2] virtio-blk: add DISCARD and WRITE ZEROES features Stefano Garzarella
2019-01-24 17:23 ` Stefano Garzarella [this message]
2019-01-24 17:55   ` [Qemu-devel] [PATCH RFC 1/2] " Dr. David Alan Gilbert
2019-01-24 18:31     ` Stefano Garzarella
2019-01-25 14:58   ` Stefan Hajnoczi
2019-01-25 16:18     ` Stefano Garzarella
2019-01-27 12:51       ` Stefan Hajnoczi
2019-01-28  8:28         ` Stefano Garzarella
2019-01-24 17:23 ` [Qemu-devel] [PATCH RFC 2/2] tests/virtio-blk: add test for WRITE_ZEROES command Stefano Garzarella
2019-01-25  6:01   ` Thomas Huth
2019-01-25  6:07     ` Thomas Huth
2019-01-25  6:07     ` Thomas Huth
2019-01-25  8:16       ` Stefano Garzarella
2019-01-25  8:49         ` Thomas Huth
2019-01-25 11:58           ` Liu, Changpeng
2019-01-25 12:48             ` Thomas Huth
2019-01-25 19:18               ` Michael S. Tsirkin
2019-01-25 15:12           ` Stefan Hajnoczi
2019-01-25 19:17             ` Michael S. Tsirkin
2019-01-25 19:17               ` [virtio-comment] " Michael S. Tsirkin
2019-01-27 12:57               ` Stefan Hajnoczi
2019-01-27 18:42                 ` Michael S. Tsirkin
2019-01-27 18:42                   ` [virtio-comment] " Michael S. Tsirkin
2019-01-30  7:39                   ` Stefan Hajnoczi
2019-01-30  7:39                     ` [virtio-comment] " Stefan Hajnoczi
2019-01-30  7:59                     ` Liu, Changpeng
2019-01-30  7:59                       ` [virtio-comment] " Liu, Changpeng
2019-01-25 19:14           ` Michael S. Tsirkin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190124172323.230296-2-sgarzare@redhat.com \
    --to=sgarzare@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=lvivier@redhat.com \
    --cc=mreitz@redhat.com \
    --cc=mst@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@redhat.com \
    --cc=thuth@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.