On Tue, Dec 22, 2020 at 3:19 PM Bob Peterson <[email protected]> wrote:
>
> Hi,
>
> Comments inline.
>
> ----- Original Message -----
> > Wake up log waiters in gfs2_log_release when log space has actually become
> > available.  This is a much better place for the wakeup than gfs2_logd.
> >
> > Check if enough log space is immeditely available before anything else.  If
> > there isn't, use io_wait_event to wait instead of open-coding it.
> >
> > Signed-off-by: Andreas Gruenbacher <[email protected]>
> > ---
> >  fs/gfs2/log.c | 54 ++++++++++++++++++++++-----------------------------
> >  1 file changed, 23 insertions(+), 31 deletions(-)
> >
> > diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c
> > index 95ad444bd3dc..7a65823ad1f3 100644
> > --- a/fs/gfs2/log.c
> > +++ b/fs/gfs2/log.c
> > @@ -420,6 +420,8 @@ void gfs2_log_release(struct gfs2_sbd *sdp, unsigned int
> > blks)
> >       trace_gfs2_log_blocks(sdp, blks);
> >       gfs2_assert_withdraw(sdp, atomic_read(&sdp->sd_log_blks_free) <=
> >                                 sdp->sd_jdesc->jd_blocks);
> > +     if (atomic_read(&sdp->sd_log_blks_needed))
> > +             wake_up(&sdp->sd_log_waitq);
> >  }
> >
> >  /**
> > @@ -444,36 +446,33 @@ void gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned
> > int blks)
> >  {
> >       unsigned reserved_blks = 7 * (4096 / sdp->sd_vfs->s_blocksize);
> >       unsigned wanted = blks + reserved_blks;
> > -     DEFINE_WAIT(wait);
> > -     int did_wait = 0;
> >       unsigned int free_blocks;
> >
> > -     atomic_add(blks, &sdp->sd_log_blks_needed);
> > -retry:
> >       free_blocks = atomic_read(&sdp->sd_log_blks_free);
> > -     if (unlikely(free_blocks <= wanted)) {
> > -             do {
> > -                     prepare_to_wait_exclusive(&sdp->sd_log_waitq, &wait,
> > -                                     TASK_UNINTERRUPTIBLE);
> > +     while (free_blocks >= wanted) {
> > +             if (atomic_try_cmpxchg(&sdp->sd_log_blks_free, &free_blocks,
> > +                                    free_blocks - blks))
> > +                     return;
>
> This would be a good place to have cond_resched() or schedule() or something, 
> no?

No, this is just an atomic_sub_if_positive(); see
atomic_dec_if_positive in atomic-fallback.h.

> > +     }
> > +
> > +     atomic_add(blks, &sdp->sd_log_blks_needed);
> > +     for (;;) {
> > +             if (current != sdp->sd_logd_process)
> >                       wake_up(&sdp->sd_logd_waitq);
> > -                     did_wait = 1;
> > -                     if (atomic_read(&sdp->sd_log_blks_free) <= wanted)
> > -                             io_schedule();
> > -                     free_blocks = atomic_read(&sdp->sd_log_blks_free);
> > -             } while(free_blocks <= wanted);
> > -             finish_wait(&sdp->sd_log_waitq, &wait);
> > +             io_wait_event(sdp->sd_log_waitq,
> > +                     (free_blocks = atomic_read(&sdp->sd_log_blks_free),
> > +                      free_blocks >= wanted));
> > +             do {
> > +                     if (atomic_try_cmpxchg(&sdp->sd_log_blks_free,
> > +                                            &free_blocks,
> > +                                            free_blocks - blks))
> > +                             goto reserved;
>
> Same here. We need to test these patches with a minimal number of cpus.
>
> > +             } while (free_blocks >= wanted);
> >       }
> > -     if (atomic_cmpxchg(&sdp->sd_log_blks_free, free_blocks,
> > -                             free_blocks - blks) != free_blocks)
> > -             goto retry;
> > -     atomic_sub(blks, &sdp->sd_log_blks_needed);
> > -     trace_gfs2_log_blocks(sdp, -blks);
> >
> > -     /*
> > -      * If we waited, then so might others, wake them up _after_ we get
> > -      * our share of the log.
> > -      */
> > -     if (unlikely(did_wait))
> > +reserved:
> > +     trace_gfs2_log_blocks(sdp, -blks);
> > +     if (atomic_sub_return(blks, &sdp->sd_log_blks_needed))
> >               wake_up(&sdp->sd_log_waitq);
> >  }
> >
> > @@ -1190,7 +1189,6 @@ int gfs2_logd(void *data)
> >       struct gfs2_sbd *sdp = data;
> >       unsigned long t = 1;
> >       DEFINE_WAIT(wait);
> > -     bool did_flush;
> >
> >       while (!kthread_should_stop()) {
> >
> > @@ -1209,12 +1207,10 @@ int gfs2_logd(void *data)
> >                       continue;
> >               }
> >
> > -             did_flush = false;
> >               if (gfs2_jrnl_flush_reqd(sdp) || t == 0) {
> >                       gfs2_ail1_empty(sdp, 0);
> >                       gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL |
> >                                      GFS2_LFC_LOGD_JFLUSH_REQD);
> > -                     did_flush = true;
> >               }
> >
> >               if (gfs2_ail_flush_reqd(sdp)) {
> > @@ -1223,12 +1219,8 @@ int gfs2_logd(void *data)
> >                       gfs2_ail1_empty(sdp, 0);
> >                       gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL |
> >                                      GFS2_LFC_LOGD_AIL_FLUSH_REQD);
> > -                     did_flush = true;
> >               }
> >
> > -             if (!gfs2_ail_flush_reqd(sdp) || did_flush)
> > -                     wake_up(&sdp->sd_log_waitq);
> > -
> >               t = gfs2_tune_get(sdp, gt_logd_secs) * HZ;
> >
> >               try_to_freeze();
> > --
> > 2.26.2
> >
> >

Thanks,
Andreas

Reply via email to