Commit e268ca52328eb0460ae0d10b7f4313a63d5b000c
1 parent
94909d9f
implement qemu_blockalign (Stefano Stabellini)
this patch adds a buffer_alignment field to BlockDriverState and implements a qemu_blockalign function that uses that field to allocate a memory aligned buffer to be used by the block driver. buffer_alignment is initialized to 512 but each block driver can set a different value (at the moment none of them do). This patch modifies ide.c, block-qcow.c, block-qcow2.c and block.c to use qemu_blockalign instead of qemu_memalign. There is only one place left that still uses qemu_memalign to allocate buffers used by block drivers that is posix-aio-compat:handle_aiocb_rw because it is not possible to get the BlockDriverState from that function. However I think it is not important because posix-aio-compat already deals with driver specific code so it is supposed to know its own needs. Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@7229 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
6 changed files
with
18 additions
and
6 deletions
block-qcow.c
... | ... | @@ -641,7 +641,7 @@ static BlockDriverAIOCB *qcow_aio_readv(BlockDriverState *bs, |
641 | 641 | acb->sector_num = sector_num; |
642 | 642 | acb->qiov = qiov; |
643 | 643 | if (qiov->niov > 1) |
644 | - acb->buf = acb->orig_buf = qemu_memalign(512, qiov->size); | |
644 | + acb->buf = acb->orig_buf = qemu_blockalign(bs, qiov->size); | |
645 | 645 | else |
646 | 646 | acb->buf = (uint8_t *)qiov->iov->iov_base; |
647 | 647 | acb->nb_sectors = nb_sectors; |
... | ... | @@ -736,7 +736,7 @@ static BlockDriverAIOCB *qcow_aio_writev(BlockDriverState *bs, |
736 | 736 | acb->sector_num = sector_num; |
737 | 737 | acb->qiov = qiov; |
738 | 738 | if (qiov->niov > 1) { |
739 | - acb->buf = acb->orig_buf = qemu_memalign(512, qiov->size); | |
739 | + acb->buf = acb->orig_buf = qemu_blockalign(bs, qiov->size); | |
740 | 740 | qemu_iovec_to_buffer(qiov, acb->buf); |
741 | 741 | } else { |
742 | 742 | acb->buf = (uint8_t *)qiov->iov->iov_base; | ... | ... |
block-qcow2.c
... | ... | @@ -1412,7 +1412,7 @@ static QCowAIOCB *qcow_aio_setup(BlockDriverState *bs, |
1412 | 1412 | acb->sector_num = sector_num; |
1413 | 1413 | acb->qiov = qiov; |
1414 | 1414 | if (qiov->niov > 1) { |
1415 | - acb->buf = acb->orig_buf = qemu_memalign(512, qiov->size); | |
1415 | + acb->buf = acb->orig_buf = qemu_blockalign(bs, qiov->size); | |
1416 | 1416 | if (is_write) |
1417 | 1417 | qemu_iovec_to_buffer(qiov, acb->buf); |
1418 | 1418 | } else { | ... | ... |
block-raw-posix.c
... | ... | @@ -165,7 +165,7 @@ static int raw_open(BlockDriverState *bs, const char *filename, int flags) |
165 | 165 | s->fd = fd; |
166 | 166 | s->aligned_buf = NULL; |
167 | 167 | if ((flags & BDRV_O_NOCACHE)) { |
168 | - s->aligned_buf = qemu_memalign(512, ALIGNED_BUFFER_SIZE); | |
168 | + s->aligned_buf = qemu_blockalign(bs, ALIGNED_BUFFER_SIZE); | |
169 | 169 | if (s->aligned_buf == NULL) { |
170 | 170 | ret = -errno; |
171 | 171 | close(fd); | ... | ... |
block.c
... | ... | @@ -362,6 +362,8 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, |
362 | 362 | bs->is_temporary = 0; |
363 | 363 | bs->encrypted = 0; |
364 | 364 | bs->valid_key = 0; |
365 | + /* buffer_alignment defaulted to 512, drivers can change this value */ | |
366 | + bs->buffer_alignment = 512; | |
365 | 367 | |
366 | 368 | if (flags & BDRV_O_SNAPSHOT) { |
367 | 369 | BlockDriverState *bs1; |
... | ... | @@ -1390,7 +1392,7 @@ static BlockDriverAIOCB *bdrv_aio_rw_vector(BlockDriverState *bs, |
1390 | 1392 | acb = qemu_aio_get(bs, cb, opaque); |
1391 | 1393 | acb->is_write = is_write; |
1392 | 1394 | acb->qiov = qiov; |
1393 | - acb->bounce = qemu_memalign(512, qiov->size); | |
1395 | + acb->bounce = qemu_blockalign(bs, qiov->size); | |
1394 | 1396 | |
1395 | 1397 | if (!acb->bh) |
1396 | 1398 | acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb); |
... | ... | @@ -1640,3 +1642,8 @@ BlockDriverAIOCB *bdrv_aio_ioctl(BlockDriverState *bs, |
1640 | 1642 | return drv->bdrv_aio_ioctl(bs, req, buf, cb, opaque); |
1641 | 1643 | return NULL; |
1642 | 1644 | } |
1645 | + | |
1646 | +void *qemu_blockalign(BlockDriverState *bs, size_t size) | |
1647 | +{ | |
1648 | + return qemu_memalign((bs && bs->buffer_alignment) ? bs->buffer_alignment : 512, size); | |
1649 | +} | ... | ... |
block_int.h
... | ... | @@ -145,6 +145,9 @@ struct BlockDriverState { |
145 | 145 | /* Whether the disk can expand beyond total_sectors */ |
146 | 146 | int growable; |
147 | 147 | |
148 | + /* the memory alignment required for the buffers handled by this driver */ | |
149 | + int buffer_alignment; | |
150 | + | |
148 | 151 | /* NOTE: the following infos are only hints for real hardware |
149 | 152 | drivers. They are not used by the block driver */ |
150 | 153 | int cyls, heads, secs, translation; |
... | ... | @@ -173,6 +176,8 @@ void *qemu_aio_get_pool(AIOPool *pool, BlockDriverState *bs, |
173 | 176 | BlockDriverCompletionFunc *cb, void *opaque); |
174 | 177 | void qemu_aio_release(void *p); |
175 | 178 | |
179 | +void *qemu_blockalign(BlockDriverState *bs, size_t size); | |
180 | + | |
176 | 181 | extern BlockDriverState *bdrv_first; |
177 | 182 | |
178 | 183 | #endif /* BLOCK_INT_H */ | ... | ... |
hw/ide.c
... | ... | @@ -2788,11 +2788,11 @@ static void ide_init2(IDEState *ide_state, |
2788 | 2788 | |
2789 | 2789 | for(i = 0; i < 2; i++) { |
2790 | 2790 | s = ide_state + i; |
2791 | - s->io_buffer = qemu_memalign(512, IDE_DMA_BUF_SECTORS*512 + 4); | |
2792 | 2791 | if (i == 0) |
2793 | 2792 | s->bs = hd0; |
2794 | 2793 | else |
2795 | 2794 | s->bs = hd1; |
2795 | + s->io_buffer = qemu_blockalign(s->bs, IDE_DMA_BUF_SECTORS*512 + 4); | |
2796 | 2796 | if (s->bs) { |
2797 | 2797 | bdrv_get_geometry(s->bs, &nb_sectors); |
2798 | 2798 | bdrv_guess_geometry(s->bs, &cylinders, &heads, &secs); | ... | ... |