From patchwork Fri May 3 11:52:51 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Hajnoczi X-Patchwork-Id: 241299 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id DE4272C00D0 for ; Fri, 3 May 2013 22:29:51 +1000 (EST) Received: from localhost ([::1]:33178 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UYEfI-00063g-Hl for incoming@patchwork.ozlabs.org; Fri, 03 May 2013 08:00:40 -0400 Received: from eggs.gnu.org ([208.118.235.92]:41092) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UYEYQ-0003mB-C9 for qemu-devel@nongnu.org; Fri, 03 May 2013 07:53:37 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UYEYN-000166-NG for qemu-devel@nongnu.org; Fri, 03 May 2013 07:53:34 -0400 Received: from mx1.redhat.com ([209.132.183.28]:25936) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UYEYN-000162-Gd for qemu-devel@nongnu.org; Fri, 03 May 2013 07:53:31 -0400 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r43BrUtV015388 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 3 May 2013 07:53:30 -0400 Received: from localhost (ovpn-112-30.ams2.redhat.com [10.36.112.30]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id r43BrToR002239; Fri, 3 May 2013 07:53:30 -0400 From: Stefan Hajnoczi To: Date: Fri, 3 May 2013 13:52:51 +0200 Message-Id: <1367581972-4208-15-git-send-email-stefanha@redhat.com> In-Reply-To: <1367581972-4208-1-git-send-email-stefanha@redhat.com> References: <1367581972-4208-1-git-send-email-stefanha@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.12 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: Anthony Liguori , Stefan Hajnoczi Subject: [Qemu-devel] [PATCH 14/15] nbd: support large NBD requests X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org The Linux nbd driver recently increased the maximum supported request size up to 32 MB: commit 078be02b80359a541928c899c2631f39628f56df Author: Michal Belczyk Date: Tue Apr 30 15:28:28 2013 -0700 nbd: increase default and max request sizes Raise the default max request size for nbd to 128KB (from 127KB) to get it 4KB aligned. This patch also allows the max request size to be increased (via /sys/block/nbd/queue/max_sectors_kb) to 32MB. QEMU's 1 MB buffers are too small to handle these requests. This patch allocates data buffers dynamically and allows up to 32 MB per request. Reported-by: Nick Thomas Signed-off-by: Stefan Hajnoczi --- include/block/nbd.h | 3 ++- nbd.c | 17 +++++++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/include/block/nbd.h b/include/block/nbd.h index 0903d7a..c90f5e4 100644 --- a/include/block/nbd.h +++ b/include/block/nbd.h @@ -58,7 +58,8 @@ enum { #define NBD_DEFAULT_PORT 10809 -#define NBD_BUFFER_SIZE (1024*1024) +/* Maximum size of a single READ/WRITE data buffer */ +#define NBD_MAX_BUFFER_SIZE (32 * 1024 * 1024) ssize_t nbd_wr_sync(int fd, void *buffer, size_t size, bool do_read); int tcp_socket_incoming(const char *address, uint16_t port); diff --git a/nbd.c b/nbd.c index 761f4ec..2606403 100644 --- a/nbd.c +++ b/nbd.c @@ -844,13 +844,11 @@ void nbd_client_close(NBDClient *client) static NBDRequest *nbd_request_get(NBDClient *client) { NBDRequest *req; - NBDExport *exp = client->exp; assert(client->nb_requests <= MAX_NBD_REQUESTS - 1); client->nb_requests++; req = g_slice_new0(NBDRequest); - req->data = qemu_blockalign(exp->bs, NBD_BUFFER_SIZE); nbd_client_get(client); req->client = client; return req; @@ -860,7 +858,9 @@ static void nbd_request_put(NBDRequest *req) { NBDClient *client = req->client; - qemu_vfree(req->data); + if (req->data) { + qemu_vfree(req->data); + } g_slice_free(NBDRequest, req); if (client->nb_requests-- == MAX_NBD_REQUESTS) { @@ -1007,6 +1007,7 @@ static ssize_t nbd_co_receive_request(NBDRequest *req, struct nbd_request *reque { NBDClient *client = req->client; int csock = client->sock; + uint32_t command; ssize_t rc; client->recv_coroutine = qemu_coroutine_self(); @@ -1018,9 +1019,9 @@ static ssize_t nbd_co_receive_request(NBDRequest *req, struct nbd_request *reque goto out; } - if (request->len > NBD_BUFFER_SIZE) { + if (request->len > NBD_MAX_BUFFER_SIZE) { LOG("len (%u) is larger than max len (%u)", - request->len, NBD_BUFFER_SIZE); + request->len, NBD_MAX_BUFFER_SIZE); rc = -EINVAL; goto out; } @@ -1034,7 +1035,11 @@ static ssize_t nbd_co_receive_request(NBDRequest *req, struct nbd_request *reque TRACE("Decoding type"); - if ((request->type & NBD_CMD_MASK_COMMAND) == NBD_CMD_WRITE) { + command = request->type & NBD_CMD_MASK_COMMAND; + if (command == NBD_CMD_READ || command == NBD_CMD_WRITE) { + req->data = qemu_blockalign(client->exp->bs, request->len); + } + if (command == NBD_CMD_WRITE) { TRACE("Reading %u byte(s)", request->len); if (qemu_co_recv(csock, req->data, request->len) != request->len) {