]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs: use percpu_counter_read_positive for mp->m_icount
authorGeorge Wang <xuw2015@gmail.com>
Fri, 31 Jul 2015 01:12:44 +0000 (11:12 +1000)
committerDave Chinner <david@fromorbit.com>
Fri, 31 Jul 2015 01:12:44 +0000 (11:12 +1000)
Function percpu_counter_read just return the current counter, which can be
negative. This will cause the checking of "allocated inode
counts <= m_maxicount" false positive. Use percpu_counter_read_positive can
solve this problem, and be consistent with the purpose to introduce percpu
mechanism to xfs.

Signed-off-by: George Wang <xuw2015@gmail.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
libxfs/libxfs_priv.h
libxfs/xfs_ialloc.c

index 25f750859ad7102041be254ee6e69cfaeaaf246b..ffc3e456d8d1eceef1684ae0b1612c7d243ef383 100644 (file)
@@ -173,8 +173,9 @@ enum ce { CE_DEBUG, CE_CONT, CE_NOTE, CE_WARN, CE_ALERT, CE_PANIC };
 #define rcu_read_unlock()      ((void) 0)
 #define WARN_ON_ONCE(expr)     ((void) 0)
 
-#define percpu_counter_read(x) (*x)
-#define percpu_counter_sum(x)  (*x)
+#define percpu_counter_read(x)         (*x)
+#define percpu_counter_read_positive(x)        ((*x) > 0 ? (*x) : 0)
+#define percpu_counter_sum(x)          (*x)
 
 /*
  * prandom_u32 is used for di_gen inode allocation, it must be zero for libxfs
index 5e512be9fec3511f7b59abf211500f381365af02..b57f89a7e0c80ac798ab9b13f0eefd4222f8edae 100644 (file)
@@ -621,7 +621,7 @@ xfs_ialloc_ag_alloc(
         */
        newlen = args.mp->m_ialloc_inos;
        if (args.mp->m_maxicount &&
-           percpu_counter_read(&args.mp->m_icount) + newlen >
+           percpu_counter_read_positive(&args.mp->m_icount) + newlen >
                                                        args.mp->m_maxicount)
                return -ENOSPC;
        args.minlen = args.maxlen = args.mp->m_ialloc_blks;
@@ -1699,10 +1699,13 @@ xfs_dialloc(
         * If we have already hit the ceiling of inode blocks then clear
         * okalloc so we scan all available agi structures for a free
         * inode.
+        *
+        * Read rough value of mp->m_icount by percpu_counter_read_positive,
+        * which will sacrifice the preciseness but improve the performance.
         */
        if (mp->m_maxicount &&
-           percpu_counter_read(&mp->m_icount) + mp->m_ialloc_inos >
-                                                       mp->m_maxicount) {
+           percpu_counter_read_positive(&mp->m_icount) + mp->m_ialloc_inos
+                                                       mp->m_maxicount) {
                noroom = 1;
                okalloc = 0;
        }