[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [Qemu-block] [PATCH] block/iscsi: handle zero events fr
From: |
Stefan Hajnoczi |
Subject: |
Re: [Qemu-devel] [Qemu-block] [PATCH] block/iscsi: handle zero events from iscsi_which_events |
Date: |
Thu, 9 Apr 2015 10:24:15 +0100 |
On Tue, Apr 7, 2015 at 9:08 PM, Peter Lieven <address@hidden> wrote:
CCing the entirety of this patch to address@hidden It is also
available in the address@hidden mailing list archives:
http://permalink.gmane.org/gmane.comp.emulators.qemu.block/460
> newer libiscsi versions may return zero events from iscsi_which_events.
>
> In this case iscsi_service will return immediately without any progress.
> To avoid busy waiting for iscsi_which_events to change we deregister all
> read and write handlers in this case and schedule a timer to periodically
> check iscsi_which_events for changed events.
>
> Next libiscsi version will introduce async reconnects and zero events
> are returned while libiscsi is waiting for a reconnect retry.
>
> Signed-off-by: Peter Lieven <address@hidden>
> ---
> block/iscsi.c | 33 +++++++++++++++++++++++++++------
> 1 file changed, 27 insertions(+), 6 deletions(-)
>
> diff --git a/block/iscsi.c b/block/iscsi.c
> index 3e34b1f..ba33290 100644
> --- a/block/iscsi.c
> +++ b/block/iscsi.c
> @@ -56,6 +56,7 @@ typedef struct IscsiLun {
> uint64_t num_blocks;
> int events;
> QEMUTimer *nop_timer;
> + QEMUTimer *event_timer;
> uint8_t lbpme;
> uint8_t lbprz;
> uint8_t has_write_same;
> @@ -95,6 +96,7 @@ typedef struct IscsiAIOCB {
> #endif
> } IscsiAIOCB;
>
> +#define EVENT_INTERVAL 250
> #define NOP_INTERVAL 5000
> #define MAX_NOP_FAILURES 3
> #define ISCSI_CMD_RETRIES ARRAY_SIZE(iscsi_retry_times)
> @@ -256,21 +258,30 @@ static void
> iscsi_set_events(IscsiLun *iscsilun)
> {
> struct iscsi_context *iscsi = iscsilun->iscsi;
> - int ev;
> + int ev = iscsi_which_events(iscsi);
>
> - /* We always register a read handler. */
> - ev = POLLIN;
> - ev |= iscsi_which_events(iscsi);
> if (ev != iscsilun->events) {
> aio_set_fd_handler(iscsilun->aio_context,
> iscsi_get_fd(iscsi),
> - iscsi_process_read,
> + (ev & POLLIN) ? iscsi_process_read : NULL,
> (ev & POLLOUT) ? iscsi_process_write : NULL,
> iscsilun);
> + iscsilun->events = ev;
> + }
>
> + /* newer versions of libiscsi may return zero events. In this
> + * case start a timer to ensure we are able to return to service
> + * once this situation changes. */
> + if (!ev) {
> + timer_mod(iscsilun->event_timer,
> + qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + EVENT_INTERVAL);
> }
> +}
>
> - iscsilun->events = ev;
> +static void iscsi_timed_set_events(void *opaque)
> +{
> + IscsiLun *iscsilun = opaque;
> + iscsi_set_events(iscsilun);
> }
>
> static void
> @@ -1214,6 +1225,11 @@ static void iscsi_detach_aio_context(BlockDriverState
> *bs)
> timer_free(iscsilun->nop_timer);
> iscsilun->nop_timer = NULL;
> }
> + if (iscsilun->event_timer) {
> + timer_del(iscsilun->event_timer);
> + timer_free(iscsilun->event_timer);
> + iscsilun->event_timer = NULL;
> + }
> }
>
> static void iscsi_attach_aio_context(BlockDriverState *bs,
> @@ -1230,6 +1246,11 @@ static void iscsi_attach_aio_context(BlockDriverState
> *bs,
> iscsi_nop_timed_event, iscsilun);
> timer_mod(iscsilun->nop_timer,
> qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + NOP_INTERVAL);
> +
> + /* Prepare a timer for a delayed call to iscsi_set_events */
> + iscsilun->event_timer = aio_timer_new(iscsilun->aio_context,
> + QEMU_CLOCK_REALTIME, SCALE_MS,
> + iscsi_timed_set_events, iscsilun);
> }
>
> static bool iscsi_is_write_protected(IscsiLun *iscsilun)
> --
> 1.7.9.5
>
>