]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
super: fix calculation of shrinkable objects for small numbers
authorGlauber Costa <glommer@openvz.org>
Wed, 19 Jun 2013 00:06:44 +0000 (10:06 +1000)
committerStephen Rothwell <sfr@canb.auug.org.au>
Wed, 19 Jun 2013 07:13:27 +0000 (17:13 +1000)
The sysctl knob sysctl_vfs_cache_pressure is used to determine which
percentage of the shrinkable objects in our cache we should actively try
to shrink.

It works great in situations in which we have many objects (at least more
than 100), because the aproximation errors will be negligible.  But if
this is not the case, specially when total_objects < 100, we may end up
concluding that we have no objects at all (total / 100 = 0, if total <
100).

This is certainly not the biggest killer in the world, but may matter in
very low kernel memory situations.

Signed-off-by: Glauber Costa <glommer@openvz.org>
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Acked-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Acked-by: Mel Gorman <mgorman@suse.de>
Cc: Dave Chinner <david@fromorbit.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: "Theodore Ts'o" <tytso@mit.edu>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Cc: Arve Hjønnevåg <arve@android.com>
Cc: Carlos Maiolino <cmaiolino@redhat.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Chuck Lever <chuck.lever@oracle.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: David Rientjes <rientjes@google.com>
Cc: Gleb Natapov <gleb@redhat.com>
Cc: Greg Thelen <gthelen@google.com>
Cc: J. Bruce Fields <bfields@redhat.com>
Cc: Jan Kara <jack@suse.cz>
Cc: Jerome Glisse <jglisse@redhat.com>
Cc: John Stultz <john.stultz@linaro.org>
Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Kent Overstreet <koverstreet@google.com>
Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Cc: Mel Gorman <mgorman@suse.de>
Cc: Steven Whitehouse <swhiteho@redhat.com>
Cc: Thomas Hellstrom <thellstrom@vmware.com>
Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
fs/gfs2/glock.c
fs/gfs2/quota.c
fs/mbcache.c
fs/nfs/dir.c
fs/quota/dquot.c
fs/super.c
fs/xfs/xfs_qm.c
include/linux/dcache.h

index 9435384562a271cacd5219651269b36d5d2923c4..3bd27480ac56a27264ee588c69d8fc525f8f5cdb 100644 (file)
@@ -1463,7 +1463,7 @@ static int gfs2_shrink_glock_memory(struct shrinker *shrink,
                gfs2_scan_glock_lru(sc->nr_to_scan);
        }
 
-       return (atomic_read(&lru_count) / 100) * sysctl_vfs_cache_pressure;
+       return vfs_pressure_ratio(atomic_read(&lru_count));
 }
 
 static struct shrinker glock_shrinker = {
index 3768c2f40e43350f3586769e9b40974ac9138a74..d550a5d6a05f263187842ea0aa6f4e2a4d70fa0a 100644 (file)
@@ -114,7 +114,7 @@ int gfs2_shrink_qd_memory(struct shrinker *shrink, struct shrink_control *sc)
        spin_unlock(&qd_lru_lock);
 
 out:
-       return (atomic_read(&qd_lru_count) * sysctl_vfs_cache_pressure) / 100;
+       return vfs_pressure_ratio(atomic_read(&qd_lru_count));
 }
 
 static u64 qd2index(struct gfs2_quota_data *qd)
index 8c32ef3ba88e7ac25a197866a38c4590836f12be..5eb04767cb29c0cd7c9be618a2aa29d595995671 100644 (file)
@@ -189,7 +189,7 @@ mb_cache_shrink_fn(struct shrinker *shrink, struct shrink_control *sc)
        list_for_each_entry_safe(entry, tmp, &free_list, e_lru_list) {
                __mb_cache_entry_forget(entry, gfp_mask);
        }
-       return (count / 100) * sysctl_vfs_cache_pressure;
+       return vfs_pressure_ratio(count);
 }
 
 
index 3cfd20852d844d7bae7aa9d6c150c3185566e05b..0d2cdad2863e42cf0ef74a6da22f6235e431bae0 100644 (file)
@@ -2004,7 +2004,7 @@ remove_lru_entry:
        }
        spin_unlock(&nfs_access_lru_lock);
        nfs_access_free_list(&head);
-       return (atomic_long_read(&nfs_access_nr_entries) / 100) * sysctl_vfs_cache_pressure;
+       return vfs_pressure_ratio(atomic_long_read(&nfs_access_nr_entries));
 }
 
 static void __nfs_access_zap_cache(struct nfs_inode *nfsi, struct list_head *head)
index 3e64169ef52710ff11f9c7f8c44ee3c910cbd321..762b09c2b0e43bcaf788c81f11681876ce5786fd 100644 (file)
@@ -719,9 +719,8 @@ static int shrink_dqcache_memory(struct shrinker *shrink,
                prune_dqcache(nr);
                spin_unlock(&dq_list_lock);
        }
-       return ((unsigned)
-               percpu_counter_read_positive(&dqstats.counter[DQST_FREE_DQUOTS])
-               /100) * sysctl_vfs_cache_pressure;
+       return vfs_pressure_ratio(
+       percpu_counter_read_positive(&dqstats.counter[DQST_FREE_DQUOTS]));
 }
 
 static struct shrinker dqcache_shrinker = {
index 7465d4364208a2e751d2d3a7c8a8c1cc10d2d7c3..2a37fd618ac2753cf3af1e4e4a700d428606f4dd 100644 (file)
@@ -82,13 +82,13 @@ static int prune_super(struct shrinker *shrink, struct shrink_control *sc)
                int     inodes;
 
                /* proportion the scan between the caches */
-               dentries = (sc->nr_to_scan * sb->s_nr_dentry_unused) /
-                                                       total_objects;
-               inodes = (sc->nr_to_scan * sb->s_nr_inodes_unused) /
-                                                       total_objects;
+               dentries = mult_frac(sc->nr_to_scan, sb->s_nr_dentry_unused,
+                                                       total_objects);
+               inodes = mult_frac(sc->nr_to_scan, sb->s_nr_inodes_unused,
+                                                       total_objects);
                if (fs_objects)
-                       fs_objects = (sc->nr_to_scan * fs_objects) /
-                                                       total_objects;
+                       fs_objects = mult_frac(sc->nr_to_scan, fs_objects,
+                                                       total_objects);
                /*
                 * prune the dcache first as the icache is pinned by it, then
                 * prune the icache, followed by the filesystem specific caches
@@ -104,7 +104,7 @@ static int prune_super(struct shrinker *shrink, struct shrink_control *sc)
                                sb->s_nr_inodes_unused + fs_objects;
        }
 
-       total_objects = (total_objects / 100) * sysctl_vfs_cache_pressure;
+       total_objects = vfs_pressure_ratio(total_objects);
        drop_super(sb);
        return total_objects;
 }
index b75c9bb6e71e34b0c65158f63ba475a217d9e347..f10506b88348a0c12c68051559d1b575bf3a9e54 100644 (file)
@@ -1605,7 +1605,7 @@ xfs_qm_shake(
        }
 
 out:
-       return (qi->qi_lru_count / 100) * sysctl_vfs_cache_pressure;
+       return vfs_pressure_ratio(qi->qi_lru_count);
 }
 
 /*
index 1a82bdbce73fb5da9512c374e63029cb8982b9d5..bd082856cbec8545b1044d98ece973e828e1cd7d 100644 (file)
@@ -411,4 +411,8 @@ static inline bool d_mountpoint(struct dentry *dentry)
 
 extern int sysctl_vfs_cache_pressure;
 
+static inline unsigned long vfs_pressure_ratio(unsigned long val)
+{
+       return mult_frac(val, sysctl_vfs_cache_pressure, 100);
+}
 #endif /* __LINUX_DCACHE_H */