Revision a76bab49

b/Makefile
51 51
BLOCK_OBJS+=block-cow.o block-qcow.o aes.o block-vmdk.o block-cloop.o
52 52
BLOCK_OBJS+=block-dmg.o block-bochs.o block-vpc.o block-vvfat.o
53 53
BLOCK_OBJS+=block-qcow2.o block-parallels.o block-nbd.o
54
BLOCK_OBJS+=nbd.o block.o
54
BLOCK_OBJS+=nbd.o block.o aio.o
55 55

  
56 56
ifdef CONFIG_WIN32
57 57
BLOCK_OBJS += block-raw-win32.o
b/Makefile.target
474 474
ifndef CONFIG_USER_ONLY
475 475

  
476 476
OBJS=vl.o osdep.o monitor.o pci.o loader.o isa_mmio.o machine.o net-checksum.o
477
OBJS+=fw_cfg.o
477
OBJS+=fw_cfg.o aio.o
478 478
ifdef CONFIG_WIN32
479 479
OBJS+=block-raw-win32.o
480 480
else
b/aio.c
1
/*
2
 * QEMU aio implementation
3
 *
4
 * Copyright IBM, Corp. 2008
5
 *
6
 * Authors:
7
 *  Anthony Liguori   <aliguori@us.ibm.com>
8
 *
9
 * This work is licensed under the terms of the GNU GPL, version 2.  See
10
 * the COPYING file in the top-level directory.
11
 *
12
 */
13

  
14
#include "qemu-common.h"
15
#include "block.h"
16
#include "sys-queue.h"
17
#include "qemu_socket.h"
18

  
19
typedef struct AioHandler AioHandler;
20

  
21
/* The list of registered AIO handlers */
22
static LIST_HEAD(, AioHandler) aio_handlers;
23

  
24
/* This is a simple lock used to protect the aio_handlers list.  Specifically,
25
 * it's used to ensure that no callbacks are removed while we're walking and
26
 * dispatching callbacks.
27
 */
28
static int walking_handlers;
29

  
30
struct AioHandler
31
{
32
    int fd;
33
    IOHandler *io_read;
34
    IOHandler *io_write;
35
    AioFlushHandler *io_flush;
36
    int deleted;
37
    void *opaque;
38
    LIST_ENTRY(AioHandler) node;
39
};
40

  
41
static AioHandler *find_aio_handler(int fd)
42
{
43
    AioHandler *node;
44

  
45
    LIST_FOREACH(node, &aio_handlers, node) {
46
        if (node->fd == fd)
47
            return node;
48
    }
49

  
50
    return NULL;
51
}
52

  
53
int qemu_aio_set_fd_handler(int fd,
54
                            IOHandler *io_read,
55
                            IOHandler *io_write,
56
                            AioFlushHandler *io_flush,
57
                            void *opaque)
58
{
59
    AioHandler *node;
60

  
61
    node = find_aio_handler(fd);
62

  
63
    /* Are we deleting the fd handler? */
64
    if (!io_read && !io_write) {
65
        if (node) {
66
            /* If the lock is held, just mark the node as deleted */
67
            if (walking_handlers)
68
                node->deleted = 1;
69
            else {
70
                /* Otherwise, delete it for real.  We can't just mark it as
71
                 * deleted because deleted nodes are only cleaned up after
72
                 * releasing the walking_handlers lock.
73
                 */
74
                LIST_REMOVE(node, node);
75
                qemu_free(node);
76
            }
77
        }
78
    } else {
79
        if (node == NULL) {
80
            /* Alloc and insert if it's not already there */
81
            node = qemu_mallocz(sizeof(AioHandler));
82
            if (node == NULL)
83
                return -ENOMEM;
84
            node->fd = fd;
85
            LIST_INSERT_HEAD(&aio_handlers, node, node);
86
        }
87
        /* Update handler with latest information */
88
        node->io_read = io_read;
89
        node->io_write = io_write;
90
        node->io_flush = io_flush;
91
        node->opaque = opaque;
92
    }
93

  
94
    qemu_set_fd_handler2(fd, NULL, io_read, io_write, opaque);
95

  
96
    return 0;
97
}
98

  
99
void qemu_aio_flush(void)
100
{
101
    AioHandler *node;
102
    int ret;
103

  
104
    do {
105
        ret = 0;
106

  
107
        LIST_FOREACH(node, &aio_handlers, node) {
108
            ret |= node->io_flush(node->opaque);
109
        }
110

  
111
        qemu_aio_wait();
112
    } while (ret > 0);
113
}
114

  
115
void qemu_aio_wait(void)
116
{
117
    int ret;
118

  
119
    if (qemu_bh_poll())
120
        return;
121

  
122
    do {
123
        AioHandler *node;
124
        fd_set rdfds, wrfds;
125
        int max_fd = -1;
126

  
127
        walking_handlers = 1;
128

  
129
        /* fill fd sets */
130
        LIST_FOREACH(node, &aio_handlers, node) {
131
            /* If there aren't pending AIO operations, don't invoke callbacks.
132
             * Otherwise, if there are no AIO requests, qemu_aio_wait() would
133
             * wait indefinitely.
134
             */
135
            if (node->io_flush && node->io_flush(node->opaque) == 0)
136
                continue;
137

  
138
            if (!node->deleted && node->io_read) {
139
                FD_SET(node->fd, &rdfds);
140
                max_fd = MAX(max_fd, node->fd + 1);
141
            }
142
            if (!node->deleted && node->io_write) {
143
                FD_SET(node->fd, &wrfds);
144
                max_fd = MAX(max_fd, node->fd + 1);
145
            }
146
        }
147

  
148
        walking_handlers = 0;
149

  
150
        /* No AIO operations?  Get us out of here */
151
        if (max_fd == -1)
152
            break;
153

  
154
        /* wait until next event */
155
        ret = select(max_fd, &rdfds, &wrfds, NULL, NULL);
156
        if (ret == -1 && errno == EINTR)
157
            continue;
158

  
159
        /* if we have any readable fds, dispatch event */
160
        if (ret > 0) {
161
            walking_handlers = 1;
162

  
163
            /* we have to walk very carefully in case
164
             * qemu_aio_set_fd_handler is called while we're walking */
165
            node = LIST_FIRST(&aio_handlers);
166
            while (node) {
167
                AioHandler *tmp;
168

  
169
                if (!node->deleted &&
170
                    FD_ISSET(node->fd, &rdfds) &&
171
                    node->io_read) {
172
                    node->io_read(node->opaque);
173
                }
174
                if (!node->deleted &&
175
                    FD_ISSET(node->fd, &wrfds) &&
176
                    node->io_write) {
177
                    node->io_write(node->opaque);
178
                }
179

  
180
                tmp = node;
181
                node = LIST_NEXT(node, node);
182

  
183
                if (tmp->deleted) {
184
                    LIST_REMOVE(tmp, node);
185
                    qemu_free(tmp);
186
                }
187
            }
188

  
189
            walking_handlers = 0;
190
        }
191
    } while (ret == 0);
192
}
b/block-raw-posix.c
101 101
#endif
102 102
} BDRVRawState;
103 103

  
104
static int posix_aio_init(void);
105

  
104 106
static int fd_open(BlockDriverState *bs);
105 107

  
106 108
static int raw_open(BlockDriverState *bs, const char *filename, int flags)
......
108 110
    BDRVRawState *s = bs->opaque;
109 111
    int fd, open_flags, ret;
110 112

  
113
    posix_aio_init();
114

  
111 115
    s->lseek_err_cnt = 0;
112 116

  
113 117
    open_flags = O_BINARY;
......
437 441
    int ret;
438 442
} RawAIOCB;
439 443

  
440
static int aio_sig_fd = -1;
441
static int aio_sig_num = SIGUSR2;
442
static RawAIOCB *first_aio; /* AIO issued */
443
static int aio_initialized = 0;
444
typedef struct PosixAioState
445
{
446
    int fd;
447
    RawAIOCB *first_aio;
448
} PosixAioState;
444 449

  
445
static void qemu_aio_poll(void *opaque)
450
static void posix_aio_read(void *opaque)
446 451
{
452
    PosixAioState *s = opaque;
447 453
    RawAIOCB *acb, **pacb;
448 454
    int ret;
449 455
    size_t offset;
......
457 463
    while (offset < 128) {
458 464
        ssize_t len;
459 465

  
460
        len = read(aio_sig_fd, sig.buf + offset, 128 - offset);
466
        len = read(s->fd, sig.buf + offset, 128 - offset);
461 467
        if (len == -1 && errno == EINTR)
462 468
            continue;
463 469
        if (len == -1 && errno == EAGAIN) {
......
472 478
    }
473 479

  
474 480
    for(;;) {
475
        pacb = &first_aio;
481
        pacb = &s->first_aio;
476 482
        for(;;) {
477 483
            acb = *pacb;
478 484
            if (!acb)
......
507 513
 the_end: ;
508 514
}
509 515

  
510
void qemu_aio_init(void)
516
static int posix_aio_flush(void *opaque)
511 517
{
512
    sigset_t mask;
518
    PosixAioState *s = opaque;
519
    return !!s->first_aio;
520
}
513 521

  
514
    if (aio_initialized)
515
        return;
522
static PosixAioState *posix_aio_state;
516 523

  
517
    aio_initialized = 1;
524
static int posix_aio_init(void)
525
{
526
    sigset_t mask;
527
    PosixAioState *s;
528
  
529
    if (posix_aio_state)
530
        return 0;
531

  
532
    s = qemu_malloc(sizeof(PosixAioState));
533
    if (s == NULL)
534
        return -ENOMEM;
518 535

  
519 536
    /* Make sure to block AIO signal */
520 537
    sigemptyset(&mask);
521
    sigaddset(&mask, aio_sig_num);
538
    sigaddset(&mask, SIGUSR2);
522 539
    sigprocmask(SIG_BLOCK, &mask, NULL);
523 540
    
524
    aio_sig_fd = qemu_signalfd(&mask);
541
    s->first_aio = NULL;
542
    s->fd = qemu_signalfd(&mask);
525 543

  
526
    fcntl(aio_sig_fd, F_SETFL, O_NONBLOCK);
544
    fcntl(s->fd, F_SETFL, O_NONBLOCK);
527 545

  
528
    qemu_set_fd_handler2(aio_sig_fd, NULL, qemu_aio_poll, NULL, NULL);
546
    qemu_aio_set_fd_handler(s->fd, posix_aio_read, NULL, posix_aio_flush, s);
529 547

  
530 548
#if defined(__GLIBC__) && defined(__linux__)
531 549
    {
......
539 557
        aio_init(&ai);
540 558
    }
541 559
#endif
542
}
543

  
544
/* Wait for all IO requests to complete.  */
545
void qemu_aio_flush(void)
546
{
547
    qemu_aio_poll(NULL);
548
    while (first_aio) {
549
        qemu_aio_wait();
550
    }
551
}
552

  
553
void qemu_aio_wait(void)
554
{
555
    int ret;
556

  
557
    if (qemu_bh_poll())
558
        return;
559

  
560
    if (!first_aio)
561
        return;
562

  
563
    do {
564
        fd_set rdfds;
565

  
566
        FD_ZERO(&rdfds);
567
        FD_SET(aio_sig_fd, &rdfds);
560
    posix_aio_state = s;
568 561

  
569
        ret = select(aio_sig_fd + 1, &rdfds, NULL, NULL, NULL);
570
        if (ret == -1 && errno == EINTR)
571
            continue;
572
    } while (ret == 0);
573

  
574
    qemu_aio_poll(NULL);
562
    return 0;
575 563
}
576 564

  
577 565
static RawAIOCB *raw_aio_setup(BlockDriverState *bs,
......
588 576
    if (!acb)
589 577
        return NULL;
590 578
    acb->aiocb.aio_fildes = s->fd;
591
    acb->aiocb.aio_sigevent.sigev_signo = aio_sig_num;
579
    acb->aiocb.aio_sigevent.sigev_signo = SIGUSR2;
592 580
    acb->aiocb.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
593 581
    acb->aiocb.aio_buf = buf;
594 582
    if (nb_sectors < 0)
......
596 584
    else
597 585
        acb->aiocb.aio_nbytes = nb_sectors * 512;
598 586
    acb->aiocb.aio_offset = sector_num * 512;
599
    acb->next = first_aio;
600
    first_aio = acb;
587
    acb->next = posix_aio_state->first_aio;
588
    posix_aio_state->first_aio = acb;
601 589
    return acb;
602 590
}
603 591

  
......
688 676
    }
689 677

  
690 678
    /* remove the callback from the queue */
691
    pacb = &first_aio;
679
    pacb = &posix_aio_state->first_aio;
692 680
    for(;;) {
693 681
        if (*pacb == NULL) {
694 682
            break;
......
701 689
    }
702 690
}
703 691

  
704
# else /* CONFIG_AIO */
705

  
706
void qemu_aio_init(void)
692
#else /* CONFIG_AIO */
693
static int posix_aio_init(void)
707 694
{
708 695
}
709

  
710
void qemu_aio_flush(void)
711
{
712
}
713

  
714
void qemu_aio_wait(void)
715
{
716
    qemu_bh_poll();
717
}
718

  
719 696
#endif /* CONFIG_AIO */
720 697

  
721 698
static void raw_close(BlockDriverState *bs)
......
921 898
    BDRVRawState *s = bs->opaque;
922 899
    int fd, open_flags, ret;
923 900

  
901
    posix_aio_init();
902

  
924 903
#ifdef CONFIG_COCOA
925 904
    if (strstart(filename, "/dev/cdrom", NULL)) {
926 905
        kern_return_t kernResult;
b/block-raw-win32.c
339 339
    return 0;
340 340
}
341 341

  
342
void qemu_aio_init(void)
343
{
344
}
345

  
346
void qemu_aio_flush(void)
347
{
348
}
349

  
350
void qemu_aio_wait(void)
351
{
352
    qemu_bh_poll();
353
}
354

  
355 342
BlockDriver bdrv_raw = {
356 343
    "raw",
357 344
    sizeof(BDRVRawState),
b/block.c
1310 1310
    bdrv_register(&bdrv_qcow2);
1311 1311
    bdrv_register(&bdrv_parallels);
1312 1312
    bdrv_register(&bdrv_nbd);
1313

  
1314
    qemu_aio_init();
1315 1313
}
1316 1314

  
1317 1315
void *qemu_aio_get(BlockDriverState *bs, BlockDriverCompletionFunc *cb,
b/block.h
1 1
#ifndef BLOCK_H
2 2
#define BLOCK_H
3 3

  
4
#include "qemu-aio.h"
5

  
4 6
/* block.c */
5 7
typedef struct BlockDriver BlockDriver;
6 8

  
......
87 89
                                 BlockDriverCompletionFunc *cb, void *opaque);
88 90
void bdrv_aio_cancel(BlockDriverAIOCB *acb);
89 91

  
90
void qemu_aio_init(void);
91
void qemu_aio_flush(void);
92
void qemu_aio_wait(void);
93

  
94 92
int qemu_key_check(BlockDriverState *bs, const char *name);
95 93

  
96 94
/* Ensure contents are flushed to disk.  */
b/qemu-aio.h
1
/*
2
 * QEMU aio implementation
3
 *
4
 * Copyright IBM, Corp. 2008
5
 *
6
 * Authors:
7
 *  Anthony Liguori   <aliguori@us.ibm.com>
8
 *
9
 * This work is licensed under the terms of the GNU GPL, version 2.  See
10
 * the COPYING file in the top-level directory.
11
 *
12
 */
13

  
14
#ifndef QEMU_AIO_H
15
#define QEMU_AIO_H
16

  
17
#include "qemu-common.h"
18
#include "qemu-char.h"
19

  
20
/* Returns 1 if there are still outstanding AIO requests; 0 otherwise */
21
typedef int (AioFlushHandler)(void *opaque);
22

  
23
/* Flush any pending AIO operation. This function will block until all
24
 * outstanding AIO operations have been completed or cancelled. */
25
void qemu_aio_flush(void);
26

  
27
/* Wait for a single AIO completion to occur.  This function will until a
28
 * single AIO opeartion has completed.  It is intended to be used as a looping
29
 * primative when simulating synchronous IO based on asynchronous IO. */
30
void qemu_aio_wait(void);
31

  
32
/* Register a file descriptor and associated callbacks.  Behaves very similarly
33
 * to qemu_set_fd_handler2.  Unlike qemu_set_fd_handler2, these callbacks will
34
 * be invoked when using either qemu_aio_wait() or qemu_aio_flush().
35
 *
36
 * Code that invokes AIO completion functions should rely on this function
37
 * instead of qemu_set_fd_handler[2].
38
 */
39
int qemu_aio_set_fd_handler(int fd,
40
                            IOHandler *io_read,
41
                            IOHandler *io_write,
42
                            AioFlushHandler *io_flush,
43
                            void *opaque);
44

  
45
#endif

Also available in: Unified diff