From: Mark McLoughlin <markmc@redhat.com>
To: Keir Fraser <keir@xensource.com>
Cc: xen-devel <xen-devel@lists.xensource.com>
Subject: Re: [PATCH] Segments can span multiple clusters with tap:qcow
Date: Thu, 26 Apr 2007 11:21:01 +0100 [thread overview]
Message-ID: <1177582861.3487.45.camel@blaa> (raw)
In-Reply-To: <C25636E6.DF42%keir@xensource.com>
[-- Attachment #1: Type: text/plain, Size: 1082 bytes --]
On Thu, 2007-04-26 at 11:00 +0100, Keir Fraser wrote:
> On 26/4/07 10:18, "Mark McLoughlin" <markmc@redhat.com> wrote:
>
> >> The current code allocates aio-request info for every segment in a request
> >> ring (MAX_AIO_REQUESTS == BLK_RING_SIZE * MAX_SEGMENTS_PER_REQUEST). This
> >> patch seems to take into account that each segment (part-of-page) can itself
> >> be split into clusters, hence the page_size/cluster_size calculation, but
> >> shouldn't this be multiplied by the existing MAX_AIO_REQUESTS? Otherwise you
> >> provide only enough aio requests for one segment at a time, rather than a
> >> request ring's worth of segments?
> >
> > Absolutely, well spotted. I fixed that typo after testing, but
> > obviously forgot to run "quilt refresh" before sending ...
> >
> > Fixed version attached.
>
> This one doesn't build (free_aio_state: line 164: structure has no member
> named 'private'). Perhaps free_aio_state() should take a 'struct
> disk_driver' rather than a 'struct td_state'?
Gah, merge error going from 3.0.4 to 3.0.5. This one builds.
Thanks,
Mark.
[-- Attachment #2: block-qcow-multiple-aio-requests-per-segment.patch --]
[-- Type: text/x-patch, Size: 4894 bytes --]
diff -r 33e22185002a tools/blktap/drivers/block-qcow.c
--- a/tools/blktap/drivers/block-qcow.c Wed Apr 25 13:50:20 2007 +0100
+++ b/tools/blktap/drivers/block-qcow.c Thu Apr 26 11:15:46 2007 +0100
@@ -55,7 +55,6 @@
/******AIO DEFINES******/
#define REQUEST_ASYNC_FD 1
-#define MAX_AIO_REQS (MAX_REQUESTS * MAX_SEGMENTS_PER_REQ)
struct pending_aio {
td_callback_t cb;
@@ -146,18 +145,37 @@ struct tdqcow_state {
AES_KEY aes_encrypt_key; /*AES key*/
AES_KEY aes_decrypt_key; /*AES key*/
/* libaio state */
- io_context_t aio_ctx;
- struct iocb iocb_list [MAX_AIO_REQS];
- struct iocb *iocb_free [MAX_AIO_REQS];
- struct pending_aio pending_aio[MAX_AIO_REQS];
- int iocb_free_count;
- struct iocb *iocb_queue[MAX_AIO_REQS];
- int iocb_queued;
- int poll_fd; /* NB: we require aio_poll support */
- struct io_event aio_events[MAX_AIO_REQS];
+ io_context_t aio_ctx;
+ int max_aio_reqs;
+ struct iocb *iocb_list;
+ struct iocb **iocb_free;
+ struct pending_aio *pending_aio;
+ int iocb_free_count;
+ struct iocb **iocb_queue;
+ int iocb_queued;
+ int poll_fd; /* NB: we require aio_poll support */
+ struct io_event *aio_events;
};
static int decompress_cluster(struct tdqcow_state *s, uint64_t cluster_offset);
+
+static void free_aio_state(struct disk_driver *dd)
+{
+ struct tdqcow_state *s = (struct disk_driver *)dd->private;
+
+ if (s->sector_lock)
+ free(s->sector_lock);
+ if (s->iocb_list)
+ free(s->iocb_list);
+ if (s->pending_aio)
+ free(s->pending_aio);
+ if (s->aio_events)
+ free(s->aio_events);
+ if (s->iocb_free)
+ free(s->iocb_free);
+ if (s->iocb_queue)
+ free(s->iocb_queue);
+}
static int init_aio_state(struct disk_driver *dd)
{
@@ -166,6 +184,12 @@ static int init_aio_state(struct disk_dr
struct tdqcow_state *s = (struct tdqcow_state *)dd->private;
long ioidx;
+ s->iocb_list = NULL;
+ s->pending_aio = NULL;
+ s->aio_events = NULL;
+ s->iocb_free = NULL;
+ s->iocb_queue = NULL;
+
/*Initialize Locking bitmap*/
s->sector_lock = calloc(1, bs->size);
@@ -174,13 +198,26 @@ static int init_aio_state(struct disk_dr
goto fail;
}
+ /* A segment (i.e. a page) can span multiple clusters */
+ s->max_aio_reqs = (getpagesize() / s->cluster_size) + 1;
+
/* Initialize AIO */
- s->iocb_free_count = MAX_AIO_REQS;
+ s->iocb_free_count = s->max_aio_reqs;
s->iocb_queued = 0;
+
+ if (!(s->iocb_list = malloc(sizeof(struct iocb) * s->max_aio_reqs)) ||
+ !(s->pending_aio = malloc(sizeof(struct pending_aio) * s->max_aio_reqs)) ||
+ !(s->aio_events = malloc(sizeof(struct io_event) * s->max_aio_reqs)) ||
+ !(s->iocb_free = malloc(sizeof(struct iocb *) * s->max_aio_reqs)) ||
+ !(s->iocb_queue = malloc(sizeof(struct iocb *) * s->max_aio_reqs))) {
+ DPRINTF("Failed to allocate AIO structs (max_aio_reqs = %d)\n",
+ s->max_aio_reqs);
+ goto fail;
+ }
/*Signal kernel to create Poll FD for Asyc completion events*/
s->aio_ctx = (io_context_t) REQUEST_ASYNC_FD;
- s->poll_fd = io_setup(MAX_AIO_REQS, &s->aio_ctx);
+ s->poll_fd = io_setup(s->max_aio_reqs, &s->aio_ctx);
if (s->poll_fd < 0) {
if (s->poll_fd == -EAGAIN) {
@@ -198,7 +235,7 @@ static int init_aio_state(struct disk_dr
goto fail;
}
- for (i=0;i<MAX_AIO_REQS;i++)
+ for (i=0;i<s->max_aio_reqs;i++)
s->iocb_free[i] = &s->iocb_list[i];
DPRINTF("AIO state initialised\n");
@@ -946,6 +983,7 @@ int tdqcow_open (struct disk_driver *dd,
end_xenhdr:
if (init_aio_state(dd)!=0) {
DPRINTF("Unable to initialise AIO state\n");
+ free_aio_state(dd);
goto fail;
}
init_fds(dd);
@@ -962,6 +1000,7 @@ int tdqcow_open (struct disk_driver *dd,
fail:
DPRINTF("QCOW Open failed\n");
+ free_aio_state(dd);
free(s->l1_table);
free(s->l2_cache);
free(s->cluster_cache);
@@ -1145,7 +1184,7 @@ int tdqcow_do_callbacks(struct disk_driv
if (sid > MAX_IOFD) return 1;
/* Non-blocking test for completed io. */
- ret = io_getevents(prv->aio_ctx, 0, MAX_AIO_REQS, prv->aio_events,
+ ret = io_getevents(prv->aio_ctx, 0, prv->max_aio_reqs, prv->aio_events,
NULL);
for (ep = prv->aio_events, i = ret; i-- > 0; ep++) {
[-- Attachment #3: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
next prev parent reply other threads:[~2007-04-26 10:21 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-04-25 20:41 [PATCH] Segments can span multiple clusters with tap:qcow Mark McLoughlin
2007-04-26 9:09 ` Keir Fraser
2007-04-26 9:18 ` Mark McLoughlin
2007-04-26 10:00 ` Keir Fraser
2007-04-26 10:21 ` Mark McLoughlin [this message]
2007-05-03 1:06 ` [PATCH] Segments can span multiple clusters withtap:qcow Jake Wires
2007-05-03 17:40 ` Keir Fraser
2007-05-03 17:47 ` Mark McLoughlin
2007-05-03 17:54 ` Mark McLoughlin
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=1177582861.3487.45.camel@blaa \
--to=markmc@redhat.com \
--cc=keir@xensource.com \
--cc=xen-devel@lists.xensource.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.