xfs
[Top] [All Lists]

Re: [PATCH 4/5] xfs: use generic percpu counters for free block counter

To: Dave Chinner <david@xxxxxxxxxxxxx>
Subject: Re: [PATCH 4/5] xfs: use generic percpu counters for free block counter
From: Christoph Hellwig <hch@xxxxxxxxxxxxx>
Date: Mon, 2 Feb 2015 08:48:47 -0800
Cc: xfs@xxxxxxxxxxx
Delivered-to: xfs@xxxxxxxxxxx
In-reply-to: <1422826983-29570-5-git-send-email-david@xxxxxxxxxxxxx>
References: <1422826983-29570-1-git-send-email-david@xxxxxxxxxxxxx> <1422826983-29570-5-git-send-email-david@xxxxxxxxxxxxx>
User-agent: Mutt/1.5.23 (2014-03-12)
>       case XFS_SBS_FDBLOCKS:
>  
>               if (delta > 0) {                /* Putting blocks back */
> +                     if (mp->m_resblks == mp->m_resblks_avail) {
> +                             percpu_counter_add(&mp->m_sb.sb_fdblocks, 
> delta);
> +                             return 0;
> +                     }
> +
> +                     /* put blocks back into reserve pool first */
> +                     spin_lock(&mp->m_sb_lock);
> +                     res_used = (long long)
> +                                     (mp->m_resblks - mp->m_resblks_avail);
> +
>                       if (res_used > delta) {
>                               mp->m_resblks_avail += delta;
>                       } else {
> +                             delta -= res_used;
>                               mp->m_resblks_avail = mp->m_resblks;
> +                             percpu_counter_add(&mp->m_sb.sb_fdblocks, 
> delta);
>                       }
> +                     spin_unlock(&mp->m_sb_lock);
> +                     return 0;
>  
> +             }

>  
> +             /*
> +              * Taking blocks away, need to be more accurate the closer we
> +              * are to zero.
> +              *
> +              * batch size is set to a maximum of 1024 blocks - if we are
> +              * allocating of freeing extents larger than this then we aren't
> +              * going to be hammering the counter lock so a lock per update
> +              * is not a problem.
> +              *
> +              * If the counter has a value of less than 2 * max batch size,
> +              * then make everything serialise as we are real close to
> +              * ENOSPC.
> +              */
> +#define __BATCH      1024
> +             if (percpu_counter_compare(&mp->m_sb.sb_fdblocks,
> +                                        2 * __BATCH) < 0)
> +                     batch = 1;
> +             else
> +                     batch = __BATCH;
> +
> +             __percpu_counter_add(&mp->m_sb.sb_fdblocks, delta, batch);
> +             if (percpu_counter_compare(&mp->m_sb.sb_fdblocks,
> +                                        XFS_ALLOC_SET_ASIDE(mp)) >= 0) {
> +                     /* we had space! */
> +                     return 0;
>               }
>  
> +             /*
> +              * lock up the sb for dipping into reserves before releasing
> +              * the space that took us to ENOSPC.
> +              */
> +             spin_lock(&mp->m_sb_lock);
> +             percpu_counter_add(&mp->m_sb.sb_fdblocks, -delta);
> +             if (!rsvd)
> +                     goto fdblocks_enospc;
> +
> +             lcounter = (long long)mp->m_resblks_avail + delta;
> +             if (lcounter >= 0) {
> +                     mp->m_resblks_avail = lcounter;
> +                     spin_unlock(&mp->m_sb_lock);
> +                     return 0;
> +             }
> +             printk_once(KERN_WARNING
> +                     "Filesystem \"%s\": reserve blocks depleted! "
> +                     "Consider increasing reserve pool size.",
> +                     mp->m_fsname);
> +fdblocks_enospc:
> +             spin_unlock(&mp->m_sb_lock);
> +             return -ENOSPC;
> +

This screams for having two different helpers for removing vs adding back
reserved blocks.

<Prev in Thread] Current Thread [Next in Thread>