Skip to content
  • Sergio Lopez's avatar
    f148ae7d
    nbd/server: Quiesce coroutines on context switch · f148ae7d
    Sergio Lopez authored
    When switching between AIO contexts we need to me make sure that both
    recv_coroutine and send_coroutine are not scheduled to run. Otherwise,
    QEMU may crash while attaching the new context with an error like
    this one:
    
    aio_co_schedule: Co-routine was already scheduled in 'aio_co_schedule'
    
    To achieve this we need a local implementation of
    'qio_channel_readv_all_eof' named 'nbd_read_eof' (a trick already done
    by 'nbd/client.c') that allows us to interrupt the operation and to
    know when recv_coroutine is yielding.
    
    With this in place, we delegate detaching the AIO context to the
    owning context with a BH ('nbd_aio_detach_bh') scheduled using
    'aio_wait_bh_oneshot'. This BH signals that we need to quiesce the
    channel by setting 'client->quiescing' to 'true', and either waits for
    the coroutine to finish using AIO_WAIT_WHILE or, if it's yielding in
    'nbd_read_eof', actively enters the coroutine to interrupt it.
    
    RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1900326
    
    
    Signed-off-by: default avatarSergio Lopez <slp@redhat.com>
    Reviewed-by: default avatarEric Blake <eblake@redhat.com>
    Message-Id: <20201214170519.223781-4-slp@redhat.com>
    Signed-off-by: default avatarEric Blake <eblake@redhat.com>
    f148ae7d
    nbd/server: Quiesce coroutines on context switch
    Sergio Lopez authored
    When switching between AIO contexts we need to me make sure that both
    recv_coroutine and send_coroutine are not scheduled to run. Otherwise,
    QEMU may crash while attaching the new context with an error like
    this one:
    
    aio_co_schedule: Co-routine was already scheduled in 'aio_co_schedule'
    
    To achieve this we need a local implementation of
    'qio_channel_readv_all_eof' named 'nbd_read_eof' (a trick already done
    by 'nbd/client.c') that allows us to interrupt the operation and to
    know when recv_coroutine is yielding.
    
    With this in place, we delegate detaching the AIO context to the
    owning context with a BH ('nbd_aio_detach_bh') scheduled using
    'aio_wait_bh_oneshot'. This BH signals that we need to quiesce the
    channel by setting 'client->quiescing' to 'true', and either waits for
    the coroutine to finish using AIO_WAIT_WHILE or, if it's yielding in
    'nbd_read_eof', actively enters the coroutine to interrupt it.
    
    RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1900326
    
    
    Signed-off-by: default avatarSergio Lopez <slp@redhat.com>
    Reviewed-by: default avatarEric Blake <eblake@redhat.com>
    Message-Id: <20201214170519.223781-4-slp@redhat.com>
    Signed-off-by: default avatarEric Blake <eblake@redhat.com>
Loading