From: Zhu Yangyang <zhuyangyan...@huawei.com>

On Mon, 24 Mar 2025 14:09:13 -0400, Stefan Hajnoczi wrote:
> On Fri, Mar 21, 2025 at 03:09:16PM +0800, zoudongjie wrote:
> > From: Zhu Yangyang <zhuyangyan...@huawei.com>
> >
> > The bdrv_drained_begin() function is a blocking function. In scenarios 
> > where network storage
> > is used and network links fail, it may block for a long time.
> > Therefore, we add a timeout parameter to control the duration of the block.
> >
> > Since bdrv_drained_begin() has been widely adopted, both 
> > bdrv_drained_begin()
> > and bdrv_drained_begin_timeout() will be retained.
> ...
> 
> > +/**
> > + * AIO_WAIT_WHILE_TIMEOUT:
> > + *
> > + * Refer to the implementation of AIO_WAIT_WHILE_INTERNAL,
> > + * the timeout parameter is added.
> > + * @timeout_ns: maximum duration to wait, in nanoseconds, except the value
> > + *              is unsigned, 0 means infinite.
> > + */
> > +#define AIO_WAIT_WHILE_TIMEOUT(ctx, cond, timeout_ns) ({                 \
> > +    int ret_ = 0;                                                        \
> > +    uint64_t timeout_ = (timeout_ns);                                    \
> > +    AioWait *wait_ = &global_aio_wait;                                   \
> > +    AioContext *ctx_ = (ctx);                                            \
> > +    AioContext *current_ctx_ = NULL;                                     \
> > +    QEMUTimer timer_;                                                    \
> > +    /* Increment wait_->num_waiters before evaluating cond. */           \
> > +    qatomic_inc(&wait_->num_waiters);                                    \
> > +    /* Paired with smp_mb in aio_wait_kick(). */                         \
> > +    smp_mb__after_rmw();                                                 \
> > +    if (ctx_ && in_aio_context_home_thread(ctx_)) {                      \
> > +        current_ctx_ = ctx_;                                             \
> > +    } else {                                                             \
> > +        assert(qemu_get_current_aio_context() ==                         \
> > +               qemu_get_aio_context());                                  \
> > +        current_ctx_ = qemu_get_aio_context();                           \
> > +    }                                                                    \
> > +    if (timeout_ > 0) {                                                  \
> > +        timer_init_full(&timer_, &current_ctx_->tlg,                     \
> > +                        QEMU_CLOCK_REALTIME,                             \
> > +                        SCALE_NS, 0, aio_wait_timer_cb, NULL);           \
> > +        timer_mod_ns(&timer_,                                            \
> > +                     qemu_clock_get_ns(QEMU_CLOCK_REALTIME) +            \
> > +                     timeout_);                                          \
> > +    }                                                                    \
> > +    while ((cond)) {                                                     \
> > +        aio_poll(current_ctx_, true);                                    \
> > +        if (timeout_ > 0 && !timer_pending(&timer_)) {                   \
> > +            ret_ = -ETIMEDOUT;                                           \
> > +            break;                                                       \
> > +        }                                                                \
> > +    }                                                                    \
> > +    if (timeout_ > 0) {                                                  \
> > +        timer_del(&timer_);                                              \
> > +    }                                                                    \
> > +    qatomic_dec(&wait_->num_waiters);                                    \
> > +    ret_; })
> > +
> >  #define AIO_WAIT_WHILE(ctx, cond)                                  \
> >      AIO_WAIT_WHILE_INTERNAL(ctx, cond)
>
> It would be nice to unify AIO_WAIT_WHILE_INTERNAL() and
> AIO_WAIT_WHILE_TIMEOUT(). I don't see any caller that uses the waited_
> return value from AIO_WAIT_WHILE_INTERNAL(), so I think it's possible to
> replace AIO_WAIT_WHILE_INTERNAL() with AIO_WAIT_WHILE_TIMEOUT(.., ..., 0).
>

Yes, there is no difference between AIO_WAIT_WHILE_INTERNAL() and
AIO_WAIT_WHILE_TIMEOUT() except the return value. It's right to keep the
code uniform. I will modify it in the next version.



Reply via email to