From patchwork Thu Nov 26 14:33:49 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gerd Hoffmann X-Patchwork-Id: 39524 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 080A91007D1 for ; Fri, 27 Nov 2009 02:06:55 +1100 (EST) Received: from localhost ([127.0.0.1]:42096 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NDfvo-00089M-Vh for incoming@patchwork.ozlabs.org; Thu, 26 Nov 2009 10:06:53 -0500 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1NDfQi-0006eC-E6 for qemu-devel@nongnu.org; Thu, 26 Nov 2009 09:34:44 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1NDfQc-0006be-KB for qemu-devel@nongnu.org; Thu, 26 Nov 2009 09:34:43 -0500 Received: from [199.232.76.173] (port=56151 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NDfQb-0006bJ-Vv for qemu-devel@nongnu.org; Thu, 26 Nov 2009 09:34:38 -0500 Received: from mx1.redhat.com ([209.132.183.28]:23488) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1NDfQb-0000Dd-A2 for qemu-devel@nongnu.org; Thu, 26 Nov 2009 09:34:37 -0500 Received: from int-mx05.intmail.prod.int.phx2.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.18]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id nAQEYaRg005908 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Thu, 26 Nov 2009 09:34:36 -0500 Received: from zweiblum.home.kraxel.org (vpn2-8-164.ams2.redhat.com [10.36.8.164]) by int-mx05.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with SMTP id nAQEYQ55029180; Thu, 26 Nov 2009 09:34:29 -0500 Received: by zweiblum.home.kraxel.org (Postfix, from userid 500) id CEFD412006; Thu, 26 Nov 2009 15:34:17 +0100 (CET) From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Thu, 26 Nov 2009 15:33:49 +0100 Message-Id: <1259246056-5389-4-git-send-email-kraxel@redhat.com> In-Reply-To: <1259246056-5389-1-git-send-email-kraxel@redhat.com> References: <1259246056-5389-1-git-send-email-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.18 X-detected-operating-system: by monty-python.gnu.org: Genre and OS details not recognized. Cc: Gerd Hoffmann Subject: [Qemu-devel] [PATCH 03/30] scsi: move request lists to QTAILQ. X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Changes: * Move from open-coded lists to QTAILQ macros. * Move the struct elements to the common data structures (SCSIDevice + SCSIRequest). * Drop free request pools. * Fix request cleanup in the destroy callback. Signed-off-by: Gerd Hoffmann --- hw/scsi-bus.c | 1 + hw/scsi-disk.c | 67 +++++++++++++++------------------------------- hw/scsi-generic.c | 76 +++++++++++----------------------------------------- hw/scsi.h | 2 + 4 files changed, 41 insertions(+), 105 deletions(-) diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c index 641db81..801922b 100644 --- a/hw/scsi-bus.c +++ b/hw/scsi-bus.c @@ -50,6 +50,7 @@ static int scsi_qdev_init(DeviceState *qdev, DeviceInfo *base) bus->devs[dev->id] = dev; dev->info = info; + QTAILQ_INIT(&dev->requests); rc = dev->info->init(dev); if (rc != 0) { bus->devs[dev->id] = NULL; diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index 142d81d..997eef6 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -55,7 +55,6 @@ typedef struct SCSIDiskReq { uint32_t sector_count; struct iovec iov; QEMUIOVector qiov; - struct SCSIDiskReq *next; uint32_t status; } SCSIDiskReq; @@ -63,7 +62,6 @@ struct SCSIDiskState { SCSIDevice qdev; DriveInfo *dinfo; - SCSIDiskReq *requests; /* The qemu block layer uses a fixed 512 byte sector size. This is the number of 512 byte blocks in a single scsi sector. */ int cluster_size; @@ -73,64 +71,37 @@ struct SCSIDiskState QEMUBH *bh; }; -/* Global pool of SCSIRequest structures. */ -static SCSIDiskReq *free_requests = NULL; - static SCSIDiskReq *scsi_new_request(SCSIDevice *d, uint32_t tag) { - SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d); SCSIDiskReq *r; - if (free_requests) { - r = free_requests; - free_requests = r->next; - } else { - r = qemu_malloc(sizeof(SCSIDiskReq)); - r->iov.iov_base = qemu_memalign(512, SCSI_DMA_BUF_SIZE); - } + r = qemu_mallocz(sizeof(SCSIDiskReq)); + r->iov.iov_base = qemu_memalign(512, SCSI_DMA_BUF_SIZE); r->req.bus = scsi_bus_from_device(d); r->req.dev = d; r->req.tag = tag; - r->sector_count = 0; - r->iov.iov_len = 0; - r->req.aiocb = NULL; - r->status = 0; - r->next = s->requests; - s->requests = r; + QTAILQ_INSERT_TAIL(&d->requests, &r->req, next); return r; } static void scsi_remove_request(SCSIDiskReq *r) { - SCSIDiskReq *last; - SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); - - if (s->requests == r) { - s->requests = r->next; - } else { - last = s->requests; - while (last && last->next != r) - last = last->next; - if (last) { - last->next = r->next; - } else { - BADF("Orphaned request\n"); - } - } - r->next = free_requests; - free_requests = r; + qemu_free(r->iov.iov_base); + QTAILQ_REMOVE(&r->req.dev->requests, &r->req, next); + qemu_free(r); } static SCSIDiskReq *scsi_find_request(SCSIDiskState *s, uint32_t tag) { - SCSIDiskReq *r; - - r = s->requests; - while (r && r->req.tag != tag) - r = r->next; + SCSIRequest *req; - return r; + QTAILQ_FOREACH(req, &s->qdev.requests, next) { + if (req->tag == tag) { + return DO_UPCAST(SCSIDiskReq, req, req); + } + } + return NULL; } /* Helper function for command completion. */ @@ -310,17 +281,18 @@ static int scsi_write_data(SCSIDevice *d, uint32_t tag) static void scsi_dma_restart_bh(void *opaque) { SCSIDiskState *s = opaque; - SCSIDiskReq *r = s->requests; + SCSIRequest *req; + SCSIDiskReq *r; qemu_bh_delete(s->bh); s->bh = NULL; - while (r) { + QTAILQ_FOREACH(req, &s->qdev.requests, next) { + r = DO_UPCAST(SCSIDiskReq, req, req); if (r->status & SCSI_REQ_STATUS_RETRY) { r->status &= ~SCSI_REQ_STATUS_RETRY; scsi_write_request(r); } - r = r->next; } } @@ -959,7 +931,12 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag, static void scsi_destroy(SCSIDevice *dev) { SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev); + SCSIDiskReq *r; + while (!QTAILQ_EMPTY(&s->qdev.requests)) { + r = DO_UPCAST(SCSIDiskReq, req, QTAILQ_FIRST(&s->qdev.requests)); + scsi_remove_request(r); + } drive_uninit(s->dinfo); } diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c index 89f3080..1fa9d33 100644 --- a/hw/scsi-generic.c +++ b/hw/scsi-generic.c @@ -56,7 +56,6 @@ typedef struct SCSIGenericState SCSIGenericState; typedef struct SCSIGenericReq { SCSIRequest req; - struct SCSIGenericReq *next; uint8_t cmd[SCSI_CMD_BUF_SIZE]; int cmdlen; uint8_t *buf; @@ -68,7 +67,6 @@ typedef struct SCSIGenericReq { struct SCSIGenericState { SCSIDevice qdev; - SCSIGenericReq *requests; DriveInfo *dinfo; int type; int blocksize; @@ -78,68 +76,36 @@ struct SCSIGenericState uint8_t senselen; }; -/* Global pool of SCSIGenericReq structures. */ -static SCSIGenericReq *free_requests = NULL; - static SCSIGenericReq *scsi_new_request(SCSIDevice *d, uint32_t tag) { - SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d); SCSIGenericReq *r; - if (free_requests) { - r = free_requests; - free_requests = r->next; - } else { - r = qemu_malloc(sizeof(SCSIGenericReq)); - r->buf = NULL; - r->buflen = 0; - } + r = qemu_mallocz(sizeof(SCSIGenericReq)); r->req.bus = scsi_bus_from_device(d); r->req.dev = d; r->req.tag = tag; - memset(r->cmd, 0, sizeof(r->cmd)); - memset(&r->io_header, 0, sizeof(r->io_header)); - r->cmdlen = 0; - r->len = 0; - r->req.aiocb = NULL; - /* link */ - - r->next = s->requests; - s->requests = r; + QTAILQ_INSERT_TAIL(&d->requests, &r->req, next); return r; } static void scsi_remove_request(SCSIGenericReq *r) { - SCSIGenericReq *last; - SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev); - - if (s->requests == r) { - s->requests = r->next; - } else { - last = s->requests; - while (last && last->next != r) - last = last->next; - if (last) { - last->next = r->next; - } else { - BADF("Orphaned request\n"); - } - } - r->next = free_requests; - free_requests = r; + qemu_free(r->buf); + QTAILQ_REMOVE(&r->req.dev->requests, &r->req, next); + qemu_free(r); } static SCSIGenericReq *scsi_find_request(SCSIGenericState *s, uint32_t tag) { - SCSIGenericReq *r; - - r = s->requests; - while (r && r->req.tag != tag) - r = r->next; + SCSIRequest *req; - return r; + QTAILQ_FOREACH(req, &s->qdev.requests, next) { + if (req->tag == tag) { + return DO_UPCAST(SCSIGenericReq, req, req); + } + } + return NULL; } /* Helper function for command completion. */ @@ -653,22 +619,12 @@ static int get_stream_blocksize(BlockDriverState *bdrv) static void scsi_destroy(SCSIDevice *d) { SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d); - SCSIGenericReq *r, *n; - - r = s->requests; - while (r) { - n = r->next; - qemu_free(r); - r = n; - } + SCSIGenericReq *r; - r = free_requests; - while (r) { - n = r->next; - qemu_free(r); - r = n; + while (!QTAILQ_EMPTY(&s->qdev.requests)) { + r = DO_UPCAST(SCSIGenericReq, req, QTAILQ_FIRST(&s->qdev.requests)); + scsi_remove_request(r); } - drive_uninit(s->dinfo); } diff --git a/hw/scsi.h b/hw/scsi.h index 7906877..a9b846c 100644 --- a/hw/scsi.h +++ b/hw/scsi.h @@ -21,6 +21,7 @@ typedef struct SCSIRequest { SCSIDevice *dev; uint32_t tag; BlockDriverAIOCB *aiocb; + QTAILQ_ENTRY(SCSIRequest) next; } SCSIRequest; struct SCSIDevice @@ -28,6 +29,7 @@ struct SCSIDevice DeviceState qdev; uint32_t id; SCSIDeviceInfo *info; + QTAILQ_HEAD(, SCSIRequest) requests; }; /* cdrom.c */