From mboxrd@z Thu Jan 1 00:00:00 1970 From: Dave Chinner Subject: [PATCH] fs: use approximate counter values for inodes and dentries. (was Re: [patch] fs: use fast counters for vfs caches) Date: Thu, 9 Dec 2010 18:45:03 +1100 Message-ID: <20101209074503.GD8259@dastard> References: <20101129105733.GA3241@amd> <20101209054343.GA8259@dastard> <20101209061644.GA3667@amd> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: QUOTED-PRINTABLE Cc: linux-fsdevel@vger.kernel.org, Linus Torvalds , Al Viro , Christoph Hellwig To: Nick Piggin Return-path: Received: from bld-mail18.adl2.internode.on.net ([150.101.137.103]:47670 "EHLO mail.internode.on.net" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751890Ab0LIHp1 (ORCPT ); Thu, 9 Dec 2010 02:45:27 -0500 Content-Disposition: inline In-Reply-To: <20101209061644.GA3667@amd> Sender: linux-fsdevel-owner@vger.kernel.org List-ID: On Thu, Dec 09, 2010 at 05:16:44PM +1100, Nick Piggin wrote: > On Thu, Dec 09, 2010 at 04:43:43PM +1100, Dave Chinner wrote: > > On Mon, Nov 29, 2010 at 09:57:33PM +1100, Nick Piggin wrote: > > > Hey, > > >=20 > > > What was the reason behind not using my approach to use fast per-= cpu > > > counters for inode and dentry counters, and instead using the > > > percpu_counter lib (which is not useful unless very fast approxim= ate > > > access to the global counter is required, or performance is not > > > critical, which is somewhat of an oxymoron if you're using per-co= unters > > > in the first place). It is a difference between this: > >=20 > > Hi Nick - sorry for being slow to answer this - I only just found > > this email. > >=20 > > The reason for using the generic counters is because the shrinkers > > read the current value of the global counter on every call and henc= e > > they can be read thousands of times a second. The only way to do th= at > > efficiently is to use the approximately value the generic counters > > provide. >=20 > That is not what is happening, though, so I assume that no measuremen= ts > were done. > > In fact what happens now is that *both* type of counters use the crap= py > percpu counter library, and the shrinkers actually do a per-cpu loop > over the counters to get the sum. More likely that the overhead was hidden in the noise on the size of machines most people test on. It certainly wasn't measurable on my 16p machine, and nobody who reviewed it at the time (=D1=95everal peopl= e) picked it up. So thanks for reviewing it - the simple fix is below. Cheers, Dave. --=20 Dave Chinner david@fromorbit.com fs: Use approximate values for number of inodes and dentries =46rom: Dave Chinner The number of inodes and dentries are percpu counters that are summed by the shrinkers. This can result in summing across all CPUs thousands of times per second per counter which is very inefficient. The approximate counter value should be used instead to keep the overhead to a minimum. Signed-off-by: Dave Chinner --- fs/dcache.c | 4 ++-- fs/inode.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/dcache.c b/fs/dcache.c index 23702a9..a533184 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -546,7 +546,7 @@ static void prune_dcache(int count) { struct super_block *sb, *p =3D NULL; int w_count; - int unused =3D percpu_counter_sum_positive(&nr_dentry_unused); + int unused =3D percpu_counter_read_positive(&nr_dentry_unused); int prune_ratio; int pruned; =20 @@ -916,7 +916,7 @@ static int shrink_dcache_memory(struct shrinker *sh= rink, int nr, gfp_t gfp_mask) prune_dcache(nr); } =20 - nr_unused =3D percpu_counter_sum_positive(&nr_dentry_unused); + nr_unused =3D percpu_counter_read_positive(&nr_dentry_unused); return (nr_unused / 100) * sysctl_vfs_cache_pressure; } =20 diff --git a/fs/inode.c b/fs/inode.c index ae2727a..975a651 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -109,12 +109,12 @@ static struct kmem_cache *inode_cachep __read_mos= tly; =20 static inline int get_nr_inodes(void) { - return percpu_counter_sum_positive(&nr_inodes); + return percpu_counter_read_positive(&nr_inodes); } =20 static inline int get_nr_inodes_unused(void) { - return percpu_counter_sum_positive(&nr_inodes_unused); + return percpu_counter_read_positive(&nr_inodes_unused); } =20 int get_nr_dirty_inodes(void) -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel= " in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html