From patchwork Tue Nov 17 10:17:39 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gerd Hoffmann X-Patchwork-Id: 38608 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 97AC3B7B61 for ; Tue, 17 Nov 2009 21:25:09 +1100 (EST) Received: from localhost ([127.0.0.1]:50099 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NALFA-00025o-Ap for incoming@patchwork.ozlabs.org; Tue, 17 Nov 2009 05:25:04 -0500 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1NAL8T-0000Em-PA for qemu-devel@nongnu.org; Tue, 17 Nov 2009 05:18:09 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1NAL8L-0000A8-41 for qemu-devel@nongnu.org; Tue, 17 Nov 2009 05:18:05 -0500 Received: from [199.232.76.173] (port=58243 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NAL8K-00009c-Mj for qemu-devel@nongnu.org; Tue, 17 Nov 2009 05:18:00 -0500 Received: from mx1.redhat.com ([209.132.183.28]:62381) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1NAL8K-0006ud-3w for qemu-devel@nongnu.org; Tue, 17 Nov 2009 05:18:00 -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 nAHAHx00020146 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Tue, 17 Nov 2009 05:17:59 -0500 Received: from zweiblum.home.kraxel.org (vpn1-7-195.ams2.redhat.com [10.36.7.195]) by int-mx05.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with SMTP id nAHAHrk8023682; Tue, 17 Nov 2009 05:17:54 -0500 Received: by zweiblum.home.kraxel.org (Postfix, from userid 500) id 1F3F970060; Tue, 17 Nov 2009 11:17:52 +0100 (CET) From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Tue, 17 Nov 2009 11:17:39 +0100 Message-Id: <1258453071-3496-4-git-send-email-kraxel@redhat.com> In-Reply-To: <1258453071-3496-1-git-send-email-kraxel@redhat.com> References: <1258453071-3496-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/15] 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). * Fix request cleanup in the destroy callback. Signed-off-by: Gerd Hoffmann Reviewed-by: Christoph Hellwig --- hw/scsi-bus.c | 1 + hw/scsi-disk.c | 58 ++++++++++++++++++---------------------------- hw/scsi-generic.c | 66 ++++++++++++++-------------------------------------- hw/scsi.h | 2 + 4 files changed, 44 insertions(+), 83 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..2b13635 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; @@ -74,16 +72,15 @@ struct SCSIDiskState }; /* Global pool of SCSIRequest structures. */ -static SCSIDiskReq *free_requests = NULL; +static QTAILQ_HEAD(, SCSIRequest) free_requests = QTAILQ_HEAD_INITIALIZER(free_requests); 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; + if (!QTAILQ_EMPTY(&free_requests)) { + r = DO_UPCAST(SCSIDiskReq, req, QTAILQ_FIRST(&free_requests)); + QTAILQ_REMOVE(&free_requests, &r->req, next); } else { r = qemu_malloc(sizeof(SCSIDiskReq)); r->iov.iov_base = qemu_memalign(512, SCSI_DMA_BUF_SIZE); @@ -96,41 +93,26 @@ static SCSIDiskReq *scsi_new_request(SCSIDevice *d, uint32_t tag) 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; + QTAILQ_REMOVE(&r->req.dev->requests, &r->req, next); + QTAILQ_INSERT_HEAD(&free_requests, &r->req, next); } static SCSIDiskReq *scsi_find_request(SCSIDiskState *s, uint32_t tag) { - SCSIDiskReq *r; + SCSIRequest *req; - r = s->requests; - while (r && r->req.tag != tag) - r = r->next; - - 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 +292,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 +942,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..5ca6840 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; @@ -79,16 +77,15 @@ struct SCSIGenericState }; /* Global pool of SCSIGenericReq structures. */ -static SCSIGenericReq *free_requests = NULL; +static QTAILQ_HEAD(, SCSIRequest) free_requests = QTAILQ_HEAD_INITIALIZER(free_requests); 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; + if (!QTAILQ_EMPTY(&free_requests)) { + r = DO_UPCAST(SCSIGenericReq, req, QTAILQ_FIRST(&free_requests)); + QTAILQ_REMOVE(&free_requests, &r->req, next); } else { r = qemu_malloc(sizeof(SCSIGenericReq)); r->buf = NULL; @@ -103,43 +100,26 @@ static SCSIGenericReq *scsi_new_request(SCSIDevice *d, uint32_t tag) 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; + QTAILQ_REMOVE(&r->req.dev->requests, &r->req, next); + QTAILQ_INSERT_HEAD(&free_requests, &r->req, next); } 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 +633,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 */