xfs
[Top] [All Lists]

[PATCH 4/7] xfs: Remove icsb infrastructure

To: xfs@xxxxxxxxxxx
Subject: [PATCH 4/7] xfs: Remove icsb infrastructure
From: Dave Chinner <david@xxxxxxxxxxxxx>
Date: Thu, 5 Feb 2015 07:54:06 +1100
Delivered-to: xfs@xxxxxxxxxxx
In-reply-to: <1423083249-27493-1-git-send-email-david@xxxxxxxxxxxxx>
References: <1423083249-27493-1-git-send-email-david@xxxxxxxxxxxxx>
From: Dave Chinner <dchinner@xxxxxxxxxx>

Now that the in-core superblock infrastructure has been replaced with
generic per-cpu counters, we don't need it anymore. Nuke it from
orbit so we are sure that it won't haunt us again...

Signed-off-by: Dave Chinner <dchinner@xxxxxxxxxx>
---
 fs/xfs/libxfs/xfs_sb.c   |   8 +-
 fs/xfs/xfs_fsops.c       |   2 -
 fs/xfs/xfs_iomap.c       |   1 -
 fs/xfs/xfs_linux.h       |   9 -
 fs/xfs/xfs_log_recover.c |   4 +-
 fs/xfs/xfs_mount.c       | 516 +----------------------------------------------
 fs/xfs/xfs_mount.h       |  67 ------
 fs/xfs/xfs_super.c       |  84 ++++++--
 fs/xfs/xfs_super.h       |   2 +
 9 files changed, 72 insertions(+), 621 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c
index 31a3e97..a270095 100644
--- a/fs/xfs/libxfs/xfs_sb.c
+++ b/fs/xfs/libxfs/xfs_sb.c
@@ -743,17 +743,15 @@ xfs_initialize_perag_data(
                btree += pag->pagf_btreeblks;
                xfs_perag_put(pag);
        }
-       /*
-        * Overwrite incore superblock counters with just-read data
-        */
+
+       /* Overwrite incore superblock counters with just-read data */
        spin_lock(&mp->m_sb_lock);
        sbp->sb_ifree = ifree;
        sbp->sb_icount = ialloc;
        sbp->sb_fdblocks = bfree + bfreelst + btree;
        spin_unlock(&mp->m_sb_lock);
 
-       /* Fixup the per-cpu counters as well. */
-       xfs_icsb_reinit_counters(mp);
+       xfs_reinit_percpu_counters(mp);
 
        return 0;
 }
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
index fed97a9..a45c82b4 100644
--- a/fs/xfs/xfs_fsops.c
+++ b/fs/xfs/xfs_fsops.c
@@ -630,7 +630,6 @@ xfs_fs_counts(
        xfs_mount_t             *mp,
        xfs_fsop_counts_t       *cnt)
 {
-       xfs_icsb_sync_counters(mp, XFS_ICSB_LAZY_COUNT);
        cnt->allocino = percpu_counter_read_positive(&mp->m_icount);
        cnt->freeino = percpu_counter_read_positive(&mp->m_ifree);
        cnt->freedata = percpu_counter_read_positive(&mp->m_fdblocks) -
@@ -694,7 +693,6 @@ xfs_reserve_blocks(
         */
 retry:
        spin_lock(&mp->m_sb_lock);
-       xfs_icsb_sync_counters_locked(mp, 0);
 
        /*
         * If our previous reservation was larger than the current value,
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index 205b948..38e633b 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -460,7 +460,6 @@ xfs_iomap_prealloc_size(
        alloc_blocks = XFS_FILEOFF_MIN(roundup_pow_of_two(MAXEXTLEN),
                                       alloc_blocks);
 
-       xfs_icsb_sync_counters(mp, XFS_ICSB_LAZY_COUNT);
        freesp = percpu_counter_read_positive(&mp->m_fdblocks);
        if (freesp < mp->m_low_space[XFS_LOWSP_5_PCNT]) {
                shift = 2;
diff --git a/fs/xfs/xfs_linux.h b/fs/xfs/xfs_linux.h
index c31d2c2..7c7842c 100644
--- a/fs/xfs/xfs_linux.h
+++ b/fs/xfs/xfs_linux.h
@@ -116,15 +116,6 @@ typedef __uint64_t __psunsigned_t;
 #undef XFS_NATIVE_HOST
 #endif
 
-/*
- * Feature macros (disable/enable)
- */
-#ifdef CONFIG_SMP
-#define HAVE_PERCPU_SB /* per cpu superblock counters are a 2.6 feature */
-#else
-#undef  HAVE_PERCPU_SB /* per cpu superblock counters are a 2.6 feature */
-#endif
-
 #define irix_sgid_inherit      xfs_params.sgid_inherit.val
 #define irix_symlink_mode      xfs_params.symlink_mode.val
 #define xfs_panic_mask         xfs_params.panic_mask.val
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index a5a945f..4f5784f 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -4463,10 +4463,10 @@ xlog_do_recover(
        xfs_sb_from_disk(sbp, XFS_BUF_TO_SBP(bp));
        ASSERT(sbp->sb_magicnum == XFS_SB_MAGIC);
        ASSERT(xfs_sb_good_version(sbp));
+       xfs_reinit_percpu_counters(log->l_mp);
+
        xfs_buf_relse(bp);
 
-       /* We've re-read the superblock so re-initialize per-cpu counters */
-       xfs_icsb_reinit_counters(log->l_mp);
 
        xlog_recover_check_summary(log);
 
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 9e433b2..1d26200 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -43,18 +43,6 @@
 #include "xfs_sysfs.h"
 
 
-#ifdef HAVE_PERCPU_SB
-STATIC void    xfs_icsb_balance_counter(xfs_mount_t *, xfs_sb_field_t,
-                                               int);
-STATIC void    xfs_icsb_balance_counter_locked(xfs_mount_t *, xfs_sb_field_t,
-                                               int);
-STATIC void    xfs_icsb_disable_counter(xfs_mount_t *, xfs_sb_field_t);
-#else
-
-#define xfs_icsb_balance_counter(mp, a, b)             do { } while (0)
-#define xfs_icsb_balance_counter_locked(mp, a, b)      do { } while (0)
-#endif
-
 static DEFINE_MUTEX(xfs_uuid_table_mutex);
 static int xfs_uuid_table_size;
 static uuid_t *xfs_uuid_table;
@@ -347,8 +335,7 @@ reread:
                goto reread;
        }
 
-       /* Initialize per-cpu counters */
-       xfs_icsb_reinit_counters(mp);
+       xfs_reinit_percpu_counters(mp);
 
        /* no need to be quiet anymore, so reset the buf ops */
        bp->b_ops = &xfs_sb_buf_ops;
@@ -1087,8 +1074,6 @@ xfs_log_sbcount(xfs_mount_t *mp)
        if (!xfs_fs_writable(mp, SB_FREEZE_COMPLETE))
                return 0;
 
-       xfs_icsb_sync_counters(mp, 0);
-
        /*
         * we don't need to do this if we are updating the superblock
         * counters on every modification.
@@ -1467,502 +1452,3 @@ xfs_dev_is_read_only(
        }
        return 0;
 }
-
-#ifdef HAVE_PERCPU_SB
-/*
- * Per-cpu incore superblock counters
- *
- * Simple concept, difficult implementation
- *
- * Basically, replace the incore superblock counters with a distributed per cpu
- * counter for contended fields (e.g.  free block count).
- *
- * Difficulties arise in that the incore sb is used for ENOSPC checking, and
- * hence needs to be accurately read when we are running low on space. Hence
- * there is a method to enable and disable the per-cpu counters based on how
- * much "stuff" is available in them.
- *
- * Basically, a counter is enabled if there is enough free resource to justify
- * running a per-cpu fast-path. If the per-cpu counter runs out (i.e. a local
- * ENOSPC), then we disable the counters to synchronise all callers and
- * re-distribute the available resources.
- *
- * If, once we redistributed the available resources, we still get a failure,
- * we disable the per-cpu counter and go through the slow path.
- *
- * The slow path is the current xfs_mod_incore_sb() function.  This means that
- * when we disable a per-cpu counter, we need to drain its resources back to
- * the global superblock. We do this after disabling the counter to prevent
- * more threads from queueing up on the counter.
- *
- * Essentially, this means that we still need a lock in the fast path to enable
- * synchronisation between the global counters and the per-cpu counters. This
- * is not a problem because the lock will be local to a CPU almost all the time
- * and have little contention except when we get to ENOSPC conditions.
- *
- * Basically, this lock becomes a barrier that enables us to lock out the fast
- * path while we do things like enabling and disabling counters and
- * synchronising the counters.
- *
- * Locking rules:
- *
- *     1. m_sb_lock before picking up per-cpu locks
- *     2. per-cpu locks always picked up via for_each_online_cpu() order
- *     3. accurate counter sync requires m_sb_lock + per cpu locks
- *     4. modifying per-cpu counters requires holding per-cpu lock
- *     5. modifying global counters requires holding m_sb_lock
- *     6. enabling or disabling a counter requires holding the m_sb_lock 
- *        and _none_ of the per-cpu locks.
- *
- * Disabled counters are only ever re-enabled by a balance operation
- * that results in more free resources per CPU than a given threshold.
- * To ensure counters don't remain disabled, they are rebalanced when
- * the global resource goes above a higher threshold (i.e. some hysteresis
- * is present to prevent thrashing).
- */
-
-#ifdef CONFIG_HOTPLUG_CPU
-/*
- * hot-plug CPU notifier support.
- *
- * We need a notifier per filesystem as we need to be able to identify
- * the filesystem to balance the counters out. This is achieved by
- * having a notifier block embedded in the xfs_mount_t and doing pointer
- * magic to get the mount pointer from the notifier block address.
- */
-STATIC int
-xfs_icsb_cpu_notify(
-       struct notifier_block *nfb,
-       unsigned long action,
-       void *hcpu)
-{
-       xfs_icsb_cnts_t *cntp;
-       xfs_mount_t     *mp;
-
-       mp = (xfs_mount_t *)container_of(nfb, xfs_mount_t, m_icsb_notifier);
-       cntp = (xfs_icsb_cnts_t *)
-                       per_cpu_ptr(mp->m_sb_cnts, (unsigned long)hcpu);
-       switch (action) {
-       case CPU_UP_PREPARE:
-       case CPU_UP_PREPARE_FROZEN:
-               /* Easy Case - initialize the area and locks, and
-                * then rebalance when online does everything else for us. */
-               memset(cntp, 0, sizeof(xfs_icsb_cnts_t));
-               break;
-       case CPU_ONLINE:
-       case CPU_ONLINE_FROZEN:
-               xfs_icsb_lock(mp);
-               xfs_icsb_unlock(mp);
-               break;
-       case CPU_DEAD:
-       case CPU_DEAD_FROZEN:
-               /* Disable all the counters, then fold the dead cpu's
-                * count into the total on the global superblock and
-                * re-enable the counters. */
-               xfs_icsb_lock(mp);
-               spin_lock(&mp->m_sb_lock);
-
-               memset(cntp, 0, sizeof(xfs_icsb_cnts_t));
-
-               spin_unlock(&mp->m_sb_lock);
-               xfs_icsb_unlock(mp);
-               break;
-       }
-
-       return NOTIFY_OK;
-}
-#endif /* CONFIG_HOTPLUG_CPU */
-
-int
-xfs_icsb_init_counters(
-       xfs_mount_t     *mp)
-{
-       xfs_icsb_cnts_t *cntp;
-       int             error;
-       int             i;
-
-       error = percpu_counter_init(&mp->m_icount, 0, GFP_KERNEL);
-       if (error)
-               return error;
-
-       error = percpu_counter_init(&mp->m_ifree, 0, GFP_KERNEL);
-       if (error)
-               goto free_icount;
-
-       error = percpu_counter_init(&mp->m_fdblocks, 0, GFP_KERNEL);
-       if (error)
-               goto free_ifree;
-
-       mp->m_sb_cnts = alloc_percpu(xfs_icsb_cnts_t);
-       if (!mp->m_sb_cnts) {
-               error = -ENOMEM;
-               goto free_fdblocks;
-       }
-
-       for_each_online_cpu(i) {
-               cntp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, i);
-               memset(cntp, 0, sizeof(xfs_icsb_cnts_t));
-       }
-
-       mutex_init(&mp->m_icsb_mutex);
-
-       /*
-        * start with all counters disabled so that the
-        * initial balance kicks us off correctly
-        */
-       mp->m_icsb_counters = -1;
-
-#ifdef CONFIG_HOTPLUG_CPU
-       mp->m_icsb_notifier.notifier_call = xfs_icsb_cpu_notify;
-       mp->m_icsb_notifier.priority = 0;
-       register_hotcpu_notifier(&mp->m_icsb_notifier);
-#endif /* CONFIG_HOTPLUG_CPU */
-
-       return 0;
-
-free_fdblocks:
-       percpu_counter_destroy(&mp->m_fdblocks);
-free_ifree:
-       percpu_counter_destroy(&mp->m_ifree);
-free_icount:
-       percpu_counter_destroy(&mp->m_icount);
-       return error;
-}
-
-void
-xfs_icsb_reinit_counters(
-       xfs_mount_t     *mp)
-{
-       percpu_counter_set(&mp->m_icount, mp->m_sb.sb_icount);
-       percpu_counter_set(&mp->m_ifree, mp->m_sb.sb_ifree);
-       percpu_counter_set(&mp->m_fdblocks, mp->m_sb.sb_fdblocks);
-
-       xfs_icsb_lock(mp);
-       /*
-        * start with all counters disabled so that the
-        * initial balance kicks us off correctly
-        */
-       mp->m_icsb_counters = -1;
-       xfs_icsb_unlock(mp);
-}
-
-void
-xfs_icsb_destroy_counters(
-       xfs_mount_t     *mp)
-{
-       if (mp->m_sb_cnts) {
-               unregister_hotcpu_notifier(&mp->m_icsb_notifier);
-               free_percpu(mp->m_sb_cnts);
-       }
-
-       percpu_counter_destroy(&mp->m_icount);
-       percpu_counter_destroy(&mp->m_ifree);
-       percpu_counter_destroy(&mp->m_fdblocks);
-
-       mutex_destroy(&mp->m_icsb_mutex);
-}
-
-STATIC void
-xfs_icsb_lock_cntr(
-       xfs_icsb_cnts_t *icsbp)
-{
-       while (test_and_set_bit(XFS_ICSB_FLAG_LOCK, &icsbp->icsb_flags)) {
-               ndelay(1000);
-       }
-}
-
-STATIC void
-xfs_icsb_unlock_cntr(
-       xfs_icsb_cnts_t *icsbp)
-{
-       clear_bit(XFS_ICSB_FLAG_LOCK, &icsbp->icsb_flags);
-}
-
-
-STATIC void
-xfs_icsb_lock_all_counters(
-       xfs_mount_t     *mp)
-{
-       xfs_icsb_cnts_t *cntp;
-       int             i;
-
-       for_each_online_cpu(i) {
-               cntp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, i);
-               xfs_icsb_lock_cntr(cntp);
-       }
-}
-
-STATIC void
-xfs_icsb_unlock_all_counters(
-       xfs_mount_t     *mp)
-{
-       xfs_icsb_cnts_t *cntp;
-       int             i;
-
-       for_each_online_cpu(i) {
-               cntp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, i);
-               xfs_icsb_unlock_cntr(cntp);
-       }
-}
-
-STATIC void
-xfs_icsb_count(
-       xfs_mount_t     *mp,
-       xfs_icsb_cnts_t *cnt,
-       int             flags)
-{
-       memset(cnt, 0, sizeof(xfs_icsb_cnts_t));
-
-       if (!(flags & XFS_ICSB_LAZY_COUNT))
-               xfs_icsb_lock_all_counters(mp);
-
-
-       if (!(flags & XFS_ICSB_LAZY_COUNT))
-               xfs_icsb_unlock_all_counters(mp);
-}
-
-STATIC int
-xfs_icsb_counter_disabled(
-       xfs_mount_t     *mp,
-       xfs_sb_field_t  field)
-{
-       return test_bit(field, &mp->m_icsb_counters);
-}
-
-STATIC void
-xfs_icsb_disable_counter(
-       xfs_mount_t     *mp,
-       xfs_sb_field_t  field)
-{
-       xfs_icsb_cnts_t cnt;
-
-       /*
-        * If we are already disabled, then there is nothing to do
-        * here. We check before locking all the counters to avoid
-        * the expensive lock operation when being called in the
-        * slow path and the counter is already disabled. This is
-        * safe because the only time we set or clear this state is under
-        * the m_icsb_mutex.
-        */
-       if (xfs_icsb_counter_disabled(mp, field))
-               return;
-
-       xfs_icsb_lock_all_counters(mp);
-       if (!test_and_set_bit(field, &mp->m_icsb_counters)) {
-               /* drain back to superblock */
-
-               xfs_icsb_count(mp, &cnt, XFS_ICSB_LAZY_COUNT);
-               switch(field) {
-               default:
-                       BUG();
-               }
-       }
-
-       xfs_icsb_unlock_all_counters(mp);
-}
-
-STATIC void
-xfs_icsb_enable_counter(
-       xfs_mount_t     *mp,
-       xfs_sb_field_t  field,
-       uint64_t        count,
-       uint64_t        resid)
-{
-       int             i;
-
-       xfs_icsb_lock_all_counters(mp);
-       for_each_online_cpu(i) {
-               switch (field) {
-               default:
-                       BUG();
-                       break;
-               }
-               resid = 0;
-       }
-       clear_bit(field, &mp->m_icsb_counters);
-       xfs_icsb_unlock_all_counters(mp);
-}
-
-void
-xfs_icsb_sync_counters_locked(
-       xfs_mount_t     *mp,
-       int             flags)
-{
-       xfs_icsb_cnts_t cnt;
-
-       xfs_icsb_count(mp, &cnt, flags);
-}
-
-/*
- * Accurate update of per-cpu counters to incore superblock
- */
-void
-xfs_icsb_sync_counters(
-       xfs_mount_t     *mp,
-       int             flags)
-{
-       spin_lock(&mp->m_sb_lock);
-       xfs_icsb_sync_counters_locked(mp, flags);
-       spin_unlock(&mp->m_sb_lock);
-}
-
-/*
- * Balance and enable/disable counters as necessary.
- *
- * Thresholds for re-enabling counters are somewhat magic.  inode counts are
- * chosen to be the same number as single on disk allocation chunk per CPU, and
- * free blocks is something far enough zero that we aren't going thrash when we
- * get near ENOSPC. We also need to supply a minimum we require per cpu to
- * prevent looping endlessly when xfs_alloc_space asks for more than will
- * be distributed to a single CPU but each CPU has enough blocks to be
- * reenabled.
- *
- * Note that we can be called when counters are already disabled.
- * xfs_icsb_disable_counter() optimises the counter locking in this case to
- * prevent locking every per-cpu counter needlessly.
- */
-
-#define XFS_ICSB_INO_CNTR_REENABLE     (uint64_t)64
-#define XFS_ICSB_FDBLK_CNTR_REENABLE(mp) \
-               (uint64_t)(512 + XFS_ALLOC_SET_ASIDE(mp))
-STATIC void
-xfs_icsb_balance_counter_locked(
-       xfs_mount_t     *mp,
-       xfs_sb_field_t  field,
-       int             min_per_cpu)
-{
-       uint64_t        count, resid;
-
-       /* disable counter and sync counter */
-       xfs_icsb_disable_counter(mp, field);
-
-       /* update counters  - first CPU gets residual*/
-       switch (field) {
-       default:
-               BUG();
-               count = resid = 0;      /* quiet, gcc */
-               break;
-       }
-
-       xfs_icsb_enable_counter(mp, field, count, resid);
-}
-
-STATIC void
-xfs_icsb_balance_counter(
-       xfs_mount_t     *mp,
-       xfs_sb_field_t  fields,
-       int             min_per_cpu)
-{
-       spin_lock(&mp->m_sb_lock);
-       xfs_icsb_balance_counter_locked(mp, fields, min_per_cpu);
-       spin_unlock(&mp->m_sb_lock);
-}
-
-int
-xfs_icsb_modify_counters(
-       xfs_mount_t     *mp,
-       xfs_sb_field_t  field,
-       int64_t         delta,
-       int             rsvd)
-{
-       xfs_icsb_cnts_t *icsbp;
-       int             ret = 0;
-
-       might_sleep();
-again:
-       preempt_disable();
-       icsbp = this_cpu_ptr(mp->m_sb_cnts);
-
-       /*
-        * if the counter is disabled, go to slow path
-        */
-       if (unlikely(xfs_icsb_counter_disabled(mp, field)))
-               goto slow_path;
-       xfs_icsb_lock_cntr(icsbp);
-       if (unlikely(xfs_icsb_counter_disabled(mp, field))) {
-               xfs_icsb_unlock_cntr(icsbp);
-               goto slow_path;
-       }
-
-       switch (field) {
-       default:
-               BUG();
-               goto balance_counter; /* be still, gcc */
-       }
-       xfs_icsb_unlock_cntr(icsbp);
-       preempt_enable();
-       return 0;
-
-slow_path:
-       preempt_enable();
-
-       /*
-        * serialise with a mutex so we don't burn lots of cpu on
-        * the superblock lock. We still need to hold the superblock
-        * lock, however, when we modify the global structures.
-        */
-       xfs_icsb_lock(mp);
-
-       /*
-        * Now running atomically.
-        *
-        * If the counter is enabled, someone has beaten us to rebalancing.
-        * Drop the lock and try again in the fast path....
-        */
-       if (!(xfs_icsb_counter_disabled(mp, field))) {
-               xfs_icsb_unlock(mp);
-               goto again;
-       }
-
-       /*
-        * The counter is currently disabled. Because we are
-        * running atomically here, we know a rebalance cannot
-        * be in progress. Hence we can go straight to operating
-        * on the global superblock. We do not call xfs_mod_incore_sb()
-        * here even though we need to get the m_sb_lock. Doing so
-        * will cause us to re-enter this function and deadlock.
-        * Hence we get the m_sb_lock ourselves and then call
-        * xfs_mod_incore_sb_unlocked() as the unlocked path operates
-        * directly on the global counters.
-        */
-       spin_lock(&mp->m_sb_lock);
-       ret = xfs_mod_incore_sb_unlocked(mp, field, delta, rsvd);
-       spin_unlock(&mp->m_sb_lock);
-
-       /*
-        * Now that we've modified the global superblock, we
-        * may be able to re-enable the distributed counters
-        * (e.g. lots of space just got freed). After that
-        * we are done.
-        */
-       if (ret != -ENOSPC)
-               xfs_icsb_balance_counter(mp, field, 0);
-       xfs_icsb_unlock(mp);
-       return ret;
-
-balance_counter:
-       xfs_icsb_unlock_cntr(icsbp);
-       preempt_enable();
-
-       /*
-        * We may have multiple threads here if multiple per-cpu
-        * counters run dry at the same time. This will mean we can
-        * do more balances than strictly necessary but it is not
-        * the common slowpath case.
-        */
-       xfs_icsb_lock(mp);
-
-       /*
-        * running atomically.
-        *
-        * This will leave the counter in the correct state for future
-        * accesses. After the rebalance, we simply try again and our retry
-        * will either succeed through the fast path or slow path without
-        * another balance operation being required.
-        */
-       xfs_icsb_balance_counter(mp, field, delta);
-       xfs_icsb_unlock(mp);
-       goto again;
-}
-
-#endif
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 76f5d25..ff1d1d5 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -18,8 +18,6 @@
 #ifndef __XFS_MOUNT_H__
 #define        __XFS_MOUNT_H__
 
-#ifdef __KERNEL__
-
 struct xlog;
 struct xfs_inode;
 struct xfs_mru_cache;
@@ -29,43 +27,6 @@ struct xfs_quotainfo;
 struct xfs_dir_ops;
 struct xfs_da_geometry;
 
-#ifdef HAVE_PERCPU_SB
-
-/*
- * Valid per-cpu incore superblock counters. Note that if you add new counters,
- * you may need to define new counter disabled bit field descriptors as there
- * are more possible fields in the superblock that can fit in a bitfield on a
- * 32 bit platform. The XFS_SBS_* values for the current current counters just
- * fit.
- */
-typedef struct xfs_icsb_cnts {
-       uint64_t        icsb_fdblocks;
-       uint64_t        icsb_ifree;
-       unsigned long   icsb_flags;
-} xfs_icsb_cnts_t;
-
-#define XFS_ICSB_FLAG_LOCK     (1 << 0)        /* counter lock bit */
-
-#define XFS_ICSB_LAZY_COUNT    (1 << 1)        /* accuracy not needed */
-
-extern int     xfs_icsb_init_counters(struct xfs_mount *);
-extern void    xfs_icsb_reinit_counters(struct xfs_mount *);
-extern void    xfs_icsb_destroy_counters(struct xfs_mount *);
-extern void    xfs_icsb_sync_counters(struct xfs_mount *, int);
-extern void    xfs_icsb_sync_counters_locked(struct xfs_mount *, int);
-extern int     xfs_icsb_modify_counters(struct xfs_mount *, xfs_sb_field_t,
-                                               int64_t, int);
-
-#else
-#define xfs_icsb_init_counters(mp)             (0)
-#define xfs_icsb_destroy_counters(mp)          do { } while (0)
-#define xfs_icsb_reinit_counters(mp)           do { } while (0)
-#define xfs_icsb_sync_counters(mp, flags)      do { } while (0)
-#define xfs_icsb_sync_counters_locked(mp, flags) do { } while (0)
-#define xfs_icsb_modify_counters(mp, field, delta, rsvd) \
-       xfs_mod_incore_sb(mp, field, delta, rsvd)
-#endif
-
 /* dynamic preallocation free space thresholds, 5% down to 1% */
 enum {
        XFS_LOWSP_1_PCNT = 0,
@@ -156,12 +117,6 @@ typedef struct xfs_mount {
        const struct xfs_dir_ops *m_nondir_inode_ops; /* !dir inode ops */
        uint                    m_chsize;       /* size of next field */
        atomic_t                m_active_trans; /* number trans frozen */
-#ifdef HAVE_PERCPU_SB
-       xfs_icsb_cnts_t __percpu *m_sb_cnts;    /* per-cpu superblock counters 
*/
-       unsigned long           m_icsb_counters; /* disabled per-cpu counters */
-       struct notifier_block   m_icsb_notifier; /* hotplug cpu notifier */
-       struct mutex            m_icsb_mutex;   /* balancer sync lock */
-#endif
        struct xfs_mru_cache    *m_filestream;  /* per-mount filestream data */
        struct delayed_work     m_reclaim_work; /* background inode reclaim */
        struct delayed_work     m_eofblocks_work; /* background eof blocks
@@ -294,26 +249,6 @@ xfs_daddr_to_agbno(struct xfs_mount *mp, xfs_daddr_t d)
 }
 
 /*
- * Per-cpu superblock locking functions
- */
-#ifdef HAVE_PERCPU_SB
-static inline void
-xfs_icsb_lock(xfs_mount_t *mp)
-{
-       mutex_lock(&mp->m_icsb_mutex);
-}
-
-static inline void
-xfs_icsb_unlock(xfs_mount_t *mp)
-{
-       mutex_unlock(&mp->m_icsb_mutex);
-}
-#else
-#define xfs_icsb_lock(mp)
-#define xfs_icsb_unlock(mp)
-#endif
-
-/*
  * This structure is for use by the xfs_mod_incore_sb_batch() routine.
  * xfs_growfs can specify a few fields which are more than int limit
  */
@@ -396,6 +331,4 @@ extern int  xfs_dev_is_read_only(struct xfs_mount *, char 
*);
 
 extern void    xfs_set_low_space_thresholds(struct xfs_mount *);
 
-#endif /* __KERNEL__ */
-
 #endif /* __XFS_MOUNT_H__ */
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 4c6af31..af6d268 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -1035,23 +1035,6 @@ xfs_free_fsname(
        kfree(mp->m_logname);
 }
 
-STATIC void
-xfs_fs_put_super(
-       struct super_block      *sb)
-{
-       struct xfs_mount        *mp = XFS_M(sb);
-
-       xfs_filestream_unmount(mp);
-       xfs_unmountfs(mp);
-
-       xfs_freesb(mp);
-       xfs_icsb_destroy_counters(mp);
-       xfs_destroy_mount_workqueues(mp);
-       xfs_close_devices(mp);
-       xfs_free_fsname(mp);
-       kfree(mp);
-}
-
 STATIC int
 xfs_fs_sync_fs(
        struct super_block      *sb,
@@ -1100,7 +1083,6 @@ xfs_fs_statfs(
        statp->f_fsid.val[0] = (u32)id;
        statp->f_fsid.val[1] = (u32)(id >> 32);
 
-       xfs_icsb_sync_counters(mp, XFS_ICSB_LAZY_COUNT);
        icount = percpu_counter_sum(&mp->m_icount);
        ifree = percpu_counter_sum(&mp->m_ifree);
        fdblocks = percpu_counter_sum(&mp->m_fdblocks);
@@ -1405,6 +1387,51 @@ xfs_finish_flags(
        return 0;
 }
 
+static int
+xfs_init_percpu_counters(
+       struct xfs_mount        *mp)
+{
+       int             error;
+
+       error = percpu_counter_init(&mp->m_icount, 0, GFP_KERNEL);
+       if (error)
+               return ENOMEM;
+
+       error = percpu_counter_init(&mp->m_ifree, 0, GFP_KERNEL);
+       if (error)
+               goto free_icount;
+
+       error = percpu_counter_init(&mp->m_fdblocks, 0, GFP_KERNEL);
+       if (error)
+               goto free_ifree;
+
+       return 0;
+
+free_ifree:
+       percpu_counter_destroy(&mp->m_ifree);
+free_icount:
+       percpu_counter_destroy(&mp->m_icount);
+       return -ENOMEM;
+}
+
+void
+xfs_reinit_percpu_counters(
+       struct xfs_mount        *mp)
+{
+       percpu_counter_set(&mp->m_icount, mp->m_sb.sb_icount);
+       percpu_counter_set(&mp->m_ifree, mp->m_sb.sb_ifree);
+       percpu_counter_set(&mp->m_fdblocks, mp->m_sb.sb_fdblocks);
+}
+
+static void
+xfs_destroy_percpu_counters(
+       struct xfs_mount        *mp)
+{
+       percpu_counter_destroy(&mp->m_icount);
+       percpu_counter_destroy(&mp->m_ifree);
+       percpu_counter_destroy(&mp->m_fdblocks);
+}
+
 STATIC int
 xfs_fs_fill_super(
        struct super_block      *sb,
@@ -1453,7 +1480,7 @@ xfs_fs_fill_super(
        if (error)
                goto out_close_devices;
 
-       error = xfs_icsb_init_counters(mp);
+       error = xfs_init_percpu_counters(mp);
        if (error)
                goto out_destroy_workqueues;
 
@@ -1511,7 +1538,7 @@ xfs_fs_fill_super(
  out_free_sb:
        xfs_freesb(mp);
  out_destroy_counters:
-       xfs_icsb_destroy_counters(mp);
+       xfs_destroy_percpu_counters(mp);
 out_destroy_workqueues:
        xfs_destroy_mount_workqueues(mp);
  out_close_devices:
@@ -1528,6 +1555,23 @@ out_destroy_workqueues:
        goto out_free_sb;
 }
 
+STATIC void
+xfs_fs_put_super(
+       struct super_block      *sb)
+{
+       struct xfs_mount        *mp = XFS_M(sb);
+
+       xfs_filestream_unmount(mp);
+       xfs_unmountfs(mp);
+
+       xfs_freesb(mp);
+       xfs_destroy_percpu_counters(mp);
+       xfs_destroy_mount_workqueues(mp);
+       xfs_close_devices(mp);
+       xfs_free_fsname(mp);
+       kfree(mp);
+}
+
 STATIC struct dentry *
 xfs_fs_mount(
        struct file_system_type *fs_type,
diff --git a/fs/xfs/xfs_super.h b/fs/xfs/xfs_super.h
index 2b830c2..499058f 100644
--- a/fs/xfs/xfs_super.h
+++ b/fs/xfs/xfs_super.h
@@ -72,6 +72,8 @@ extern const struct export_operations xfs_export_operations;
 extern const struct xattr_handler *xfs_xattr_handlers[];
 extern const struct quotactl_ops xfs_quotactl_operations;
 
+extern void xfs_reinit_percpu_counters(struct xfs_mount *mp);
+
 #define XFS_M(sb)              ((struct xfs_mount *)((sb)->s_fs_info))
 
 #endif /* __XFS_SUPER_H__ */
-- 
2.0.0

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