diff options
author | David Chinner <dgc@sgi.com> | 2006-03-13 21:29:16 -0500 |
---|---|---|
committer | Nathan Scott <nathans@sgi.com> | 2006-03-13 21:29:16 -0500 |
commit | 01e1b69cfcdcfdd5b405165eaba29428f8b18a7c (patch) | |
tree | 3ca7e8d0047ff03ca532f39b0fc4cd50381e8ecc /fs/xfs/xfs_mount.c | |
parent | 87cbc49cd4b773a972bce56c5dd09c4717f3285b (diff) |
[XFS] using a spinlock per cpu for superblock counter exclusion results in
a preēmpt counter overflow at 256p and above. Change the exclusion
mechanism to use atomic bit operations and busy wait loops to emulate the
spin lock exclusion mechanism but without the preempt count issues.
SGI-PV: 950027
SGI-Modid: xfs-linux-melb:xfs-kern:25338a
Signed-off-by: David Chinner <dgc@sgi.com>
Signed-off-by: Nathan Scott <nathans@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_mount.c')
-rw-r--r-- | fs/xfs/xfs_mount.c | 37 |
1 files changed, 24 insertions, 13 deletions
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 | ||
1818 | STATIC inline void | ||
1819 | xfs_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 | |||
1827 | STATIC inline void | ||
1828 | xfs_icsb_unlock_cntr( | ||
1829 | xfs_icsb_cnts_t *icsbp) | ||
1830 | { | ||
1831 | clear_bit(XFS_ICSB_FLAG_LOCK, &icsbp->icsb_flags); | ||
1832 | } | ||
1833 | |||
1823 | 1834 | ||
1824 | STATIC inline void | 1835 | STATIC inline void |
1825 | xfs_icsb_lock_all_counters( | 1836 | xfs_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( | |||
2070 | again: | 2081 | again: |
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 | */ |
2122 | slow_path: | 2133 | slow_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 |