aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/linux-2.6/xfs_linux.h1
-rw-r--r--fs/xfs/xfs_mount.c37
-rw-r--r--fs/xfs/xfs_mount.h4
3 files changed, 28 insertions, 14 deletions
diff --git a/fs/xfs/linux-2.6/xfs_linux.h b/fs/xfs/linux-2.6/xfs_linux.h
index 9fdc14cffb70..bd88ccb0cad0 100644
--- a/fs/xfs/linux-2.6/xfs_linux.h
+++ b/fs/xfs/linux-2.6/xfs_linux.h
@@ -75,6 +75,7 @@
75#include <linux/sort.h> 75#include <linux/sort.h>
76#include <linux/cpu.h> 76#include <linux/cpu.h>
77#include <linux/notifier.h> 77#include <linux/notifier.h>
78#include <linux/delay.h>
78 79
79#include <asm/page.h> 80#include <asm/page.h>
80#include <asm/div64.h> 81#include <asm/div64.h>
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index a64110b9023b..d62aee027368 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -1746,10 +1746,7 @@ xfs_icsb_cpu_notify(
1746 case CPU_UP_PREPARE: 1746 case CPU_UP_PREPARE:
1747 /* Easy Case - initialize the area and locks, and 1747 /* Easy Case - initialize the area and locks, and
1748 * then rebalance when online does everything else for us. */ 1748 * then rebalance when online does everything else for us. */
1749 spin_lock_init(&cntp->icsb_lock); 1749 memset(cntp, 0, sizeof(xfs_icsb_cnts_t));
1750 cntp->icsb_icount = 0;
1751 cntp->icsb_ifree = 0;
1752 cntp->icsb_fdblocks = 0;
1753 break; 1750 break;
1754 case CPU_ONLINE: 1751 case CPU_ONLINE:
1755 xfs_icsb_balance_counter(mp, XFS_SBS_ICOUNT, 0); 1752 xfs_icsb_balance_counter(mp, XFS_SBS_ICOUNT, 0);
@@ -1769,9 +1766,7 @@ xfs_icsb_cpu_notify(
1769 mp->m_sb.sb_ifree += cntp->icsb_ifree; 1766 mp->m_sb.sb_ifree += cntp->icsb_ifree;
1770 mp->m_sb.sb_fdblocks += cntp->icsb_fdblocks; 1767 mp->m_sb.sb_fdblocks += cntp->icsb_fdblocks;
1771 1768
1772 cntp->icsb_icount = 0; 1769 memset(cntp, 0, sizeof(xfs_icsb_cnts_t));
1773 cntp->icsb_ifree = 0;
1774 cntp->icsb_fdblocks = 0;
1775 1770
1776 xfs_icsb_balance_counter(mp, XFS_SBS_ICOUNT, XFS_ICSB_SB_LOCKED); 1771 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); 1772 xfs_icsb_balance_counter(mp, XFS_SBS_IFREE, XFS_ICSB_SB_LOCKED);
@@ -1800,7 +1795,7 @@ xfs_icsb_init_counters(
1800 1795
1801 for_each_online_cpu(i) { 1796 for_each_online_cpu(i) {
1802 cntp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, i); 1797 cntp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, i);
1803 spin_lock_init(&cntp->icsb_lock); 1798 memset(cntp, 0, sizeof(xfs_icsb_cnts_t));
1804 } 1799 }
1805 /* 1800 /*
1806 * start with all counters disabled so that the 1801 * start with all counters disabled so that the
@@ -1820,6 +1815,22 @@ xfs_icsb_destroy_counters(
1820 } 1815 }
1821} 1816}
1822 1817
1818STATIC inline void
1819xfs_icsb_lock_cntr(
1820 xfs_icsb_cnts_t *icsbp)
1821{
1822 while (test_and_set_bit(XFS_ICSB_FLAG_LOCK, &icsbp->icsb_flags)) {
1823 ndelay(1000);
1824 }
1825}
1826
1827STATIC inline void
1828xfs_icsb_unlock_cntr(
1829 xfs_icsb_cnts_t *icsbp)
1830{
1831 clear_bit(XFS_ICSB_FLAG_LOCK, &icsbp->icsb_flags);
1832}
1833
1823 1834
1824STATIC inline void 1835STATIC inline void
1825xfs_icsb_lock_all_counters( 1836xfs_icsb_lock_all_counters(
@@ -1830,7 +1841,7 @@ xfs_icsb_lock_all_counters(
1830 1841
1831 for_each_online_cpu(i) { 1842 for_each_online_cpu(i) {
1832 cntp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, i); 1843 cntp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, i);
1833 spin_lock(&cntp->icsb_lock); 1844 xfs_icsb_lock_cntr(cntp);
1834 } 1845 }
1835} 1846}
1836 1847
@@ -1843,7 +1854,7 @@ xfs_icsb_unlock_all_counters(
1843 1854
1844 for_each_online_cpu(i) { 1855 for_each_online_cpu(i) {
1845 cntp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, i); 1856 cntp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, i);
1846 spin_unlock(&cntp->icsb_lock); 1857 xfs_icsb_unlock_cntr(cntp);
1847 } 1858 }
1848} 1859}
1849 1860
@@ -2070,7 +2081,7 @@ xfs_icsb_modify_counters_int(
2070again: 2081again:
2071 cpu = get_cpu(); 2082 cpu = get_cpu();
2072 icsbp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, cpu), 2083 icsbp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, cpu),
2073 spin_lock(&icsbp->icsb_lock); 2084 xfs_icsb_lock_cntr(icsbp);
2074 if (unlikely(xfs_icsb_counter_disabled(mp, field))) 2085 if (unlikely(xfs_icsb_counter_disabled(mp, field)))
2075 goto slow_path; 2086 goto slow_path;
2076 2087
@@ -2104,7 +2115,7 @@ again:
2104 BUG(); 2115 BUG();
2105 break; 2116 break;
2106 } 2117 }
2107 spin_unlock(&icsbp->icsb_lock); 2118 xfs_icsb_unlock_cntr(icsbp);
2108 put_cpu(); 2119 put_cpu();
2109 if (locked) 2120 if (locked)
2110 XFS_SB_UNLOCK(mp, s); 2121 XFS_SB_UNLOCK(mp, s);
@@ -2120,7 +2131,7 @@ again:
2120 * manner. 2131 * manner.
2121 */ 2132 */
2122slow_path: 2133slow_path:
2123 spin_unlock(&icsbp->icsb_lock); 2134 xfs_icsb_unlock_cntr(icsbp);
2124 put_cpu(); 2135 put_cpu();
2125 2136
2126 /* need to hold superblock incase we need 2137 /* need to hold superblock incase we need
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 9d2ffbdc37a9..29cfcf0c11be 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -280,9 +280,11 @@ typedef struct xfs_icsb_cnts {
280 uint64_t icsb_fdblocks; 280 uint64_t icsb_fdblocks;
281 uint64_t icsb_ifree; 281 uint64_t icsb_ifree;
282 uint64_t icsb_icount; 282 uint64_t icsb_icount;
283 spinlock_t icsb_lock; 283 unsigned long icsb_flags;
284} xfs_icsb_cnts_t; 284} xfs_icsb_cnts_t;
285 285
286#define XFS_ICSB_FLAG_LOCK (1 << 0) /* counter lock bit */
287
286#define XFS_ICSB_SB_LOCKED (1 << 0) /* sb already locked */ 288#define XFS_ICSB_SB_LOCKED (1 << 0) /* sb already locked */
287#define XFS_ICSB_LAZY_COUNT (1 << 1) /* accuracy not needed */ 289#define XFS_ICSB_LAZY_COUNT (1 << 1) /* accuracy not needed */
288 290