aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRonnie Sahlberg <ronniesahlberg@gmail.com>2012-05-22 19:56:36 +1000
committerPaolo Bonzini <pbonzini@redhat.com>2012-05-28 14:04:06 +0200
commitc9b9f6824fd82058f6918b64d8fd9b1578fac353 (patch)
tree4a09da68c2d313cc249dc9be40df62f117928ddb
parent12badfc2385ae6822cbcbcc8d1c0ed71c9e0ff09 (diff)
ISCSI: redo how we set up the events
Call qemu_notify_event() after updating events. Otherwise, If we add an event for -is-writeable but the socket is already writeable there may be a delay before the event callback is actually triggered. Those delays would in particular hurt performance during BIOS boot and when the GRUB bootloader reads the kernel and initrd. But first call out to the socket write functions directly, and only set up the write event if the socket is full. This will happen very rarely and this improves performance. Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
-rw-r--r--block/iscsi.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/block/iscsi.c b/block/iscsi.c
index d37c4ee171..db41bb7582 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -39,6 +39,7 @@ typedef struct IscsiLun {
int lun;
int block_size;
unsigned long num_blocks;
+ int events;
} IscsiLun;
typedef struct IscsiAIOCB {
@@ -104,11 +105,27 @@ static void
iscsi_set_events(IscsiLun *iscsilun)
{
struct iscsi_context *iscsi = iscsilun->iscsi;
+ int ev;
- qemu_aio_set_fd_handler(iscsi_get_fd(iscsi), iscsi_process_read,
- (iscsi_which_events(iscsi) & POLLOUT)
- ? iscsi_process_write : NULL,
- iscsi_process_flush, iscsilun);
+ /* We always register a read handler. */
+ ev = POLLIN;
+ ev |= iscsi_which_events(iscsi);
+ if (ev != iscsilun->events) {
+ qemu_aio_set_fd_handler(iscsi_get_fd(iscsi),
+ iscsi_process_read,
+ (ev & POLLOUT) ? iscsi_process_write : NULL,
+ iscsi_process_flush,
+ iscsilun);
+
+ }
+
+ /* If we just added an event, the callback might be delayed
+ * unless we call qemu_notify_event().
+ */
+ if (ev & ~iscsilun->events) {
+ qemu_notify_event();
+ }
+ iscsilun->events = ev;
}
static void