From patchwork Mon Jun 6 16:26:56 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 99015 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 8A1D3B6FA3 for ; Tue, 7 Jun 2011 05:39:30 +1000 (EST) Received: from localhost ([::1]:53137 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QTfe1-0003PI-77 for incoming@patchwork.ozlabs.org; Mon, 06 Jun 2011 15:39:25 -0400 Received: from eggs.gnu.org ([140.186.70.92]:43683) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QTceI-00041T-Rt for qemu-devel@nongnu.org; Mon, 06 Jun 2011 12:27:31 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QTceH-0003wV-0G for qemu-devel@nongnu.org; Mon, 06 Jun 2011 12:27:30 -0400 Received: from mail-px0-f174.google.com ([209.85.212.174]:57224) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QTceG-0003wK-Cl for qemu-devel@nongnu.org; Mon, 06 Jun 2011 12:27:28 -0400 Received: by pxi15 with SMTP id 15so964653pxi.33 for ; Mon, 06 Jun 2011 09:27:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:sender:from:to:subject:date:message-id:x-mailer :in-reply-to:references; bh=fde6RluFKBSpsC2KI495LNLHkQ/xZWaRcmA11TUna+g=; b=BKMoohASjpGT3Vr4+0JZ5WAJTPykpDtkbfAAlOS0pzCQnEE4bLTs4yNm0qwku/vTyB 40PNnALxtXNKIhPlKSeSRNi8ss0r4MAyVneEgfBJYuDjiJe95+H/2ErpqKs3K4E0nNWE 1poZKkzW6bFVG1iyu5q6IlbLgvR1tPxmOEKKg= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=sender:from:to:subject:date:message-id:x-mailer:in-reply-to :references; b=MSB9ExndDdWNq3tIwTZhkiXX6hR8ujDOCVA1Juj8efk+dOLcrrV6qoJ/Dh8I6ULoHy 9A4TDv7dXLQBKZjbB5PIDnsepNHa2Yvov8apCaV6g7pulfTZSHEx4trLO0czvxpbH5/x IGbnV0pbzUAvbTsDsecpZ8IgCfrlYuAhh9hm4= Received: by 10.68.34.202 with SMTP id b10mr2051515pbj.494.1307377647085; Mon, 06 Jun 2011 09:27:27 -0700 (PDT) Received: from localhost.localdomain (93-34-184-88.ip51.fastwebnet.it [93.34.184.88]) by mx.google.com with ESMTPS id y2sm3785829pbi.51.2011.06.06.09.27.24 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 06 Jun 2011 09:27:26 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Mon, 6 Jun 2011 18:26:56 +0200 Message-Id: <1307377620-7538-6-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.7.4.4 In-Reply-To: <1307377620-7538-1-git-send-email-pbonzini@redhat.com> References: <1307377620-7538-1-git-send-email-pbonzini@redhat.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 209.85.212.174 Subject: [Qemu-devel] [RFC PATCH 5/9] scsi-disk: lazily allocate bounce buffer 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 Signed-off-by: Paolo Bonzini --- hw/scsi-disk.c | 32 ++++++++++++++++++++++---------- 1 files changed, 22 insertions(+), 10 deletions(-) diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index 21eb249..bc6003c 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -54,6 +54,7 @@ typedef struct SCSIDiskReq { /* Both sector and sector_count are in terms of qemu 512 byte blocks. */ uint64_t sector; uint32_t sector_count; + uint32_t buflen; struct iovec iov; QEMUIOVector qiov; uint32_t status; @@ -78,7 +79,7 @@ struct SCSIDiskState }; static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type); -static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf); +static int scsi_disk_emulate_command(SCSIDiskReq *r); static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun) @@ -89,7 +90,6 @@ static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, req = scsi_req_alloc(sizeof(SCSIDiskReq), &s->qdev, tag, lun); r = DO_UPCAST(SCSIDiskReq, req, req); - r->iov.iov_base = qemu_blockalign(s->bs, SCSI_DMA_BUF_SIZE); return req; } @@ -97,7 +97,9 @@ static void scsi_free_request(SCSIRequest *req) { SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req); - qemu_vfree(r->iov.iov_base); + if (r->iov.iov_base) { + qemu_vfree(r->iov.iov_base); + } } static void scsi_disk_clear_sense(SCSIDiskState *s) @@ -136,8 +138,13 @@ static void scsi_cancel_io(SCSIRequest *req) static uint32_t scsi_init_iovec(SCSIDiskReq *r) { - n = MIN(r->sector_count, SCSI_DMA_BUF_SIZE / 512); - r->iov.iov_len = n * 512; + SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); + + if (!r->iov.iov_base) { + r->buflen = SCSI_DMA_BUF_SIZE; + r->iov.iov_base = qemu_blockalign(s->bs, r->buflen); + } + r->iov.iov_len = MIN(r->sector_count * 512, r->buflen); qemu_iovec_init_external(&r->qiov, &r->iov, 1); return r->qiov.size / 512; } @@ -322,7 +329,7 @@ static void scsi_dma_restart_bh(void *opaque) scsi_write_data(&r->req); break; case SCSI_REQ_STATUS_RETRY_FLUSH: - ret = scsi_disk_emulate_command(r, r->iov.iov_base); + ret = scsi_disk_emulate_command(r); if (ret == 0) { scsi_command_complete(r, GOOD, SENSE_CODE(NO_SENSE)); } @@ -815,14 +822,21 @@ static int scsi_disk_emulate_read_toc(SCSIRequest *req, uint8_t *outbuf) return toclen; } -static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf) +static int scsi_disk_emulate_command(SCSIDiskReq *r) { SCSIRequest *req = &r->req; SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev); uint64_t nb_sectors; + uint8_t *outbuf; int buflen = 0; int ret; + if (!r->iov.iov_base) { + r->iov.iov_base = qemu_blockalign(s->bs, 4096); + r->buflen = 4096; + } + + outbuf = r->iov.iov_base; switch (req->cmd.buf[0]) { case TEST_UNIT_READY: if (!bdrv_is_inserted(s->bs)) @@ -1000,11 +1014,9 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf) SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev); int32_t len; uint8_t command; - uint8_t *outbuf; int rc; command = buf[0]; - outbuf = (uint8_t *)r->iov.iov_base; DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", lun, tag, buf[0]); if (scsi_req_parse(&r->req, buf) != 0) { @@ -1051,7 +1063,7 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf) case REPORT_LUNS: case VERIFY: case REZERO_UNIT: - rc = scsi_disk_emulate_command(r, outbuf); + rc = scsi_disk_emulate_command(r); if (rc < 0) { return 0; }