aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Chinner <dgc@sgi.com>2006-03-13 21:23:52 -0500
committerNathan Scott <nathans@sgi.com>2006-03-13 21:23:52 -0500
commite8234a6871aa0de1ed0aeeecb5230ecf3ab414e2 (patch)
treeb88093459262dcae16a237faf45200052629d19b
parent2d0f864be3266eb0a8b4b48f36e2f777eace00b3 (diff)
[XFS] Add support for hotplug CPUs to the per-CPU superblock counters by
registering a notifier callback that listens to CPU up/down events to modify the counters appropriately. SGI-PV: 949726 SGI-Modid: xfs-linux-melb:xfs-kern:25214a Signed-off-by: David Chinner <dgc@sgi.com> Signed-off-by: Nathan Scott <nathans@sgi.com>
-rw-r--r--fs/xfs/linux-2.6/xfs_linux.h2
-rw-r--r--fs/xfs/xfs_mount.c74
-rw-r--r--fs/xfs/xfs_mount.h1
3 files changed, 75 insertions, 2 deletions
diff --git a/fs/xfs/linux-2.6/xfs_linux.h b/fs/xfs/linux-2.6/xfs_linux.h
index e2be64982bc1..9fdc14cffb70 100644
--- a/fs/xfs/linux-2.6/xfs_linux.h
+++ b/fs/xfs/linux-2.6/xfs_linux.h
@@ -73,6 +73,8 @@
73#include <linux/list.h> 73#include <linux/list.h>
74#include <linux/proc_fs.h> 74#include <linux/proc_fs.h>
75#include <linux/sort.h> 75#include <linux/sort.h>
76#include <linux/cpu.h>
77#include <linux/notifier.h>
76 78
77#include <asm/page.h> 79#include <asm/page.h>
78#include <asm/div64.h> 80#include <asm/div64.h>
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 9b43b7b3d760..a64110b9023b 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -60,6 +60,7 @@ STATIC int xfs_icsb_modify_counters(xfs_mount_t *, xfs_sb_field_t,
60 int, int); 60 int, int);
61STATIC int xfs_icsb_modify_counters_locked(xfs_mount_t *, xfs_sb_field_t, 61STATIC int xfs_icsb_modify_counters_locked(xfs_mount_t *, xfs_sb_field_t,
62 int, int); 62 int, int);
63STATIC int xfs_icsb_disable_counter(xfs_mount_t *, xfs_sb_field_t);
63 64
64#else 65#else
65 66
@@ -1716,9 +1717,72 @@ xfs_mount_log_sbunit(
1716 * To ensure counters don't remain disabled, they are rebalanced when 1717 * To ensure counters don't remain disabled, they are rebalanced when
1717 * the global resource goes above a higher threshold (i.e. some hysteresis 1718 * the global resource goes above a higher threshold (i.e. some hysteresis
1718 * is present to prevent thrashing). 1719 * is present to prevent thrashing).
1720 */
1721
1722/*
1723 * hot-plug CPU notifier support.
1719 * 1724 *
1720 * Note: hotplug CPUs not yet supported 1725 * We cannot use the hotcpu_register() function because it does
1726 * not allow notifier instances. We need a notifier per filesystem
1727 * as we need to be able to identify the filesystem to balance
1728 * the counters out. This is acheived by having a notifier block
1729 * embedded in the xfs_mount_t and doing pointer magic to get the
1730 * mount pointer from the notifier block address.
1721 */ 1731 */
1732STATIC int
1733xfs_icsb_cpu_notify(
1734 struct notifier_block *nfb,
1735 unsigned long action,
1736 void *hcpu)
1737{
1738 xfs_icsb_cnts_t *cntp;
1739 xfs_mount_t *mp;
1740 int s;
1741
1742 mp = (xfs_mount_t *)container_of(nfb, xfs_mount_t, m_icsb_notifier);
1743 cntp = (xfs_icsb_cnts_t *)
1744 per_cpu_ptr(mp->m_sb_cnts, (unsigned long)hcpu);
1745 switch (action) {
1746 case CPU_UP_PREPARE:
1747 /* Easy Case - initialize the area and locks, and
1748 * then rebalance when online does everything else for us. */
1749 spin_lock_init(&cntp->icsb_lock);
1750 cntp->icsb_icount = 0;
1751 cntp->icsb_ifree = 0;
1752 cntp->icsb_fdblocks = 0;
1753 break;
1754 case CPU_ONLINE:
1755 xfs_icsb_balance_counter(mp, XFS_SBS_ICOUNT, 0);
1756 xfs_icsb_balance_counter(mp, XFS_SBS_IFREE, 0);
1757 xfs_icsb_balance_counter(mp, XFS_SBS_FDBLOCKS, 0);
1758 break;
1759 case CPU_DEAD:
1760 /* Disable all the counters, then fold the dead cpu's
1761 * count into the total on the global superblock and
1762 * re-enable the counters. */
1763 s = XFS_SB_LOCK(mp);
1764 xfs_icsb_disable_counter(mp, XFS_SBS_ICOUNT);
1765 xfs_icsb_disable_counter(mp, XFS_SBS_IFREE);
1766 xfs_icsb_disable_counter(mp, XFS_SBS_FDBLOCKS);
1767
1768 mp->m_sb.sb_icount += cntp->icsb_icount;
1769 mp->m_sb.sb_ifree += cntp->icsb_ifree;
1770 mp->m_sb.sb_fdblocks += cntp->icsb_fdblocks;
1771
1772 cntp->icsb_icount = 0;
1773 cntp->icsb_ifree = 0;
1774 cntp->icsb_fdblocks = 0;
1775
1776 xfs_icsb_balance_counter(mp, XFS_SBS_ICOUNT, XFS_ICSB_SB_LOCKED);
1777 xfs_icsb_balance_counter(mp, XFS_SBS_IFREE, XFS_ICSB_SB_LOCKED);
1778 xfs_icsb_balance_counter(mp, XFS_SBS_FDBLOCKS, XFS_ICSB_SB_LOCKED);
1779 XFS_SB_UNLOCK(mp, s);
1780 break;
1781 }
1782
1783 return NOTIFY_OK;
1784}
1785
1722int 1786int
1723xfs_icsb_init_counters( 1787xfs_icsb_init_counters(
1724 xfs_mount_t *mp) 1788 xfs_mount_t *mp)
@@ -1730,6 +1794,10 @@ xfs_icsb_init_counters(
1730 if (mp->m_sb_cnts == NULL) 1794 if (mp->m_sb_cnts == NULL)
1731 return -ENOMEM; 1795 return -ENOMEM;
1732 1796
1797 mp->m_icsb_notifier.notifier_call = xfs_icsb_cpu_notify;
1798 mp->m_icsb_notifier.priority = 0;
1799 register_cpu_notifier(&mp->m_icsb_notifier);
1800
1733 for_each_online_cpu(i) { 1801 for_each_online_cpu(i) {
1734 cntp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, i); 1802 cntp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, i);
1735 spin_lock_init(&cntp->icsb_lock); 1803 spin_lock_init(&cntp->icsb_lock);
@@ -1746,8 +1814,10 @@ STATIC void
1746xfs_icsb_destroy_counters( 1814xfs_icsb_destroy_counters(
1747 xfs_mount_t *mp) 1815 xfs_mount_t *mp)
1748{ 1816{
1749 if (mp->m_sb_cnts) 1817 if (mp->m_sb_cnts) {
1818 unregister_cpu_notifier(&mp->m_icsb_notifier);
1750 free_percpu(mp->m_sb_cnts); 1819 free_percpu(mp->m_sb_cnts);
1820 }
1751} 1821}
1752 1822
1753 1823
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 7cca5110ca44..9d2ffbdc37a9 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -401,6 +401,7 @@ typedef struct xfs_mount {
401#ifdef HAVE_PERCPU_SB 401#ifdef HAVE_PERCPU_SB
402 xfs_icsb_cnts_t *m_sb_cnts; /* per-cpu superblock counters */ 402 xfs_icsb_cnts_t *m_sb_cnts; /* per-cpu superblock counters */
403 unsigned long m_icsb_counters; /* disabled per-cpu counters */ 403 unsigned long m_icsb_counters; /* disabled per-cpu counters */
404 struct notifier_block m_icsb_notifier; /* hotplug cpu notifier */
404#endif 405#endif
405} xfs_mount_t; 406} xfs_mount_t;
406 407