qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] block/mirror: Sleep periodically during bitmap scanning
@ 2015-05-13  3:11 Fam Zheng
  2015-05-13  5:17 ` Wen Congyang
                   ` (5 more replies)
  0 siblings, 6 replies; 10+ messages in thread
From: Fam Zheng @ 2015-05-13  3:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kevin Wolf, pbonzini, Jeff Cody, qemu-block

Before, we only yield after initializing dirty bitmap, where the QMP
command would return. That may take very long, and guest IO will be
blocked.

Add sleep points like the later mirror iterations.

Signed-off-by: Fam Zheng <famz@redhat.com>
---
 block/mirror.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/block/mirror.c b/block/mirror.c
index 1a1d997..baed225 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -467,11 +467,23 @@ static void coroutine_fn mirror_run(void *opaque)
     sectors_per_chunk = s->granularity >> BDRV_SECTOR_BITS;
     mirror_free_init(s);
 
+    last_pause_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
     if (!s->is_none_mode) {
         /* First part, loop on the sectors and initialize the dirty bitmap.  */
         BlockDriverState *base = s->base;
         for (sector_num = 0; sector_num < end; ) {
             int64_t next = (sector_num | (sectors_per_chunk - 1)) + 1;
+            int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
+
+            if (now - last_pause_ns > SLICE_TIME) {
+                last_pause_ns = now;
+                block_job_sleep_ns(&s->common, QEMU_CLOCK_REALTIME, 0);
+            }
+
+            if (block_job_is_cancelled(&s->common)) {
+                goto immediate_exit;
+            }
+
             ret = bdrv_is_allocated_above(bs, base,
                                           sector_num, next - sector_num, &n);
 
@@ -490,7 +502,6 @@ static void coroutine_fn mirror_run(void *opaque)
     }
 
     bdrv_dirty_iter_init(s->dirty_bitmap, &s->hbi);
-    last_pause_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
     for (;;) {
         uint64_t delay_ns = 0;
         int64_t cnt;
-- 
2.4.0

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH] block/mirror: Sleep periodically during bitmap scanning
  2015-05-13  3:11 [Qemu-devel] [PATCH] block/mirror: Sleep periodically during bitmap scanning Fam Zheng
@ 2015-05-13  5:17 ` Wen Congyang
  2015-05-13  6:40   ` Fam Zheng
  2015-05-13  7:11 ` Wen Congyang
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 10+ messages in thread
From: Wen Congyang @ 2015-05-13  5:17 UTC (permalink / raw)
  To: Fam Zheng, qemu-devel; +Cc: Kevin Wolf, pbonzini, Jeff Cody, qemu-block

On 05/13/2015 11:11 AM, Fam Zheng wrote:
> Before, we only yield after initializing dirty bitmap, where the QMP
> command would return. That may take very long, and guest IO will be
> blocked.

Do you have such case to reproduce it? If the disk image is too larger,
and I think qemu doesn't cache all metedata in the memory. So we will
yield in bdrv_is_allocated_above() when we read the metedata from the
disk.

Thanks
Wen Congyang

> 
> Add sleep points like the later mirror iterations.
> 
> Signed-off-by: Fam Zheng <famz@redhat.com>
> ---
>  block/mirror.c | 13 ++++++++++++-
>  1 file changed, 12 insertions(+), 1 deletion(-)
> 
> diff --git a/block/mirror.c b/block/mirror.c
> index 1a1d997..baed225 100644
> --- a/block/mirror.c
> +++ b/block/mirror.c
> @@ -467,11 +467,23 @@ static void coroutine_fn mirror_run(void *opaque)
>      sectors_per_chunk = s->granularity >> BDRV_SECTOR_BITS;
>      mirror_free_init(s);
>  
> +    last_pause_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
>      if (!s->is_none_mode) {
>          /* First part, loop on the sectors and initialize the dirty bitmap.  */
>          BlockDriverState *base = s->base;
>          for (sector_num = 0; sector_num < end; ) {
>              int64_t next = (sector_num | (sectors_per_chunk - 1)) + 1;
> +            int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
> +
> +            if (now - last_pause_ns > SLICE_TIME) {
> +                last_pause_ns = now;
> +                block_job_sleep_ns(&s->common, QEMU_CLOCK_REALTIME, 0);
> +            }
> +
> +            if (block_job_is_cancelled(&s->common)) {
> +                goto immediate_exit;
> +            }
> +
>              ret = bdrv_is_allocated_above(bs, base,
>                                            sector_num, next - sector_num, &n);
>  
> @@ -490,7 +502,6 @@ static void coroutine_fn mirror_run(void *opaque)
>      }
>  
>      bdrv_dirty_iter_init(s->dirty_bitmap, &s->hbi);
> -    last_pause_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
>      for (;;) {
>          uint64_t delay_ns = 0;
>          int64_t cnt;
> 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH] block/mirror: Sleep periodically during bitmap scanning
  2015-05-13  5:17 ` Wen Congyang
@ 2015-05-13  6:40   ` Fam Zheng
  2015-06-05  2:50     ` Wen Congyang
  0 siblings, 1 reply; 10+ messages in thread
From: Fam Zheng @ 2015-05-13  6:40 UTC (permalink / raw)
  To: Wen Congyang; +Cc: Kevin Wolf, pbonzini, Jeff Cody, qemu-devel, qemu-block

On Wed, 05/13 13:17, Wen Congyang wrote:
> On 05/13/2015 11:11 AM, Fam Zheng wrote:
> > Before, we only yield after initializing dirty bitmap, where the QMP
> > command would return. That may take very long, and guest IO will be
> > blocked.
> 
> Do you have such case to reproduce it? If the disk image is too larger,
> and I think qemu doesn't cache all metedata in the memory. So we will
> yield in bdrv_is_allocated_above() when we read the metedata from the
> disk.

True for qcow2, but raw-posix has no such yield points, because it uses
lseek(..., SEEK_HOLE). I do have a reproducer - just try a big raw image on
your ext4.

Fam

> 
> Thanks
> Wen Congyang
> 
> > 
> > Add sleep points like the later mirror iterations.
> > 
> > Signed-off-by: Fam Zheng <famz@redhat.com>
> > ---
> >  block/mirror.c | 13 ++++++++++++-
> >  1 file changed, 12 insertions(+), 1 deletion(-)
> > 
> > diff --git a/block/mirror.c b/block/mirror.c
> > index 1a1d997..baed225 100644
> > --- a/block/mirror.c
> > +++ b/block/mirror.c
> > @@ -467,11 +467,23 @@ static void coroutine_fn mirror_run(void *opaque)
> >      sectors_per_chunk = s->granularity >> BDRV_SECTOR_BITS;
> >      mirror_free_init(s);
> >  
> > +    last_pause_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
> >      if (!s->is_none_mode) {
> >          /* First part, loop on the sectors and initialize the dirty bitmap.  */
> >          BlockDriverState *base = s->base;
> >          for (sector_num = 0; sector_num < end; ) {
> >              int64_t next = (sector_num | (sectors_per_chunk - 1)) + 1;
> > +            int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
> > +
> > +            if (now - last_pause_ns > SLICE_TIME) {
> > +                last_pause_ns = now;
> > +                block_job_sleep_ns(&s->common, QEMU_CLOCK_REALTIME, 0);
> > +            }
> > +
> > +            if (block_job_is_cancelled(&s->common)) {
> > +                goto immediate_exit;
> > +            }
> > +
> >              ret = bdrv_is_allocated_above(bs, base,
> >                                            sector_num, next - sector_num, &n);
> >  
> > @@ -490,7 +502,6 @@ static void coroutine_fn mirror_run(void *opaque)
> >      }
> >  
> >      bdrv_dirty_iter_init(s->dirty_bitmap, &s->hbi);
> > -    last_pause_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
> >      for (;;) {
> >          uint64_t delay_ns = 0;
> >          int64_t cnt;
> > 
> 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH] block/mirror: Sleep periodically during bitmap scanning
  2015-05-13  3:11 [Qemu-devel] [PATCH] block/mirror: Sleep periodically during bitmap scanning Fam Zheng
  2015-05-13  5:17 ` Wen Congyang
@ 2015-05-13  7:11 ` Wen Congyang
  2015-05-13  9:30 ` Paolo Bonzini
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Wen Congyang @ 2015-05-13  7:11 UTC (permalink / raw)
  To: Fam Zheng, qemu-devel; +Cc: Kevin Wolf, pbonzini, Jeff Cody, qemu-block

On 05/13/2015 11:11 AM, Fam Zheng wrote:
> Before, we only yield after initializing dirty bitmap, where the QMP
> command would return. That may take very long, and guest IO will be
> blocked.
> 
> Add sleep points like the later mirror iterations.
> 
> Signed-off-by: Fam Zheng <famz@redhat.com>

Reviewed-by: Wen Congyang <wency@cn.fujitsu.com>

> ---
>  block/mirror.c | 13 ++++++++++++-
>  1 file changed, 12 insertions(+), 1 deletion(-)
> 
> diff --git a/block/mirror.c b/block/mirror.c
> index 1a1d997..baed225 100644
> --- a/block/mirror.c
> +++ b/block/mirror.c
> @@ -467,11 +467,23 @@ static void coroutine_fn mirror_run(void *opaque)
>      sectors_per_chunk = s->granularity >> BDRV_SECTOR_BITS;
>      mirror_free_init(s);
>  
> +    last_pause_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
>      if (!s->is_none_mode) {
>          /* First part, loop on the sectors and initialize the dirty bitmap.  */
>          BlockDriverState *base = s->base;
>          for (sector_num = 0; sector_num < end; ) {
>              int64_t next = (sector_num | (sectors_per_chunk - 1)) + 1;
> +            int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
> +
> +            if (now - last_pause_ns > SLICE_TIME) {
> +                last_pause_ns = now;
> +                block_job_sleep_ns(&s->common, QEMU_CLOCK_REALTIME, 0);
> +            }
> +
> +            if (block_job_is_cancelled(&s->common)) {
> +                goto immediate_exit;
> +            }
> +
>              ret = bdrv_is_allocated_above(bs, base,
>                                            sector_num, next - sector_num, &n);
>  
> @@ -490,7 +502,6 @@ static void coroutine_fn mirror_run(void *opaque)
>      }
>  
>      bdrv_dirty_iter_init(s->dirty_bitmap, &s->hbi);
> -    last_pause_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
>      for (;;) {
>          uint64_t delay_ns = 0;
>          int64_t cnt;
> 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH] block/mirror: Sleep periodically during bitmap scanning
  2015-05-13  3:11 [Qemu-devel] [PATCH] block/mirror: Sleep periodically during bitmap scanning Fam Zheng
  2015-05-13  5:17 ` Wen Congyang
  2015-05-13  7:11 ` Wen Congyang
@ 2015-05-13  9:30 ` Paolo Bonzini
  2015-05-19 10:46 ` [Qemu-devel] [Qemu-block] " Stefan Hajnoczi
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Paolo Bonzini @ 2015-05-13  9:30 UTC (permalink / raw)
  To: Fam Zheng, qemu-devel; +Cc: Kevin Wolf, Jeff Cody, qemu-block



On 13/05/2015 05:11, Fam Zheng wrote:
> Before, we only yield after initializing dirty bitmap, where the QMP
> command would return. That may take very long, and guest IO will be
> blocked.
> 
> Add sleep points like the later mirror iterations.

You were also planning to let bdrv_co_is_allocated/get_block_status
return a larger p_num than nb_sectors---which maybe could make
nb_sectors obsolete completely, I don't know.  But this is already an
improvement.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>

Thanks,

Paolo

> 
> Signed-off-by: Fam Zheng <famz@redhat.com>
> ---
>  block/mirror.c | 13 ++++++++++++-
>  1 file changed, 12 insertions(+), 1 deletion(-)
> 
> diff --git a/block/mirror.c b/block/mirror.c
> index 1a1d997..baed225 100644
> --- a/block/mirror.c
> +++ b/block/mirror.c
> @@ -467,11 +467,23 @@ static void coroutine_fn mirror_run(void *opaque)
>      sectors_per_chunk = s->granularity >> BDRV_SECTOR_BITS;
>      mirror_free_init(s);
>  
> +    last_pause_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
>      if (!s->is_none_mode) {
>          /* First part, loop on the sectors and initialize the dirty bitmap.  */
>          BlockDriverState *base = s->base;
>          for (sector_num = 0; sector_num < end; ) {
>              int64_t next = (sector_num | (sectors_per_chunk - 1)) + 1;
> +            int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
> +
> +            if (now - last_pause_ns > SLICE_TIME) {
> +                last_pause_ns = now;
> +                block_job_sleep_ns(&s->common, QEMU_CLOCK_REALTIME, 0);
> +            }
> +
> +            if (block_job_is_cancelled(&s->common)) {
> +                goto immediate_exit;
> +            }
> +
>              ret = bdrv_is_allocated_above(bs, base,
>                                            sector_num, next - sector_num, &n);
>  
> @@ -490,7 +502,6 @@ static void coroutine_fn mirror_run(void *opaque)
>      }
>  
>      bdrv_dirty_iter_init(s->dirty_bitmap, &s->hbi);
> -    last_pause_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
>      for (;;) {
>          uint64_t delay_ns = 0;
>          int64_t cnt;
> 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [Qemu-block] [PATCH] block/mirror: Sleep periodically during bitmap scanning
  2015-05-13  3:11 [Qemu-devel] [PATCH] block/mirror: Sleep periodically during bitmap scanning Fam Zheng
                   ` (2 preceding siblings ...)
  2015-05-13  9:30 ` Paolo Bonzini
@ 2015-05-19 10:46 ` Stefan Hajnoczi
  2015-06-15 16:35 ` Stefan Hajnoczi
  2015-06-16  4:06 ` [Qemu-devel] " Jeff Cody
  5 siblings, 0 replies; 10+ messages in thread
From: Stefan Hajnoczi @ 2015-05-19 10:46 UTC (permalink / raw)
  To: Fam Zheng; +Cc: pbonzini, Jeff Cody, qemu-devel, qemu-block

[-- Attachment #1: Type: text/plain, Size: 1966 bytes --]

On Wed, May 13, 2015 at 11:11:13AM +0800, Fam Zheng wrote:
> Before, we only yield after initializing dirty bitmap, where the QMP
> command would return. That may take very long, and guest IO will be
> blocked.
> 
> Add sleep points like the later mirror iterations.
> 
> Signed-off-by: Fam Zheng <famz@redhat.com>
> ---
>  block/mirror.c | 13 ++++++++++++-
>  1 file changed, 12 insertions(+), 1 deletion(-)

CCing Jeff Cody for block jobs.

> 
> diff --git a/block/mirror.c b/block/mirror.c
> index 1a1d997..baed225 100644
> --- a/block/mirror.c
> +++ b/block/mirror.c
> @@ -467,11 +467,23 @@ static void coroutine_fn mirror_run(void *opaque)
>      sectors_per_chunk = s->granularity >> BDRV_SECTOR_BITS;
>      mirror_free_init(s);
>  
> +    last_pause_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
>      if (!s->is_none_mode) {
>          /* First part, loop on the sectors and initialize the dirty bitmap.  */
>          BlockDriverState *base = s->base;
>          for (sector_num = 0; sector_num < end; ) {
>              int64_t next = (sector_num | (sectors_per_chunk - 1)) + 1;
> +            int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
> +
> +            if (now - last_pause_ns > SLICE_TIME) {
> +                last_pause_ns = now;
> +                block_job_sleep_ns(&s->common, QEMU_CLOCK_REALTIME, 0);
> +            }
> +
> +            if (block_job_is_cancelled(&s->common)) {
> +                goto immediate_exit;
> +            }
> +
>              ret = bdrv_is_allocated_above(bs, base,
>                                            sector_num, next - sector_num, &n);
>  
> @@ -490,7 +502,6 @@ static void coroutine_fn mirror_run(void *opaque)
>      }
>  
>      bdrv_dirty_iter_init(s->dirty_bitmap, &s->hbi);
> -    last_pause_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
>      for (;;) {
>          uint64_t delay_ns = 0;
>          int64_t cnt;
> -- 
> 2.4.0
> 
> 

[-- Attachment #2: Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH] block/mirror: Sleep periodically during bitmap scanning
  2015-05-13  6:40   ` Fam Zheng
@ 2015-06-05  2:50     ` Wen Congyang
  0 siblings, 0 replies; 10+ messages in thread
From: Wen Congyang @ 2015-06-05  2:50 UTC (permalink / raw)
  To: Fam Zheng; +Cc: Kevin Wolf, pbonzini, Jeff Cody, qemu-devel, qemu-block

On 05/13/2015 02:40 PM, Fam Zheng wrote:
> On Wed, 05/13 13:17, Wen Congyang wrote:
>> On 05/13/2015 11:11 AM, Fam Zheng wrote:
>>> Before, we only yield after initializing dirty bitmap, where the QMP
>>> command would return. That may take very long, and guest IO will be
>>> blocked.
>>
>> Do you have such case to reproduce it? If the disk image is too larger,
>> and I think qemu doesn't cache all metedata in the memory. So we will
>> yield in bdrv_is_allocated_above() when we read the metedata from the
>> disk.
> 
> True for qcow2, but raw-posix has no such yield points, because it uses
> lseek(..., SEEK_HOLE). I do have a reproducer - just try a big raw image on
> your ext4.

It is the filesystem's problem. If we mirror a big empty raw image,
lseek(..., SEEK_DATA) may needs some seconds(about 5s for 500G empty
raw image). Even if the granularity is 64K, we need to call this
syscall 8192000(500G/64K) times. We may need more than half year...

So I think we should allow bdrv_is_allocated() and other APIs to return
a larger p_num than nb_sectors.

Thanks
Wen Congyang

> 
> Fam
> 
>>
>> Thanks
>> Wen Congyang
>>
>>>
>>> Add sleep points like the later mirror iterations.
>>>
>>> Signed-off-by: Fam Zheng <famz@redhat.com>
>>> ---
>>>  block/mirror.c | 13 ++++++++++++-
>>>  1 file changed, 12 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/block/mirror.c b/block/mirror.c
>>> index 1a1d997..baed225 100644
>>> --- a/block/mirror.c
>>> +++ b/block/mirror.c
>>> @@ -467,11 +467,23 @@ static void coroutine_fn mirror_run(void *opaque)
>>>      sectors_per_chunk = s->granularity >> BDRV_SECTOR_BITS;
>>>      mirror_free_init(s);
>>>  
>>> +    last_pause_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
>>>      if (!s->is_none_mode) {
>>>          /* First part, loop on the sectors and initialize the dirty bitmap.  */
>>>          BlockDriverState *base = s->base;
>>>          for (sector_num = 0; sector_num < end; ) {
>>>              int64_t next = (sector_num | (sectors_per_chunk - 1)) + 1;
>>> +            int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
>>> +
>>> +            if (now - last_pause_ns > SLICE_TIME) {
>>> +                last_pause_ns = now;
>>> +                block_job_sleep_ns(&s->common, QEMU_CLOCK_REALTIME, 0);
>>> +            }
>>> +
>>> +            if (block_job_is_cancelled(&s->common)) {
>>> +                goto immediate_exit;
>>> +            }
>>> +
>>>              ret = bdrv_is_allocated_above(bs, base,
>>>                                            sector_num, next - sector_num, &n);
>>>  
>>> @@ -490,7 +502,6 @@ static void coroutine_fn mirror_run(void *opaque)
>>>      }
>>>  
>>>      bdrv_dirty_iter_init(s->dirty_bitmap, &s->hbi);
>>> -    last_pause_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
>>>      for (;;) {
>>>          uint64_t delay_ns = 0;
>>>          int64_t cnt;
>>>
>>
> .
> 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [Qemu-block] [PATCH] block/mirror: Sleep periodically during bitmap scanning
  2015-05-13  3:11 [Qemu-devel] [PATCH] block/mirror: Sleep periodically during bitmap scanning Fam Zheng
                   ` (3 preceding siblings ...)
  2015-05-19 10:46 ` [Qemu-devel] [Qemu-block] " Stefan Hajnoczi
@ 2015-06-15 16:35 ` Stefan Hajnoczi
  2015-06-16  4:06 ` [Qemu-devel] " Jeff Cody
  5 siblings, 0 replies; 10+ messages in thread
From: Stefan Hajnoczi @ 2015-06-15 16:35 UTC (permalink / raw)
  To: Fam Zheng; +Cc: pbonzini, qemu-devel, qemu-block

[-- Attachment #1: Type: text/plain, Size: 491 bytes --]

On Wed, May 13, 2015 at 11:11:13AM +0800, Fam Zheng wrote:
> Before, we only yield after initializing dirty bitmap, where the QMP
> command would return. That may take very long, and guest IO will be
> blocked.
> 
> Add sleep points like the later mirror iterations.
> 
> Signed-off-by: Fam Zheng <famz@redhat.com>
> ---
>  block/mirror.c | 13 ++++++++++++-
>  1 file changed, 12 insertions(+), 1 deletion(-)

Ping for Jeff

Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>

[-- Attachment #2: Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH] block/mirror: Sleep periodically during bitmap scanning
  2015-05-13  3:11 [Qemu-devel] [PATCH] block/mirror: Sleep periodically during bitmap scanning Fam Zheng
                   ` (4 preceding siblings ...)
  2015-06-15 16:35 ` Stefan Hajnoczi
@ 2015-06-16  4:06 ` Jeff Cody
  2015-06-29  8:56   ` Alexandre DERUMIER
  5 siblings, 1 reply; 10+ messages in thread
From: Jeff Cody @ 2015-06-16  4:06 UTC (permalink / raw)
  To: Fam Zheng; +Cc: Kevin Wolf, pbonzini, qemu-devel, qemu-block

On Wed, May 13, 2015 at 11:11:13AM +0800, Fam Zheng wrote:
> Before, we only yield after initializing dirty bitmap, where the QMP
> command would return. That may take very long, and guest IO will be
> blocked.
> 
> Add sleep points like the later mirror iterations.
> 
> Signed-off-by: Fam Zheng <famz@redhat.com>
> ---
>  block/mirror.c | 13 ++++++++++++-
>  1 file changed, 12 insertions(+), 1 deletion(-)
> 
> diff --git a/block/mirror.c b/block/mirror.c
> index 1a1d997..baed225 100644
> --- a/block/mirror.c
> +++ b/block/mirror.c
> @@ -467,11 +467,23 @@ static void coroutine_fn mirror_run(void *opaque)
>      sectors_per_chunk = s->granularity >> BDRV_SECTOR_BITS;
>      mirror_free_init(s);
>  
> +    last_pause_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
>      if (!s->is_none_mode) {
>          /* First part, loop on the sectors and initialize the dirty bitmap.  */
>          BlockDriverState *base = s->base;
>          for (sector_num = 0; sector_num < end; ) {
>              int64_t next = (sector_num | (sectors_per_chunk - 1)) + 1;
> +            int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
> +
> +            if (now - last_pause_ns > SLICE_TIME) {
> +                last_pause_ns = now;
> +                block_job_sleep_ns(&s->common, QEMU_CLOCK_REALTIME, 0);
> +            }
> +
> +            if (block_job_is_cancelled(&s->common)) {
> +                goto immediate_exit;
> +            }
> +
>              ret = bdrv_is_allocated_above(bs, base,
>                                            sector_num, next - sector_num, &n);
>  
> @@ -490,7 +502,6 @@ static void coroutine_fn mirror_run(void *opaque)
>      }
>  
>      bdrv_dirty_iter_init(s->dirty_bitmap, &s->hbi);
> -    last_pause_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
>      for (;;) {
>          uint64_t delay_ns = 0;
>          int64_t cnt;
> -- 
> 2.4.0
>

Thanks, applied to my block tree:
https://github.com/codyprime/qemu-kvm-jtc/commits/block

Jeff

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH] block/mirror: Sleep periodically during bitmap scanning
  2015-06-16  4:06 ` [Qemu-devel] " Jeff Cody
@ 2015-06-29  8:56   ` Alexandre DERUMIER
  0 siblings, 0 replies; 10+ messages in thread
From: Alexandre DERUMIER @ 2015-06-29  8:56 UTC (permalink / raw)
  To: Fam Zheng; +Cc: Kevin Wolf, pbonzini, Jeff Cody, qemu-devel, qemu-block

Hi,

I'm currently testing this patch,
and it still hanging for me (mirroring a raw file from nfs)


I just wonder why block_job_sleep_ns is set to 0 ?

+                block_job_sleep_ns(&s->common, QEMU_CLOCK_REALTIME, 0);


I have tried to increasing it to a bigger value

+                block_job_sleep_ns(&s->common, QEMU_CLOCK_REALTIME, 100000000);


And now it's working fine for me, no more qemu hang



----- Mail original -----
De: "Jeff Cody" <jcody@redhat.com>
À: "Fam Zheng" <famz@redhat.com>
Cc: "Kevin Wolf" <kwolf@redhat.com>, "pbonzini" <pbonzini@redhat.com>, "qemu-devel" <qemu-devel@nongnu.org>, qemu-block@nongnu.org
Envoyé: Mardi 16 Juin 2015 06:06:25
Objet: Re: [Qemu-devel] [PATCH] block/mirror: Sleep periodically during	bitmap scanning

On Wed, May 13, 2015 at 11:11:13AM +0800, Fam Zheng wrote: 
> Before, we only yield after initializing dirty bitmap, where the QMP 
> command would return. That may take very long, and guest IO will be 
> blocked. 
> 
> Add sleep points like the later mirror iterations. 
> 
> Signed-off-by: Fam Zheng <famz@redhat.com> 
> --- 
> block/mirror.c | 13 ++++++++++++- 
> 1 file changed, 12 insertions(+), 1 deletion(-) 
> 
> diff --git a/block/mirror.c b/block/mirror.c 
> index 1a1d997..baed225 100644 
> --- a/block/mirror.c 
> +++ b/block/mirror.c 
> @@ -467,11 +467,23 @@ static void coroutine_fn mirror_run(void *opaque) 
> sectors_per_chunk = s->granularity >> BDRV_SECTOR_BITS; 
> mirror_free_init(s); 
> 
> + last_pause_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME); 
> if (!s->is_none_mode) { 
> /* First part, loop on the sectors and initialize the dirty bitmap. */ 
> BlockDriverState *base = s->base; 
> for (sector_num = 0; sector_num < end; ) { 
> int64_t next = (sector_num | (sectors_per_chunk - 1)) + 1; 
> + int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME); 
> + 
> + if (now - last_pause_ns > SLICE_TIME) { 
> + last_pause_ns = now; 
> + block_job_sleep_ns(&s->common, QEMU_CLOCK_REALTIME, 0); 
> + } 
> + 
> + if (block_job_is_cancelled(&s->common)) { 
> + goto immediate_exit; 
> + } 
> + 
> ret = bdrv_is_allocated_above(bs, base, 
> sector_num, next - sector_num, &n); 
> 
> @@ -490,7 +502,6 @@ static void coroutine_fn mirror_run(void *opaque) 
> } 
> 
> bdrv_dirty_iter_init(s->dirty_bitmap, &s->hbi); 
> - last_pause_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME); 
> for (;;) { 
> uint64_t delay_ns = 0; 
> int64_t cnt; 
> -- 
> 2.4.0 
> 

Thanks, applied to my block tree: 
https://github.com/codyprime/qemu-kvm-jtc/commits/block 

Jeff 

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2015-06-29  8:56 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-05-13  3:11 [Qemu-devel] [PATCH] block/mirror: Sleep periodically during bitmap scanning Fam Zheng
2015-05-13  5:17 ` Wen Congyang
2015-05-13  6:40   ` Fam Zheng
2015-06-05  2:50     ` Wen Congyang
2015-05-13  7:11 ` Wen Congyang
2015-05-13  9:30 ` Paolo Bonzini
2015-05-19 10:46 ` [Qemu-devel] [Qemu-block] " Stefan Hajnoczi
2015-06-15 16:35 ` Stefan Hajnoczi
2015-06-16  4:06 ` [Qemu-devel] " Jeff Cody
2015-06-29  8:56   ` Alexandre DERUMIER

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).