On 2018-01-19 21:58, John Snow wrote: > We're attempting to slacken the mirror loop in three different places, > but we can combine these three attempts. Combine the early loop call to > block_job_pause_point with the two late-loop calls to block_job_sleep_ns. > > When delay_ns is 0 and it has not been SLICE_TIME since the last yield, > block_job_relax is merely a call to block_job_pause_point, so this should > be equivalent with the exception that if we have managed to not yield at > all in the last SLICE_TIME ns, we will now do so. > > I am not sure that condition was possible, > so this loop should be equivalent.
Well, to me it even sounds like a positive change if it was a change. We want the job to yield after SLICE_TIME ns, after all, and I don't think it matters where that happens, exactly. > > Signed-off-by: John Snow <js...@redhat.com> > --- > block/mirror.c | 22 +++++++++++----------- > block/trace-events | 2 +- > 2 files changed, 12 insertions(+), 12 deletions(-) > > diff --git a/block/mirror.c b/block/mirror.c > index a0e0044de2..192e03694f 100644 > --- a/block/mirror.c > +++ b/block/mirror.c > @@ -761,7 +761,7 @@ static void coroutine_fn mirror_run(void *opaque) > assert(!s->dbi); > s->dbi = bdrv_dirty_iter_new(s->dirty_bitmap); > for (;;) { > - uint64_t delay_ns = 0; > + static uint64_t delay_ns = 0; Errr. Are you sure about that? Now every mirror job in the qeny process will share this single variable. Was that your intention? > int64_t cnt, delta; > bool should_complete; > > @@ -770,9 +770,16 @@ static void coroutine_fn mirror_run(void *opaque) > goto immediate_exit; > } > > - block_job_pause_point(&s->common); > - > cnt = bdrv_get_dirty_count(s->dirty_bitmap); > + > + trace_mirror_before_relax(s, cnt, s->synced, delay_ns); > + if (block_job_relax(&s->common, delay_ns)) { See the reply to <a href="HEAD^^">that patch</a>. > + if (!s->synced) { > + goto immediate_exit; > + } > + } > + delay_ns = 0; > + > /* s->common.offset contains the number of bytes already processed so > * far, cnt is the number of dirty bytes remaining and > * s->bytes_in_flight is the number of bytes currently being > @@ -849,15 +856,8 @@ static void coroutine_fn mirror_run(void *opaque) > } > > ret = 0; > - trace_mirror_before_sleep(s, cnt, s->synced, delay_ns); > - if (!s->synced) { > - block_job_sleep_ns(&s->common, delay_ns); > - if (block_job_is_cancelled(&s->common)) { > - break; > - } > - } else if (!should_complete) { > + if (s->synced && !should_complete) { > delay_ns = (s->in_flight == 0 && cnt == 0 ? SLICE_TIME : 0); > - block_job_sleep_ns(&s->common, delay_ns); > } > } Basic idea looks good to me (apart from the static delay_ns), but, well, block-job-cancel on a busy job still breaks. Max
signature.asc
Description: OpenPGP digital signature